<template>
  <div v-if="curQue" class="voice-matrix">
    <div class="voice-matrix-audio">
      <div v-if="curQue.voiceMatrix.isAudioNumber" class="audio-number">
        <span
          :class="[
            themeColor.length === 0 || themeColor === 'red'
              ? 'serial-number'
              : `serial-number-${themeColor}`
          ]"
        >
          {{ curQue.voiceMatrix.audioSerialNumber }}
        </span>
      </div>
      <div v-show="hasSelectedCell" class="audio-simple">
        <img :src="playing ? voicePlaySrc : voicePauseSrc" @click="playAudio">
        <span
          :class="['Repeat-16', isRepeat ? '' : 'disabled']"
          @click="isRepeat = !isRepeat"
        />
      </div>
      <audio-line
        v-show="!hasSelectedCell"
        ref="audioLine"
        audio-id="voiceMatrixAudio"
        :mp3="mp3Url"
        :get-cur-time="getCurTime"
        :stop-audio="stopAudio"
        :mp3-source="mp3Source"
        @handleChangeStopAudio="handleChangeStopAudio"
        @playChange="playChange"
      />
    </div>
    <!-- 语音矩阵 -->
    <div class="voice-matrix-container">
      <div
        v-if="curQue.voiceMatrix.matrix.length > 0"
        class="matrix"
        :style="{
          'grid-template': `36px repeat(${curQue.voiceMatrix.matrix.length}, auto) minmax(36px, 1fr) / 36px repeat(${curQue.voiceMatrix.matrix[0].length}, auto) minmax(36px, 1fr)`
        }"
        @mouseleave="clearSelectCell"
      >
        <!-- 顶部单元格 -->
        <div class="matrix-top" @mouseenter="clearSelectCell" />
        <template v-for="(row, i) in curQue.voiceMatrix.matrix[0]">
          <div
            :key="`top-${i}`"
            :class="[
              'matrix-top',
              curQue.voiceMatrix.columnSelection &&
                (selectColumn === i ||
                  (selectedLine.type === 'column' && selectedLine.index === i))
                ? 'read'
                : ''
            ]"
            @mouseenter="checkboxMouseenter(selectColumn === i, 'column')"
          >
            <span
              v-if="
                row.type !== 'connection' && curQue.voiceMatrix.columnSelection
              "
              v-show="
                selectColumn === i ||
                  (selectedLine.type === 'column' && selectedLine.index === i)
              "
              :class="[
                `matrix-checkbox-row-${themeColor}`,
                selectedLine.type === 'column' && selectedLine.index === i
                  ? 'active'
                  : ''
              ]"
              @click="selectRowOrColumn(i, 'column')"
            />
          </div>
        </template>
        <div class="matrix-top" @mouseenter="clearSelectCell" />
        <!-- 主矩阵 -->
        <template v-for="(row, i) in curQue.voiceMatrix.matrix">
          <div
            :key="`start-${i}`"
            :class="[
              'column-wrapper',
              curQue.voiceMatrix.rowSelection &&
                (selectRow === i ||
                  (selectedLine.type === 'row' && selectedLine.index === i))
                ? 'read'
                : ''
            ]"
            @mouseenter="checkboxMouseenter(selectRow === i, 'row')"
          >
            <span
              v-if="curQue.voiceMatrix.rowSelection"
              v-show="
                selectRow === i ||
                  (selectedLine.type === 'row' && selectedLine.index === i)
              "
              :class="[
                `matrix-checkbox-column-${themeColor}`,
                selectedLine.type === 'row' && selectedLine.index === i
                  ? 'active'
                  : ''
              ]"
              @click="selectRowOrColumn(i, 'row')"
            />
          </div>
          <!-- 单元格 -->
          <template v-for="(column, j) in row">
            <div
              :key="`wrapper-${i}-${j}`"
              :class="[
                'column-wrapper',
                (curQue.voiceMatrix.rowSelection && selectRow === i) ||
                  (curQue.voiceMatrix.columnSelection && selectColumn === j) ||
                  (curQue.voiceMatrix.columnSelection &&
                    selectedLine.type === 'column' &&
                    selectedLine.index === j) ||
                  (curQue.voiceMatrix.rowSelection &&
                    selectedLine.type === 'row' &&
                    selectedLine.index === i)
                  ? 'read'
                  : '',
                (i === 0 && curQue.voiceMatrix.firstLineHighlight) ||
                  (j === row.length - 1 && curQue.voiceMatrix.lastColumnHighlight)
                  ? `highlight-${themeColor}`
                  : ''
              ]"
              @mouseenter="matrixCellMouseenter(i, j, column.type)"
            >
              <!-- 文本 -->
              <div
                v-if="column.type === 'text'"
                :key="`column-${i}-${j}`"
                :class="[
                  column.text.length === 0 ? 'space' : `column-${themeColor}`,
                  (selectCell.row === i && selectCell.column === j) ||
                    (selectedLine.type === 'column' &&
                      selectedLine.index === j) ||
                    (selectedLine.type === 'row' && selectedLine.index === i)
                    ? 'selected'
                    : '',
                  playing &&
                    column.lrc_data.begin_time / 1000 <= curTime &&
                    (curTime < column.lrc_data.end_time / 1000 ||
                      column.lrc_data.end_time === -1)
                    ? 'playing'
                    : '',
                  column.isTitle ? 'title' : ''
                ]"
                @click="matrixCellClick(i, j)"
              >
                <span>{{ column.text }}</span>
              </div>
              <!-- 连接线 -->
              <div
                v-else-if="column.type === 'connection'"
                :key="`column-${i}-${j}`"
                :class="[
                  'connection',
                  i === 0 && curQue.voiceMatrix.firstLineHighlight
                    ? `highlight-bc-${themeColor}`
                    : ''
                ]"
              />
              <!-- 分词 -->
              <div
                v-else-if="column.type === 'SentenceSegwordChs'"
                :key="`column-${i}-${j}`"
                :class="[
                  `sentence-${themeColor}`,
                  (selectCell.row === i && selectCell.column === j) ||
                    (selectedLine.type === 'column' &&
                      selectedLine.index === j) ||
                    (selectedLine.type === 'row' && selectedLine.index === i)
                    ? 'selected'
                    : '',
                  playing &&
                    column.lrc_data.begin_time / 1000 <= curTime &&
                    (curTime < column.lrc_data.end_time / 1000 ||
                      column.lrc_data.end_time === -1)
                    ? 'playing'
                    : '',
                  column.isTitle ? 'title' : ''
                ]"
                :style="{
                  'grid-template-columns': `repeat(${column.sentence_data.wordsList.length}, auto)`
                }"
                @click="matrixCellClick(i, j)"
              >
                <template v-for="(word, w) in column.sentence_data.wordsList">
                  <span
                    v-if="column.sentence_data.pyPosition === 'top'"
                    :key="`pinyin-${w}`"
                    class="pinyin"
                  >
                    {{ word.pinyin }}
                  </span>
                  <span v-else :key="`chs-${w}`" class="chs">
                    {{ word.chs }}
                  </span>
                </template>
                <template v-for="(word, w) in column.sentence_data.wordsList">
                  <span
                    v-if="column.sentence_data.pyPosition === 'top'"
                    :key="`chs-${w}`"
                    class="chs"
                  >
                    {{ word.chs }}
                  </span>
                  <span v-else :key="`pinyin-${w}`" class="pinyin">
                    {{ word.pinyin }}
                  </span>
                </template>
              </div>
              <!-- 拼音 + 英文 -->
              <div
                v-else-if="column.type === 'PinyinEnglish'"
                :key="`column-${i}-${j}`"
                :class="[
                  `pinyinEnglish-${themeColor}`,
                  (selectCell.row === i && selectCell.column === j) ||
                    (selectedLine.type === 'column' &&
                      selectedLine.index === j) ||
                    (selectedLine.type === 'row' && selectedLine.index === i)
                    ? 'selected'
                    : '',
                  playing &&
                    column.lrc_data.begin_time / 1000 <= curTime &&
                    (curTime < column.lrc_data.end_time / 1000 ||
                      column.lrc_data.end_time === -1)
                    ? 'playing'
                    : '',
                  column.isTitle ? 'title' : ''
                ]"
                @click="matrixCellClick(i, j)"
              >
                <div class="inside-wrapper">
                  <div class="pinyin">
                    {{ column.pinyin_english_data.pinyin }}
                  </div>
                  <div class="english">
                    {{ column.pinyin_english_data.english }}
                  </div>
                </div>
              </div>
              <!-- 文本中有括号 -->
              <div
                v-else-if="column.type === 'textBrackets'"
                :key="`column-${i}-${j}`"
                :class="[
                  `textBrackets-${themeColor}`,
                  (selectCell.row === i && selectCell.column === j) ||
                    (selectedLine.type === 'column' &&
                      selectedLine.index === j) ||
                    (selectedLine.type === 'row' && selectedLine.index === i)
                    ? 'selected'
                    : '',
                  playing &&
                    column.lrc_data.begin_time / 1000 <= curTime &&
                    (curTime < column.lrc_data.end_time / 1000 ||
                      column.lrc_data.end_time === -1)
                    ? 'playing'
                    : '',
                  column.isTitle ? 'title' : ''
                ]"
                @click="matrixCellClick(i, j)"
              >
                <span>
                  <span class="brackets-text">{{
                    column.text_brackets.brackets_outer
                  }}</span>
                  <span class="brackets">&nbsp;[&nbsp;</span>
                  <span class="brackets-text">{{
                    column.text_brackets.brackets_inner
                  }}</span>
                  <span class="brackets">&nbsp;]</span>
                </span>
              </div>
            </div>
          </template>

          <div
            :key="`end-${i}`"
            :class="[
              curQue.voiceMatrix.rowSelection &&
                (selectRow === i ||
                  (selectedLine.type === 'row' && selectedLine.index === i))
                ? 'read'
                : ''
            ]"
            @mouseenter="clearSelectCell"
          />
        </template>
        <!-- 底部格子 -->
        <div class="matrix-bottom" @mouseenter="clearSelectCell" />
        <template v-for="(row, i) in curQue.voiceMatrix.matrix[0]">
          <div
            :key="`bottom-${i}`"
            :class="[
              'matrix-bottom',
              curQue.voiceMatrix.columnSelection &&
                (selectColumn === i ||
                  (selectedLine.type === 'column' && selectedLine.index === i))
                ? 'read'
                : ''
            ]"
            @mouseenter="clearSelectCell"
          />
        </template>
        <div class="matrix-bottom" @mouseenter="clearSelectCell" />
      </div>
    </div>

    <div class="voice-luyin">
      <soundrecord
        type="promax"
        class="luyin-box"
        :file-name="fileName"
        :select-data="selectData"
        @getWavblob="getWavblob"
        @getSelectData="getSelectData"
        @handleParentPlay="handleParentPlay"
        @sentPause="sentPause"
      />
      <audio-compare
        :theme-color="themeColor"
        :wavblob="wavblob"
        :url="mp3Url"
        :is-record="isRecord"
        :sent-pause="sentPause"
        :matrix-select-lrc="matrixSelectLrc"
        :get-cur-time="getCurTime"
        :cur-time="curTime"
        :handle-change-stop-audio="handleChangeStopAudio"
        @playing="playChange"
      />
    </div>
  </div>
