element ui,TTS,

35 阅读7分钟

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 }