PopFrame.vue 8.2 KB
<template>
  <div id="pop-frame">
    <transition-group name="slide">
      <div v-for="item in data" :key="item" :class="item.ranksBackground ? 'pop-box away-bg' : 'pop-box home-bg'">
        <div class="left">
          <div class="time">{{ showStatusTime(item) }}<i class="flicker" v-if="showStatusTime(item) != ''">'</i></div>
          <div class="type-icon">
            <template v-if="type_config[item.isType].icon == 'jinqiu'">
              <svg-icon className="jinqiu" :iconName="type_config[item.isType].icon"></svg-icon>
            </template>
            <template v-else>
              <svg-icon :iconName="type_config[item.isType].icon"></svg-icon>
            </template>
          </div>
        </div>
        <div class="center">
          <div class="home">{{ teamName(item, 'host') }}</div>
          <div class="home-score">{{ item.score[0] }}</div>
          <div class="vs">-</div>
          <div class="away-score">{{ item.score[1] }}</div>
          <div class="away">{{ teamName(item, 'away') }}</div>
        </div>
        <div class="right">
          <div :style="{ color: type_config[item.isType].color }">
            {{ type_config[item.isType].text }}
          </div>
        </div>
      </div>
    </transition-group>
  </div>
</template>

<script lang="ts">export default { name: 'PopFrame' };</script>
<script lang="ts" setup>
import { ref, onMounted, computed } from 'vue';
import { useStore } from 'vuex';
import { default as _ } from 'lodash';
import moment from 'moment';
import { watch } from 'vue';

const store = useStore();
const data: any = ref([]);
const idArr: any = ref({ score: [], red: [], yellow: [] });
const typeArr = ['score', 'red', 'yellow'];

const type_config: any = {
  score: { text: '进球', color: '#2482FF', icon: 'jinqiu' },
  red: { text: '红牌', color: '#FF1818', icon: 'hongpai' },
  yellow: { text: '黄牌', color: '#FFCD00', icon: 'huangpai' },
};

const common_data: any = computed(() => store.state.common_data);

const delItem = (id: any, type: any) => {
  for (let i = 0; i < data.value.length; i++) {
    let item = data.value[i];
    if (item.id == id && item.isType == type) {
      data.value.splice(i, 1);
      break;
    }
  }
  idArr.value[type].splice(idArr.value[type].indexOf(id), 1);
  // console.log('delItem', id, type, moment().format('mm:ss'));
};
const delType = (type: any) => {
  idArr.value[type] = [];
  for (let i = 0; i < data.value.length; i++) {
    let item = data.value[i];
    if (item.isType == type) {
      data.value.splice(i, 1);
      i--;
    }
  }
  // console.log('delType', type, moment().format('mm:ss'));
};
watch(() => store.state.high_light, (newVal: any, oldVal: any) => {
  if (!switchPopFrame.value) return;
  let high_light = JSON.parse(JSON.stringify(newVal));
  // console.log('change', high_light, moment().format('mm:ss'));
  for (let i = 0; i < typeArr.length; i++) {
    let type = typeArr[i];
    let lenArr = Object.keys(high_light[type]);
    if (oldVal[type].length < 1 && lenArr.length < 1) continue;
    if (lenArr.length < 1) { // 移除大类
      if (idArr.value[type].length > 0) delType(type);
    } else {
      for (let index = 0; index < lenArr.length; index++) { // 新增
        let id = lenArr[index];
        let item = _.clone(high_light[type][id]);
        if (!idArr.value[type].includes(id)) {
          // 提示范围
          if (store.state.set_config.type == 'jz' && !item.is_jingcai) continue;
          if (store.state.set_config.type == 'follow' && !store.state.attention_id_list.includes(id)) continue;
          // 提示类型
          if (type == 'score' && !store.state.set_config.goal) continue;
          if (type == 'red' && !store.state.set_config.red) continue;
          if (type == 'yellow' && !store.state.set_config.yellow) continue;
          idArr.value[type].push(id);
          item.isType = type;
          data.value.push(item);
          // 提示声音
          if (!store.state.set_config.switch) continue;
          switch (type) {
            case 'score':
              goalPlayer.value.play();
              break;
            case 'red':
              redPlayer.value.play();
              break;
            case 'yellow':
              yellowPlayer.value.play();
              break;
          }
        }
      }
      for (let index1 = 0; index1 < idArr.value[type].length; index1++) { // 移除
        let id = idArr.value[type][index1];
        if (!lenArr.includes(id)) delItem(id, type);
      }
    }
  }
}, { deep: true });

