语音训练调整
This commit is contained in:
parent
aa2648231f
commit
f9d2d8a0ac
@ -162,3 +162,19 @@ export function getPayQrCode(mapId, monthAmount) {
|
||||
method: 'post'
|
||||
});
|
||||
}
|
||||
/** 场景语音训练上传录音文件 */
|
||||
export function uploadAudioFilesInSence(competitionId, actionId, file) {
|
||||
return request({
|
||||
url: `/api/v1/competitionPractical/voice/record/${competitionId}/${actionId}`,
|
||||
method: 'post',
|
||||
data: file
|
||||
});
|
||||
}
|
||||
/** 场景语音训练更新录音文件 */
|
||||
export function updateAuidoFilesInSence( recordId, file) {
|
||||
return request({
|
||||
url: `/api/v1/competitionPractical/voice/record/${recordId}`,
|
||||
method: 'put',
|
||||
data: file
|
||||
});
|
||||
}
|
||||
|
@ -8,3 +8,4 @@ export function uploadAudioFiles(file) {
|
||||
data: file
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -169,6 +169,7 @@ const MapGroup = () => import('@/views/publish/mapGroup/index');
|
||||
const DemoTraining = () => import('@/views/newMap/displayNew/demoTraining');
|
||||
const OrgDetail = () => import('@/views/system/companyManage/orgDetail');
|
||||
const VoiceTraining = () => import('@/views/system/voiceTraining/index');
|
||||
const SceneVoiceTraining = () => import('@/views/drts/scene/voiceTraining');
|
||||
|
||||
// import { GenerateRouteProjectList } from '@/scripts/ProjectConfig';
|
||||
// import { getSessionStorage } from '@/utils/auth';
|
||||
@ -1259,6 +1260,11 @@ export const asyncRouter = [
|
||||
path: 'questionUpdate/:questionId',
|
||||
component: QuestionUpdatePage,
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'voiceTraining',
|
||||
component: SceneVoiceTraining,
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ export default {
|
||||
{
|
||||
type: 'button',
|
||||
title: '操 作',
|
||||
width: '420',
|
||||
width: '480',
|
||||
buttons: [
|
||||
{
|
||||
name: '更 新',
|
||||
@ -91,6 +91,11 @@ export default {
|
||||
name: '导 出',
|
||||
handleClick: this.doExport,
|
||||
type: 'primary'
|
||||
},
|
||||
{
|
||||
name: '语音训练',
|
||||
handleClick: this.voiceTraining,
|
||||
type: 'primary'
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -141,6 +146,9 @@ export default {
|
||||
doModify(index, row) {
|
||||
this.$refs.modifyStep.doShow(row);
|
||||
},
|
||||
voiceTraining(index, row) {
|
||||
this.$router.push({ path: '/design/race/voiceTraining', query: { scriptId: row.scriptId, sceneId: row.id} });
|
||||
},
|
||||
doExport(index, row) {
|
||||
getSceneExport(row.id).then(res=>{
|
||||
const resultData = res.data;
|
||||
|
413
src/views/drts/scene/voiceTraining.vue
Normal file
413
src/views/drts/scene/voiceTraining.vue
Normal file
@ -0,0 +1,413 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="text-align: center;margin: 20px;font-size: 26px;">场景语音训练</div>
|
||||
<el-table :data="actionList" border style="width:1320px;margin: 0 auto;" :span-method="objectSpanMethod">
|
||||
<el-table-column label="步骤名称" width="100">
|
||||
<template slot-scope="scope">
|
||||
<div v-if="stepVOs[scope.row.id]">
|
||||
{{ stepVOs[scope.row.id].description||'' }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="动作id" width="70" prop="id" />
|
||||
<el-table-column label="动作内容" width="350">
|
||||
<template slot-scope="scope">
|
||||
<!-- v-model="scope.row.id" -->
|
||||
<el-checkbox v-if="isModify" v-model="checkBoxActionList[scope.row.id].status" :disabled="checkBoxActionList[scope.row.id].disabled" class="checkBoxAction" @change="((val)=>{changeSelectActionId(val, scope.row.id, scope.$index)})" />
|
||||
<el-radio v-if="isOperate" v-model="radioBoxAction" :label="scope.row.id" name="operateAction" class="checkBoxAction" @change="((val)=>{changeSelectRadioActionId(val, scope.row.id, scope.$index)})">{{ '' }}</el-radio>
|
||||
<div>{{ covert(scope.row) }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="语音识别关键词列表" width="350">
|
||||
<template v-if="scope.row.type=='Conversation'&&scope.row.memberId=='1'" slot-scope="scope">
|
||||
<div v-if="commandEvaluationRuleVOs[scope.row.id]&&commandEvaluationRuleVOs[scope.row.id].keyWords">
|
||||
<el-tag v-for="(tag,index) in commandEvaluationRuleVOs[scope.row.id].keyWords" :key="index" :disable-transitions="false">{{ tag }}</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="录音">
|
||||
<template slot-scope="scope">
|
||||
<el-button class="chat-box-footer-create chat-box-footer-send" :class="{'active': recordSending}" size="mini" type="primary" @click="startRecording(scope.row)">
|
||||
<el-progress class="record_progress_bar" type="circle" :show-text="false" :percentage="100/60*seconds" :width="40" :stroke-width="2" status="success" />
|
||||
<i v-if="recordSending" class="el-icon-close close_icon" @click.stop="cancleRecording()" />
|
||||
<span class="iconfont icon-yuyin"></span>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getScriptByIdNew} from '@/api/script';
|
||||
import { getCompetitionPracticalSceneById } from '@/api/competition';
|
||||
import { loadMapDataById } from '@/utils/loaddata';
|
||||
import ConstConfig from '@/scripts/ConstConfig';
|
||||
import Cookies from 'js-cookie';
|
||||
import {covertOperate} from '@/views/newMap/displayNew/scriptDisplay/component/covertOperation';
|
||||
import RecordRTC from 'recordrtc';
|
||||
import { uploadAudioFilesInSence, updateAuidoFilesInSence } from '@/api/competition';
|
||||
export default {
|
||||
name: 'VoiceTraining',
|
||||
data() {
|
||||
return {
|
||||
actionList:[],
|
||||
startArray: [],
|
||||
endArray: [],
|
||||
jsonData: '',
|
||||
stepVOs: {},
|
||||
memberList: [],
|
||||
isModify:false,
|
||||
isOperate:false,
|
||||
commandEvaluationRuleVOs:{},
|
||||
seconds: 0,
|
||||
recordSending: false,
|
||||
recorders: null,
|
||||
microphone:null
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
'$store.state.map.mapDataLoadedCount': function (val) {
|
||||
this.parseMember();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initFunction();
|
||||
},
|
||||
methods: {
|
||||
initFunction() {
|
||||
getScriptByIdNew(this.$route.query.scriptId).then(res=>{
|
||||
const dispatcher = res.data.memberList.find(member => member.type === 'DISPATCHER');
|
||||
this.actionList = res.data.actionList.filter(action=>{
|
||||
return action.type == 'Conversation' && action.memberId == dispatcher.id;
|
||||
});
|
||||
this.jsonData = res;
|
||||
getCompetitionPracticalSceneById(this.$route.query.sceneId).then(response=>{
|
||||
const commandEvaluationRuleVOs = {};
|
||||
if (response.data.commandEvaluationRuleVOs) {
|
||||
response.data.commandEvaluationRuleVOs.forEach(data=>{
|
||||
commandEvaluationRuleVOs[data.actionId] = data;
|
||||
});
|
||||
}
|
||||
const stepVOs = {};
|
||||
if (response.data.stepVOs) {
|
||||
response.data.stepVOs.forEach(data=>{
|
||||
stepVOs[data.startActionId] = data;
|
||||
const dataIndex = this.actionList.findIndex((value, index, arr)=>{ return value.id == data.startActionId; });
|
||||
const dataIndex1 = this.actionList.findIndex((value, index, arr)=>{ return value.id == data.endActionId; });
|
||||
this.startArray.push(dataIndex);
|
||||
this.endArray.push(dataIndex1);
|
||||
});
|
||||
}
|
||||
this.commandEvaluationRuleVOs = commandEvaluationRuleVOs;
|
||||
this.stepVOs = stepVOs;
|
||||
});
|
||||
// 加载地图数据
|
||||
loadMapDataById(res.data.mapId, 'parse');
|
||||
});
|
||||
},
|
||||
parseMember() {
|
||||
const stationMap = {};
|
||||
const stationList = this.$store.state.map.map.stationList;
|
||||
stationList.forEach(station=>{
|
||||
stationMap[station.code] = station;
|
||||
});
|
||||
let lastData = JSON.stringify(this.jsonData.data.memberList);
|
||||
const roleTypeList = ConstConfig.ConstSelect.roleTypeNew;
|
||||
roleTypeList.forEach(function(element) {
|
||||
const rolename = element.value;
|
||||
if (Cookies.get('user_lang') == 'en') {
|
||||
lastData = lastData.replace(new RegExp(rolename, 'g'), element.enLabel);
|
||||
} else {
|
||||
lastData = lastData.replace(new RegExp(rolename, 'g'), element.label);
|
||||
}
|
||||
});
|
||||
lastData = JSON.parse(lastData);
|
||||
const lastMemberList = {};
|
||||
lastData.forEach((member, index)=>{
|
||||
const userName = member.userName ? '-' + member.userName : '';
|
||||
const name = member.name ? '-' + member.name : '';
|
||||
if (member.deviceCode && member.type == '行值') {
|
||||
const device = stationMap[member.deviceCode];
|
||||
member.deviceName = device.name;
|
||||
member.label = member.type + member.deviceName + name + userName;
|
||||
member.normalName = member.type + member.deviceName + name;
|
||||
} else if (member.deviceCode && member.type == '司机') {
|
||||
member.deviceName = member.deviceCode;
|
||||
member.label = member.type + member.deviceName + name + userName;
|
||||
} else {
|
||||
member.deviceName = '';
|
||||
member.label = member.type + name + userName;
|
||||
member.normalName = member.type + name;
|
||||
}
|
||||
lastMemberList[member.id] = member;
|
||||
this.memberList = lastMemberList;
|
||||
});
|
||||
this.loading = false;
|
||||
},
|
||||
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
|
||||
if (this.startArray.length > 0) {
|
||||
if (columnIndex === 0) {
|
||||
let rowspan = 1;
|
||||
let colspan = 1;
|
||||
for (var i = 0; i < this.startArray.length; i++) {
|
||||
if (rowIndex == this.startArray[i]) {
|
||||
rowspan = this.endArray[i] - this.startArray[i] + 1;
|
||||
colspan = 1;
|
||||
} else if (rowIndex > this.startArray[i] && rowIndex <= this.endArray[i]) {
|
||||
rowspan = 0;
|
||||
colspan = 0;
|
||||
}
|
||||
}
|
||||
return {
|
||||
rowspan:rowspan,
|
||||
colspan:colspan
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
covert(element) {
|
||||
const member = this.memberList[element.memberId] || {};
|
||||
let resultData = '';
|
||||
if (element.type == 'Accept_Conversation_Invitation') {
|
||||
resultData = member.label + '请接受会话邀请';
|
||||
} else if (element.type == 'Conversation') {
|
||||
resultData = member.label + '说:' + element.content;
|
||||
} else if (element.type == 'Operation') {
|
||||
resultData = covertOperate(element.operationType, element.operationParamMap);
|
||||
resultData = resultData.replace('请', member.label);
|
||||
// this.scriptTipMessage = '请找到' + deviceName + ',执行【' + operateName.label + '】操作';
|
||||
} else if (element.type == 'Exit_Conversation') {
|
||||
resultData = member.label + '结束当前会话';
|
||||
} else if (element.type == 'Start_Conversation' ) {
|
||||
const inviteMember = [];
|
||||
// this.$emit('allowCreatCoversition');
|
||||
if (element.communicationObject) {
|
||||
if (element.communicationObject == 'ALL_STATION') {
|
||||
inviteMember.push('所有车站');
|
||||
} else if (element.communicationObject == 'ALL_TRAIN') {
|
||||
inviteMember.push('所有司机');
|
||||
}
|
||||
} else {
|
||||
element.conversationMemberIds.forEach(id=>{
|
||||
if (element.memberId != id) {
|
||||
inviteMember.push((this.memberList[id] || {label: ''}).label);
|
||||
}
|
||||
});
|
||||
}
|
||||
resultData = member.label + '创建会话,选择' + inviteMember.toString();
|
||||
} else if (element.type == 'Command') {
|
||||
const targetName = this.memberList[element.commandInitiateVO.targetMemberId];
|
||||
const CommandList = {
|
||||
Drive_Ahead:'确认运行至前方站',
|
||||
Route_Block_Drive:'进路闭塞法行车',
|
||||
Drive_Through_The_Guide_Signal:'越引导信号行驶',
|
||||
Drive_Through_The_Red_Light:'越红灯行驶',
|
||||
Drive_In_Urm_Mode:'URM模式驾驶',
|
||||
Set_Speed_Limit:'设置限速',
|
||||
Open_Or_Close_Door:'开关门',
|
||||
Switch_Hook_Lock: '道岔钩锁'
|
||||
};
|
||||
resultData = member.label + '对【' + targetName.label + '】下达【' + CommandList[element.commandInitiateVO.commandType] + '】指令';
|
||||
} else if (element.type == 'Drive') {
|
||||
if (element.targetSectionCode) {
|
||||
const section = this.$store.getters['map/getDeviceByCode'](element.targetSectionCode);
|
||||
if (section && section.name) {
|
||||
resultData = member.label + '把车开到区段' + section.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return resultData;
|
||||
},
|
||||
cancleRecording() {
|
||||
if (this.microphone) {
|
||||
clearInterval(this.inter);
|
||||
this.seconds = 0;
|
||||
this.microphone.stop();
|
||||
this.microphone = null;
|
||||
this.recordSending = false;
|
||||
this.recorders = null;
|
||||
}
|
||||
},
|
||||
// 停止录制 发送语音
|
||||
stopRecording(actionId) {
|
||||
this.audioPlay = true;
|
||||
const that = this;
|
||||
this.recorders.stopRecording(function(blobURL) {
|
||||
clearInterval(that.inter);
|
||||
that.seconds = 0;
|
||||
const blob = that.recorders.getBlob();
|
||||
const fd = new FormData();
|
||||
fd.append('file', blob);
|
||||
uploadAudioFilesInSence(this.$route.query.sceneId, actionId, fd)
|
||||
.then((resp) => {
|
||||
that.audioPlay = false;
|
||||
resp.data.command = '';
|
||||
that.messageList.push(resp.data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
that.$message.error('语音发送失败: ' + error.message);
|
||||
that.audioPlay = false;
|
||||
});
|
||||
if (that.microphone) {
|
||||
that.microphone.stop();
|
||||
that.microphone = null;
|
||||
that.recordSending = false;
|
||||
that.recorders = null;
|
||||
}
|
||||
});
|
||||
},
|
||||
getUrl(el) {
|
||||
return `https://oss.joylink.club/oss/joylink${el.filePath}`;
|
||||
},
|
||||
covertTime(time) {
|
||||
const date = new Date(time);
|
||||
let hour = date.getHours();
|
||||
let minute = date.getMinutes();
|
||||
let second = date.getSeconds();
|
||||
hour = hour > 9 ? hour : '0' + hour;
|
||||
minute = minute > 9 ? minute : '0' + minute;
|
||||
second = second > 9 ? second : '0' + second;
|
||||
return hour + ':' + minute + ':' + second;
|
||||
},
|
||||
startRecording(row) {
|
||||
this.audioPlay = true;
|
||||
const that = this;
|
||||
if (!this.recordSending) {
|
||||
if (!this.recordSending && !this.recorders && !this.microphone) {
|
||||
const StereoAudioRecorder = RecordRTC.StereoAudioRecorder;
|
||||
navigator.getUserMedia({ audio: true }, function (stream) {
|
||||
that.microphone = stream;
|
||||
that.recorders = new RecordRTC(that.microphone, {
|
||||
type: 'audio',
|
||||
recorderType: StereoAudioRecorder,
|
||||
numberOfAudioChannels: 1,
|
||||
bitsPerSecond:256000,
|
||||
desiredSampRate: 16000
|
||||
});
|
||||
that.recorders.startRecording();
|
||||
that.recordSending = true;
|
||||
that.audioPlay = false;
|
||||
that.inter = setInterval(() => {
|
||||
if (that.seconds < 60) {
|
||||
that.seconds++;
|
||||
} else {
|
||||
clearInterval(that.inter);
|
||||
that.stopRecording(row.id);
|
||||
}
|
||||
}, 1000);
|
||||
}, function (error) {
|
||||
switch (error.code || error.name) {
|
||||
case 'PERMISSION_DENIED':
|
||||
case 'PermissionDeniedError':
|
||||
that.$message({
|
||||
showClose: true,
|
||||
message: '用户拒绝提供信息',
|
||||
type: 'error'
|
||||
});
|
||||
break;
|
||||
case 'NOT_SUPPORTED_ERROR':
|
||||
case 'NotSupportedError':
|
||||
that.$message({
|
||||
showClose: true,
|
||||
message: '浏览器不支持硬件设备',
|
||||
type: 'error'
|
||||
});
|
||||
break;
|
||||
case 'MANDATORY_UNSATISFIED_ERROR':
|
||||
case 'MandatoryUnsatisfiedError':
|
||||
that.$message({
|
||||
showClose: true,
|
||||
message: '无法发现指定的硬件设备',
|
||||
type: 'error'
|
||||
});
|
||||
break;
|
||||
default:
|
||||
that.$message({
|
||||
showClose: true,
|
||||
message: '无法打开麦克风',
|
||||
type: 'error'
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.stopRecording(row.id); // 发送语音
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.record_progress_bar{
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.userHeader{margin-bottom: 2px;}
|
||||
.userChatTime{font-size: 12px;display:inline-block;}
|
||||
.chatContentInClass{
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
border: 1px solid #f1f1f1;
|
||||
}
|
||||
.leftUser{
|
||||
float: left;
|
||||
margin-left: 10px;
|
||||
margin-top: 10px;
|
||||
display: inline-block;
|
||||
}
|
||||
.chat-box-footer-create{
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
left: 5px;
|
||||
top: 6px;
|
||||
line-height: 30px;
|
||||
cursor: pointer;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background: green;
|
||||
border: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.chat-box-footer-send{
|
||||
background: #F2F2F2;
|
||||
right: 55px;
|
||||
cursor: pointer;
|
||||
.icon-yuyin{
|
||||
color: #333;
|
||||
font-size: 24px;
|
||||
margin: 0;
|
||||
}
|
||||
&.active{
|
||||
.icon-yuyin{
|
||||
color: green;
|
||||
}
|
||||
}
|
||||
.close_icon{
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 45px;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
padding: 3px;
|
||||
}
|
||||
}
|
||||
.deleteRecord{}
|
||||
/deep/.el-table .cell{
|
||||
min-height: 50px;
|
||||
}
|
||||
</style>
|
@ -239,7 +239,7 @@ export const operateEnum = {
|
||||
export function covertOperate(operationType, operationParamMap) {
|
||||
if (operationType == 'Set_Fault' || operationType == 'Cancel_Fault') {
|
||||
let deviceName = '';
|
||||
const device = store.getters['map/getDeviceByCode'](operationParamMap.code);
|
||||
const device = store.getters['map/getDeviceByCode'](operationParamMap.code) || {};
|
||||
if (device._type == 'StationStand' || device._type == 'Signal' || device._type == 'Switch') {
|
||||
const station = store.getters['map/getDeviceByCode'](device.stationCode);
|
||||
deviceName += '【车站-' + station.name + '】 / ' + deviceType[device._type] + device.name;
|
||||
@ -256,7 +256,7 @@ export function covertOperate(operationType, operationParamMap) {
|
||||
} else {
|
||||
tip += '取消故障,';
|
||||
}
|
||||
const data = deviceFaultType[device._type];
|
||||
const data = deviceFaultType[device._type] || [];
|
||||
data.forEach(each=>{
|
||||
if (each.value == operationParamMap.faultType) {
|
||||
tip += '参数为:' + each.label;
|
||||
@ -314,7 +314,7 @@ export function covertOperate(operationType, operationParamMap) {
|
||||
|
||||
function covertDeviceName(deviceInfo, deviceType) {
|
||||
let deviceName = '';
|
||||
const device = store.getters['map/getDeviceByCode'](deviceInfo);
|
||||
const device = store.getters['map/getDeviceByCode'](deviceInfo) || {};
|
||||
if (device._type == 'StationStand' || device._type == 'Signal' || device._type == 'Switch') {
|
||||
const station = store.getters['map/getDeviceByCode'](device.stationCode);
|
||||
deviceName += '车站-' + station.name + ' / ';
|
||||
@ -347,7 +347,7 @@ function covertOperation(deviceType, operationParamMap, operationType) {
|
||||
deviceName += covertDeviceName(deviceInfo, deviceType);
|
||||
} else {
|
||||
const deviceCode = operationParamMap[operateEnum[deviceType][operationType].code];
|
||||
const device = store.getters['map/routeList'].find(route=>{ return route.code == deviceCode; });
|
||||
const device = store.getters['map/routeList'].find(route=>{ return route.code == deviceCode; }) || {};
|
||||
deviceName += covertDeviceName(device.startSignalCode, deviceType);
|
||||
}
|
||||
// if (deviceInfo instanceof Array) {
|
||||
@ -446,11 +446,11 @@ function getRouteNameById(routeId) {
|
||||
}
|
||||
|
||||
function getStationNameById(stationId) {
|
||||
const station = store.getters['map/getDeviceByCode'](stationId);
|
||||
const station = store.getters['map/getDeviceByCode'](stationId) || {};
|
||||
return station.name;
|
||||
}
|
||||
function getStationResultById(stationResult) {
|
||||
const station = store.getters['map/getDeviceByCode'](stationResult.stationCode);
|
||||
const station = store.getters['map/getDeviceByCode'](stationResult.stationCode) || {};
|
||||
let param = '不同意';
|
||||
if (stationResult.agree) { param = '同意'; }
|
||||
return station.name + ' ' + param;
|
||||
|
Loading…
Reference in New Issue
Block a user