</template>

<script>
import Bus from "./components/Bus.js";
import AudioLine from "./AudioLine.vue";
import Soundrecord from "./Soundrecord.vue";
import AudioCompare from "./AudioCompareMatrix.vue";

export default {
  components: {
    AudioLine,
    Soundrecord,
    AudioCompare
  },
  props: ["curQue", "themeColor"],
  data() {
    return {
      curTime: 0,
      playing: false,
      stopAudio: true,
      unWatch: null,
      lrcArray: [],
      cellTimer: null,
      fileName: "",
      // 底色行、列
      selectRow: -1,
      selectColumn: -1,
      // 行、列选中
      selectedLine: {
        type: "",
        index: 0
      },
      // 点击选中
      selectCell: {
        row: -1,
        column: -1
      },
      isRepeat: false,
      // 跟读所需属性
      wavblob: null,
      isRecord: false,
      matrixSelectLrc: null
    };
  },
  computed: {
    mp3Url() {
      let mp3_list = this.curQue.mp3_list[0];
      if (mp3_list === undefined) return "";
      return mp3_list.url.match(/^\[FID##/)
        ? mp3_list.temporary_url
        : mp3_list.url;
    },
    mp3Source() {
      let mp3_list = this.curQue.mp3_list[0];
      if (mp3_list === undefined) return "";
      return "source" in mp3_list ? mp3_list.source : "";
    },
    mp3Duration() {
      let mp3_list = this.curQue.mp3_list[0];
      if (mp3_list === undefined) return 0;
      return mp3_list.media_duration * 1000;
    },

    hasSelectedCell() {
      let { type, index } = this.selectedLine;
      let { row, column } = this.selectCell;
      return (type.length > 0 && index >= 0) || (row >= 0 && column >= 0);
    },
    selectData() {
      let { type, index } = this.selectedLine;
      let { row, column } = this.selectCell;
      return {
        type: type.length > 0 && index >= 0 ? type : "cell",
        index,
        row,
        column
      };
    },

    voicePauseSrc() {
      let themeColor = this.themeColor;
      if (themeColor.length === 0 || themeColor === "red") {
        return require("../../../assets/NPC/play-red.png");
      }
      return require(`../../../assets/NPC/play-${themeColor}.png`);
    },
    voicePlaySrc() {
      let themeColor = this.themeColor;
      if (themeColor.length === 0 || themeColor === "red") {
        return require("../../../assets/NPC/icon-voice-play-red.png");
      }
      return require(`../../../assets/NPC/icon-voice-play-${themeColor}.png`);
    }
  },
  watch: {
    hasSelectedCell() {
      this.handleParentPlay();
    }
  },
  created() {
    Bus.$on("audioPause", () => {
      this.handleParentPlay();
    });
  },
  methods: {
    // 鼠标移入移出
    matrixCellMouseenter(i, j, type) {
      if (type === "connection") {
        this.selectRow = -1;
        this.selectColumn = -1;
      } else {
        this.selectRow = i;
        this.selectColumn = j;
      }
    },

    clearSelectCell() {
      this.selectRow = -1;
      this.selectColumn = -1;
    },

    // 单击单元格
    matrixCellClick(row, column) {
      if (this.playing) this.handleParentPlay();
      if (this.unWatch) this.unWatch();
      this.lrcArray = [];
      if (row === this.selectCell.row && column === this.selectCell.column) {
        this.selectCell = { row: -1, column: -1 };
        return;
      }
      this.selectedLine = { type: "", index: -1 };
      this.selectCell = { row, column };
      this.handleChangeTime(
        this.curQue.voiceMatrix.matrix[row][column].lrc_data
      );
      // 设置录音文件名
      this.setRecordingFileName(row, column);
    },

    setRecordingFileName(row, column) {
      let {
        type,
        text,
        sentence_data,
        pinyin_english_data,
        text_brackets
      } = this.curQue.voiceMatrix.matrix[row][column];
      if (type === "text") this.fileName = text;
      if (type === "SentenceSegwordChs") this.fileName = sentence_data.sentence;
      if (type === "PinyinEnglish") this.fileName = pinyin_english_data.pinyin;
      if (type === "textBrackets") {
        this.fileName = `${text_brackets.brackets_outer}[${text_brackets.brackets_inner}]`;
      }
    },

    checkboxMouseenter(isSelected, type) {
      if (!isSelected) return this.clearSelectCell();
      if (type === "row") this.selectColumn = -1;
      if (type === "column") this.selectRow = -1;
    },

    // 选中行、列
    selectRowOrColumn(index, type) {
      this.handleParentPlay();
      this.lrcArray = [];
      this.selectCell = { row: -1, column: -1 };
      if (this.unWatch) this.unWatch();
      if (
        this.selectedLine.type === type &&
        this.selectedLine.index === index
      ) {
        this.selectedLine = { type: "", index: -1 };
        return;
      }
      this.selectedLine = { type, index };
      let number = index;
      if (type === "column") {
        this.curQue.voiceMatrix.matrix[index].forEach(({ type }, i) => {
          if (i >= index) return;
          if (type === "connection") number -= 1;
        });
      }
      this.fileName = `第 ${number + 1} ${type === "row" ? "行" : "列"}`;
    },

    playAudio() {
      if (!this.hasSelectedCell) return;
      if (this.playing) return this.handleParentPlay();
      if (this.lrcArray.length > 0) return this.$refs.audioLine.PlayAudio();
      if (this.unWatch) this.unWatch();

      this.lrcArray = [];
      let { type, index } = this.selectedLine;
      if (type.length > 0 && index >= 0 && type === "row") {
        this.curQue.voiceMatrix.matrix[index].forEach(
          item => {
            let data = this.getLrcData(item);
            if (data) this.lrcArray.push(data);
          }
        );
        if (this.lrcArray.length > 0) this.lrcPlay(this.lrcArray[0], 0);
        return;
      }

      if (type.length > 0 && index >= 0 && type === "column") {
        this.curQue.voiceMatrix.matrix.forEach(item => {
          let data = this.getLrcData(item[index]);
          if (data) this.lrcArray.push(data);
        });
        if (this.lrcArray.length > 0) this.lrcPlay(this.lrcArray[0], 0);
        return;
      }

      let { row, column } = this.selectCell;
      if (row >= 0 && column >= 0) {
        this.handleChangeTime(
          this.curQue.voiceMatrix.matrix[row][column].lrc_data
        );
      }
    },

    lrcPlay({ begin_time, end_time }, index) {
      this.handleParentPlay();
      this.$nextTick(() => {
        this.$refs.audioLine.onTimeupdateTime(begin_time / 1000);
        this.$refs.audioLine.PlayAudio();
        if (end_time === -1) return;
        let end = end_time / 1000 - 0.01;
        this.unWatch = this.$watch("curTime", val => {
          if (val >= end) {
            if (!this.hasSelectedCell) return this.unWatch();
            this.handleParentPlay();
            this.$refs.audioLine.onTimeupdateTime(end);
            this.unWatch();
            let i = index + 1;
            if (i < this.lrcArray.length) {
              return this.lrcPlay(this.lrcArray[i], i);
            }
            if (this.isRepeat) {
              return this.lrcPlay(this.lrcArray[0], 0);
            }
            this.lrcArray = [];
          }
        });
      });
    },

    playChange(playing) {
      this.playing = playing;
      // 子组件通信，同时只能播放一个音频
      if (playing) Bus.$emit("audioPause");
    },

    // 暂停音频播放
    handleParentPlay() {
      this.stopAudio = true;
    },
    // 音频播放时改变布尔值
    handleChangeStopAudio() {
      this.stopAudio = false;
    },

    getCurTime(curTime) {
      this.curTime = curTime;
    },

    getWavblob(wavblob) {
      this.wavblob = wavblob;
    },

    getSelectData({ type, index, row, column }) {
      if (type === "") return;
      let arr = [];
      if (type.length > 0 && index >= 0 && type === "row") {
        this.curQue.voiceMatrix.matrix[index].forEach(
          item => {
            let data = this.getLrcData(item);
            if (data) arr.push(data);
          }
        );
        this.matrixSelectLrc = arr;
        return;
      }

      if (type.length > 0 && index >= 0 && type === "column") {
        this.curQue.voiceMatrix.matrix.forEach(item => {
          let data = this.getLrcData(item[index]);
          if (data) arr.push(data);
        });
        this.matrixSelectLrc = arr;
        return;
      }

      if (type === "cell" && row >= 0 && column >= 0) {
        let lrcData = this.curQue.voiceMatrix.matrix[row][column].lrc_data;
        if (lrcData.end_time === -1) lrcData.end_time = this.mp3Duration;
        this.matrixSelectLrc = [lrcData];
      }
    },

    getLrcData({ type, text, lrc_data }) {
      if (
        type === "SentenceSegwordChs" ||
        type === "PinyinEnglish" ||
        type === "textBrackets" ||
        (type === "text" && text.length > 0)
      ) {
        if (lrc_data.end_time === -1) {
          return {
            begin_time: lrc_data.begin_time,
            end_time: this.mp3Duration,
            text: lrc_data.text
          };
        }
        return lrc_data;
      }
      return false;
    },

    sentPause(isRecord) {
      this.isRecord = isRecord;
    },

    handleChangeTime({ begin_time, end_time }) {
      if (this.unWatch) this.unWatch();
      this.handleParentPlay();
      this.$nextTick(() => {
        this.$refs.audioLine.onTimeupdateTime(begin_time / 1000);
        this.$refs.audioLine.PlayAudio();
        // 监听是否已到结束时间，为了选中效果 - 0.01
        if (end_time === -1) return;
        let end = end_time / 1000 - 0.01;
        this.unWatch = this.$watch("curTime", val => {
          if (val >= end) {
            this.handleParentPlay();
            this.$refs.audioLine.onTimeupdateTime(end);
            this.unWatch();
            this.unWatch = null;
          }
        });
      });
    }
  }
};
</script>

<style lang="scss" scoped>
$select-color: #de4444;
$border-color: #e6e6e6;

$select-color-green: #24b99e;
$select-color-green-bc: rgba(36, 185, 158, 0.25);
$select-color-green-hover: #3dd4b8;
$select-color-green-active: #1fa189;

$select-color-brown: #bd8865;
$select-color-brown-bc: rgba(189, 136, 101, 0.25);
$select-color-brown-hover: #d6a687;
$select-color-brown-active: #a37557;

.voice-matrix {
  height: 100%;
  width: 100%;
  padding-bottom: 24px;
  color: #262626;

  &-audio {
    display: flex;
    height: 42px;
    border: 1px solid $border-color;
    border-radius: 8px 8px 0 0;

    .audio-number {
      padding: 11px 0 0 12px;

      %serial-number,
      .serial-number {
        display: inline-block;
        width: 16px;
        height: 16px;
        text-align: center;
        line-height: 16px;
        font-size: 12px;
        background-color: $select-color;
        font-family: "robot";
        color: #fff;
        border-radius: 50%;
      }

      .serial-number-green {
        @extend %serial-number;

        background-color: $select-color-green;
      }

      .serial-number-brown {
        @extend %serial-number;

        background-color: $select-color-brown;
      }
    }

    .audio-simple {
      flex-grow: 1;
      line-height: 46px;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: space-between;

      img {
        cursor: pointer;
        width: 16px;
        height: 16px;
        margin-left: 12px;
      }

      .Repeat-16 {
        display: inline-block;
        width: 16px;
        height: 16px;
        margin-right: 12px;
        cursor: pointer;
      }
    }
  }
  // 语音矩阵
  &-container {
    height: calc(100% - 80px);
    background-color: #f5f5f5;
    border-left: 1px solid $border-color;
    border-right: 1px solid $border-color;
    word-break: break-word;

    .matrix {
      display: inline-grid;
      width: 100%;
      height: 100%;

      %matrix-checkbox {
        position: relative;
        top: calc(50% - 5px);
        display: block;
        width: 14px;
        height: 14px;
        border: 1.5px solid #b0b0b0;
        border-radius: 4px;
        margin: 0 auto;
        cursor: pointer;

        &.active {
          border-color: $select-color;

          &::after {
            box-sizing: content-box;
            content: "";
            border: 1px solid $select-color;
            border-left: 0;
            border-top: 0;
            height: 7px;
            left: 4px;
            position: absolute;
            width: 3px;
            transform: rotate(45deg) scaleY(1);
            transition: transform 0.15s ease-in 0.05s;
            transform-origin: center;
          }
        }
      }

      .matrix-checkbox-row-,
      .matrix-checkbox-row-red {
        @extend %matrix-checkbox;
      }

      .matrix-checkbox-row-green {
        @extend %matrix-checkbox;

        &.active {
          border-color: $select-color-green-active;

          &::after {
            border-color: $select-color-green-active;
          }
        }
      }

      .matrix-checkbox-row-brown {
        @extend %matrix-checkbox;

        &.active {
          border-color: $select-color-brown-active;

          &::after {
            border-color: $select-color-brown-active;
          }
        }
      }

      %matrix-checkbox-column,
      .matrix-checkbox-column-,
      .matrix-checkbox-column-red {
        @extend %matrix-checkbox;

        top: calc(50% - 7px);
        right: -2px;
      }

      .matrix-checkbox-column-green {
        @extend %matrix-checkbox-column;

        &.active {
          border-color: $select-color-green-active;

          &::after {
            border-color: $select-color-green-active;
          }
        }
      }

      .matrix-checkbox-column-brown {
        @extend %matrix-checkbox-column;

        &.active {
          border-color: $select-color-brown-active;

          &::after {
            border-color: $select-color-brown-active;
          }
        }
      }

      .read {
        background-color: #eaeaea;
      }

      .highlight-,
      .highlight-red {
        color: $select-color;
      }

      .highlight-green {
        color: $select-color-green;
      }

      .highlight-brown {
        color: $select-color-brown;
      }

      .column-wrapper {
        padding: 4px;

        %column {
          width: 100%;
          height: 100%;
          min-height: 32px;
          background-color: #fff;
          border: 1px solid $border-color;
          border-radius: 8px;
          transition: 0.2s;
          cursor: pointer;
          user-select: none;

          &:hover {
            border-color: #8c8c8c;
          }

          &.selected {
            color: $select-color;
            border-color: $select-color;
          }

          &.playing {
            background-color: #fee;
          }

          &.title {
            background-color: transparent;
            border-color: transparent;
          }

          > span {
            display: inline-block;
            padding: 4px 12px;
            line-height: 24px;
          }
        }

        %column-red,
        .column-,
        .column-red {
          @extend %column;

          position: relative;
          font-family: "GB-PINYINOK-B", "FZJCGFKTK";

          &::before {
            display: inline-block;
            content: "";
            vertical-align: middle;
          }
        }

        .column-green {
          @extend %column-red;

          &.selected {
            color: $select-color-green;
            border-color: $select-color-green;
          }

          &.playing {
            background-color: $select-color-green-bc;
          }
        }

        .column-brown {
          @extend %column-red;

          &.selected {
            color: $select-color-brown;
            border-color: $select-color-brown;
          }

          &.playing {
            background-color: $select-color-brown-bc;
          }
        }

        %sentence,
        .sentence-,
        .sentence-red {
          @extend %column;

          display: inline-grid;
          padding: 4px 12px;
          line-height: 24px;
          column-gap: 8px;
          justify-items: center;
          justify-content: start;

          > span {
            padding: 0;
          }

          .pinyin {
            font-family: "GB-PINYINOK-B";
            opacity: 0.45;
            font-size: 12px;
            line-height: 20px;
          }

          .chs {
            font-family: "FZJCGFKTK";
            font-size: 16px;
            line-height: 24px;
          }
        }

        .sentence-green {
          @extend %sentence;

          &.selected {
            color: $select-color-green;
            border-color: $select-color-green;
          }

          &.playing {
            background-color: $select-color-green-hover;
          }
        }

        .sentence-brown {
          @extend %sentence;

          &.selected {
            color: $select-color-brown;
            border-color: $select-color-brown;
          }

          &.playing {
            background-color: $select-color-brown-hover;
          }
        }

        .connection {
          position: relative;
          top: calc(50% - 1px);
          height: 2px;
          width: 16px;
          margin: 0 -4px;
          border-radius: 4px;
          background-color: #252525;

          &.highlight-bc-,
          &.highlight-bc-red {
            background-color: $select-color;
          }

          &.highlight-bc-green {
            background-color: $select-color-green;
          }

          &.highlight-bc-brown {
            background-color: $select-color-brown;
          }
        }
        // 拼音 + 文字
        %pinyinEnglish,
        .pinyinEnglish-,
        .pinyinEnglish-red {
          @extend %column;

          .inside-wrapper {
            padding: 4px 12px;

            .pinyin {
              font-family: "GB-PINYINOK-B";
              font-size: 16px;
              line-height: 24px;
            }

            .english {
              font-family: "robot";
              opacity: 0.45;
              font-size: 12px;
              line-height: 20px;
            }
          }
        }

        .pinyinEnglish-green {
          @extend %pinyinEnglish;

          &.selected {
            color: $select-color-green;
            border-color: $select-color-green;
          }

          &.playing {
            background-color: $select-color-green-hover;
          }
        }

        .pinyinEnglish-brown {
          @extend %pinyinEnglish;

          &.selected {
            color: $select-color-brown;
            border-color: $select-color-brown;
          }

          &.playing {
            background-color: $select-color-brown-hover;
          }
        }

        %textBrackets,
        .textBrackets-,
        .textBrackets-red {
          @extend %column;

          .brackets-text {
            font-family: "GB-PINYINOK-B";
          }

          .brackets {
            font-size: 16px;
            font-family: "FZJCGFKTK";
          }
        }

        .textBrackets-green {
          @extend %textBrackets;

          &.selected {
            color: $select-color-green;
            border-color: $select-color-green;
          }

          &.playing {
            background-color: $select-color-green-hover;
          }
        }

        .textBrackets-brown {
          @extend %textBrackets;

          &.selected {
            color: $select-color-brown;
            border-color: $select-color-brown;
          }

          &.playing {
            background-color: $select-color-brown-hover;
          }
        }
      }
    }

    .matrix-audio {
      width: 228px;
      height: 40px;
      padding: 4px 4px 4px 16px;
      margin: 24px 24px 0 0;
      background-color: #fff;
      border: 1px solid $border-color;
      border-radius: 8px;
    }
  }

  .voice-luyin {
    display: flex;
    border: 1px solid $border-color;
    border-radius: 0 0 8px 8px;
    align-items: center;
    padding: 3px 16px;
    height: 40px;
  }
}
</style>

<style lang="scss" scoped>
.NNPE-tableList-tr-last {
  .voice-matrix {
    padding-bottom: 0;
  }
}
</style>

<style lang="scss">
.voice-matrix {
  &-audio {
    .audioLine {
      border-radius: 8px 8px 0 0 !important;
    }

    .el-slider {
      width: 100% !important;
    }
  }

  .luyin-box {
    .el-select .el-input {
      width: 136px;
    }
  }
}
</style>
