vr-uniapp/src/components/model-salerecords/index.vue

271 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="oh" :style="style_container">
<div :style="style_img_container + `height: ${ swiper_outer_height }px;`">
<template v-if="['translation', 'vertical'].includes(form.rotation_direction)">
<div :class="form.rotation_direction == 'vertical' ? 'swiper-free-mode' : ''" :style="`height: ${ swiper_height }px;`">
<swiper :key="carouselKey" class="w flex" :style="`height: ${ swiper_height }px;`" direction="vertical" :loop="true" :speed="swiper_speed" :autoplay="autoplay" :slides-per-view="slides_per_view" :space-between="space_between" :modules="modules">
<swiper-slide v-for="(item, index) in list" :key="index">
<div class="flex-row align-c" :style="`gap: ${ new_style.content_spacing }px;`">
<template v-if="!isEmpty(item) && is_show('head')">
<div class="oh re">
<image-empty v-model="item.user.avatar" :style="heading_img_radius"></image-empty>
</div>
</template>
<span v-if="is_show('nick_name')" class="text-line-1" :style="trends_config('nick_name')">{{ item.user.user_name_view }}</span>
<template v-if="is_show('goods_image')">
<image-empty v-model="item.images" :style="goods_image_radius"></image-empty>
</template>
<span v-if="is_show('goods_title')" class="flex-1 text-line-1" :style="trends_config('goods_title')">{{ item.title }}</span>
<span v-if="is_show('time')" class="nowrap" :style="trends_config('time')">{{ item.add_time }}</span>
</div>
</swiper-slide>
</swiper>
</div>
</template>
<template v-else>
<div class="swiper-free-mode swiper-horizontal-free-mode" :style="`height: ${ swiper_height }px;`">
<div v-for="(item, index) in new_list" :key="index" :style="`margin-bottom: ${ index < new_list.length - 1 ? space_between : 0 }px;`">
<swiper :key="carouselKey + index" class="w flex" :style="`height: ${ new_swiper_height }px;`" direction="horizontal" :loop="true" :slides-offset-before="slides_offset_before_list[index].is_left ? slides_offset_before : 0" :speed="swiper_speed + (1000 * index)" :autoplay="autoplay" slides-per-view="auto" :space-between="space_between" :modules="modules">
<swiper-slide v-for="(item1, index1) in item.split_list" :key="index1">
<div :style="swiper_horizontal_container + 'width: auto;'">
<div class="flex-row align-c" :style="swiper_horizontal_img_container + `gap: ${ new_style.content_spacing }px;`">
<template v-if="is_show('goods_image')">
<image-empty v-model="item1.images" :style="goods_image_radius"></image-empty>
</template>
<span v-if="is_show('goods_title')" class="flex-1 text-line-1" :style="trends_config('goods_title') + `max-width: ${ max_title_width }px;`">{{ item1.title }}</span>
<span v-if="is_show('time')" class="nowrap" :style="trends_config('time')">{{ item1.add_time }}</span>
</div>
</div>
</swiper-slide>
</swiper>
</div>
</div>
</template>
</div>
</div>
</template>
<script setup lang="ts">
import { common_styles_computer, common_img_computer, get_math, gradient_handle, radius_computer, background_computer, padding_computer } from '@/utils';
import { isEmpty, cloneDeep } from 'lodash';
import SalerecordsAPI from '@/api/salerecords';
import { Swiper, SwiperSlide } from 'swiper/vue';
import { Autoplay } from 'swiper/modules';
const modules = [Autoplay];
/**
* @description:
* @param value{Object}
* @param isCommonStyle{Object}
*/
const props = defineProps({
value: {
type: Object,
default: () => ({}),
},
isCommonStyle: {
type: Boolean,
default: true,
},
});
const form = computed(() => props.value?.content || {});
const new_style = computed(() => props.value?.style || {});
// 头像样式
const heading_img_radius = computed(() => {
const { heading_img_radius, heading_img_width, heading_img_height, heading_img_border_color, heading_img_border_size } = new_style.value
return `width: ${ heading_img_width }px;height: ${ heading_img_height }px;border: ${ heading_img_border_size }px solid ${ heading_img_border_color };` + radius_computer(heading_img_radius);
});
const goods_image_radius = computed(() => {
const { goods_img_radius, goods_img_width, goods_img_height, goods_img_border_color, goods_img_border_size } = new_style.value
return `width: ${ goods_img_width }px;height: ${ goods_img_height }px;border: ${ goods_img_border_size }px solid ${ goods_img_border_color };` + radius_computer(goods_img_radius);
});
// 根据传递的参数,从对象中取值
const trends_config = (key: string) => {
return style_config(new_style.value[`${key}_typeface`], new_style.value[`${key}_size`], new_style.value[`${key}_color`]);
};
// 根据传递的值,显示不同的内容
const style_config = (typeface: string, size: number, color: string | object) => {
return `font-weight:${typeface}; font-size: ${size}px;line-height: ${ size }px;color: ${color};`;
};
// 判断是否显示对应的内容
const is_show = (index: string) => {
return form.value.is_show.includes(index);
};
// 横向时的显示内容
const swiper_horizontal_container = computed(() => {
const { content_color_list, content_direction, content_radius } = new_style.value
return gradient_handle(content_color_list, content_direction) + radius_computer(content_radius);
});
// 横向时的图片显示内容
const swiper_horizontal_img_container = computed(() => {
const { content_background_img_style, content_background_img, content_padding } = new_style.value;
const data = {
background_img_style: content_background_img_style,
background_img: content_background_img,
}
return background_computer(data) + padding_computer(content_padding);
})
// 公共样式
const style_container = computed(() => common_styles_computer(new_style.value.common_style));
const style_img_container = computed(() => common_img_computer(new_style.value.common_style));
//#region 列表数据
type data_list = {
user: {
avatar: string,
user_name_view: string,
},
title: string,
images: string,
add_time: string
}
const default_list = {
user: {
avatar: '',
user_name_view: '测试昵称测试昵称测试昵称测试昵称',
},
title: '测试商品标题测试',
images: '',
add_time: '02-04 23:01:01'
};
type split_list = {
split_list: data_list[]
}
const new_list = ref<split_list[]>([]);
const list = ref<data_list[]>([]);
// 初始化的时候执行
onMounted(() => {
if (!isEmpty(form.value.data_auto_list)) {
// 筛选商品并且筛选商品数组不为空
list.value = form.value.data_auto_list;
} else {
list.value = Array(10).fill(default_list);
}
});
const get_products = () => {
const { number, keywords } = form.value;
const params = {
keywords: keywords,
number: number,
};
// 获取商品列表
SalerecordsAPI.getAutoList(params).then((res: any) => {
if (!isEmpty(res.data)) {
list.value = res.data;
} else {
list.value = Array(10).fill(default_list);
}
});
};
// 取出监听的数据
const watch_data = computed(() => {
const { keywords, number } = form.value;
return { keywords, number };
})
// 初始化的时候不执行, 监听数据变化
watch(() => watch_data.value, (val, oldVal) => {
// 使用JSON.stringify()进行判断 新值和旧值是否一样 不一样就重新获取数据
if ((JSON.stringify(val) !== JSON.stringify(oldVal)) || props.isCommonStyle) {
get_products();
}
}, { immediate: true, deep: true });
//#endregion
//#region 轮播设置
// 轮播图key值
const carouselKey = ref('0');
// 是否开启轮播
const autoplay = ref<boolean | object>(false);
// 轮播内容显示数量
const slides_per_view = ref(1);
// 轮播内容间隔
const space_between = ref(0);
// 纵向轮播时的轮播图高度
const swiper_height = ref(0);
// 整个容器的高度
const swiper_outer_height = ref(0);
// 移动时间
const swiper_speed = ref(0);
// 商品标题最大可见数量
const max_title_width = ref(0);
// 横向滑动时轮播图高度
const new_swiper_height = ref(0);
// 设置初始偏移量
const slides_offset_before = ref(0);
type before_list = { is_left: boolean }
const slides_offset_before_list = ref<before_list[]>([]);
const size_handle = (val: number, type: string) => {
return form.value.is_show.includes(type) ? val : 0;
};
const slideChange = (swiper: { realIndex: number }, index: number, value_length: number) => {
if (swiper.realIndex >= value_length - 1) {
slides_offset_before_list.value[index].is_left = false;
}
}
// 内容参数的集合
watchEffect(() => {
const { rotation_direction, interval_time, show_number = 1, is_roll } = form.value;
// 是否滚动
if ((is_roll == '1' || rotation_direction == 'horizontal') && list.value.length > 0) {
autoplay.value = {
delay: rotation_direction == 'translation' ? interval_time * 1000 : 0,
waitForTransition: true,
pauseOnMouseEnter: true,
};
} else {
autoplay.value = false;
}
// 数据间距
space_between.value = new_style.value.data_spacing;
// 显示数量
const show_num = show_number || 1;
slides_per_view.value = show_num;
// 轮播图速度
swiper_speed.value = rotation_direction == 'translation' ? 1000 : interval_time * 1000;
// 轮播图高度
const { heading_img_height, nick_name_size, goods_img_height, goods_title_size, time_size, data_spacing, common_style, content_padding } = new_style.value;
if (['translation', 'vertical'].includes(rotation_direction)) {
swiper_height.value = Math.max(size_handle(heading_img_height, 'head'), size_handle(nick_name_size, 'nick_name'), size_handle(goods_img_height, 'goods_image'), size_handle(goods_title_size, 'goods_title'), size_handle(time_size, 'time')) * show_num + (data_spacing * (show_num - 1));
} else {
// 设置初始偏移量
slides_offset_before.value = 390 - common_style.margin_left + common_style.margin_right - common_style.padding_left - common_style.padding_right;
max_title_width.value = goods_title_size * 9;
new_list.value = [];
slides_offset_before_list.value = [];
// 拆分的数量
const split_num = Math.ceil(list.value.length / show_num);
let new_num = show_num;
for (let i = 0; i < show_num; i++) {
if (!isEmpty(list.value[i * split_num])) {
new_list.value.push({ split_list: list.value.slice(i * split_num, (i + 1) * split_num) });
slides_offset_before_list.value.push({ is_left: true });
} else {
new_num = i - 1;
break;
}
}
// 每个swiper的高度
new_swiper_height.value = Math.max(size_handle(goods_img_height, 'goods_image'), size_handle(goods_title_size, 'goods_title'), size_handle(time_size, 'time')) + content_padding.padding_top + content_padding.padding_bottom;
// 总的高度
swiper_height.value = new_swiper_height.value * new_num + (data_spacing * (new_num - 1));
}
swiper_outer_height.value = swiper_height.value + common_style.padding_top + common_style.padding_bottom;
// 更新轮播图的key确保更换时能重新更新轮播图
carouselKey.value = get_math();
});
//#endregion
</script>
<style lang="scss" scoped>
:deep(.el-image) {
background-color: #fff;
.image-slot img {
width: 2rem;
height: 2rem;
}
}
.swiper-free-mode :deep(.swiper-wrapper) {
transition-timing-function: linear !important;
}
.swiper-horizontal-free-mode :deep(.swiper-slide) {
width: auto !important;
}
</style>