Merge remote-tracking branch 'origin/dev-yxl' into dev-sws

master
sws 2024-09-19 18:10:34 +08:00
commit 4efca75ac1
13 changed files with 935 additions and 41 deletions

View File

@ -181,4 +181,16 @@ export function get_math () {
randomString = randomString.length >= 6 ? randomString : randomString.padStart(6, '0');
// 截取掉随机字符串开头的'0.'部分获得最终的6位随机字符串。
return randomString.substring(2);
}
}
/**
* 将大小计算成百分比
*
* @param num 当前的大小或位置
* @param size 容器的大小
* @returns 计算后的百分比值含4位小数
*/
export const percentage_count = (num, container_size) => {
const marks = (num / container_size) * 100;
return marks.toFixed(4) + '%';
};

86
components/diy/custom.vue Normal file
View File

@ -0,0 +1,86 @@
<template>
<view ref="container" :style="style_container + 'height:'+ form.height * 2 + 'rpx;'">
<view class="wh-auto ht-auto pr">
<view v-for="item in form.custom_list" :key="item.id" class="main-content" :style="{'left': get_percentage_count(item.location.x, div_width) , 'top': get_percentage_count(item.location.y, form.height), 'width': get_percentage_count(item.com_data.com_width, div_width), 'height': get_percentage_count(item.com_data.com_height, form.height)}">
<template v-if="item.key == 'text'">
<model-text :key="item.com_data" :value="item.com_data" :source-list="form.data_source_content" @url_open="url_open"></model-text>
</template>
<template v-else-if="item.key == 'img'">
<model-image :key="item.com_data" :value="item.com_data" :source-list="form.data_source_content" @url_open="url_open"></model-image>
</template>
<template v-else-if="item.key == 'auxiliary-line'">
<model-lines :key="item.com_data" :value="item.com_data" :source-list="form.data_source_content"></model-lines>
</template>
</view>
</view>
</view>
</template>
<script>
import { common_styles_computer, percentage_count } from '@/common/js/common/common.js';
const app = getApp();
var system = app.globalData.get_system_info(null, null, true);
var sys_width = app.globalData.window_width_handle(system.windowWidth);
import modelText from '@/components/diy/modules/custom/model-text.vue';
import modelLines from '@/components/diy/modules/custom/model-lines.vue';
import modelImage from '@/components/diy/modules/custom/model-image.vue';
export default {
components: {
modelText,
modelLines,
modelImage
},
props: {
value: {
type: Object,
default: () => {
return {};
},
},
},
data() {
return {
form: {},
new_style: {},
style_container: '',
custom_height: 0,
};
},
computed: {
get_percentage_count() {
return (num, container_size) => {
return this.percentage_count(num, container_size);
}
}
},
created() {
this.setData({
form: this.value.content,
new_style: this.value.style,
});
this.init();
},
methods: {
percentage_count,
init() {
this.setData({
style_container: common_styles_computer(this.new_style.common_style) + 'box-sizing: border-box;', //
div_width: sys_width
});
},
url_open(link) {
if (!isEmpty(link)) {
app.globalData.url_open(link);
}
},
},
};
</script>
<style scoped lang="scss">
.main-content {
position: absolute;
overflow: hidden;
}
</style>

View File

