feat:完成大屏播报功能

main
@0Melon0 12 months ago
parent 3bbdb3301c
commit 81d7140c35

@ -1,46 +1,69 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>Speech Synthesis Example</title> <title>Speech Synthesis Example</title>
</head> </head>
<body> <body>
<h1>Speech Synthesis Example</h1> <h1>Speech Synthesis Example</h1>
<input type="text" id="text" value="请0的家属到手术室门口接病人"> <input type="text" id="text" value="请0的家属到手术室门口接病人" />
<br> <br />
<label for="rate">Rate:</label>
<input type="number" id="rate" value="1" step="0.1" min="0.1" max="10" />
<br />
<label for="voice">Voice:</label>
<select id="voiceSelect"></select>
<br />
<button onclick="speakText()">Speak</button> <button onclick="speakText()">Speak</button>
<script> <script>
const synth = window.speechSynthesis; const synth = window.speechSynthesis;
const voiceSelect = document.getElementById('voiceSelect');
function populateVoiceList() {
const voices = synth.getVoices();
console.log(voices);
if (voices.length === 0) {
synth.onvoiceschanged = populateVoiceList;
} else {
voiceSelect.innerHTML = ''; // 清空之前的选项
voices.forEach((voice, index) => {
const option = document.createElement('option');
option.textContent = `${voice.name} (${voice.lang})`;
console.log(`${voice.name} (${voice.lang})`);
option.value = index;
voiceSelect.appendChild(option);
});
}
}
populateVoiceList();
if (typeof synth.onvoiceschanged !== 'undefined') {
synth.onvoiceschanged = populateVoiceList;
}
function speakText() { function speakText() {
window.speechSynthesis.cancel(); // 清除之前的语音合成
setTimeout(() => {
const textInput = document.getElementById('text').value; const textInput = document.getElementById('text').value;
const utterance = new SpeechSynthesisUtterance(textInput); const rate = parseFloat(document.getElementById('rate').value);
// 固定播放速度和语音
utterance.rate = 1.0; // 播放速度
const voices = synth.getVoices();
const selectedVoice = voices.find(voice => voice.lang === 'zh-CN'); // 固定选择中文(普通话)的语音
if (selectedVoice) { const utterance = new SpeechSynthesisUtterance([textInput, textInput, textInput].join(''));
utterance.voice = selectedVoice;
} const selectedVoiceIndex = voiceSelect.selectedOptions[0].value;
const voices = synth.getVoices();
utterance.voice = voices[selectedVoiceIndex];
utterance.rate = rate;
// 添加 onend 事件处理器 utterance.onend = function (event) {
utterance.onend = function(event) {
console.log('Speech has finished.'); console.log('Speech has finished.');
alert('Speech has finished.');
}; };
window.speechSynthesis.speak(utterance); window.speechSynthesis.speak(utterance);
}, 100); // 延迟 100 毫秒
} }
// 等待语音列表加载完成
function checkVoices() {
if (synth.getVoices().length !== 0) {
clearInterval(voicesCheckInterval);
}
}
const voicesCheckInterval = setInterval(checkVoices, 100);
</script> </script>
</body> </body>
</html> </html>