const showStatusTime = (data: any) => {
  let contrastTime: any = store.state.nm_live_message[data.id]?.score[4] ?
    moment(store.state.nm_live_message[data.id]?.score[4] * 1000) : '';
  if (contrastTime == '') return '';
  let startTime = moment(contrastTime).valueOf();
  let abs: any = moment(store.state.server_time).diff(startTime, 'minutes') + 1;
  if (abs < 1) return '';
  if (data.status == 2 && abs > 45) {
    abs = '45+';
  } else if (data.status == 4 && abs > 90) {
    abs = '90+';
  } else {
    abs = abs + (data.status == 4 ? 45 : 0);
  }
  return abs;
};
const teamName = (data: any, type: string) => {
  return data[`${type}_short_name`] ? data[`${type}_short_name`] : data[`${type}_name`] ? data[`${type}_name`] : '';
};

const goalPlayer = ref(new Audio('https://img2.ydniu.com/app/other/goal.mp3'));
const redPlayer = ref(new Audio('https://img2.ydniu.com/app/other/red.mp3'));
const yellowPlayer = ref(new Audio('https://img2.ydniu.com/app/other/yellow.mp3'));

const switchPopFrame = ref(false);
onMounted(() => {
  
  let timer: any = setTimeout(() => {
    if(!common_data.value.isApp){ // 非app中才弹框
      switchPopFrame.value = true;
      clearTimeout(timer);
      timer = null;
    }
  }, 5000);
});
</script>

<style lang="scss" scoped>
#pop-frame {
  z-index: 999999;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 38px;
  margin: 0 auto;
  max-width: 769Px;
  min-width: 320Px;
  pointer-events: none;

  .pop-box {
    width: 94%;
    height: 44px;
    padding: 0 3%;
    margin: 10px auto 0 auto;
    color: #202020;
    font-size: 14px;
    line-height: 44px;
    text-align: center;
    border-radius: 22px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: #000;

    .left {
      width: 18%;
      display: flex;

      .time {
        flex: 1;
        color: #ffffff;

        i {
          color: #ffffff;
        }
      }

      .type-icon {
        flex: 1;

        svg {
          width: 14px;
          height: 14px;
        }
      }
    }

    .center {
      width: 64%;
      display: flex;

      .home {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: flex-end;
        font-size: 14px;
        font-weight: bold;
        line-height: 20px;
        white-space: normal;
      }

      .home-score {
        width: 18px;
        font-size: 18px;
        font-weight: bold;
      }

      .vs {
        width: auto;
        padding: 0 2px;
        font-size: 20px;
        font-weight: bold;
      }

      .away-score {
        width: 18px;
        font-size: 18px;
        font-weight: bold;
      }

      .away {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: flex-start;
        font-size: 14px;
        font-weight: bold;
        line-height: 20px;
        white-space: normal;
      }
    }

    .right {
      width: 18%;
      display: flex;

      div {
        flex: 1;
        text-align: center;
      }
    }
  }

  .home-bg {
    background: linear-gradient(90deg, #FF8E8E 0%, #FFF3D7 100%);

    .home,
    .home-score {
      color: #DA2323;
    }
  }

  .away-bg {
    background: linear-gradient(90deg, #FFF3D7 0%, #FF8E8E 100%);

    .time {
      color: #333333 !important;

      i {
        color: #333333 !important;
      }
    }

    .away,
    .away-score {
      color: #DA2323;
    }
  }
}

.slide-enter-active {
  animation: slideInLeft 0.6s;
}

.slide-leave-active {
  animation: slideOutRight 0.3s;
}

@keyframes flicker {
  0% {
    opacity: 1;
  }

  50% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }
}

.flicker {
  animation: flicker 1s infinite;
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

.jinqiu {
  animation: rotate 1s linear infinite;
}
</style>