feat(GoodMusic): 添加外部录音数据支持并优化显示
- 新增recordData prop接收外部录音数据 - 实现processedRecordings计算属性处理外部数据 - 添加销售员姓名和评分显示 - 优化转录文本和录音分析功能
This commit is contained in:
@@ -18,9 +18,9 @@
|
|||||||
|
|
||||||
<!-- 录音文件列表 -->
|
<!-- 录音文件列表 -->
|
||||||
<div v-if="!showTranscriptView">
|
<div v-if="!showTranscriptView">
|
||||||
<div class="recording-list" v-if="recordings.length > 0">
|
<div class="recording-list" v-if="processedRecordings.length > 0">
|
||||||
<div
|
<div
|
||||||
v-for="(recording, index) in recordings"
|
v-for="(recording, index) in processedRecordings"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="recording-item"
|
class="recording-item"
|
||||||
:class="{ active: selectedRecording === index }"
|
:class="{ active: selectedRecording === index }"
|
||||||
@@ -29,8 +29,10 @@
|
|||||||
<div class="recording-info">
|
<div class="recording-info">
|
||||||
<div class="recording-name" :title="recording.name">{{ recording.name.length > 10 ? recording.name.substring(0, 10) + '...' : recording.name }}</div>
|
<div class="recording-name" :title="recording.name">{{ recording.name.length > 10 ? recording.name.substring(0, 10) + '...' : recording.name }}</div>
|
||||||
<div class="recording-meta">
|
<div class="recording-meta">
|
||||||
|
<span v-if="recording.sale_name" class="sale-name">{{ recording.sale_name }}</span>
|
||||||
|
<span v-if="recording.score" class="score">评分: {{ recording.score }}</span>
|
||||||
<span class="file-size">{{ formatFileSize(recording.size) }}</span>
|
<span class="file-size">{{ formatFileSize(recording.size) }}</span>
|
||||||
<span class="upload-time">{{ recording.uploadTime }}</span>
|
<span class="upload-time">{{ recording.uploadTime || recording.date }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="recording-actions">
|
<div class="recording-actions">
|
||||||
@@ -180,47 +182,16 @@ import MarkdownIt from 'markdown-it'
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'GroupRank',
|
name: 'GoodMusic',
|
||||||
|
props: {
|
||||||
|
recordData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
recordings: [
|
recordings: [ ],
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: '常家硕-张三丰-亮剑二部-20分钟通话-25-07-16_18-23-04-44196-215.mp3',
|
|
||||||
size: 2048576, // 2MB
|
|
||||||
duration: '00:03:45',
|
|
||||||
date: '2024-01-15',
|
|
||||||
url: '/recordings/sample_call_1.mp3',
|
|
||||||
transcription: null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: '常家硕-张三丰-亮剑二部-20分钟通话-25-07-16_18-23-01-439240-599.mp3',
|
|
||||||
size: 3145728, // 3MB
|
|
||||||
duration: '00:05:20',
|
|
||||||
date: '2024-01-14',
|
|
||||||
url: '/recordings/sample_call_2.mp3',
|
|
||||||
transcription: null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
name: '常家硕-张三丰-亮剑二部-20分钟通话-25-07-16_18-23-02-754615-508.mp3',
|
|
||||||
size: 2048576, // 2MB
|
|
||||||
duration: '00:03:45',
|
|
||||||
date: '2024-01-15',
|
|
||||||
url: '/recordings/sample_call_1.mp3',
|
|
||||||
transcription: null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
name: '丁传辉-丁传辉-勇士二部-20分钟通话-25-07-10_10-32-54-813815-322.mp3',
|
|
||||||
size: 3145728, // 3MB
|
|
||||||
duration: '00:05:20',
|
|
||||||
date: '2024-01-14',
|
|
||||||
url: '/recordings/sample_call_2.mp3',
|
|
||||||
transcription: null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
selectedRecording: null,
|
selectedRecording: null,
|
||||||
currentAudio: null,
|
currentAudio: null,
|
||||||
showTranscriptView: false,
|
showTranscriptView: false,
|
||||||
@@ -252,6 +223,38 @@ export default {
|
|||||||
formattedAnalysisResult() {
|
formattedAnalysisResult() {
|
||||||
if (!this.analysisResult) return ''
|
if (!this.analysisResult) return ''
|
||||||
return this.md.render(this.analysisResult)
|
return this.md.render(this.analysisResult)
|
||||||
|
},
|
||||||
|
// 处理外部传入的录音数据
|
||||||
|
processedRecordings() {
|
||||||
|
let externalRecordings = []
|
||||||
|
|
||||||
|
// 处理外部传入的数据
|
||||||
|
if (this.recordData && this.recordData.excellent_record_list) {
|
||||||
|
const recordList = this.recordData.excellent_record_list
|
||||||
|
|
||||||
|
// 遍历每个销售人员的录音
|
||||||
|
Object.keys(recordList).forEach(saleName => {
|
||||||
|
recordList[saleName].forEach((record, index) => {
|
||||||
|
externalRecordings.push({
|
||||||
|
id: `${saleName}_${index}`,
|
||||||
|
name: record.obj_file_name ? record.obj_file_name.split('/').pop() : `${record.sale_name}的录音`,
|
||||||
|
size: 2048576, // 默认大小
|
||||||
|
duration: '未知',
|
||||||
|
date: new Date().toLocaleDateString(),
|
||||||
|
url: record.obj_file_name,
|
||||||
|
transcription: record.context || null,
|
||||||
|
score: record.score,
|
||||||
|
sale_name: record.sale_name,
|
||||||
|
sop: record.sop,
|
||||||
|
isPlaying: false,
|
||||||
|
isConverting: false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 合并外部数据和本地数据
|
||||||
|
return [...externalRecordings, ...this.recordings]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
@@ -274,7 +277,13 @@ export default {
|
|||||||
isConverting: false,
|
isConverting: false,
|
||||||
transcript: null
|
transcript: null
|
||||||
}
|
}
|
||||||
this.recordings.push(recording)
|
// 如果没有外部数据,则添加到本地recordings数组
|
||||||
|
if (!this.recordData || !this.recordData.excellent_record_list) {
|
||||||
|
this.recordings.push(recording)
|
||||||
|
} else {
|
||||||
|
// 如果有外部数据,可以触发事件通知父组件或其他处理逻辑
|
||||||
|
this.$emit('file-uploaded', recording)
|
||||||
|
}
|
||||||
// 清空input以便重复选择同一文件
|
// 清空input以便重复选择同一文件
|
||||||
event.target.value = ''
|
event.target.value = ''
|
||||||
}
|
}
|
||||||
@@ -285,12 +294,12 @@ export default {
|
|||||||
},
|
},
|
||||||
// 播放/暂停录音
|
// 播放/暂停录音
|
||||||
togglePlay(index) {
|
togglePlay(index) {
|
||||||
const recording = this.recordings[index]
|
const recording = this.processedRecordings[index]
|
||||||
|
|
||||||
// 停止当前播放的音频
|
// 停止当前播放的音频
|
||||||
if (this.currentAudio) {
|
if (this.currentAudio) {
|
||||||
this.currentAudio.pause()
|
this.currentAudio.pause()
|
||||||
this.recordings.forEach(r => r.isPlaying = false)
|
this.processedRecordings.forEach(r => r.isPlaying = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!recording.isPlaying) {
|
if (!recording.isPlaying) {
|
||||||
@@ -303,48 +312,7 @@ export default {
|
|||||||
this.currentAudio = null
|
this.currentAudio = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 转换为文本
|
|
||||||
async convertToText(index) {
|
|
||||||
const recording = this.recordings[index]
|
|
||||||
this.selectedRecording = index
|
|
||||||
this.showTranscriptView = true
|
|
||||||
this.isConverting = true
|
|
||||||
this.currentTranscript = null
|
|
||||||
this.currentViewType = 'transcript'
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 模拟转换过程
|
|
||||||
await axios.post('http://192.168.3.104:8000/api/asr/sync?priority=10', {
|
|
||||||
url: recording.url
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
// 这里应该调用实际的语音转文本API
|
|
||||||
// 目前使用模拟数据
|
|
||||||
recording.transcript = `这是 ${recording.name} 的转换文本示例。在实际应用中,这里会显示真实的语音转文本结果。您可以集成百度、阿里云、腾讯云等语音识别服务来实现真正的语音转文本功能。`
|
|
||||||
this.currentTranscript = recording.transcript
|
|
||||||
|
|
||||||
// 转换完成后自动开始录音分析
|
|
||||||
this.startRecordingAnalysis(recording)
|
|
||||||
|
|
||||||
// 添加转换完成的动画效果
|
|
||||||
const resultElement = document.querySelector('.conversion-result')
|
|
||||||
if (resultElement) {
|
|
||||||
resultElement.classList.add('show-result')
|
|
||||||
setTimeout(() => {
|
|
||||||
resultElement.classList.remove('show-result')
|
|
||||||
}, 1000)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('转换失败:', error)
|
|
||||||
alert('转换失败,请重试')
|
|
||||||
this.showTranscriptView = false
|
|
||||||
} finally {
|
|
||||||
this.isConverting = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 开始通话录音分析
|
// 开始通话录音分析
|
||||||
async startRecordingAnalysis(recording) {
|
async startRecordingAnalysis(recording) {
|
||||||
this.isAnalyzing = true
|
this.isAnalyzing = true
|
||||||
@@ -361,7 +329,7 @@ export default {
|
|||||||
录音信息:
|
录音信息:
|
||||||
文件名:${recording.name}
|
文件名:${recording.name}
|
||||||
文件大小:${this.formatFileSize(recording.size)}
|
文件大小:${this.formatFileSize(recording.size)}
|
||||||
转换文本:${recording.transcript}`
|
转换文本:${recording.transcription}`
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.chatService_02.sendMessage(
|
await this.chatService_02.sendMessage(
|
||||||
@@ -436,16 +404,58 @@ export default {
|
|||||||
fileInput.click()
|
fileInput.click()
|
||||||
document.body.removeChild(fileInput)
|
document.body.removeChild(fileInput)
|
||||||
},
|
},
|
||||||
downloadRecording(index) {
|
// 转换为文字
|
||||||
const recording = this.recordings[index]
|
convertToText(index) {
|
||||||
if (recording && recording.url) {
|
const recording = this.processedRecordings[index]
|
||||||
const link = document.createElement('a')
|
if (recording.isConverting) return
|
||||||
link.href = recording.url
|
|
||||||
link.download = recording.name
|
// 如果有外部传入的transcription,直接显示
|
||||||
document.body.appendChild(link)
|
if (recording.transcription) {
|
||||||
link.click()
|
this.currentTranscript = recording.transcription
|
||||||
document.body.removeChild(link)
|
this.showTranscriptView = true
|
||||||
|
this.currentViewType = 'transcript'
|
||||||
|
|
||||||
|
// 开始录音分析
|
||||||
|
this.switchViewType('analysis')
|
||||||
|
this.startRecordingAnalysis(recording)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recording.isConverting = true
|
||||||
|
this.isConverting = true
|
||||||
|
this.showTranscriptView = true
|
||||||
|
this.currentViewType = 'transcript'
|
||||||
|
|
||||||
|
// 模拟转换过程(用于本地上传的文件)
|
||||||
|
setTimeout(() => {
|
||||||
|
const transcriptText = `这是录音 "${recording.name}" 的转录文本内容。这里会显示实际的语音转文字结果。`
|
||||||
|
recording.transcription = transcriptText
|
||||||
|
this.currentTranscript = transcriptText
|
||||||
|
recording.isConverting = false
|
||||||
|
this.isConverting = false
|
||||||
|
|
||||||
|
// 开始录音分析
|
||||||
|
this.startRecordingAnalysis(recording)
|
||||||
|
}, 2000)
|
||||||
|
},
|
||||||
|
downloadRecording(index) {
|
||||||
|
const recording = this.processedRecordings[index]
|
||||||
|
|
||||||
|
// 使用obj_file_name字段作为下载链接
|
||||||
|
const downloadUrl = recording.url
|
||||||
|
|
||||||
|
if (!downloadUrl) {
|
||||||
|
alert('录音文件不可用')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const link = document.createElement('a')
|
||||||
|
link.href = downloadUrl
|
||||||
|
link.download = recording.name
|
||||||
|
link.style.display = 'none'
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
document.body.removeChild(link)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -585,6 +595,16 @@ export default {
|
|||||||
color: #909399;
|
color: #909399;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sale-name {
|
||||||
|
color: #409eff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.score {
|
||||||
|
color: #67c23a;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
.recording-actions {
|
.recording-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
@@ -797,11 +817,13 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.transcript-text {
|
.transcript-text {
|
||||||
padding: 16px;
|
padding: 8px;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
color: #303133;
|
color: #303133;
|
||||||
background: white;
|
background: white;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
max-height: 200px;
|
||||||
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
animation: fadeIn 0.5s ease;
|
animation: fadeIn 0.5s ease;
|
||||||
}
|
}
|
||||||
@@ -819,7 +841,9 @@ export default {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
background: #fafafa;
|
background: #fafafa;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 20px;
|
padding: 8px;
|
||||||
|
max-height: 200px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.analysis-content h1,
|
.analysis-content h1,
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user