【vue】使用系统提示音

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Block List</title>
  <style>
    * {
      
      
      margin: 0;
      padding: 0;
    }

    body {
      
      
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 0;
    }

    .container {
      
      
      padding: 10px;
      overflow-y: scroll;
      height: 80vh;
    }

    .block {
      
      
      margin-bottom: 20px;
      border: 1px solid #ccc;
      border-radius: 8px;
      padding: 10px;
      width: 80%;
      margin-left: auto;
      margin-right: auto;
      background-color: #fff;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
      transition: transform 0.3s ease-in-out;
      display: flex;
      justify-content: space-between;
      align-items: center;
      position: relative;
    }

    .block:hover {
      
      
      transform: scale(1.05);
    }

    .block.selected {
      
      
      background-color: #ffcc00;
    }

    .block-content {
      
      
      padding: 10px;
      flex: 3;
      text-align: left;
      position: relative;
    }



    .block-title {
      
      
      font-size: 18px;
      font-weight: bold;
      margin-bottom: 5px;
    }

    .block-quantity {
      
      
      font-size: 14px;

    }

    .block-quantity input {
      
      
      border: none;
      background-color: transparent;
      text-align: center;
      width: 50px;
    }

    .block-icon {
      
      
      font-size: 24px;
      color: red;
      /* position: absolute;
      top: 50%;
      left: 80%; */
      transform: scale(1.5);


    }

    .block-number {
      
      
      display: none;
    }

    .block.show-icon .block-number {
      
      
      /* display: block; */
      display: block;
    }



    .block-button {
      
      
      background-color: #ffcc00;
      color: #fff;
      border: none;
      padding: 8px 12px;
      border-radius: 4px;
      cursor: pointer;
      transition: background-color 0.3s ease-in-out;
    }

    .block-button:hover {
      
      
      background-color: #ff9900;
    }
  </style>
</head>

