APP:
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { speak } from './utils/tts'
import { timeoutFunc } from './utils/timeJob'
const tbody1 = ref()
const tbody2 = ref()
const tbody3 = ref()
const tableData: any = ref({
NotConfigList: [],
NotProofreadList: [],
NotAuditList: [],
PersonSummaryList: []
})
const url = 'http://10.146.241.17:7008/api/TaskApi/FindNotFinishMessage'
// const url = 'http://10.146.37.40:7001/tts'
const timeList = [
'8:30:00',
'10:30:00',
'12:30:00',
'14:30:00',
'16:30:00',
]
// 请求数据
const getData = async () => {
const res = await fetch(url, {
method: 'GET'
})
const data: any = await res.json()
tableData.value = data.Data
console.log(tableData.value)
}
// 自动滚动
const autoScroll = (dom: any) => {
setInterval(() => {
dom.scrollTop += 2
// 判断是否滚动到底部,如果到底部了置为0(可视高度+距离顶部=整个高度)
if (dom.clientHeight + dom.scrollTop >= dom.scrollHeight) {
dom.scrollTop = 0
}
}, 100)
}
// 轮询请求
getData()
const getDataByTime = () => {
setInterval(() => {
getData()
}, 60 * 1 * 1000)
}
const speakList = (list: any) => {
if (list && list.length > 0) {
const text = list.reduce((acc: any, cur: any) => {
return acc + cur.SummaryText
}, '')
speak({ text }, null, null)
}
}
// 叫号
const callSpeak = () => {
timeList.map((time: string) => {
timeoutFunc({
interval: 1,
runNow: false,
time
}, () => {
speakList(tableData.value['PersonSummaryList'])
})
})
}
onMounted(() => {
getDataByTime()
autoScroll(tbody1.value.$refs.bodyWrapper.firstElementChild.firstElementChild)
autoScroll(tbody2.value.$refs.bodyWrapper.firstElementChild.firstElementChild)
autoScroll(tbody3.value.$refs.bodyWrapper.firstElementChild.firstElementChild)
callSpeak()
})
</script>
<template>
<div class="container">
<div class="orderTable">
<div class="order">
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAZCAYAAADqrKTxAAAAAXNSR0IArs4c6QAAAoNJREFUOE+V1M9LFVEUB/Bz7h1HLB9Rzn1QQiiUbd7OFj5IsH20CBR34aIigqBFexf1H0TLdtGiVUTZ7kFi5EIXkqklJWVhklr6dO4998eJmdd7iWS+Zj2fOefce76DzICIwPAfDzKPCpj4dBjOPagiNIdraGrhGGzvtEHlyRcchXBQUWQGUR0f7IipqgA4itcLszj02P8L5gjGBzuIqkoEp8BYjI5vTeDZKbsfxK9Pew8V4pPtsdRJHJzyREXpjYf1lec4sqT/BpErvYmFwqkWLmyB04l3WiHpIljygu1DHHpb3QuRKwOJD64MPjoiMVoGa5KQIW8UkPFCm3s4svRjN8wr+dBeRnKl4FCi4HdoKQFrFDithCUP2+ldvP5ttQ5zBKG9HMiV2HJPsJ6khBmwaZKhHBIFCHQbr6wvZ7DWHnIZ0wz5nmB8N3vejCRNZzOi1UUgo9BrBqev4g2z2GiPKZSY3Bkg18UUOsH5tag1nUJKFbhsvlShNQhghhvtOQolzCvZbja+MxhWkdQVKVILLgOpAkvZB17h1vN+1dYq+jCrlCPXzeROIPhpieka5nOZHLG185iml3cdxG9EtgsCv5FI34XTirOZcqTnwPy8hTfBNO4JCUve+B4EWBRgN2r3pFUGg6V5YVfu4DXIV+vPQehQYhArgn0Vs8Hr9+TtAsQf7+MQNJa41h4U+pwVFIE0ntJiHbGj93J4/tHekObtEcRJ7NsEhB1VRyKYD3hp5sU+CzsQVaU6muVJWFtEr5UM9jNenHy9bzT25ikis4oXXs4dEMJRAeOzeQhjCZt4fizfr6aSC7jjsP/ZxkGgduTZj2VxsgVPj5lmQI6afXH3e78A2Fu7vD8LKwAAAAAASUVORK5CYII="
alt="" style="margin: 0 10px;">
<div style="color: #fff;font-size: 18px;font-weight: bolder;">未配置订单</div>
</div>
<div class="line">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</div>
<el-table ref="tbody1" :header-cell-style="{ color: 'rgb(34, 172, 228)' }" :data="tableData.NotConfigList"
style="width: 100%" max-height="250">
<el-table-column prop="OrderId" label="工单编号" width="400" />
<el-table-column prop="ProductId" label="产品编号" width="400" />
<el-table-column prop="ProductName" label="产品名称" width="500" />
<el-table-column prop="UserName" label="用户名" width="300" />
<el-table-column prop="ProductNum" label="产品数量" />
</el-table>
</div>
<div class="orderTable">
<div class="order">
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAZCAYAAADqrKTxAAAAAXNSR0IArs4c6QAAAoNJREFUOE+V1M9LFVEUB/Bz7h1HLB9Rzn1QQiiUbd7OFj5IsH20CBR34aIigqBFexf1H0TLdtGiVUTZ7kFi5EIXkqklJWVhklr6dO4998eJmdd7iWS+Zj2fOefce76DzICIwPAfDzKPCpj4dBjOPagiNIdraGrhGGzvtEHlyRcchXBQUWQGUR0f7IipqgA4itcLszj02P8L5gjGBzuIqkoEp8BYjI5vTeDZKbsfxK9Pew8V4pPtsdRJHJzyREXpjYf1lec4sqT/BpErvYmFwqkWLmyB04l3WiHpIljygu1DHHpb3QuRKwOJD64MPjoiMVoGa5KQIW8UkPFCm3s4svRjN8wr+dBeRnKl4FCi4HdoKQFrFDithCUP2+ldvP5ttQ5zBKG9HMiV2HJPsJ6khBmwaZKhHBIFCHQbr6wvZ7DWHnIZ0wz5nmB8N3vejCRNZzOi1UUgo9BrBqev4g2z2GiPKZSY3Bkg18UUOsH5tag1nUJKFbhsvlShNQhghhvtOQolzCvZbja+MxhWkdQVKVILLgOpAkvZB17h1vN+1dYq+jCrlCPXzeROIPhpieka5nOZHLG185iml3cdxG9EtgsCv5FI34XTirOZcqTnwPy8hTfBNO4JCUve+B4EWBRgN2r3pFUGg6V5YVfu4DXIV+vPQehQYhArgn0Vs8Hr9+TtAsQf7+MQNJa41h4U+pwVFIE0ntJiHbGj93J4/tHekObtEcRJ7NsEhB1VRyKYD3hp5sU+CzsQVaU6muVJWFtEr5UM9jNenHy9bzT25ikis4oXXs4dEMJRAeOzeQhjCZt4fizfr6aSC7jjsP/ZxkGgduTZj2VxsgVPj5lmQI6afXH3e78A2Fu7vD8LKwAAAAAASUVORK5CYII="
alt="" style="margin: 0 10px;">
<div style="color: #fff;font-size: 18px;font-weight: bolder;">未校对订单</div>
</div>
<div class="line">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</div>
<el-table ref="tbody2" :header-cell-style="{ color: 'rgb(34, 172, 228)' }" :data="tableData.NotProofreadList"
style="width: 100%" max-height="250">
<el-table-column prop="OrderId" label="工单编号" width="400" />
<el-table-column prop="ProductId" label="产品编号" width="400" />
<el-table-column prop="ProductName" label="产品名称" width="500" />
<el-table-column prop="UserName" label="用户名" width="300" />
<el-table-column prop="ProductNum" label="产品数量" />
</el-table>
</div>
<div class="orderTable">
<div class="order">
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAZCAYAAADqrKTxAAAAAXNSR0IArs4c6QAAAoNJREFUOE+V1M9LFVEUB/Bz7h1HLB9Rzn1QQiiUbd7OFj5IsH20CBR34aIigqBFexf1H0TLdtGiVUTZ7kFi5EIXkqklJWVhklr6dO4998eJmdd7iWS+Zj2fOefce76DzICIwPAfDzKPCpj4dBjOPagiNIdraGrhGGzvtEHlyRcchXBQUWQGUR0f7IipqgA4itcLszj02P8L5gjGBzuIqkoEp8BYjI5vTeDZKbsfxK9Pew8V4pPtsdRJHJzyREXpjYf1lec4sqT/BpErvYmFwqkWLmyB04l3WiHpIljygu1DHHpb3QuRKwOJD64MPjoiMVoGa5KQIW8UkPFCm3s4svRjN8wr+dBeRnKl4FCi4HdoKQFrFDithCUP2+ldvP5ttQ5zBKG9HMiV2HJPsJ6khBmwaZKhHBIFCHQbr6wvZ7DWHnIZ0wz5nmB8N3vejCRNZzOi1UUgo9BrBqev4g2z2GiPKZSY3Bkg18UUOsH5tag1nUJKFbhsvlShNQhghhvtOQolzCvZbja+MxhWkdQVKVILLgOpAkvZB17h1vN+1dYq+jCrlCPXzeROIPhpieka5nOZHLG185iml3cdxG9EtgsCv5FI34XTirOZcqTnwPy8hTfBNO4JCUve+B4EWBRgN2r3pFUGg6V5YVfu4DXIV+vPQehQYhArgn0Vs8Hr9+TtAsQf7+MQNJa41h4U+pwVFIE0ntJiHbGj93J4/tHekObtEcRJ7NsEhB1VRyKYD3hp5sU+CzsQVaU6muVJWFtEr5UM9jNenHy9bzT25ikis4oXXs4dEMJRAeOzeQhjCZt4fizfr6aSC7jjsP/ZxkGgduTZj2VxsgVPj5lmQI6afXH3e78A2Fu7vD8LKwAAAAAASUVORK5CYII="
alt="" style="margin: 0 10px;">
<div style="color: #fff;font-size: 18px;font-weight: bolder;">未审核订单</div>
</div>
<div class="line">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</div>
<el-table ref="tbody3" :header-cell-style="{ color: 'rgb(34, 172, 228)' }" :data="tableData.NotAuditList"
style="width: 100%" max-height="250">
<el-table-column prop="OrderId" label="工单编号" width="400" />
<el-table-column prop="ProductId" label="产品编号" width="400" />
<el-table-column prop="ProductName" label="产品名称" width="500" />
<el-table-column prop="UserName" label="用户名" width="300" />
<el-table-column prop="ProductNum" label="产品数量" />
</el-table>
</div>
</div>
</template>
<style lang="scss">
* {
padding: 0;
margin: 0;
}
.container {
background-color: #000;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
overflow: hidden;
height: 100%;
}
.orderTable {
height: 33.333vh;
width: 100%;
background: linear-gradient(to bottom, rgba(15, 33, 74, 0.8), rgba(20, 55, 111, 0.85), rgba(7, 14, 38, 0.85));
}
.order {
display: flex;
flex-direction: row;
padding: 10px 0;
}
.line {
display: flex;
flex-direction: row;
}
.line1 {
width: 70px;
height: 8px;
border-bottom: 2px solid rgb(11, 196, 255);
margin-left: 12px;
float: left;
}
.line2 {
width: calc(100% - 165px);
height: 8px;
border-bottom: 2px solid rgba(90, 172, 255, 0.5);
margin-left: 4px;
float: left;
}
.line3 {
width: 60px;
height: 8px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAAICAYAAAClF5zJAAAAAXNSR0IArs4c6QAAA6hJREFUSEt9VV2IVVUYXevb51wHmx9MQ3TGBmmohslHQUhISKLC0YoYmYfAUgTLgZgMJ+lBfJoe5qGCfhgEKTMohizQxgQfNAYiehwUp6uBzsWxjO7MQzP3MueLb599zj13lA5c7uacvc7+1rfWtw6PlHUsAYaRXQpQoA5Qx/QngEZAIsRr73fzW9s6dktHhTgc2XPbF/bbOrI1oLQ1kTjBwVfX8azhzt3T4wIcLGKyM5rOc1h2wNtbHuI5w838qyMO2Ge1GDamr8fOga/PIZEEiAxHvBeTP+WcCgtClcNlfA1gL5g+YYFsXkx6bzEi+kce5WVV5YezOCXEK77QYoPUE/WF+aKIpVgw8NJaThnuQhWfMMHuYpOKeGdNAmA4Ebzet5q/GO6PJYxR8UIsOVkTo0EYgDVYgFpMvEXyt5WkPcWhGV0VOUxSseP/CHsSwD8Enh3p5vQ3qqU7FXzviKd9l5sdkRJuKF8tEf3963jNcB1/44wjtkVWfCi6SeHMWYIqlzHY287r09Naau3BOBVbzUVeaUFCBTJnSeZOwbwD9pMsF0kHTYGjZe2oE1eg2GJWvE+x8KJA4nZM7BjexNnRsna0teCCE/TmpM3ORZc01rNQ7NrzCCvn72l7SfCdAx63s/JCM6KhBrsfEZVSgr2bW3nnmmpb6xJOC9FjuNCw1NoSxk+8Q6zZcwDeIGn/mXsb/IdmtCsWTBHoymezMcPpPAcVHTBdr2HnyGOsfnpLO8XhohAb/fOVli6SF1wVxZ4X13J+8k/d0BLjrAAbfIGFPPDnF7JEiOtJCwafJBfmVNcndZyhYn1wncYOiakXmp7Y/aCmKXyA5EJwb7PLj/yuT0FwWYCO3GKahlexCaGDVzq7sHuArI1XtFeByUjQ7gMrkMwKyt4VnDO18DAGDXdpXp+IljEhRFuWBd6e2TgYaWugEVL8ungT+/v6WLur2qN1fBERrWZpe254W/sZTxXOLpvlwyTruaWLtN+9qc9Q8aMjSsXQuo9waruJoU7sI6knK7odxEQExCGhi45IU78x0z88twaHDPdzVbdR8aUQcXaeKdY02w3c+e5VeMdwf9V0qwKfORrHdJ7zr0pD4YzaRQDHHkjYdhy9oQMCnHZiX6m00CbChUCKiI/f3Mhjhjs5py87xXgE0GfBijzIrBve9fnONTxhuKl53SXAR+K/iiEAQ6A5I2IqWkBZeic4tWk1PzDc3UV9PnYYdQD9vmwsQpCtSOmv/gP1ONCE8HgXKQAAAABJRU5ErkJggg==) no-repeat 100%;
margin-right: 15px;
float: right;
}
.title {
font-size: 12px;
margin: 10px;
font-weight: bold;
}
/*最外层透明*/
.el-table,
.el-table__expanded-cell {
background-color: transparent !important;
--el-table-border-color: transparent !important;
}
.el-table__row {
border: transparent !important;
}
/* 表格内背景颜色 */
.el-table th,
.el-table tr,
.el-table td {
color: #fff;
background-color: transparent !important;
}
th {
color: rgb(34, 172, 228);
background-color: transparent !important;
}
/* 去除最底层表格的下划线 */
el-table::before {
left: 0;
bottom: 0;
width: 100%;
height: 0px;
}
</style>
timeJob.js:
// config:{//参数的说明
// interval: 1, //间隔天数,间隔为整数
// runNow: false, //是否立即运行
// time: "14:00:00" //执行的时间点 时在0~23之间
// }
const timeoutFunc=(config, func) => {
config.runNow && func()
let nowTime = new Date().getTime()
let timePoints = config.time.split(':').map(i => parseInt(i))
let recent = new Date().setHours(...timePoints)
recent >= nowTime || (recent += 24 * 3600000 )
setTimeout(() => {
func()
setInterval(func, config.interval * 3600000 )
}, recent - nowTime)
}
export {timeoutFunc}
tts.js:
/**
* @description 文字转语音方法
* @public
* @param { text, rate, lang, volume, pitch } object
* @param text 要合成的文字内容,字符串
* @param rate 读取文字的语速 0.1~10 正常1
* @param lang 读取文字时的语言
* @param volume 读取时声音的音量 0~1 正常1
* @param pitch 读取时声音的音高 0~2 正常1
* @returns SpeechSynthesisUtterance
*/
function speak({ text, speechRate, lang, volume, pitch }, endEvent, startEvent) {
if (!window.SpeechSynthesisUtterance) {
console.warn('当前浏览器不支持文字转语音服务')
return
}
if (!text) {
return
}
const speechUtterance = new SpeechSynthesisUtterance()
speechUtterance.text = text
speechUtterance.rate = speechRate || 1
speechUtterance.lang = lang || 'zh-CN'
speechUtterance.volume = volume || 1
speechUtterance.pitch = pitch || 1
speechUtterance.onend = function() {
endEvent && endEvent()
}
speechUtterance.onstart = function() {
startEvent && startEvent()
}
// const voices = speechSynthesis.getVoices()
// speechUtterance.voice = voices.find(item => item.name.includes('Yunjian'))
// console.log(speechSynthesis, voices)
speechSynthesis.speak(speechUtterance)
return speechUtterance
}
export { speak }