| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- <template>
- <div class="time-line" v-show="isShow">
- <div class="play" @click="handleChange">
- <img
- class="icon"
- :src="`/src/assets/images/warningHome/${isCounting ? 'transparent-pause-icon.png' : 'transparent-play-icon.png'}`"
- alt=""
- />
- </div>
- <div class="line">
- <div class="active-line" :style="{ width: numList[active] + '%' }"></div>
- <div :class="['dot-item', { mr: index === list.length - 1 }]" v-for="(item, index) in list" :key="index">
- <div :class="['dot', { active: active === index }]"></div>
- <span :class="{ text: active === index }">{{ item }}</span>
- </div>
- </div>
- </div>
- </template>
- <script setup>
- import { ref, onDeactivated,computed ,watch, onMounted} from "vue";
- import { useStore } from "vuex";
- const store = useStore();
- const isShow = ref(true)
- // const explainParams = computed(() => store.state.home.explainData);
- // // 监听 periodId 的变化
- // watch(() => explainParams.value, (newValue, oldValue) => {
- // isShow.value = false
- // if (newValue.id) {
- // isShow.value = true
- // }
- // });
- onMounted(()=>{
- // restActive()
- fetchYearQuarter()
- })
- const fetchYearQuarter = () => {
- VE_API.warning.fetchYearQuarter().then(res => {
- if (res.code === 0 && res.data && res.data.length > 0) {
- // 转换接口数据为时间轴显示格式
- const formattedList = res.data.map((item) =>
- formatYearQuarter(item.year, item.quarter)
- );
-
- // 更新时间轴列表
- list.value = formattedList;
-
- // 重置激活状态
- // restActive();
- }
- });
- }
- const active = ref(0);
- const isCounting = ref(false);
- // 计算进度条百分比位置(根据数据数量动态计算)
- const numList = computed(() => {
- return [4,17,31,45,59,72,86,99];
- // const count = list.value.length;
- // if (count <= 1) return [100];
- // const step = 100 / (count - 1);
- // return Array.from({ length: count }, (_, i) => parseFloat((i * step).toFixed(1)));
- });
- // 格式化年季度数据为显示文本
- function formatYearQuarter(year, quarter) {
- return `${year}Q${quarter}`;
- }
- // 时间轴列表数据
- const list = ref([]);
- const incrementInterval = 3000; // 默认间隔3秒
- const specialIncrementInterval = 3000; // 特殊间隔3秒
- const timer = ref(null);
- const incrementCount = (type) => {
- const maxIndex = list.value.length - 1;
- if (active.value >= maxIndex) {
- active.value = 0;
- } else {
- if(type!=='original'){
- active.value += 1;
- }
- }
- let time = incrementInterval;
- if (active.value === 0 || active.value === maxIndex) {
- time = specialIncrementInterval;
- }
- timer.value = setTimeout(() => {
- if (isCounting.value) incrementCount();
- }, time);
- };
- const timerId = ref(null);
- const handleChange = () => {
- clearTime()
- const maxIndex = list.value.length - 1;
- if (active.value === 0 || active.value === maxIndex) {
- timerId.value = setTimeout(() => {
- if (isCounting.value) incrementCount();
- }, specialIncrementInterval);
- } else {
- incrementCount('original');
- }
- isCounting.value = !isCounting.value;
- };
- onDeactivated(() => {
- clearTime();
- });
- //清除定时器
- const clearTime = () => {
- if (timerId.value) {
- clearTimeout(timerId.value);
- }
- if (timer.value) {
- clearTimeout(timer.value);
- }
- };
- const restActive = () => {
- clearTime();
- active.value = 0;
- isCounting.value = false;
- handleChange();
- };
- defineExpose({ restActive });
- </script>
- <style lang="scss" scoped>
- .time-line {
- width: 100%;
- height: 100%;
- border-radius: 10px 10px 20px 20px;
- background: rgba(35, 35, 35, 0.6);
- border: 1px solid rgba(255,255,255,0.4);
- display: flex;
- align-items: center;
- box-sizing: border-box;
- padding: 0 20px;
- .play {
- display: flex;
- align-items: center;
- margin-right: 25px;
- .icon {
- width: 46px;
- }
- }
- .line {
- background: linear-gradient(30deg, #fff 0% , rgba(44, 44, 44,0.6) 100%);
- border-radius: 2px;
- width: 88%;
- height: 2px;
- display: flex;
- justify-content: space-between;
- position: relative;
- z-index: 2;
- position: relative;
- top: -4px;
- .active-line {
- background: linear-gradient(30deg, #eccd9b 0% ,#F3C11D 100%,);
- position: absolute;
- top: 0;
- left: 0;
- height: 2px;
- z-index: 1;
- }
- .dot-item {
- color: #fff;
- font-size: 16px;
- position: relative;
- z-index: 2;
- .dot {
- width: 8px;
- height: 8px;
- background: #E6E6E6;
- border-radius: 50%;
- margin: -2.2px 0 6px 28px;
- position: relative;
- &::after{
- content: '';
- position: absolute;
- top: -2px;
- left: -2px;
- width: 8px;
- height: 8px;
- border-radius: 50%;
- border: 2px solid rgba(255,255,255,0.2);
- }
- }
- .active {
- width: 8px;
- height: 8px;
- position: relative;
- background: #F3C11D;
-
- &::after{
- content: '';
- position: absolute;
- top: -2px;
- left: -2px;
- width: 8px;
- height: 8px;
- border-radius: 50%;
- border: 2px solid rgba(243,193,29,0.2);
- }
- }
- .text {
- background: #ED9E1E;
- padding: 1px 10px;
- border-radius: 36px;
- margin-left: -8px;
- }
- }
- .mr{
- margin-right: -35px;
- }
- }
- }
- </style>
|