@ -0,0 +1,320 @@
<template>
<view ref="container" class="img-magic" :style="'height:' + container_size + ';' + style_container">
<view class="pr" :style="'width:calc(100% + ' + outer_spacing + ');height:calc(100% + ' + outer_spacing +');margin:-' + spacing + ';'">
<!-- 风格9 -->
<template v-if="form.style_actived == 7">
<view class="flex-row align-c jc-c style-size flex-wrap">
<view v-for="(item, index) in data_magic_list" :key="index" :style="item.data_style.background_style + content_radius + 'margin:'+ spacing + ';' + ([0, 1].includes(index) ? 'width:calc(50% - ' + outer_spacing + ');height:calc(50% - ' + outer_spacing +')' : 'width:calc((100% / 3) - ' + outer_spacing + ');height:calc(50% - ' + outer_spacing + ')')" class="style9">
<template v-if="item.data_content.data_type == 'goods'">
<view class="wh-auto ht-auto flex-col gap-20" :style="[0, 1].includes(index) ? item.data_style.chunk_padding_data : ''">
<view v-if="(!isEmpty(item.data_content.heading_title) || !isEmpty(item.data_content.subtitle)) && [0, 1].includes(index)" class="flex-col gap-5 tl">
<p class="ma-0 wh-auto text-line-1" :style="item.data_style.daheading_style">{{ item.data_content.heading_title || '' }}</p>
<p class="ma-0 wh-auto text-line-1" :style="item.data_style.subtitle_style">{{ item.data_content.subtitle || '' }}</p>
</view>
<view class="wh-auto ht-auto">
<magic-carousel :value="item" :content-img-radius="content_img_radius" :actived="form.style_actived" type="product" @carousel_change="carousel_change($event, index)"></magic-carousel>
</view>
</view>
</template>
<template v-else>
<magic-carousel :value="item" :content-img-radius="content_img_radius" type="img" :actived="form.style_actived" @carousel_change="carousel_change($event, index)"></magic-carousel>
</template>
<view v-if="item.data_style.is_show == '1' && item.data_content.list.length > 1" :class="{'dot-center': item.data_style.indicator_location == 'center', 'dot-right': item.data_style.indicator_location == 'flex-end' }" class="dot flex-row pa" :style="{'bottom': item.data_style.indicator_bottom * 2 +'rpx'}">
<template v-if="item.data_style.indicator_style == 'num'">
<view :style="item.data_style.indicator_styles" class="dot-item">
<span class="num-active" :style="{'color': item.data_style.actived_color }">{{ item.actived_index + 1 }}</span><span>/{{ item.data_content.list.length }}</span>
</view>
</template>
<template v-else>
<view v-for="(item3, index3) in item.data_content.list" :key="index3" :style="item.data_style.indicator_styles + style_actived_color(item, index3)" class="dot-item" />
</template>
</view>
</view>
</view>
</template>
<template v-else>
<view v-for="(item, index) in data_magic_list" :key="index" class="cube-selected cr-main" :style="selected_style(item) + item.data_style.background_style + content_radius + ';margin:'+ spacing + ';'">
<template v-if="item.data_content.data_type == 'goods'">
<view :class="[spacing_processing(index) ? 'gap-20 wh-auto ht-auto flex-col' : 'gap-10 wh-auto ht-auto flex-col']" :style="item.data_style.chunk_padding_data">
<view v-if="!isEmpty(item.data_content.heading_title) || !isEmpty(item.data_content.subtitle)" class="flex-col gap-5 tl">
<p class="ma-0 wh-auto text-line-1" :style="item.data_style.heading_style">{{ item.data_content.heading_title || '' }}</p>
<p class="ma-0 wh-auto text-line-1" :style="item.data_style.subtitle_style">{{ item.data_content.subtitle || '' }}</p>
</view>
<view class="wh-auto ht-auto">
<magic-carousel :value="item" :content-img-radius="content_img_radius" type="product" :actived="form.style_actived" @carousel_change="carousel_change($event, index)"></magic-carousel>
</view>
</view>
</template>
<template v-else>
<magic-carousel :value="item" :content-img-radius="content_img_radius" type="img" :actived="form.style_actived" @carousel_change="carousel_change($event, index)"></magic-carousel>
</template>
<view v-if="item.data_style.is_show == '1' && item.data_content.list.length > 1" :class="{'dot-center': item.data_style.indicator_location == 'center', 'dot-right': item.data_style.indicator_location == 'flex-end' }" class="dot flex-row pa" :style="{'bottom': item.data_style.indicator_bottom * 2 +'rpx'}">
<template v-if="item.data_style.indicator_style == 'num'">
<view :style="item.data_style.indicator_styles" class="dot-item">
<span class="num-active" :style="{'color': item.data_style.actived_color }">{{ item.actived_index + 1 }}</span><span>/{{ item.data_content.list.length }}</span>
</view>
</template>
<template v-else>
<view v-for="(item3, index3) in item.data_content.list" :key="index3" :style="item.data_style.indicator_styles + style_actived_color(item, index3)" class="dot-item" />
</template>
</view>
</view>
</template>
</view>
</view>
</template>
<script>
const app = getApp();
import magicCarousel from '@/components/diy/modules/data-magic/magic-carousel.vue';
import { background_computer, common_styles_computer, gradient_computer, radius_computer, percentage_count, isEmpty, padding_computer } from '@/common/js/common/common.js';
var system = app.globalData.get_system_info(null, null, true);
var sys_width = app.globalData.window_width_handle(system.windowWidth);
export default {
components: {
magicCarousel,
},
props: {
value: {
type: Object,
default: () => ({}),
},
},
data() {
return {
form: {},
new_style: {},
//
default_list: {
title: '测试商品标题',
min_original_price: '41.2',
show_original_price_symbol: '¥',
show_original_price_unit: '/ 台',
min_price: '51',
show_price_symbol: '¥',
show_price_unit: '/ 台',
sales_count: '1000',
images: '',
new_cover: [],
plugins_view_icon_data: [
{
name: '满减活动',
bg_color: '#EA3323',
br_color: '',
color: '#fff',
url: '',
},
{
name: '包邮',
bg_color: '',
br_color: '#EA3323',
color: '#EA3323',
url: '',
},
{
name: '领劵',
bg_color: '',
br_color: '#EA9223',
color: '#EA9223',
url: '',
},
],
},
outer_spacing: '',
//
spacing: '',
//
content_radius: '',
//
content_img_radius: '',
data_magic_list: [],
cubeCellWidth: 0,
container_size: 0,
style_container: '',
};
},
computed: {
//
selected_style() {
return (item) => {
return `overflow: hidden;width: calc(${this.percentage(this.getSelectedWidth(item))} - ${ this.outer_spacing } ); height: calc(${this.percentage(this.getSelectedHeight(item))} - ${ this.outer_spacing } ); top: ${this.percentage(this.getSelectedTop(item))}; left: ${this.percentage(this.getSelectedLeft(item))};`;
}
},
style_actived_color() {
return (item, index) => {
return item.actived_index == index ? `background: ${ item.data_style.actived_color };` : '';
}
}
},
created() {
this.setData({
form: this.value.content,
new_style: this.value.style,
});
this.init();
},
methods: {
isEmpty,
init() {
const density = 4;
this.setData({
outer_spacing: this.new_style.image_spacing * 2 + 'rpx',
spacing: this.new_style.image_spacing + 'rpx',
content_radius: radius_computer(this.new_style.data_radius),
content_img_radius: radius_computer(this.new_style.img_radius),
cubeCellWidth: sys_width / density,
container_size: sys_width * 2 + 'rpx',
data_magic_list: this.get_data_magic_list(this.form.data_magic_list),
style_container: common_styles_computer(this.new_style.common_style) + 'box-sizing: border-box;', //
})
},
get_data_magic_list(data) {
data.forEach((item) => {
const data_content = item.data_content;
const data_style = item.data_style;
const key = data_style.carouselKey;
item.actived_index = 0;
//
data_style.indicator_styles = this.indicator_style(data_style);
data_style.background_style = this.background_style(data_style);
data_style.chunk_padding_data = padding_computer(item.data_style.chunk_padding) + 'box-sizing: border-box;';
data_style.heading_style = this.trends_config(item.data_style, 'heading');
data_style.subtitle_style = this.trends_config(item.data_style, 'subtitle');
const { goods_list, images_list } = data_content;
if (data_content.data_type == 'goods') {
data_content.list = this.commodity_list(data_content.goods_list, item.num);
} else {
data_content.list = data_content.images_list;
}
});
return data;
},
/*
** 组装产品的数据
** @param {Array} list 商品列表
** @param {Number} num 显示数量
** @return {Array}
*/
commodity_list(list, num) {
if (list.length > 0) {
//
const goods_list = JSON.parse(JSON.stringify(list)).map((item) => ({
...item.data,
title: !isEmpty(item.new_title) ? item.new_title : item.data.title,
new_cover: item.new_cover,
}));
//
let nav_list = [];
//
const split_num = Math.ceil(goods_list.length / num);
for (let i = 0; i < split_num; i++) {
nav_list.push({ split_list: goods_list.slice(i * num, (i + 1) * num) });
}
return nav_list;
} else {
return [{ split_list: Array(num).fill(this.default_list)}];
}
},
background_style(item) {
return gradient_computer(item) + background_computer(item);
},
getSelectedWidth (item) {
return (item.end.x - item.start.x + 1) * this.cubeCellWidth;
},
//
getSelectedHeight(item) {
return (item.end.y - item.start.y + 1) * this.cubeCellWidth;
},
//
getSelectedTop(item) {
return (item.start.y - 1) * this.cubeCellWidth;
},
//
getSelectedLeft(item) {
return (item.start.x - 1) * this.cubeCellWidth;
},
//
percentage(num) {
return percentage_count(num, sys_width);
},
//
trends_config(style, key) {
return this.text_style(style[`${key}_typeface`], style[`${key}_size`], style[`${key}_color`]);
},
text_style(typeface, size, color) {
return `font-weight:${ typeface }; font-size: ${ size * 2 }rpx; color: ${ color };`;
},
// 99
spacing_processing(index) {
return this.form.style_actived !== 8 || (this.form.style_actived === 8 && [0, 1].includes(index))
},
//
indicator_style(item) {
let styles = '';
if (!isEmpty(item.indicator_radius)) {
styles += radius_computer(item.indicator_radius)
}
const size = item.indicator_size || 5;
if (item.indicator_style == 'num') {
styles += `color: ${item.color || '#DDDDDD'};`;
styles += `font-size: ${size * 2}rpx;`;
} else if (item.indicator_style == 'elliptic') {
styles += `background: ${item.color || '#DDDDDD'};`;
styles += `width: ${size * 6 }rpx; height: ${size * 2}rpx;`;
} else {
styles += `background: ${item.color || '#DDDDDD'};`;
styles += `width: ${size * 2}rpx; height: ${size * 2 }rpx;`;
}
return styles;
},
carousel_change(e, key) {
if (this.data_magic_list[key]) {
this.data_magic_list[key].actived_index = e.target.current;
}
}
},
};
</script>
<style lang="scss" scoped>
//
.img-magic {
width: 100%;
overflow: hidden;
}
.cube-selected {
position: absolute;
text-align: center;
box-sizing: border-box;
}
.text-line-1 {
word-break: break-word;
overflow-wrap: break-word;
word-wrap: break-word;
}
.style-size {
height: 100%;
width: 100%;
.style9 {
position: relative;
overflow: hidden;
}
}
.dot-center {
left: 50%;
transform: translateX(-50%);
}
.dot-right {
right: 0;
}
.dot {
z-index: 3;
.dot-item {
margin: 0 0.3rem;
}
}
.gap-20 {
gap: 40rpx;
}
</style>