@ -116,7 +116,7 @@ export default {
this.patientList[groupIndex] = [element]; this.patientList[groupIndex] = [element];
} }
} }
if (!this.carouselTimer) { if (!this.carouselTimer && res['Data']['length'] > this.showItemNum) {
this.onCarouselTimer(); this.onCarouselTimer();
} }
} else { } else {

@ -47,6 +47,13 @@
</el-carousel> </el-carousel>
</template> </template>
</div> </div>
<div class="popupBox" v-if="showPopup">
<div>
<p v-for="(item, index) in popupMag" :key="index">
{{ item }}
</p>
</div>
</div>
</div> </div>
<div class="absolute bottom-2 left-1/2 -translate-x-1/2 flex"> <div class="absolute bottom-2 left-1/2 -translate-x-1/2 flex">
@ -68,7 +75,7 @@
<script> <script>
import { getAnesPatientList } from '@/api/waitList'; import { getAnesPatientList } from '@/api/waitList';
import { Carousel, CarouselItem, Notification } from 'element-ui'; import { Carousel, CarouselItem } from 'element-ui';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { statusToTxt, textWaitToColor } from '@/utils/common'; import { statusToTxt, textWaitToColor } from '@/utils/common';
import Stomp from 'stompjs'; import Stomp from 'stompjs';
@ -90,7 +97,11 @@ export default {
carouselTimer: null, carouselTimer: null,
activeIndex: 0, activeIndex: 0,
getDataTimer: null, getDataTimer: null,
popupMsg: '', popupMsgList: [],
showPopup: false,
hasPlay: false,
popupMag: [],
popupTimer: null,
synth: window.speechSynthesis, synth: window.speechSynthesis,
}; };
}, },
@ -113,7 +124,7 @@ export default {
this.patientList[groupIndex] = [element]; this.patientList[groupIndex] = [element];
} }
} }
if (!this.carouselTimer) { if (!this.carouselTimer && res['Data']['length'] > this.showItemNum) {
this.onCarouselTimer(); this.onCarouselTimer();
} }
} else { } else {
@ -172,7 +183,7 @@ export default {
try { try {
if (frame.body) { if (frame.body) {
let data = JSON.parse(frame.body); let data = JSON.parse(frame.body);
this.popupMsg = data['msg']; this.popupMsgList.push(data['msg'].replaceAll('', ','));
} }
} catch (e) { } catch (e) {
console.log(e); console.log(e);
@ -186,56 +197,29 @@ export default {
this.connect(); this.connect();
}, 5000); }, 5000);
}, },
}, onPopupPlay() {
mounted() { if (!this.hasPlay && this.popupMsgList.length) {
this.$nextTick(() => { this.hasPlay = true;
this.onCalculate(); this.popupMag = this.popupMsgList[0].replace(/[,]/g, '').split('#');
this.showPopup = true;
//
this.dateTimer = setInterval(() => {
this.currentDateTime = dayjs().format('YYYY-MM-DD HH:mm dddd');
}, 10000);
this.onGetPageData();
this.getDataTimer = setInterval(() => {
this.onGetPageData();
}, 35000);
window.addEventListener('resize', this.onCalculate);
this.setRabitMQ();
// setTimeout(() => {
// this.popupMsg = `0`;
// }, 1000);
});
},
components: {
'el-carousel': Carousel,
'el-carousel-item': CarouselItem,
},
watch: {
popupMsg(newVal) {
if (newVal) {
const h = this.$createElement;
Notification({
title: '呼叫信息',
message: h('i', { style: 'color: teal;font-size:24px' }, newVal),
duration: 12000,
});
if (this.synth) { if (this.synth) {
console.log(this.synth); const utterance = new SpeechSynthesisUtterance([this.popupMsgList[0]].join(''));
const utterance = new SpeechSynthesisUtterance([newVal, newVal, newVal].join('')); utterance.rate = 0.4;
utterance.rate = 0.6;
const voices = this.synth.getVoices(); const voices = this.synth.getVoices();
const selectedVoice = voices.find(voice => voice.lang === 'zh-CN'); const selectedVoice = voices.find(voice => voice.lang === 'zh-TW');
if (selectedVoice) { if (selectedVoice) {
utterance.voice = selectedVoice; utterance.voice = selectedVoice;
} else {
console.log('voices not fount');
} }
// onend // onend
utterance.onend = function () { utterance.onend = function () {
this.popupMsg = ''; this.popupMag = [];
// Notification.colseAll(); this.showPopup = false;
console.log('Speech has finished.'); this.hasPlay = false;
}; this.popupMsgList.shift();
}.bind(this);
this.synth.speak(utterance); this.synth.speak(utterance);
@ -251,6 +235,34 @@ export default {
} }
}, },
}, },
mounted() {
this.$nextTick(() => {
this.onCalculate();
//
this.dateTimer = setInterval(() => {
this.currentDateTime = dayjs().format('YYYY-MM-DD HH:mm dddd');
}, 10000);
this.onGetPageData();
this.getDataTimer = setInterval(() => {
this.onGetPageData();
}, 35000);
this.popupTimer = setInterval(() => {
this.onPopupPlay();
}, 2000);
window.addEventListener('resize', this.onCalculate);
this.setRabitMQ();
// setTimeout(() => {
// this.popupMsgList.push(',,#,');
// }, 3000);
});
},
components: {
'el-carousel': Carousel,
'el-carousel-item': CarouselItem,
},
computed: { computed: {
formatDate() { formatDate() {
const timeArr = this.currentDateTime.split(' '); const timeArr = this.currentDateTime.split(' ');
@ -284,6 +296,7 @@ export default {
clearInterval(this.dateTimer); clearInterval(this.dateTimer);
clearInterval(this.carouselTimer); clearInterval(this.carouselTimer);
clearInterval(this.getDataTimer); clearInterval(this.getDataTimer);
clearInterval(this.popupTimer);
// resize // resize
window.removeEventListener('resize', this.onCalculate); window.removeEventListener('resize', this.onCalculate);
}, },
@ -306,4 +319,28 @@ export default {
} }
} }
} }
.popupBox {
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
z-index: 9999;
div {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0px 3px 14px 0px rgba(0, 0, 0, 0.2);
font-size: 9vh;
white-space: nowrap;
padding: 3vh;
backdrop-filter: blur(2px);
background: #ece5ffe6;
p {
color: #333;
text-align: center;
}
}
}
</style> </style>

Loading…
Cancel
Save