<body>
  <div id="app" class="container">
    <input type="text" v-model="scanUpc" ref="countInput" @keyup.enter="CountProducts" @blur="compareNumbers"
      style="opacity: 0;">
    <div v-for="(item, index) in blocks" :key="index"
      :class="['block', {'selected': item.selected, 'show-icon': showWarningIcon(item)}]" v-if="blocks.length!==0">

      <div class="block-content">
        <h3 class="block-title">upc:{
   
   { item.upc }}</h3>
        <p v-if="item.sku">sku:{
   
   {item.sku}}</p>
        <div class="block-quantity">
          <div>Quantity: {
   
   { item.qtv }}</div>
          <div>
            Scan Quantity:
            <input type="text" v-model="item.scanQtv" @input="validateQuantity(item)" @blur="updataSingle(item)">

          </div>

        </div>
        <div v-show="!item.scanQtv">
          <span style="color: red;font-size: 14px">Not scanned yet</span>
        </div>
        <div v-show="showWarningIcon(item) && item.scanQtv" class="block-number">
          <i class="block-icon">&#9888;</i>
          <span style="color: red;font-size: 14px">The scanned data is different from the original data!</span>
        </div>

      </div>
      <div @click="handleScanButtonClick(item,index)">
        <svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
          width="45" height="45" x="0" y="0" viewBox="0 0 45 45" style="enable-background:new 0 0 45 45;"
          xml:space="preserve">
          <path fill="#437DFF" d="M2.8,14L2.8,14c-1.1,0-2-0.9-2-2V4.2c0-0.9,0.4-1.8,1-2.4l0,0c0.6-0.6,1.5-1,2.4-1h7.8c1.1,0,2,0.9,2,2v0
       c0,1.1-0.9,2-2,2H6.8c-1.1,0-2,0.9-2,2V12C4.8,13.1,3.9,14,2.8,14z M12.1,44.2H4.2c-0.9,0-1.8-0.4-2.4-1l0,0c-0.6-0.6-1-1.5-1-2.4
       V33c0-1.1,0.9-2,2-2h0c1.1,0,2,0.9,2,2v5.2c0,1.1,0.9,2,2,2h5.3c1.1,0,2,0.9,2,2v0C14.1,43.3,13.2,44.2,12.1,44.2z M42.2,14L42.2,14
       c-1.1,0-2-0.9-2-2V6.8c0-1.1-0.9-2-2-2h-5.3c-1.1,0-2-0.9-2-2v0c0-1.1,0.9-2,2-2h7.8c0.9,0,1.8,0.4,2.4,1l0,0c0.6,0.6,1,1.5,1,2.4
       V12C44.2,13.1,43.3,14,42.2,14z M40.8,44.2H29.5c-1.1,0-2-0.9-2-2v0c0-1.1,0.9-2,2-2h8.7c1.1,0,2-0.9,2-2v-6.6c0-1.1,0.9-2,2-2h0
       c1.1,0,2,0.9,2,2v9.1c0,0.9-0.4,1.8-1,2.4l0,0C42.5,43.8,41.7,44.2,40.8,44.2z" />
          <path fill="#CCCCCC" d="M12.8,13.7L12.8,13.7c0.8,0,1.4,0.6,1.4,1.4v3.6c0,0.8-0.6,1.4-1.4,1.4h0c-0.8,0-1.4-0.6-1.4-1.4v-3.6
       C11.4,14.3,12.1,13.7,12.8,13.7z M19.6,24.4L19.6,24.4c0.8,0,1.4,0.6,1.4,1.4v5.1c0,0.8-0.6,1.4-1.4,1.4h0c-0.8,0-1.4-0.6-1.4-1.4
       v-5.1C18.2,25,18.8,24.4,19.6,24.4z M12.8,24.4L12.8,24.4c0.8,0,1.4,0.6,1.4,1.4V30c0,0.8-0.6,1.4-1.4,1.4h0c-0.8,0-1.4-0.6-1.4-1.4
       v-4.2C11.4,25,12.1,24.4,12.8,24.4z M26.3,24.4L26.3,24.4c0.8,0,1.4,0.6,1.4,1.4v3.5c0,0.8-0.6,1.4-1.4,1.4h0
       c-0.8,0-1.4-0.6-1.4-1.4v-3.5C24.9,25,25.6,24.4,26.3,24.4z M32.6,24.4L32.6,24.4c0.8,0,1.4,0.6,1.4,1.4v6c0,0.8-0.6,1.4-1.4,1.4h0
       c-0.8,0-1.4-0.6-1.4-1.4v-6C31.2,25,31.8,24.4,32.6,24.4z M32.6,11.2L32.6,11.2c0.8,0,1.4,0.6,1.4,1.4v6.1c0,0.8-0.6,1.4-1.4,1.4h0
       c-0.8,0-1.4-0.6-1.4-1.4v-6.1C31.2,11.8,31.8,11.2,32.6,11.2z M19.6,12.1L19.6,12.1c0.8,0,1.4,0.6,1.4,1.4v5.3
       c0,0.8-0.6,1.4-1.4,1.4h0c-0.8,0-1.4-0.6-1.4-1.4l0-5.3C18.2,12.7,18.8,12.1,19.6,12.1z M26.3,13.5L26.3,13.5c0.8,0,1.4,0.6,1.4,1.4
       v3.8c0,0.8-0.6,1.4-1.4,1.4h0c-0.8,0-1.4-0.6-1.4-1.4v-3.8C24.9,14.1,25.6,13.5,26.3,13.5z" />
          <path fill="#437DFF" d="M1.4,20.8h42.2c0.8,0,1.4,0.6,1.4,1.4v0c0,0.8-0.6,1.4-1.4,1.4H1.4c-0.8,0-1.4-0.6-1.4-1.4v0
       C0,21.4,0.6,20.8,1.4,20.8z" />
        </svg>

      </div>
      <!-- <button class="block-button" @click="handleScanButtonClick(item,index)">Scan</button> -->
    </div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
  <!-- <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> -->
  <script src="https://bluewingfishing.com/config/axios.min.js"></script>
  <script>
    new Vue({
      
      
      el: '#app',
      data () {
      
      
        return {
      
      
          blocks: [],
          countIndex: null,
          audioContext: null,
          oscillator: null,
          gainNode: null,
          delayTimeout: null,
          timeoutId: null,
          scanUpc: ""
        };
      },
      created () {
      
      
        this.getList()
      },
      mounted () {
      
      
        // document.addEventListener("click", e => {
      
      
        //   // console.log("e", e);
        //   this.$nextTick(() => {
      
      
        //     this.$refs.countInput.focus();
        //   })

        // });

      },
      methods: {
      
      

        handleScanButtonClick (item, index) {
      
      
          if (this.countIndex) {
      
      
            this.updataNumber(this.blocks[this.countIndex])
          }
          let confirmFlag = confirm('Are you sure to start scanning?')
          if (confirmFlag == true) {
      
      
            this.blocks.forEach((b) => {
      
      
              b.selected = false;
            });
            item.selected = true;

            this.countIndex = index
            this.$nextTick(() => {
      
      
              // this.$refs.countInput[index].focus()
              this.$refs.countInput.focus()
            })
          } else {
      
      
            // this.$refs.countInput[this.countIndex].focus()
          }


        },
        CountProducts () {
      
      
          console.log("upc", this.scanUpc, this.blocks[this.countIndex].upc);
          if (this.scanUpc == this.blocks[this.countIndex].upc) {
      
      
            this.scanUpc = ''
            this.blocks[this.countIndex].scanQtv++
            if (this.blocks[this.countIndex].scanQtv >= this.blocks[this.countIndex].qtv) {
      
      
              // 提示音
              clearTimeout(this.timeoutId); // 清除之前的延迟执行函数
              this.timeoutId = setTimeout(() => {
      
      
                this.playAlertSound();
              }, 500); // 设置延迟执行时间为1秒
              // this.playAlertSound()
            }
          } else {
      
      
            alert('The upc currently being scanned does not match the expected one')
          }


        },
        // 失去焦点的时候提示
        compareNumbers () {
      
      

          if (this.blocks[this.countIndex].scanQtv != this.blocks[this.countIndex].qtv) {
      
      
            // 提示音
            this.playAlertSound()
          }
          this.updataNumber(this.blocks[this.countIndex])

        },
        // 提示音
        playAlertSound () {
      
      


          // 创建音频上下文
          this.audioContext = new (window.AudioContext || window.webkitAudioContext)();

          // 发出警告音频的频率和持续时间
          const frequency = 440; // 警告音频频率(440Hz为A音)
          const duration = 1000; // 持续时间(以毫秒为单位)

          // 创建音调节点
          this.oscillator = this.audioContext.createOscillator();
          this.oscillator.frequency.value = frequency;

          // 创建音量节点
          this.gainNode = this.audioContext.createGain();
          this.gainNode.gain.setValueAtTime(1, this.audioContext.currentTime);
          this.gainNode.gain.exponentialRampToValueAtTime(0.001, this.audioContext.currentTime + duration / 1000);

          // 连接节点
          this.oscillator.connect(this.gainNode);
          this.gainNode.connect(this.audioContext.destination);

          // 播放音频
          this.oscillator.start();
          this.oscillator.stop(this.audioContext.currentTime + duration / 1000);

          // 延迟重置音频上下文和音调节点
          clearTimeout(this.delayTimeout);
          this.delayTimeout = setTimeout(() => {
      
      
            this.resetAudioContext();
          }, duration);
        },
        resetAudioContext () {
      
      
          // 重置音频上下文和音调节点
          this.audioContext.close();
          this.audioContext = null;
          this.oscillator = null;
          this.gainNode = null;
          this.delayTimeout = null;
        },

        updataSingle (item) {
      
      
          this.updataNumber(item)
        },



        validateQuantity (block) {
      
      
          if (block.scanQtv !== '') {
      
      
            // block.scanQtv = Math.max(0, parseInt(block.scanQtv)).toString();
            block.scanQtv = Math.max(0, parseInt(block.scanQtv));
          }
        },
        showWarningIcon (block) {
      
      
          return block.qtv != block.scanQtv;
        },
        getList () {
      
      

          axios.post(("https://bluewingfishing.com/qdlsApi" + "/opean_api_qd/wms/wmsScanTask/list"), {
      
      
            pageNum: 1,
            pageSize: 10
          }).then(res => {
      
      
            console.log("res", res.data.rows);
            this.blocks = res.data.rows
          }).catch(error => {
      
      

          });
        },
        updataNumber (data) {
      
      
          axios.post(("https://bluewingfishing.com/qdlsApi" + "/opean_api_qd/wms/wmsScanTask/update"), {
      
      
            id: data.id,
            scanQtv: data.scanQtv
          }).then(res => {
      
      
            console.log("调用", res.data.rows);
          }).catch(error => {
      
      

          });
        },

        // 获取屏幕点击事件

        getApiUrl (url) {
      
      
          return "http://192.168.30.153:9090" + url
        },

      }
    });
  </script>
</body>

</html>

猜你喜欢

转载自blog.csdn.net/liqiannan8023/article/details/131534441