<template>
|
<el-row>
|
<!-- 步骤1 数据产品生成选项 -->
|
<div :class="active == 1 ? 'prod-active' : 'prod-inactive'" ref="step1Ref">
|
<transition
|
name="el-fade-in"
|
@after-leave="handleTransitionContentEnd(1)"
|
>
|
<div v-show="showStep1Content">
|
<template v-if="$slots.step1">
|
<slot name="step1"></slot>
|
</template>
|
<template v-else>
|
<ProdQueryOpt :loading="loading" @submit="onSearch"> </ProdQueryOpt>
|
</template>
|
</div>
|
</transition>
|
<transition
|
name="el-fade-in"
|
@after-leave="handleTransitionThumbnailEnd(1)"
|
>
|
<div
|
v-show="showStep1Thumbnail"
|
class="prod-thumbnail-wrapper"
|
:style="{ height: viewHeight }"
|
@click="changeActive(1)"
|
>
|
<div class="prod-thumbnail">①修改选项</div>
|
</div>
|
</transition>
|
</div>
|
<!-- 步骤2 数据产品结果预览 -->
|
<div :class="active == 2 ? 'prod-active' : 'prod-inactive'" ref="step2Ref">
|
<transition
|
name="el-fade-in"
|
@after-leave="handleTransitionContentEnd(2)"
|
>
|
<div v-show="showStep2Content">
|
<div ref="titleRef" class="prod-title">
|
<el-text tag="b" size="large">数据产品预览</el-text>
|
</div>
|
<slot name="step2" :contentHeight="contentHeight"></slot>
|
</div>
|
</transition>
|
<transition
|
name="el-fade-in"
|
@after-leave="handleTransitionThumbnailEnd(2)"
|
>
|
<div
|
v-show="showStep2Thumbnail"
|
class="prod-thumbnail-wrapper"
|
:style="{ height: viewHeight }"
|
@click="changeActive(2)"
|
>
|
<div
|
:class="
|
'prod-thumbnail prod-thumbnail_middle ' +
|
(active < 2 ? 'prod-thumbnail-disabled' : '')
|
"
|
>
|
②数据产品预览
|
</div>
|
</div>
|
</transition>
|
</div>
|
<!-- 步骤3 数据产品表单下载 -->
|
<div :class="active == 3 ? 'prod-active' : 'prod-inactive'" ref="step3Ref">
|
<transition
|
name="el-fade-in"
|
@after-leave="handleTransitionContentEnd(3)"
|
>
|
<div v-show="showStep3Content">
|
<template v-if="$slots.step3">
|
<slot name="step3"></slot>
|
</template>
|
<template v-else>
|
<ProdDownload></ProdDownload>
|
</template>
|
</div>
|
</transition>
|
<transition
|
name="el-fade-in"
|
@after-leave="handleTransitionThumbnailEnd(3)"
|
>
|
<div
|
v-show="showStep3Thumbnail"
|
class="prod-thumbnail-wrapper"
|
:style="{ height: viewHeight }"
|
@click="changeActive(3)"
|
>
|
<div
|
:class="
|
'prod-thumbnail prod-thumbnail_end ' +
|
(active < 3 ? 'prod-thumbnail-disabled' : '')
|
"
|
>
|
③数据产品下载
|
</div>
|
</div>
|
</transition>
|
</div>
|
</el-row>
|
</template>
|
<script setup>
|
import { computed, inject, ref, watch, onMounted } from 'vue';
|
import { unCalc } from '@/utils/css-util';
|
import ProdQueryOpt from '@/views/fysp/data-product/base-data-product/components/ProdQueryOpt.vue';
|
import ProdDownload from '@/views/fysp/data-product/base-data-product/components/ProdDownload.vue';
|
|
const props = defineProps({
|
active: {
|
type: Number,
|
default: 1
|
},
|
loading: {
|
type: Boolean,
|
default: false
|
}
|
});
|
|
const emit = defineEmits(['update:active', 'onStep1']);
|
|
const viewHeight = inject('viewHeight');
|
|
const btnDisabled = ref(false);
|
|
const titleRef = ref(null);
|
const contentHeight = ref('50vh');
|
|
function calContentHeight() {
|
console.log(titleRef.value.offsetHeight);
|
contentHeight.value = `calc(${unCalc(viewHeight.value)} - ${
|
titleRef.value?.offsetHeight || 0
|
}px)`;
|
console.log(contentHeight.value);
|
|
}
|
|
// 步骤引用
|
const step1Ref = ref(null);
|
const step2Ref = ref(null);
|
const step3Ref = ref(null);
|
|
// 控制显示/隐藏的状态
|
const showStep1Content = ref(props.active === 1);
|
const showStep1Thumbnail = ref(props.active != 1);
|
const showStep2Content = ref(props.active === 2);
|
const showStep2Thumbnail = ref(props.active != 2);
|
const showStep3Content = ref(props.active === 3);
|
const showStep3Thumbnail = ref(props.active != 3);
|
|
// 记录动画是否正在进行中
|
const isAnimating = ref({});
|
|
// 监听active变化
|
watch(
|
() => props.active,
|
(newActive, oldActive) => {
|
// 标记动画开始
|
isAnimating.value[oldActive] = true;
|
isAnimating.value[newActive] = true;
|
|
// 先隐藏所有内容,等待动画结束后再显示正确的内容
|
if (oldActive === 1) {
|
showStep1Content.value = false;
|
} else if (oldActive === 2) {
|
showStep2Content.value = false;
|
} else if (oldActive === 3) {
|
showStep3Content.value = false;
|
}
|
|
if (newActive === 1) {
|
showStep1Thumbnail.value = false;
|
} else if (newActive === 2) {
|
showStep2Thumbnail.value = false;
|
} else if (newActive === 3) {
|
showStep3Thumbnail.value = false;
|
}
|
}
|
);
|
|
// 处理动画结束事件
|
function handleTransitionThumbnailEnd(stepIndex) {
|
// 检查动画是否确实结束(避免重复触发)
|
if (isAnimating.value[stepIndex]) {
|
isAnimating.value[stepIndex] = false;
|
|
// setTimeout(() => {
|
// 动画结束后,更新显示状态
|
if (stepIndex === 1) {
|
showStep1Content.value = props.active === 1;
|
} else if (stepIndex === 2) {
|
showStep2Content.value = props.active === 2;
|
} else if (stepIndex === 3) {
|
showStep3Content.value = props.active === 3;
|
}
|
// }, 50);
|
}
|
}
|
|
function handleTransitionContentEnd(stepIndex) {
|
// 检查动画是否确实结束(避免重复触发)
|
if (isAnimating.value[stepIndex]) {
|
isAnimating.value[stepIndex] = false;
|
|
// setTimeout(() => {
|
// 动画结束后,更新显示状态
|
if (stepIndex === 1) {
|
showStep1Thumbnail.value = props.active != 1;
|
} else if (stepIndex === 2) {
|
showStep2Thumbnail.value = props.active != 2;
|
} else if (stepIndex === 3) {
|
showStep3Thumbnail.value = props.active != 3;
|
}
|
// }, 50);
|
}
|
}
|
|
function onSearch(opt) {
|
emit('onStep1', opt);
|
}
|
function changeActive(index) {
|
let isAnimate = false;
|
Object.values(isAnimating.value).forEach((item) => {
|
isAnimate = isAnimate || item;
|
});
|
if (!isAnimate && !btnDisabled.value && props.active >= index) {
|
emit('update:active', index);
|
btnDisabled.value = true;
|
setTimeout(() => {
|
btnDisabled.value = false;
|
}, 500);
|
}
|
// emit('update:active', index);
|
}
|
|
onMounted(() => {
|
calContentHeight();
|
});
|
</script>
|
<style scoped>
|
.prod-active {
|
/* width: 66.667%; */
|
width: 90%;
|
transition:
|
width 0.5s ease,
|
box-shadow 0.3s ease;
|
/* background-color: #409eff; */
|
margin: 5px 0;
|
border-radius: 4px;
|
box-shadow:
|
-3px 0 6px rgba(0, 0, 0, 0.1),
|
3px 0 6px rgba(0, 0, 0, 0.1);
|
}
|
|
.prod-inactive {
|
/* width: 16.667%; */
|
width: 5%;
|
transition: width 0.5s ease;
|
/* background-color: #e4e7ed; */
|
margin: 5px 0;
|
border-radius: 4px;
|
}
|
|
.prod-title {
|
padding: 10px;
|
}
|
|
.prod-thumbnail-wrapper {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
padding: 0 2px;
|
}
|
|
.prod-thumbnail {
|
height: 90%;
|
width: 100%;
|
background-color: #409eff;
|
color: white;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
writing-mode: vertical-rl;
|
text-orientation: upright;
|
letter-spacing: 8px;
|
font-size: 18px;
|
font-weight: 500;
|
border-top-left-radius: 4px;
|
border-bottom-left-radius: 4px;
|
cursor: pointer;
|
}
|
|
.prod-thumbnail_middle {
|
border-radius: 0px;
|
}
|
|
.prod-thumbnail_end {
|
border-top-left-radius: 0px;
|
border-bottom-left-radius: 0px;
|
border-top-right-radius: 4px;
|
border-bottom-right-radius: 4px;
|
}
|
|
.prod-thumbnail-disabled {
|
background-color: #e4e7ed;
|
color: #c0c4cc;
|
cursor: not-allowed;
|
}
|
</style>
|