View File

@ -18,6 +18,8 @@
<componentDiyArticleTabs v-else-if="item.key == 'article-tabs'" :value="item.com_data"></componentDiyArticleTabs>
<componentGoodsTabs v-else-if="item.key == 'goods-tabs'" :value="item.com_data"></componentGoodsTabs>
<componentGoodsList v-else-if="item.key == 'goods-list'" :value="item.com_data"></componentGoodsList>
<componentDataMagic v-if="item.key == 'data-magic'" :value="item.com_data"></componentDataMagic>
<componentCustom v-if="item.key == 'custom'" :value="item.com_data"></componentCustom>
<componentDiyImgMagic v-else-if="item.key == 'img-magic'" :value="item.com_data"></componentDiyImgMagic>
<componentDiyHotZone v-else-if="item.key == 'hot-zone'" :value="item.com_data"></componentDiyHotZone>
<!-- 插件 -->
@ -39,38 +41,31 @@
</template>
<script>
const app = getApp();
//
import componentDiyHeader from '@/components/diy/header';
import componentDiyFooter from '@/components/diy/footer';
import componentDiyTabs from '@/components/diy/tabs';
import componentDiySearch from '@/components/diy/search';
import componentCarousel from '@/components/diy/carousel.vue';
import componentNavGroup from '@/components/diy/nav-group.vue';
import componentDiyUserInfo from '@/components/diy/user-info';
import componentDiyNotice from '@/components/diy/notice';
import componentDiyVideo from '@/components/diy/video';
import componentDiyArticleList from '@/components/diy/article-list';
import componentDiyArticleTabs from '@/components/diy/article-tabs';
import componentGoodsTabs from '@/components/diy/goods-tabs.vue';
import componentGoodsList from '@/components/diy/goods-list.vue';
import componentDiyImgMagic from '@/components/diy/img-magic';
import componentDiyHotZone from '@/components/diy/hot-zone';
//
import componentDiyCoupon from '@/components/diy/coupon';
//
import componentFloatWindow from '@/components/diy/float-window';
import componentTextTitle from '@/components/diy/text-title';
import componentDiyAuxiliaryLine from '@/components/diy/auxiliary-line';
import componentDiyRichText from '@/components/diy/rich-text.vue';
import componentAuxiliaryBlank from '@/components/diy/auxiliary-blank.vue';
import componentNavGroup from '@/components/diy/nav-group.vue';
import componentGoodsList from '@/components/diy/goods-list.vue';
import componentGoodsTabs from '@/components/diy/goods-tabs.vue';
import componentDataMagic from '@/components/diy/data-magic.vue';
import componentCustom from '@/components/diy/custom.vue';
//
var bar_height = parseInt(app.globalData.get_system_info('statusBarHeight', 0));
// #ifdef MP-TOUTIAO
bar_height = 0;
// #endif
export default {
name: 'diy',
props: {
@ -80,30 +75,26 @@
},
},
components: {
//
componentDiyHeader,
componentDiyFooter,
componentDiyTabs,
componentDiySearch,
componentCarousel,
componentNavGroup,
componentDiyUserInfo,
componentDiyNotice,
componentDiyVideo,
componentDiyArticleList,
componentDiyArticleTabs,
componentGoodsTabs,
componentGoodsList,
componentDiyImgMagic,
componentDiyHotZone,
//
componentDiyCoupon,
//
componentFloatWindow,
componentTextTitle,
componentDiyAuxiliaryLine,
componentDiyRichText,
componentFloatWindow,
componentTextTitle,
componentAuxiliaryBlank,
componentNavGroup,
componentGoodsList,
componentGoodsTabs,
componentDataMagic,
componentCustom,
},
data() {
return {

View File

@ -6,7 +6,7 @@
<view class="ring" :style="color"></view>
<view class="ring" :style="color"></view>
</block>
<image-empty :image-src="form.button_img[0]" class="img" :style="color" img_fit="aspectFill" error-style="width: 60rpx;height: 60rpx;"></image-empty>
<image-empty :image-src="form.button_img[0]" class="img" :type_style="color" img_fit="aspectFill" error-style="width: 60rpx;height: 60rpx;"></image-empty>
</view>
</view>
</view>
@ -52,7 +52,7 @@
}
const { windowHeight } = uni.getSystemInfoSync();
this.setData({
color: float_style == 'shadow' ? `box-shadow: 0 10rpx 40rpx ${float_style_color}` : `background-color: ${float_style_color}`,
color: float_style == 'shadow' ? `box-shadow: 0 10rpx 40rpx ${float_style_color};border-radius: 50%;` : `background-color: ${float_style_color};border-radius: 50%;`,
style: `bottom: ${((offset_number / windowHeight) * 100).toFixed(4) + '%'};` + location,
});
},

