修改商品显示的数量

v1.0.0
于肖磊 2024-09-02 13:36:10 +08:00
parent da9d37dafa
commit 78a99a3c8c
4 changed files with 220 additions and 78 deletions

View File

@ -1,56 +1,84 @@
<template>
<div class="oh" :style="style_container">
<div :class="outer_class" :style="onter_style">
<div v-for="(item, index) in list" :key="index" class="re" :class="layout_type" :style="layout_style">
<template v-if="theme == '6'">
<div :class="['flex-row align-c jc-sb ptb-15 mlr-10 gap-20', { 'br-b-e': index != list.length - 1 }]">
<div v-if="is_show('title')" :class="text_line" :style="trends_config('title')">{{ item.title }}</div>
<div v-if="is_show('price')" class="num nowrap" :style="`color: ${new_style.shop_price_color}`">
<span class="identifying">{{ item.show_price_symbol }}</span
><span :style="trends_config('price')">{{ item.min_price }}</span>
<span v-if="is_show('price_unit')" class="identifying">{{ item.show_price_unit }}</span>
</div>
</div>
</template>
<template v-else>
<template v-if="!isEmpty(item)">
<template v-if="!isEmpty(item.new_cover)">
<image-empty v-model="item.new_cover[0]" :class="`flex-img${theme}`" :style="content_img_radius"></image-empty>
</template>
<template v-else>
<image-empty v-model="item.images" :class="`flex-img${theme}`" :style="content_img_radius"></image-empty>
</template>
</template>
<div class="flex-col flex-1 jc-sb content gap-10" :style="content_style">
<div class="flex-col gap-10 top-title">
<template v-if="!['5'].includes(theme)">
<div v-for="(item, index) in list" :key="index" class="re" :class="layout_type" :style="layout_style">
<template v-if="theme == '6'">
<div :class="['flex-row align-c jc-sb ptb-15 mlr-10 gap-20', { 'br-b-e': index != list.length - 1 }]">
<div v-if="is_show('title')" :class="text_line" :style="trends_config('title')">{{ item.title }}</div>
<div v-if="show_content && is_show('plugins_view_icon') && !isEmpty(item.plugins_view_icon_data)" class="flex-row gap-5 align-c">
<div v-for="(icon_data, icon_index) in item.plugins_view_icon_data" :key="icon_index" class="radius-sm size-9 pl-3 pr-3" :style="icon_style(icon_data)">{{ icon_data.name }}</div>
<div v-if="is_show('price')" class="num nowrap" :style="`color: ${new_style.shop_price_color}`">
<span class="identifying">{{ item.show_price_symbol }}</span
><span :style="trends_config('price')">{{ item.min_price }}</span>
<span v-if="is_show('price_unit')" class="identifying">{{ item.show_price_unit }}</span>
</div>
</div>
<div v-if="!['3', '4', '5'].includes(form.theme)" class="flex-col gap-5 oh">
<div :class="[form.is_price_solo ? 'flex-row align-c nowrap' : 'flex-col gap-5']">
<div v-if="is_show('price')" class="num" :style="`color: ${new_style.shop_price_color}`">
<span class="identifying">{{ item.show_price_symbol }}</span
><span :style="trends_config('price')">{{ item.min_price }}</span>
<span v-if="is_show('price_unit')" class="identifying">{{ item.show_price_unit }}</span>
</div>
<div v-if="show_content && is_show('original_price')" class="size-10 flex">
<span class="original-price-left"></span
><span :class="['original-price text-line-1', { 'flex-1': form.is_price_solo }]"
>{{ item.show_original_price_symbol }}{{ item.min_original_price }}
<template v-if="is_show('original_price_unit')">
{{ item.show_original_price_unit }}
</template>
</span>
</template>
<template v-else>
<template v-if="!isEmpty(item)">
<template v-if="!isEmpty(item.new_cover)">
<image-empty v-model="item.new_cover[0]" :class="`flex-img${theme}`" :style="content_img_radius"></image-empty>
</template>
<template v-else>
<image-empty v-model="item.images" :class="`flex-img${theme}`" :style="content_img_radius"></image-empty>
</template>
</template>
<div class="flex-col flex-1 jc-sb content gap-10" :style="content_style">
<div class="flex-col gap-10 top-title">
<div v-if="is_show('title')" :class="text_line" :style="trends_config('title')">{{ item.title }}</div>
<div v-if="show_content && is_show('plugins_view_icon') && !isEmpty(item.plugins_view_icon_data)" class="flex-row gap-5 align-c">
<div v-for="(icon_data, icon_index) in item.plugins_view_icon_data" :key="icon_index" class="radius-sm size-9 pl-3 pr-3" :style="icon_style(icon_data)">{{ icon_data.name }}</div>
</div>
</div>
<div class="flex-row jc-sb align-e">
<div>
<div v-if="show_content" class="flex-row align-c size-10">
<div v-if="is_show('sales_count')" class="pr-5" :style="trends_config('sold_number')">{{ item.sales_count }}</div>
<!-- <div v-if="is_show('sales_count')" :class="['pr-5', {'br-r-e': is_show('sales_count') && is_show('4')}]" :style="trends_config('sold_number')">{{ item.sales_count }}</div> -->
<!-- <div v-if="is_show('4')" class="pl-5" :style="trends_config('score')">0</div> -->
<div v-if="!['3', '4', '5'].includes(form.theme)" class="flex-col gap-5 oh">
<div :class="[form.is_price_solo ? 'flex-row align-c nowrap' : 'flex-col gap-5']">
<div v-if="is_show('price')" class="num" :style="`color: ${new_style.shop_price_color}`">
<span class="identifying">{{ item.show_price_symbol }}</span
><span :style="trends_config('price')">{{ item.min_price }}</span>
<span v-if="is_show('price_unit')" class="identifying">{{ item.show_price_unit }}</span>
</div>
<div v-if="show_content && is_show('original_price')" class="size-10 flex">
<span class="original-price-left"></span
><span :class="['original-price text-line-1', { 'flex-1': form.is_price_solo }]"
>{{ item.show_original_price_symbol }}{{ item.min_original_price }}
<template v-if="is_show('original_price_unit')">
{{ item.show_original_price_unit }}
</template>
</span>
</div>
</div>
<div class="flex-row jc-sb align-e">
<div>
<div v-if="show_content" class="flex-row align-c size-10">
<div v-if="is_show('sales_count')" class="pr-5" :style="trends_config('sold_number')">{{ item.sales_count }}</div>
<!-- <div v-if="is_show('sales_count')" :class="['pr-5', {'br-r-e': is_show('sales_count') && is_show('4')}]" :style="trends_config('sold_number')">{{ item.sales_count }}</div> -->
<!-- <div v-if="is_show('4')" class="pl-5" :style="trends_config('score')">0</div> -->
</div>
</div>
<div v-if="form.is_shop_show">
<template v-if="form.shop_type == 'text'">
<div class="plr-11 ptb-3 round cr-f" :style="trends_config('button', 'gradient') + `color: ${ new_style.shop_button_text_color };`">{{ form.shop_button_text }}</div>
</template>
<template v-else>
<icon class="round plr-6 ptb-5" :name="!isEmpty(form.shop_button_icon_class) ? form.shop_button_icon_class : 'cart'" :color="new_style.shop_icon_color" :size="new_style.shop_icon_size + ''" :styles="button_gradient()"></icon>
</template>
</div>
</div>
</div>
<div v-else class="flex-row align-c jc-sb">
<div class="flex-row align-c nowrap">
<div v-if="is_show('price')" class="num" :style="`color: ${new_style.shop_price_color}`">
<span class="identifying">{{ item.show_price_symbol }}</span
><span :style="trends_config('price')">{{ item.min_price }}</span>
<span v-if="is_show('price_unit')" class="identifying">{{ item.show_price_unit }}</span>
</div>
<div v-if="show_content && is_show('original_price')" class="size-10 flex">
<span class="original-price-left"></span
><span :class="['original-price text-line-1', { 'flex-1': form.is_price_solo }]"
>{{ item.show_original_price_symbol }}{{ item.min_original_price }}
<template v-if="is_show('original_price_unit')">
{{ item.show_original_price_unit }}
</template>
</span>
</div>
</div>
<div v-if="form.is_shop_show">
@ -63,40 +91,64 @@
</div>
</div>
</div>
<div v-else class="flex-row align-c jc-sb">
<div class="flex-row align-c nowrap">
<div v-if="is_show('price')" class="num" :style="`color: ${new_style.shop_price_color}`">
<span class="identifying">{{ item.show_price_symbol }}</span
><span :style="trends_config('price')">{{ item.min_price }}</span>
<span v-if="is_show('price_unit')" class="identifying">{{ item.show_price_unit }}</span>
</div>
<div v-if="show_content && is_show('original_price')" class="size-10 flex">
<span class="original-price-left"></span
><span :class="['original-price text-line-1', { 'flex-1': form.is_price_solo }]"
>{{ item.show_original_price_symbol }}{{ item.min_original_price }}
<template v-if="is_show('original_price_unit')">
{{ item.show_original_price_unit }}
</template>
</span>
</div>
</div>
<div v-if="form.is_shop_show">
<template v-if="form.shop_type == 'text'">
<div class="plr-11 ptb-3 round cr-f" :style="trends_config('button', 'gradient') + `color: ${ new_style.shop_button_text_color };`">{{ form.shop_button_text }}</div>
</template>
</div>
</template>
<template v-else>
<el-carousel :key="carouselKey" indicator-position="none" :interval="interval_time" arrow="never" :autoplay="is_roll">
<el-carousel-item v-for="(item1, index1) in shop_content_list" :key="index1" class="flex-row" :style="onter_style">
<div v-for="(item, index) in item1.split_list" :key="index" class="re" :class="layout_type" :style="layout_style">
<template v-if="!isEmpty(item)">
<template v-if="!isEmpty(item.new_cover)">
<image-empty v-model="item.new_cover[0]" :class="`flex-img${theme}`" :style="content_img_radius"></image-empty>
</template>
<template v-else>
<icon class="round plr-6 ptb-5" :name="!isEmpty(form.shop_button_icon_class) ? form.shop_button_icon_class : 'cart'" :color="new_style.shop_icon_color" :size="new_style.shop_icon_size + ''" :styles="button_gradient()"></icon>
<image-empty v-model="item.images" :class="`flex-img${theme}`" :style="content_img_radius"></image-empty>
</template>
</template>
<div class="flex-col flex-1 jc-sb content gap-10" :style="content_style">
<div class="flex-col gap-10 top-title">
<div v-if="is_show('title')" :class="text_line" :style="trends_config('title')">{{ item.title }}</div>
<div v-if="show_content && is_show('plugins_view_icon') && !isEmpty(item.plugins_view_icon_data)" class="flex-row gap-5 align-c">
<div v-for="(icon_data, icon_index) in item.plugins_view_icon_data" :key="icon_index" class="radius-sm size-9 pl-3 pr-3" :style="icon_style(icon_data)">{{ icon_data.name }}</div>
</div>
</div>
<div class="flex-row align-c jc-sb">
<div class="flex-row align-c nowrap">
<div v-if="is_show('price')" class="num" :style="`color: ${new_style.shop_price_color}`">
<span class="identifying">{{ item.show_price_symbol }}</span
><span :style="trends_config('price')">{{ item.min_price }}</span>
<span v-if="is_show('price_unit')" class="identifying">{{ item.show_price_unit }}</span>
</div>
<div v-if="show_content && is_show('original_price')" class="size-10 flex">
<span class="original-price-left"></span
><span :class="['original-price text-line-1', { 'flex-1': form.is_price_solo }]"
>{{ item.show_original_price_symbol }}{{ item.min_original_price }}
<template v-if="is_show('original_price_unit')">
{{ item.show_original_price_unit }}
</template>
</span>
</div>
</div>
<div v-if="form.is_shop_show">
<template v-if="form.shop_type == 'text'">
<div class="plr-11 ptb-3 round cr-f" :style="trends_config('button', 'gradient') + `color: ${ new_style.shop_button_text_color };`">{{ form.shop_button_text }}</div>
</template>
<template v-else>
<icon class="round plr-6 ptb-5" :name="!isEmpty(form.shop_button_icon_class) ? form.shop_button_icon_class : 'cart'" :color="new_style.shop_icon_color" :size="new_style.shop_icon_size + ''" :styles="button_gradient()"></icon>
</template>
</div>
</div>
</div>
</div>
</div>
</template>
</div>
</el-carousel-item>
</el-carousel>
</template>
</div>
</div>
</template>
<script setup lang="ts">
import { common_styles_computer, gradient_handle, padding_computer, radius_computer } from '@/utils';
import { common_styles_computer, get_math, gradient_handle, padding_computer, radius_computer } from '@/utils';
import { isEmpty, cloneDeep } from 'lodash';
import ShopAPI from '@/api/shop';
@ -224,9 +276,6 @@ const content_outer_spacing = computed(() => new_style.value.content_outer_spaci
const two_columns = computed(() => content_outer_spacing.value + 'px');
//
const three_columns = computed(() => content_outer_spacing.value * 2 + 'px');
//
const multicolumn_columns_width = computed(() => new_style.value.content_outer_width + 'px');
const multicolumn_columns_height = computed(() => new_style.value.content_outer_height + 'px');
//
const outer_class = computed(() => {
@ -337,6 +386,72 @@ const style_container = computed(() => {
return '';
}
});
//#region
//
//
const multicolumn_columns_width = computed(() => {
const { single_line_number } = toRefs(form.value);
// (gap * gap) /
let gap = (new_style.value.content_outer_spacing * (single_line_number.value - 1)) / single_line_number.value;
return `calc(${ 100 / single_line_number.value }% - ${ gap }px)` ;
});
const multicolumn_columns_height = computed(() => new_style.value.content_outer_height + 'px');
const interval_list = ref({
time: 2000,
is_roll: true,
notice_length: 1
});
interface nav_list {
split_list: data_list[];
}
const shop_content_list = computed(() => {
//
const cloneList = cloneDeep(list.value);
//
if (cloneList.length > 0) {
//
const num = form.value.single_line_number;
//
let nav_list: nav_list[] = [];
//
const split_num = Math.ceil(cloneList.length / num);
for (let i = 0; i < split_num; i++) {
nav_list.push({ split_list: cloneList.slice(i * num, (i + 1) * num) });
}
return nav_list;
} else {
//
return [{ split_list: cloneList }];
}
})
//
const interval_time = ref(2000);
//
const is_roll = ref(true);
// key
const carouselKey = ref('0');
//
watchEffect(() => {
const time = (new_style.value.interval_time || 2) * 1000;
const display_is_roll = new_style.value.is_roll;
//
const notice_length = shop_content_list.value.length;
//
if (interval_list.value.time != time || interval_list.value.is_roll != display_is_roll || notice_length != interval_list.value.notice_length) {
//
interval_time.value = time;
//
interval_list.value = {
time: time,
is_roll: display_is_roll,
notice_length: notice_length
};
// key
carouselKey.value = get_math();
}
});
//#endregion
</script>
<style lang="scss" scoped>
:deep(.el-image) {
@ -400,4 +515,10 @@ const style_container = computed(() => {
width: 100%;
min-height: 10.4rem;
}
:deep(.el-carousel) {
width: 100%;
.el-carousel__container {
height: v-bind(multicolumn_columns_height);
}
}
</style>

View File

@ -8,6 +8,14 @@
<el-radio v-for="item in base_list.product_style_list" :key="item.value" :value="item.value">{{ item.name }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="form.theme == '5'" label="单行显示">
<el-radio-group v-model="form.single_line_number" class="ml-4">
<el-radio :value="1">1</el-radio>
<el-radio :value="2">2</el-radio>
<el-radio :value="3">3</el-radio>
<el-radio :value="4">4</el-radio>
</el-radio-group>
</el-form-item>
</card-container>
<div class="divider-line"></div>
<card-container>

View File

@ -37,9 +37,6 @@
<slider v-model="form.content_outer_spacing" :max="100"></slider>
</el-form-item>
<template v-if="theme == '5'">
<el-form-item label="内容宽度">
<slider v-model="form.content_outer_width" :max="1000"></slider>
</el-form-item>
<el-form-item label="内容高度">
<slider v-model="form.content_outer_height" :max="1000"></slider>
</el-form-item>
@ -47,6 +44,18 @@
</template>
</card-container>
<div class="divider-line"></div>
<template v-if="theme == '5'">
<card-container>
<div class="mb-12">轮播设置</div>
<el-form-item label="自动轮播">
<el-switch v-model="form.is_roll" />
</el-form-item>
<el-form-item label="间隔时间">
<slider v-model="form.interval_time" :max="100"></slider>
</el-form-item>
</card-container>
<div class="divider-line"></div>
</template>
<card-container>
<div class="mb-12">购物车按钮</div>
<el-form-item label="按钮颜色" class="topic">

View File

@ -3,6 +3,7 @@ interface DefaultProductList {
content: {
theme: string;
data_type: string;
single_line_number: number;
category: string[];
data_ids: string[];
product_show_list: string[];
@ -24,8 +25,9 @@ interface DefaultProductList {
shop_img_radius: radiusStyle;
shop_radius: radiusStyle;
content_outer_spacing: number;
content_outer_width: number;
content_outer_height: number;
is_roll: boolean,
interval_time: number,
content_spacing: number;
shop_title_typeface: string;
shop_title_size: number;
@ -52,6 +54,7 @@ const defaultProductList: DefaultProductList = {
content: {
theme: '0',
data_type: '0',
single_line_number: 1,
product_show_list: [],
data_list: [],
category: [],
@ -92,8 +95,9 @@ const defaultProductList: DefaultProductList = {
},
content_outer_spacing: 10, // 商品间距
content_spacing: 10,
content_outer_width: 140,
content_outer_height: 232,
is_roll: true,
interval_time: 2,
shop_title_typeface: '500',
shop_title_size: 14,
shop_title_color: "#333333",