新增条件判断内容

v1.2.0
于肖磊 2025-01-03 10:43:06 +08:00
parent 462bd52038
commit aa7918127b
20 changed files with 318 additions and 27 deletions

View File

@ -1,5 +1,5 @@
<template>
<div class="flex-1" :style="style_container">
<div v-if="is_show" class="flex-1" :style="style_container">
<div :style="style_img_container">
<div :style="style_content_container">
<div class="w h re" :style="style_content_img_container">
@ -48,7 +48,7 @@
</div>
</template>
<script setup lang="ts">
import { common_img_computer, common_styles_computer, get_math, radius_computer } from '@/utils';
import { border_width, common_img_computer, common_styles_computer, get_math, radius_computer, custom_condition_data, custom_condition_judg } from '@/utils';
import { isEmpty } from 'lodash';
import { Swiper, SwiperSlide } from 'swiper/vue';
import { Autoplay } from 'swiper/modules';
@ -92,6 +92,25 @@ const props = defineProps({
//
const form = computed(() => props.value);
const new_style = computed(() => props.value.data_style);
//
const field_list: any[] | undefined = inject('field_list', []);
const is_show = computed(() => {
//
const condition = form.value?.condition || { field: '', type: '', value: ''};
//
let option: any[] = [];
if (field_list) {
option = field_list.filter((item: any) => item.field === condition.field);
}
//
const field_value = custom_condition_data(condition?.field || '', option[0] || {}, props.sourceList, props.isCustom);
// true
if (!isEmpty(condition.field) && !props.isDisplayPanel) {
return custom_condition_judg(field_value, condition.type, condition.value);
} else {
return true;
}
});
//
const style_container = computed(() => common_styles_computer(new_style.value.common_style) + 'overflow: auto;');
const style_img_container = computed(() => common_img_computer(new_style.value.common_style));
@ -109,11 +128,11 @@ watchEffect(() => {
const { common_style, data_style, data_content_style } = new_style.value;
const old_width = props.dataWidth * props.scale;
//
const outer_spacing = common_style.margin_left + common_style.margin_right + common_style.padding_left + common_style.padding_right;
const outer_spacing = common_style.margin_left + common_style.margin_right + common_style.padding_left + common_style.padding_right + border_width(common_style);
//
const content_spacing = data_content_style.margin_left + data_content_style.margin_right + data_content_style.padding_left + data_content_style.padding_right;
const content_spacing = data_content_style.margin_left + data_content_style.margin_right + data_content_style.padding_left + data_content_style.padding_right + border_width(data_content_style);
//
const internal_spacing = data_style.margin_left + data_style.margin_right + data_style.padding_left + data_style.padding_right;
const internal_spacing = data_style.margin_left + data_style.margin_right + data_style.padding_left + data_style.padding_right + border_width(data_style);
//
const new_width = old_width - outer_spacing - internal_spacing - content_spacing;
//

View File

@ -13,6 +13,8 @@
</el-form-item>
</card-container>
<div class="bg-f5 divider-line" />
<condition-config :value="form" :options="options"></condition-config>
<div class="bg-f5 divider-line" />
<el-tabs v-model="tabs_name" class="content-tabs">
<el-tab-pane label="内容设置" name="content">
<custom-tabs-content :value="form" @custom_edit="custom_edit"></custom-tabs-content>

View File

@ -1,5 +1,5 @@
<template>
<div class="img-outer re oh flex-row w h" :style="com_style">
<div v-if="is_show" class="img-outer re oh flex-row w h" :style="com_style">
<template v-if="!isEmpty(icon_class)">
<icon :name="icon_class" :color="form.icon_color" :size="form.icon_size + ''"></icon>
</template>
@ -9,7 +9,7 @@
</div>
</template>
<script setup lang="ts">
import { radius_computer, padding_computer, gradient_handle, get_nested_property } from '@/utils';
import { radius_computer, padding_computer, gradient_handle, get_nested_property, custom_condition_judg, custom_condition_data } from '@/utils';
import { isEmpty } from 'lodash';
const props = defineProps({
value: {
@ -40,6 +40,25 @@ const props = defineProps({
});
//
const form = computed(() => props.value);
//
const field_list: any[] | undefined = inject('field_list', []);
const is_show = computed(() => {
//
const condition = form.value?.condition || { field: '', type: '', value: ''};
//
let option: any[] = [];
if (field_list) {
option = field_list.filter((item: any) => item.field === condition.field);
}
//
const field_value = custom_condition_data(condition?.field || '', option[0] || {}, props.sourceList, props.isCustom);
// true
if (!isEmpty(condition.field) && !isEmpty(condition.type) && !props.isDisplayPanel) {
return custom_condition_judg(field_value, condition.type, condition.value);
} else {
return true;
}
});
//
const icon_class = computed(() => {
if (!isEmpty(form.value.icon_class)) {

View File

@ -67,6 +67,8 @@
</el-form-item>
</card-container>
<div class="bg-f5 divider-line" />
<condition-config :value="form" :options="options"></condition-config>
<div class="bg-f5 divider-line" />
<card-container>
<div class="mb-12">边框设置</div>
<el-form-item label="边框显示">

View File

@ -1,10 +1,10 @@
<template>
<div class="img-outer re w h" :style="border_style">
<div v-if="is_show" class="img-outer re w h" :style="border_style">
<image-empty v-model="img" :style="image_style"></image-empty>
</div>
</template>
<script setup lang="ts">
import { percentage_count, radius_computer, get_nested_property } from '@/utils';
import { percentage_count, radius_computer, get_nested_property, custom_condition_judg, custom_condition_data } from '@/utils';
import { isEmpty } from 'lodash';
const props = defineProps({
value: {
@ -39,6 +39,27 @@ const props = defineProps({
});
//
const form = computed(() => props.value);
//
const field_list: any[] | undefined = inject('field_list', []);
const is_show = computed(() => {
//
const condition = form.value?.condition || { field: '', type: '', value: ''};
//
let option: any[] = [];
if (field_list) {
option = field_list.filter((item: any) => item.field === condition.field);
}
//
const field_value = custom_condition_data(condition?.field || '', option[0] || {}, props.sourceList, props.isCustom);
// true
if (!isEmpty(condition.field) && !isEmpty(condition.type) && props.isDisplayPanel) {
console.log(condition, !props.isDisplayPanel);
console.log(custom_condition_judg(field_value, condition.type, condition.value));
return custom_condition_judg(field_value, condition.type, condition.value);
} else {
return true;
}
});
//
const img = computed(() => {
if (!isEmpty(form.value.img[0])) {

View File

@ -38,6 +38,8 @@
</el-form-item> -->
</card-container>
<div class="bg-f5 divider-line" />
<condition-config :value="form" :options="options"></condition-config>
<div class="bg-f5 divider-line" />
<card-container class="h">
<div class="mb-12">边框设置</div>
<el-form-item label="边框显示">

View File

@ -1,7 +1,9 @@
<template>
<div :style="border_style"></div>
<div v-if="is_show" :style="border_style"></div>
</template>
<script setup lang="ts">
import { custom_condition_judg, custom_condition_data } from '@/utils';
import { isEmpty } from 'lodash';
const props = defineProps({
value: {
type: Object,
@ -14,6 +16,16 @@ const props = defineProps({
type: Boolean,
default: false,
},
sourceList: {
type: Object,
default: () => {
return {};
}
},
isCustom: {
type: Boolean,
default: false
},
scale: {
type: Number,
default: 1,
@ -21,6 +33,25 @@ const props = defineProps({
});
//
const form = computed(() => props.value);
//
const field_list: any[] | undefined = inject('field_list', []);
const is_show = computed(() => {
//
const condition = form.value?.condition || { field: '', type: '', value: ''};
//
let option: any[] = [];
if (field_list) {
option = field_list.filter((item: any) => item.field === condition.field);
}
//
const field_value = custom_condition_data(condition?.field || '', option[0] || {}, props.sourceList, props.isCustom);
// true
if (!isEmpty(condition.field) && !props.isDisplayPanel) {
return custom_condition_judg(field_value, condition.type, condition.value);
} else {
return true;
}
});
//
const border_style = computed(() => {
if (form.value.line_settings === 'horizontal') {

View File

@ -37,6 +37,8 @@
<el-switch v-model="form.bottom_up" active-value="1" inactive-value="0" />
</el-form-item> -->
</card-container>
<div class="bg-f5 divider-line" />
<condition-config :value="form" :options="options"></condition-config>
</el-form>
</div>
</template>
@ -47,7 +49,11 @@ const props = defineProps({
value: {
type: Object,
default: () => ({}),
}
},
options: {
type: Array<any>,
default: () => [],
},
});
//
const state = reactive({

View File

@ -1,10 +1,11 @@
<template>
<div class="w h re oh" :style="com_style">
<div v-if="is_show" class="w h re oh" :style="com_style">
<div class="w h" :style="com_img_style"></div>
</div>
</template>
<script setup lang="ts">
import { radius_computer, gradient_handle, background_computer } from '@/utils';
import { radius_computer, gradient_handle, background_computer, custom_condition_judg, custom_condition_data } from '@/utils';
import { isEmpty } from 'lodash';
const props = defineProps({
value: {
type: Object,
@ -23,6 +24,10 @@ const props = defineProps({
type: Boolean,
default: false
},
isCustom: {
type: Boolean,
default: false
},
scale: {
type: Number,
default: 1
@ -30,6 +35,25 @@ const props = defineProps({
});
//
const form = computed(() => props.value);
//
const field_list: any[] | undefined = inject('field_list', []);
const is_show = computed(() => {
//
const condition = form.value?.condition || { field: '', type: '', value: ''};
//
let option: any[] = [];
if (field_list) {
option = field_list.filter((item: any) => item.field === condition.field);
}
//
const field_value = custom_condition_data(condition?.field || '', option[0] || {}, props.sourceList, props.isCustom);
// true
if (!isEmpty(condition.field) && !props.isDisplayPanel) {
return custom_condition_judg(field_value, condition.type, condition.value);
} else {
return true;
}
});
//
const com_style = computed(() => {
let style = `${ set_count() } ${ gradient_handle(form.value.color_list, form.value.direction) } ${ radius_computer(form.value.bg_radius, props.scale) }; transform: rotate(${form.value.panel_rotate}deg);`;

View File

@ -33,6 +33,8 @@
</el-form-item>
</card-container>
<div class="bg-f5 divider-line" />
<condition-config :value="form" :options="options"></condition-config>
<div class="bg-f5 divider-line" />
<card-container>
<div class="mb-12">边框设置</div>
<el-form-item label="边框显示">

View File

@ -1,5 +1,5 @@
<template>
<div class="img-outer w h re oh" :style="com_style">
<div v-if="is_show" class="img-outer w h re oh" :style="com_style">
<div :style="text_style" class="text-word-break">
<template v-if="form.is_rich_text == '1'">
<div class="rich-text-content" :innerHTML="text_title"></div>
@ -11,7 +11,7 @@
</div>
</template>
<script setup lang="ts">
import { radius_computer, padding_computer, gradient_handle, get_nested_property } from '@/utils';
import { radius_computer, padding_computer, gradient_handle, get_nested_property, custom_condition_judg, custom_condition_data } from '@/utils';
import { isEmpty } from 'lodash';
const props = defineProps({
value: {
@ -51,6 +51,26 @@ const props = defineProps({
//
const form = computed(() => props.value);
//
const field_list: any[] | undefined = inject('field_list', []);
const is_show = computed(() => {
//
const condition = form.value?.condition || { field: '', type: '', value: ''};
//
let option: any[] = [];
if (field_list) {
option = field_list.filter((item: any) => item.field === condition.field);
}
//
const field_value = custom_condition_data(condition?.field || '', option[0] || {}, props.sourceList, props.isCustom);
// true
if (!isEmpty(condition.field) && !props.isDisplayPanel) {
return custom_condition_judg(field_value, condition.type, condition.value);
} else {
return true;
}
});
const text_title = computed(() => {
return getTextTitle(form.value, props);
});
@ -111,6 +131,7 @@ const text_title = computed(() => {
}
return text;
}
//
const data_handling = (data_source_id: string) => {
let text_title = get_nested_property(props.sourceList, data_source_id);

View File

@ -90,6 +90,8 @@
</el-form-item>
</card-container>
<div class="bg-f5 divider-line" />
<condition-config :value="form" :options="options"></condition-config>
<div class="bg-f5 divider-line" />
<card-container>
<div class="mb-12">边框设置</div>
<el-form-item label="边框显示">

View File

@ -12,7 +12,7 @@
<model-text-style :key="key" v-model:height="center_height" :options="options" :value="diy_data"></model-text-style>
</template>
<template v-else-if="diy_data.key == 'auxiliary-line'">
<model-lines-style :key="key" v-model:height="center_height" :value="diy_data"></model-lines-style>
<model-lines-style :key="key" v-model:height="center_height" :options="options" :value="diy_data"></model-lines-style>
</template>
<template v-else-if="diy_data.key == 'icon'">
<model-icon-style :key="key" v-model:height="center_height" :options="options" :value="diy_data"></model-icon-style>

View File

@ -44,7 +44,12 @@ const text_com_data = {
border_size: 1,
direction: '90deg',
color_list: [{ color: '', color_percentage: undefined }],
z_index: 0
// 条件判断
condition: {
field: '', // 字段id
type: '', // 条件类型
value: '', // 值
}
}
// 图片的默认值
const img_com_data = {
@ -83,7 +88,12 @@ const img_com_data = {
radius_bottom_right: 0,
},
border_size: 1,
z_index: 0
// 条件判断
condition: {
field: '', // 字段id
type: '', // 条件类型
value: '', // 值
}
}
// 线条的默认值
const line_com_data = {
@ -95,7 +105,12 @@ const line_com_data = {
line_width: 306,
line_size: 1,
line_color: '#000',
z_index: 0,
// 条件判断
condition: {
field: '', // 字段id
type: '', // 条件类型
value: '', // 值
}
}
// icon的默认值
@ -142,7 +157,12 @@ const icon_com_data = {
border_size: 1,
direction: '90deg',
color_list: [{ color: '', color_percentage: undefined }],
z_index: 0
// 条件判断
condition: {
field: '', // 字段id
type: '', // 条件类型
value: '', // 值
}
}
// 面板的默认值
@ -171,7 +191,12 @@ const panel_com_data = {
border_size: 1,
direction: '90deg',
color_list: [{ color: '#fff', color_percentage: undefined }],
z_index: 0
// 条件判断
condition: {
field: '', // 字段id
type: '', // 条件类型
value: '', // 值
}
}
const custom_group_com_data = {
@ -179,6 +204,12 @@ const custom_group_com_data = {
com_width: 100,
com_height: 100,
staging_height: 100,
// 条件判断
condition: {
field: '', // 字段id
type: '', // 条件类型
value: '', // 值
},
custom_list: [], // 自定义内容处理
custom_height: 100, // 自定义高度
data_source_direction: 'vertical', // 铺满方式

View File

@ -444,6 +444,7 @@ watch(() => center_height.value, () => {
},
},
}));
console.log(diy_data.value);
//
emits('rightUpdate', {});
draggable_container.value = true;

View File

@ -67,6 +67,7 @@ const props = defineProps({
default: 0,
}
});
//
const state = reactive({
form: props.value.content,
@ -74,6 +75,8 @@ const state = reactive({
});
// 使toRefs
const { form, new_style } = toRefs(state);
// ,
provide('field_list', form.value.field_list);
onBeforeMount(() => {
//
if (!Object.keys(form.value.data_source_content).includes('data_auto_list') && !Object.keys(form.value.data_source_content).includes('data_list')) {

View File

@ -303,8 +303,10 @@ const processing_data = (key: string) => {
const list = options.value.filter((item) => item.type == key);
if (list.length > 0) {
model_data_source.value = list[0].data;
form.value.field_list = list[0].data;
} else {
model_data_source.value = [];
form.value.field_list = [];
}
};
//#endregion

View File

@ -84,6 +84,7 @@ interface defaultSearch {
data_source_direction: string;
data_source_carousel_col: number;
custom_list: string[];
field_list: string[];
};
style: {
is_roll: string;
@ -133,7 +134,9 @@ const defaultSearch: defaultSearch = {
// 滑动时的显示 轮播数量
data_source_carousel_col: 1,
// 自定义内容列表
custom_list: []
custom_list: [],
// 存放所有的数据字段
field_list: [],
},
style: {
is_roll: '1',

View File

@ -1,4 +1,5 @@
import CommonAPI from '@/api/common';
import { isEmpty } from 'lodash';
// 定义一组预定义的颜色数组,用于在各种场景中轻松引用这些颜色
// 这些颜色包括从白色到黑色的不同灰度以及一些鲜艳的颜色格式有十六进制、RGB、RGBA、HSV、HSL等
export const predefine_colors = ['#fff', '#ddd', '#ccc', '#999', '#666', '#333', '#000', '#ff4500', '#ff8c00', '#ffd700', '#90ee90', '#00ced1', '#c71585', 'rgba(255, 69, 0, 0.68)', 'rgb(255, 120, 0)', 'hsv(51, 100, 98)', 'hsva(120, 40, 94, 0.5)', 'hsl(181, 100%, 37%)', '#1F93FF', '#c7158577'];
@ -137,13 +138,112 @@ export function convert_strings_to_numbers(obj: any, maxDepth: number = 100, cur
type PaddingStyle = { padding_left: number; padding_right: number;};
type BorderStyle = { border_is_show: boolean; border_size?: PaddingStyle; };
type BorderStyle = { border_is_show: string; border_size?: PaddingStyle; };
export const border_width = (style: BorderStyle): number => {
if (!style) { return 0; }
if (!style.border_is_show) { return 0; }
if (style.border_is_show == '1') {
const { padding_left = 0, padding_right = 0 } = style.border_size || {};
return padding_left + padding_right;
} else {
return 0;
}
}
/**
*
* @param fieldValue
* @param type 'contains', 'is-empty', 'greater-than'
* @param value
* @returns
*/
export const custom_condition_judg = (fieldValue: any, type: string, value: number | string): boolean => {
// 处理 null 或 undefined 的情况
if (fieldValue == null) {
return true;
}
// 提前计算并缓存转换结果
const stringValue = String(fieldValue);
const valueStr = String(value);
const numberValue = Number(value);
switch (type) {
case 'contains':
case 'does-not-contain':
// 处理包含和不包含的逻辑, 如果值为空,直接返回为空
if (!isEmpty(valueStr)) {
const result = stringValue.includes(valueStr);
return type === 'contains' ? result : !result;
} else {
return true;
}
case 'is-empty':
case 'is-not-empty':
// 处理为空和不为空的逻辑
const is_Empty = ['', '{}', '[]'].includes(stringValue.trim()) || (Array.isArray(fieldValue) && fieldValue.length === 0);
return type === 'is-empty' ? is_Empty : !is_Empty;
case 'greater-than':
case 'less-than':
case 'equal':
// 根据字段值的类型,进行数字间的比较
if (typeof fieldValue === 'number') {
return compare_numbers(fieldValue, numberValue, type);
} else if (Array.isArray(fieldValue)) {
// 如果字段值是数组,比较数组长度和指定值
const valueLength = fieldValue.length;
return compare_numbers(valueLength, numberValue, type);
} else {
// 将字段值转换为数字进行比较, 如果是字符串的话直接为NAN比对不会成功为空的时候会转为0 == 0会成功其他情况下不会成功
const numericFieldValue = +stringValue;
return compare_numbers(numericFieldValue, numberValue, type);
}
default:
return true;
}
}
/**
*
* @param a
* @param b
* @param type 'greater-than', 'less-than', 'equal'
* @returns
*/
const compare_numbers = (a: number, b: number, type: string): boolean => {
switch (type) {
case 'greater-than': return a > b;
case 'less-than': return a < b;
case 'equal': return a === b;
default: return false;
}
}
export const custom_condition_data = (data_source_id: string, option: any, sourceList: any, isCustom: boolean) => {
let data_value = '';
if (data_source_id.includes(';')) {
// 取出所有的字段,使用;分割
const ids = data_source_id.split(';');
let text = '';
ids.forEach((item: string, index: number) => {
text += data_handling(item, sourceList, isCustom) + (index != ids.length - 1 ? (option?.join || '') : '');
});
data_value = text;
} else {
// 不输入商品, 文章和品牌时,从外层处理数据
data_value = data_handling(data_source_id, sourceList, isCustom);
}
return (option?.first || '') + data_value + (option?.last || '');
}
// 数据处理
const data_handling = (data_source_id: string, sourceList: any, isCustom: boolean) => {
// 不输入商品, 文章和品牌时,从外层处理数据
let icon = get_nested_property(sourceList, data_source_id);
// 如果是商品,品牌,文章的图片, 其他的切换为从data中取数据
if (!isEmpty(sourceList.data) && isCustom) {
icon = get_nested_property(sourceList.data, data_source_id);
}
return icon;
}
/**