View File

@ -469,10 +469,15 @@
width: 100%;
height: 228rpx;
}
.flex-img4 {
min-width: 140rpx;
min-height: 140rpx;
height: 100%;
}
.flex-img5 {
width: 100%;
min-height: 208rpx;
height: 100%;
}
.plr-11 {
padding-left: 22rpx;
@ -490,10 +495,6 @@
padding-top: 10rpx;
padding-bottom: 10rpx;
}
.flex-img5 {
width: 100%;
min-height: 208rpx;
}
.ptb-15 {
padding-top: 30rpx;
padding-bottom: 30rpx;

View File

@ -0,0 +1,81 @@
<template>
<view class="img-outer pr wh-auto ht-auto" :style="border_style" @tap="url_open(form.link)">
<image-empty :image-src="img" :style="image_style" error-style="width: 60rpx;height: 60rpx;"></image-empty>
</view>
</template>
<script>
import { percentage_count, radius_computer, isEmpty } from '@/common/js/common/common.js';
import imageEmpty from '@/components/diy/modules/image-empty.vue';
export default {
components: {
imageEmpty,
},
props: {
value: {
type: Object,
default: () => {
return {};
},
required: true,
},
sourceList: {
type: Object,
default: () => {
return {};
},
},
},
data() {
return {
form: {},
img: '',
image_style: '',
border_style: '',
};
},
created() {
this.setData({
form: this.value,
});
this.init();
},
methods: {
init() {
this.setData({
img: this.get_img_url(),
image_style: this.get_image_style(),
border_style: this.get_border_style(),
});
},
get_img_url() {
if (!isEmpty(this.form.img[0])) {
return this.form.img[0];
} else {
if (!isEmpty(this.sourceList)) {
return this.sourceList[this.form.data_source_id];
} else {
return '';
}
}
},
get_image_style() {
return `width: ${percentage_count(this.form.img_width, this.form.com_width)}; height: ${percentage_count(this.form.img_height, this.form.com_height)};transform: rotate(${this.form.img_rotate}deg); ${radius_computer(this.form.img_radius)};`;
},
get_border_style() {
let style = ``;
if (this.form.border_show == '1') {
style += `border: ${this.form.border_size * 2}rpx ${this.form.border_style} ${this.form.border_color}; ${radius_computer(this.form.border_radius)};`;
}
return style;
},
url_open(link) {
this.$emit('url_open', link);
},
},
};
</script>
<style lang="scss" scoped>
.img-outer {
overflow: hidden;
}
</style>

View File

@ -0,0 +1,44 @@
<template>
<view :style="border_style"></view>
</template>
<script>
export default {
props: {
value: {
type: Object,
default: () => {
return {};
},
required: true,
}
},
data() {
return {
form: {},
border_style: '',
};
},
created() {
this.setData({
form: this.value,
});
this.init();
},
methods: {
init() {
this.setData({
border_style: this.get_border_style(),
});
},
get_border_style() {
if (this.form.line_settings === 'horizontal') {
return `margin: 5px 0;border-bottom: ${this.form.line_size * 2}rpx ${this.form.line_style} ${this.form.line_color};`;
} else {
return `margin: 0 5px;border-right: ${this.form.line_size * 2}rpx ${this.form.line_style} ${this.form.line_color};`;
}
}
},
};
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,101 @@
<template>
<view class="img-outer re oh" :style="com_style" @tap="url_open(form.text_link)">
<view :style="text_style" class="break">
<template v-if="form.is_rich_text == '1'">
<view class="rich-text-content" :innerHTML="text_title"></view>
</template>
<template v-else>
{{ text_title }}
</template>
</view>
</view>
</template>
<script>
import { radius_computer, padding_computer, isEmpty } from '@/common/js/common/common.js';
export default {
props: {
value: {
type: Object,
default: () => {
return {};
},
required: true,
},
sourceList: {
type: Object,
default: () => {
return {};
},
}
},
data() {
return {
form: {},
text_title: '',
text_style: '',
com_style: '',
};
},
created() {
this.setData({
form: this.value,
});
this.init();
},
methods: {
init() {
this.setData({
text_title: this.get_text_title(),
text_style: this.get_text_style(),
com_style: this.get_com_style(),
});
},
get_text_title() {
let text = '';
if (!isEmpty(this.form.text_title)) {
text = this.form.text_title;
} else if (!isEmpty(this.sourceList[this.form.data_source_id])) {
text = this.sourceList[this.form.data_source_id];
}
return text;
},
get_text_style() {
let style = `font-size: ${this.form.text_size * 2}rpx;color: ${this.form.text_color}; text-align: ${this.form.text_location}; transform: rotate(${this.form.text_rotate}deg);text-decoration: ${this.form.text_option};${padding_computer(this.form.text_padding)};box-sizing: border-box;`;
if (this.form.text_weight == 'italic') {
style += `font-style: italic`;
} else if (this.form.text_weight == '500') {
style += `font-weight: 500`;
}
return style;
},
get_com_style() {
let style = `background-color: ${this.form.com_bg}; ${radius_computer(this.form.bg_radius)}`;
if (this.form.border_show == '1') {
style += `border: ${this.form.border_size * 2}rpx ${this.form.border_style} ${this.form.border_color};`;
}
//
if (this.form.is_rich_text == '1' && this.form.is_up_down == '1') {
style += `overflow-y: auto;`;
}
return style;
},
url_open(link) {
this.$emit('url_open', link)
},
},
};
</script>
<style lang="scss" scoped>
.break {
word-wrap: break-word;
word-break: break-all;
}
.rich-text-content {
white-space: normal;
word-break: break-all;
* {
max-width: 100%;
}
}
</style>

View File

@ -0,0 +1,58 @@
<template>
<swiper circular="true" :autoplay="value.data_style.is_roll == '1'" :interval="value.data_style.interval_time * 1000" :duration="500" :vertical="value.data_style.rotation_direction == 'vertical'" class="swiper" style="height: 100%" @change="carousel_change">
<swiper-item v-for="(item1, index1) in value.data_content.list" :key="index1">
<template v-if="type === 'img'">
<view @tap="url_event(item1.carousel_link.page)">
<image-empty :image-src="item1.carousel_img[0]" :style="contentImgRadius" error-style="width: 80rpx;height: 80rpx;"></image-empty>
</view>
</template>
<template v-else>
<product-list-show :outerflex="value.outerflex" :flex="value.flex" :num="value.num" :actived="actived" :is-show="value.data_content.is_show" :chunk-padding="value.data_style.chunk_padding" :value="item1.split_list" :content-img-radius="contentImgRadius" @url_event="url_event"></product-list-show>
</template>
</swiper-item>
</swiper>
</template>
<script>
const app = getApp();
import imageEmpty from '@/components/diy/modules/image-empty.vue';
import productListShow from '@/components/diy/modules/data-magic/product-list-show.vue';
import { isEmpty } from '@/common/js/common/common.js';
export default {
components: {
imageEmpty,
productListShow,
},
props: {
value: {
type: Object,
default: () => ({}),
},
contentImgRadius: {
type: String,
default: () => '',
},
type: {
type: String,
default: () => '',
},
actived: {
type: Number,
default: () => 0,
},
},
methods: {
carousel_change(e) {
this.$emit('carousel_change', e);
},
//
url_event(link) {
if (!isEmpty(link)) {
app.globalData.url_open(link);
}
},
},
};
</script>
<style></style>

View File

@ -0,0 +1,182 @@
<template>
<view v-if="outerflex == 'row'" class="wh-auto ht-auto">
<view class="flex-row gap-10 align-c wh-auto ht-auto">
<template v-if="flex === 'row'">
<view v-for="(item, index) in value" :key="index" class="flex-row gap-10 half-width ht-auto" @tap="url_event(item.goods_url)">
<template v-if="!isEmpty(item.new_cover)">
<image-empty :image-src="item.new_cover[0]" class="wh-auto ht-auto" :style="contentImgRadius" error-style="width: 80rpx;height: 80rpx;"></image-empty>
</template>
<template v-else>
<image-empty :image-src="item.images" class="wh-auto ht-auto" :style="contentImgRadius" error-style="width: 80rpx;height: 80rpx;"></image-empty>
</template>
<view v-if="!isEmpty(isShow)" class="flex-col wh-auto ht-auto tl gap-10">
<view v-if="isShow.includes('title')" class="text-line-2 text-size-md shop-title">{{ item.title }}</view>
<view v-if="isShow.includes('price')" class="identifying">
<span class="num">{{ item.show_price_symbol }}</span
>{{ item.min_price }}
<template v-if="isShow.includes('price_unit')">
<span class="num">{{ item.show_price_unit }}</span>
</template>
</view>
</view>
</view>
</template>
<template v-else-if="actived != 7 || num !== 1">
<view v-for="(item, index) in value" :key="index" :class="['flex-col gap-10 ht-auto', { 'half-width': num !== 1, 'wh-auto': num == 1 }]" @tap="url_event(item.goods_url)">
<view class="wh-auto ht-auto pr">
<template v-if="!isEmpty(item.new_cover)">
<image-empty :image-src="item.new_cover[0]" class="wh-auto ht-auto" :style="contentImgRadius" error-style="width: 80rpx;height: 80rpx;"></image-empty>
</template>
<template v-else>
<image-empty :image-src="item.images" class="wh-auto ht-auto" :style="contentImgRadius" error-style="width: 80rpx;height: 80rpx;"></image-empty>
</template>
<view v-if="isShow.includes('price')" class="price-suspension text-line-1">
{{ item.show_price_symbol }}{{ item.min_price }}
<template v-if="isShow.includes('price_unit')">
{{ item.show_price_unit }}
</template>
</view>
</view>
<view v-if="isShow.includes('title')" class="text-line-1 text-size-md shop-title tl wh-auto" style="overflow: inherit">{{ item.title }}</view>
</view>
</template>
<template v-else>
<view v-for="(item, index) in value" :key="index" class="flex-col wh-auto ht-auto" @tap="url_event(item.goods_url)">
<template v-if="!isEmpty(item.new_cover)">
<image-empty :image-src="item.new_cover[0]" class="wh-auto ht-auto" :style="contentImgRadius" error-style="width: 80rpx;height: 80rpx;"></image-empty>
</template>
<template v-else>
<image-empty :image-src="item.images" class="wh-auto ht-auto" :style="contentImgRadius" error-style="width: 80rpx;height: 80rpx;"></image-empty>
</template>
<view v-if="!isEmpty(isShow)" class="flex-col wh-auto tl gap-10" :style="img_padding_computer">
<view v-if="isShow.includes('title')" class="text-line-2 text-size-md shop-title">{{ item.title }}</view>
<view v-if="isShow.includes('price')" class="identifying">
<span class="num">{{ item.show_price_symbol }}</span
>{{ item.min_price }}
<template v-if="isShow.includes('price_unit')">
<span class="num">{{ item.show_price_unit }}</span>
</template>
</view>
</view>
</view>
</template>
</view>
</view>
<view v-else class="wh-auto ht-auto">
<view class="flex-col gap-20 align-c wh-auto ht-auto">
<template v-if="flex === 'row'">
<view v-for="(item, index) in value" :key="index" class="flex-row gap-10 align-c wh-auto ht-auto shop-max-height" @tap="url_event(item.goods_url)">
<template v-if="!isEmpty(item.new_cover)">
<image-empty :image-src="item.new_cover[0]" class="wh-auto ht-auto" :style="contentImgRadius" error-style="width: 80rpx;height: 80rpx;"></image-empty>
</template>
<template v-else>
<image-empty :image-src="item.images" class="wh-auto ht-auto" :style="contentImgRadius" error-style="width: 80rpx;height: 80rpx;"></image-empty>
</template>
<view v-if="!isEmpty(isShow)" class="flex-col wh-auto ht-auto tl gap-20">
<view v-if="isShow.includes('title')" class="text-line-2 text-size-md shop-title">{{ item.title }}</view>
<view v-if="isShow.includes('price')" class="identifying">
<span class="num">{{ item.show_price_symbol }}</span
>{{ item.min_price }}
<template v-if="isShow.includes('price_unit')">
<span class="num">{{ item.show_price_unit }}</span>
</template>
</view>
</view>
</view>
</template>
</view>
</view>
</template>
<script>
import { isEmpty, padding_computer } from '@/common/js/common/common.js';
import imageEmpty from '@/components/diy/modules/image-empty.vue';
export default {
components: {
imageEmpty,
},
props: {
value: {
type: Array,
default: () => [],
},
outerflex: {
type: String,
default: () => '',
},
flex: {
type: String,
default: () => '',
},
contentImgRadius: {
type: String,
default: () => '',
},
num: {
type: Number,
default: () => 0,
},
actived: {
type: Number,
default: () => 0,
},
isShow: {
type: Array,
default: () => [],
},
chunkPadding: {
type: Object,
default: () => {},
},
},
computed: {
img_padding_computer() {
if (!isEmpty(this.chunkPadding)) {
return padding_computer(this.chunkPadding) + ';box-sizing: border-box;';
} else {
return '';
}
},
},
methods: {
isEmpty,
url_event(link) {
this.$emit('url_event', link);
},
},
};
</script>
<style scoped lang="scss">
.identifying {
font-size: 28rpx;
color: #ea3323;
.num {
font-size: 18rpx;
}
}
.price-suspension {
width: calc(100% - 32rpx);
margin: 0 8rpx;
background: #fff;
font-size: 24rpx;
line-height: 34rpx;
color: #ea3323;
text-align: center;
position: absolute;
bottom: 8rpx;
border-radius: 16rpx;
}
.shop-max-height {
max-height: calc(100% / 3);
}
.half-width {
width: 50%;
}
.shop-title {
line-height: 40rpx;
}
.gap-20 {
gap: 40rpx;
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<view class="oh img_wh" :style="empty_outer_style">
<view :class="['oh img_wh', type_class]" :style="empty_outer_style + type_style">
<image :src="imageUrl" @error="handleImageError" :mode="img_fit" :style="empty_style" />
</view>
</template>
@ -19,6 +19,14 @@
img_fit: {
type: String,
default: () => 'aspectFill',
},
type_style: {
type: String,
default: () => '',
},
type_class: {
type: String,
default: () => '',
}
},
data() {

View File

@ -2,7 +2,7 @@
<view :style="style_container">
<swiper circular="true" :autoplay="new_style.is_roll == '1'" :interval="new_style.interval_time * 1000" :duration="500" :style="{ height: newHeight }" @change="slideChange">
<swiper-item v-for="(item, index) in nav_content_list" :key="index" class="flex-row align-c" @tap="url_open(item.carousel_link)">
<view ref="bannerImg" class="flex-row flex-wrap wh-auto gap-x-10">
<view class="bannerImg flex-row flex-wrap wh-auto gap-x-10">
<view v-for="(item1, index1) in item.split_list" :key="index1" class="flex-col gap-10 align-c" :style="{ width: group_width }" @tap="url_open_event(item1.link)">
<view v-if="['image_with_text', 'image'].includes(nav_style)" class="top-img flex-row align-c jc-c">
<image-empty :image-src="item1.img[0]" :style="img_style" error-style="width: 60rpx;height: 60rpx;"></image-empty>
@ -50,7 +50,7 @@
img_style: '',
text_style: '',
indicator_style: '',
newHeight: '200rpx',
newHeight: '300rpx',
actived_index: 0,
group_width: '',
nav_content_list: [],
@ -61,15 +61,9 @@
form: this.value.content,
new_style: this.value.style,
});
this.init();
},
mounted() {
this.$nextTick(() => {
this.newHeight = this.$refs.bannerImg[0].$el.clientHeight * 2 + 'rpx';
});
window.onresize = () => {
this.newHeight = this.$refs.bannerImg[0].$el.clientHeight * 2 + 'rpx';
};
this.init();
},
methods: {
init() {
@ -83,6 +77,21 @@
nav_style: this.form.nav_style || 'image_with_text', //
nav_content_list: this.get_nav_content_list(),
});
setTimeout(() => {
const query = uni.createSelectorQuery().in(this);
//
query
.select('.bannerImg')
.boundingClientRect((res) => {
if ((res || null) != null) {
// data
this.setData({
newHeight: res.height * 2 + 'rpx',
});
}
})
.exec(); //
}, 0)
},
get_nav_content_list() {
//
@ -148,6 +157,7 @@
height: 100rpx;
width: 100rpx;
border-radius: 8rpx;
background-color: #f4fcff;
}
.dot {