<script lang="ts" setup>
|
import { computed, onMounted, ref } from 'vue';
|
|
import { LeftCircleOutlined, RightCircleOutlined } from '@ant-design/icons-vue';
|
import { Carousel } from 'ant-design-vue';
|
import { cloneDeep } from 'lodash-es';
|
|
import { getDataInterfaceRes } from '#/api/systemData/dataInterface';
|
import { getAuthMediaUrl } from '#/utils/jnpf';
|
|
import CardHeader from '../CardHeader/index.vue';
|
import webLink from '../Link/index.vue';
|
|
const props = defineProps(['activeData']);
|
const key = ref<any>();
|
const list = ref<any[]>([]);
|
|
const getDotPosition = computed(() => {
|
const position = props.activeData.option.carouselIndicatorPosition;
|
const direction = props.activeData.option.carouselDirection;
|
if (direction == 'horizontal') return position == 'topLeft' ? 'top' : 'bottom';
|
return position == 'topLeft' ? 'left' : 'right';
|
});
|
|
async function initData() {
|
const val = cloneDeep(props.activeData.option.defaultValue);
|
for (const ele of val) {
|
if (ele.dataType == 1) ele.imageUrl = getAuthMediaUrl(ele.imageUrl);
|
if (ele.dataType == 3) {
|
const res = await getDataInterfaceRes(ele.propsApi);
|
ele.imageUrl = res?.data ? res.data : [];
|
}
|
}
|
list.value = val;
|
}
|
|
onMounted(() => initData());
|
</script>
|
<template>
|
<a-card class="portal-card-box">
|
<template #title v-if="activeData.title">
|
<CardHeader :title="activeData.title" :card="activeData.card" />
|
</template>
|
<div class="portal-card-body">
|
<Carousel
|
:autoplay-speed="activeData.option.carouselInterval"
|
:autoplay="activeData.option.carouselAutoplay"
|
:dot-position="getDotPosition"
|
:dots="activeData.option.carouselIndicatorPosition !== 'none'"
|
:arrows="activeData.option.carouselArrow !== 'never'"
|
:class="{ 'carousel-arrows-hover': activeData.option.carouselArrow == 'hover' }">
|
<template #prevArrow>
|
<div class="custom-slick-arrow !left-[10px] z-[1]">
|
<LeftCircleOutlined />
|
</div>
|
</template>
|
<template #nextArrow>
|
<div class="custom-slick-arrow !right-[10px]">
|
<RightCircleOutlined />
|
</div>
|
</template>
|
<web-link
|
class="web-link"
|
:link-type="item.linkType"
|
:url-address="item.urlAddress"
|
:link-target="item.linkTarget"
|
:type="item.type"
|
:property-json="item.propertyJson"
|
v-for="(item, index) in list"
|
:key="index">
|
<img :key="key" :style="{ 'object-fit': activeData.option.imageFillStyle }" :src="item.imageUrl" />
|
<div
|
class="bottom-text text-ellipsis"
|
v-if="item.textDefaultValue"
|
:style="{
|
color: activeData.option.textFontColor,
|
'font-size': `${activeData.option.textFontSize}px`,
|
'text-align': activeData.option.textLeft,
|
'font-weight': activeData.option.textFontWeight ? 'bolder' : 'normal',
|
background: activeData.option.textBgColor,
|
padding: activeData.option.carouselIndicatorPosition == 'bottomRight' && activeData.option.carouselDirection == 'horizontal' ? '0 10px 15px' : '',
|
}">
|
{{ item.textDefaultValue }}
|
</div>
|
</web-link>
|
</Carousel>
|
</div>
|
</a-card>
|
</template>
|
<style lang="scss" scoped>
|
.ant-carousel {
|
height: 100%;
|
|
:deep(.slick-slider) {
|
height: 100% !important;
|
|
.slick-list,
|
.slick-track {
|
height: 100% !important;
|
}
|
|
.slick-slide {
|
height: 100% !important;
|
|
> div {
|
height: 100% !important;
|
}
|
}
|
|
ul {
|
margin-bottom: unset;
|
}
|
}
|
|
:deep(.slick-arrow.custom-slick-arrow) {
|
z-index: 1;
|
width: 25px;
|
height: 25px;
|
font-size: 25px;
|
color: #fff;
|
background-color: rgb(31 45 61 / 11%);
|
opacity: 0.3;
|
}
|
|
:deep(.custom-slick-arrow::before) {
|
display: none;
|
}
|
|
:deep(.custom-slick-arrow:hover) {
|
opacity: 0.5;
|
}
|
}
|
|
.carousel-arrows-hover {
|
:deep(.slick-arrow.custom-slick-arrow) {
|
display: none !important;
|
}
|
|
&:hover {
|
:deep(.slick-arrow.custom-slick-arrow) {
|
display: block !important;
|
}
|
}
|
}
|
|
.portal-card-body {
|
height: 100%;
|
|
.web-link {
|
position: relative;
|
}
|
|
.web-link,
|
img {
|
width: 100%;
|
height: 100%;
|
}
|
|
.bottom-text {
|
position: absolute;
|
bottom: 0;
|
box-sizing: content-box;
|
width: calc(100% - 20px);
|
height: 30px;
|
padding: 0 10px;
|
font-size: 14px;
|
line-height: 30px;
|
color: #fff;
|
background: #000;
|
}
|
}
|
</style>
|