修改自定义组件逻辑

v1.1.0
于肖磊 2024-12-05 18:40:40 +08:00
parent 1352204668
commit 2f535d32e0
16 changed files with 388 additions and 195 deletions

View File

@ -1,5 +1,5 @@
<template>
<el-image :src="is_obj(image) ? image?.url || '' : image" class="flex align-c jc-c w h" :fit="fit" @load="on_load">
<el-image :src="is_obj(image) ? image?.url || '' : image" class="flex align-c jc-c w h radius-sm" :fit="fit" @load="on_load">
<template #error>
<div class="image-slot" :style="errorStyle">
<img :src="error_image" :style="errorImgStyle" />

View File

@ -1,48 +1,50 @@
<template>
<div :class="props.direction == 'vertical' ? 'flex-col gap-x-18' : 'flex-row gap-y-20 jc-e'">
<div v-for="(item, index) in props.filterData" :key="index" class="filter-style flex-row gap-12">
<div v-if="!isEmpty(item.title)" :class="['title text-line-1', props.direction == 'vertical' ? '' : 'horizontal-title']" :style="`width: ${ Number(props.titleWidth) > 0 ? props.titleWidth + 'px;' : '100%' }`">{{ item.title }}</div>
<div class="w h flex-1 vertical-style">
<template v-if="item.type == 'select'">
<template v-if="item.config.is_level.toString() == '1'">
<div class="flex-row gap-10">
<el-cascader v-model="new_dataInterface[item.form_name]" :placeholder="placeholder_config(item, 'select')" clearable class="w h" collapse-tags popper-class="filter-form-cascader" placement="left" :props="{ 'expandTrigger': 'hover', 'multiple': item.config.is_multiple.toString() == '1', 'checkStrictly': true, 'emitPath': false, 'value': item.data_key, 'label': item.data_name, 'children': item.config.children }" :options="selectData(item)" />
<template v-if="item.config.is_multiple.toString() == '1'">
<el-tooltip effect="dark" :show-after="200" :hide-after="200" content="父级选中包含所有子级" raw-content placement="top">
<icon name="miaosha-hdgz" size="12" color="#999"></icon>
</el-tooltip>
</template>
</div>
<template v-for="(item, index) in props.filterData" :key="index">
<div v-if="!isEmpty(item.form_name) && !isEmpty(new_dataInterface) && !isEmpty(item.type)" class="filter-style flex-row gap-12">
<div v-if="!isEmpty(item.title)" :class="['title text-line-1', props.direction == 'vertical' ? '' : 'horizontal-title']" :style="`width: ${ Number(props.titleWidth) > 0 ? props.titleWidth + 'px;' : '100%' }`">{{ item.title }}</div>
<div class="w h flex-1 vertical-style">
<template v-if="item.type == 'select'">
<template v-if="+item?.config?.is_level == 1">
<div class="flex-row gap-10">
<el-cascader v-model="new_dataInterface[item.form_name]" :placeholder="placeholder_config(item, 'select')" clearable class="w h" collapse-tags popper-class="filter-form-cascader" :placement="item?.config?.is_level.toString() == '1' ? 'left' : 'bottom'" :props="{ 'expandTrigger': 'hover', 'multiple': +item?.config?.is_multiple == 1, 'checkStrictly': true, 'emitPath': false, 'value': item?.data_key || 'id', 'label': item?.data_name || 'name', 'children': item?.config?.children || '' }" :options="selectData(item)" />
<template v-if="+item?.config?.is_multiple == 1">
<el-tooltip effect="dark" :show-after="200" :hide-after="200" content="父级选中包含所有子级" raw-content placement="top">
<icon name="miaosha-hdgz" size="12" color="#999"></icon>
</el-tooltip>
</template>
</div>
</template>
<template v-else>
<el-select v-model="new_dataInterface[item.form_name]" :multiple="+item?.config?.is_multiple == 1" collapse-tags :placeholder="placeholder_config(item, 'select')" clearable>
<el-option v-for="item1 in selectData(item)" :key="item1[item?.data_key || 'id']" :label="item1[item?.data_name || 'name']" :value="item1[item?.data_key || 'id']" />
</el-select>
</template>
</template>
<template v-else>
<el-select v-model="new_dataInterface[item.form_name]" :multiple="item.config.is_multiple.toString() == '1'" collapse-tags :placeholder="placeholder_config(item, 'select')" clearable>
<el-option v-for="item1 in selectData(item)" :key="item1[item.data_key]" :label="item1[item.data_name]" :value="item1[item.data_key]" />
</el-select>
<template v-else-if="item.type == 'input'">
<template v-if="item?.config?.type == 'number'">
<el-input-number v-model="new_dataInterface[item.form_name]" :min="item?.config?.min || 0" :max="item?.config?.max || undefined" type="number" :placeholder="placeholder_config(item, 'input')" value-on-clear="min" class="w number-show" controls-position="right"></el-input-number>
</template>
<template v-else>
<el-input v-model="new_dataInterface[item.form_name]" :placeholder="placeholder_config(item, 'input')" clearable />
</template>
</template>
</template>
<template v-else-if="item.type == 'input'">
<template v-if="item.config.type == 'number'">
<el-input-number v-model="new_dataInterface[item.form_name]" :min="item.config?.min || 0" :max="item.config?.max || undefined" type="number" :placeholder="placeholder_config(item, 'input')" value-on-clear="min" class="w number-show" controls-position="right"></el-input-number>
<template v-else-if="item.type == 'switch'">
<el-switch v-model="new_dataInterface[item.form_name]" active-value="1" inactive-value="0" />
</template>
<template v-else>
<el-input v-model="new_dataInterface[item.form_name]" :placeholder="placeholder_config(item, 'input')" clearable />
<template v-else-if="item.type =='radio'">
<el-radio-group v-model="new_dataInterface[item.form_name]">
<el-radio v-for="item1 in selectData(item)" :key="item1[item?.data_key || 'id']" :value="item1[item?.data_key || 'name']">{{ item1[item?.data_name || 'name'] }}</el-radio>
</el-radio-group>
</template>
</template>
<template v-else-if="item.type == 'switch'">
<el-switch v-model="new_dataInterface[item.form_name]" active-value="1" inactive-value="0" />
</template>
<template v-else-if="item.type =='radio'">
<el-radio-group v-model="new_dataInterface[item.form_name]">
<el-radio v-for="item1 in selectData(item)" :key="item1[item.data_key]" :value="item1[item.data_key]">{{ item1[item.data_name] }}</el-radio>
</el-radio-group>
</template>
<template v-else-if="item.type =='checkbox'">
<el-checkbox-group v-model="new_dataInterface[item.form_name]">
<el-checkbox v-for="item1 in selectData(item)" :key="item1[item.data_key]" :value="item1[item.data_key]">{{ item1[item.data_name] }}</el-checkbox>
</el-checkbox-group>
</template>
<template v-else-if="item.type =='checkbox'">
<el-checkbox-group v-model="new_dataInterface[item.form_name]">
<el-checkbox v-for="item1 in selectData(item)" :key="item1[item?.data_key || 'id']" :value="item1[item?.data_key || 'name']">{{ item1[item?.data_name || 'name'] }}</el-checkbox>
</el-checkbox-group>
</template>
</div>
</div>
</div>
</template>
</div>
</template>
@ -86,36 +88,38 @@ const selectData = (item: any) => {
let options_list = [];
if (!isEmpty(item.data)) {
options_list = item.data;
} else {
} else if (!isEmpty(item.const_key)) {
options_list = !isEmpty((common_store.common as any)[item.const_key]) ? (common_store.common as any)[item.const_key] : [];
}
return options_list;
}
onBeforeMount(() => {
props.filterData.forEach((item: any) => {
const options_list = selectData(item);
//
const old_defalut = new_dataInterface.value[item.form_name];
//
if (old_defalut && ['select', 'radio', 'checkout'].includes(item.type)) {
if (item.type == 'select' && item.config.is_level && item.config.is_level.toString() == '1') { //
const result = contains_value(options_list, item, [], item.config.children);
new_dataInterface.value[item.form_name] = result;
} else if (item.config.is_multiple && item.config.is_multiple.toString() == '1') { //
// key
const list = options_list.filter((item1: any) => { old_defalut.length > 0 ? old_defalut.includes(item1[item.data_key]) : item1[item.data_key] == old_defalut });
if (list.length > 0) {
new_dataInterface.value[item.form_name] = list.map((item1: any) => { return item1[item.data_key] });
if (!isEmpty(item.form_name) && !isEmpty(new_dataInterface.value)) {
const options_list = selectData(item);
//
const old_defalut = new_dataInterface.value[item.form_name];
//
if (old_defalut && ['select', 'radio', 'checkout'].includes(item.type)) {
if (item.type == 'select' && +item?.config?.is_level == 1) { //
const result = contains_value(options_list, item, [], item?.config?.children || '');
new_dataInterface.value[item.form_name] = result;
} else if (+item?.config?.is_multiple == 1) { //
// key
const list = options_list.filter((item1: any) => old_defalut.length > 0 ? old_defalut.includes(item1[item?.data_key || 'id']) : (item1[item?.data_key || 'id'] === old_defalut));
if (list.length > 0) {
new_dataInterface.value[item.form_name] = list.map((item1: any) => { return item1[item?.data_key || 'id'] });
} else {
new_dataInterface.value[item.form_name] = [];
}
} else {
new_dataInterface.value[item.form_name] = [];
}
} else {
//
const list = options_list.filter((item1: any) => { item1[item.data_key] == old_defalut });
if (list.length > 0) {
new_dataInterface.value[item.form_name] = list[0][item.data_key];
} else {
new_dataInterface.value[item.form_name] = '';
//
const list = options_list.filter((item1: any) => item1[item?.data_key || 'id'] === old_defalut );
if (list.length > 0) {
new_dataInterface.value[item.form_name] = list[0][item?.data_key || 'id'];
} else {
new_dataInterface.value[item.form_name] = '';
}
}
}
}
@ -129,25 +133,25 @@ watch(() => new_dataInterface.value, (val) => {
const placeholder_config = computed(() => {
return (data: any, type: string) => {
if (!data.config.placeholder) {
if (!data.config || !data.config.placeholder) {
return type == 'select'? `请选择${ data?.title || '' }` : `请输入${ data?.title || '' }`;
} else {
return data.config.placeholder;
return data?.config?.placeholder || '';
}
}
});
//
const contains_value = (list: any[], config: any, result: any[], children?: string) => {
if (list.length > 0) {
if (list.length > 0 && !isEmpty(config.form_name) && !isEmpty(new_dataInterface.value)) {
const old_defalut = new_dataInterface.value[config.form_name];
list.forEach((item: any) => {
if (config.config.is_multiple && config.config.is_multiple.toString() == '1') {
if ((old_defalut.length > 0 && old_defalut.includes(item[config.data_key])) || item[config.data_key] == old_defalut) {
result.push(item[config.data_key]);
if (+config?.config?.is_multiple == 1) {
if ((old_defalut.length > 0 && old_defalut.includes(item[config?.data_key || 'id'])) || item[config?.data_key || 'id'] == old_defalut) {
result.push(item[config?.data_key || 'id']);
}
} else {
if (item[config.data_key] == old_defalut) {
result.push(item[config.data_key]);
if (item[config?.data_key || 'id'] == old_defalut) {
result.push(item[config?.data_key || 'id']);
}
}
if (children && item[children]) {

View File

@ -1,5 +1,5 @@
<template>
<el-table :data="tableData" class="custom-table" style="width: 100%" height="438" :header-cell-style="{ background: '#f7f7f7' }" @row-click="row_click" @select="handle_select" @select-all="handle_select" >
<el-table :data="tableData" class="custom-table" style="width: 100%" height="438" :row-class-name="tableRowClassName" :header-cell-style="{ background: '#f7f7f7' }" @row-click="row_click" @select="handle_select" @select-all="handle_select" >
<el-table-column v-if="multiple" type="selection" width="60" />
<el-table-column v-else label="#" width="60" type="">
<template #default="scope">
@ -7,16 +7,18 @@
</template>
</el-table-column>
<template v-for="(item, index) in tableColumnList" :key="index">
<el-table-column :prop="item.field" :label="item.name" :width="item?.width || ''">
<template #default="scope">
<template v-if="item.type == 'images'">
<image-empty v-if="scope.row[item.field]" v-model="scope.row[item.field]" fit="contain" class="img"></image-empty>
<template v-if="item.field">
<el-table-column :prop="item.field" :label="item?.name || item.field" :width="item?.width || ''">
<template #default="scope">
<template v-if="item.type == 'images'">
<image-empty v-if="scope.row[item.field]" v-model="scope.row[item.field]" fit="contain" class="img"></image-empty>
</template>
<template v-else>
{{ scope.row[item.field] }}
</template>
</template>
<template v-else-if="item.type == 'text'">
{{ scope.row[item.field] }}
</template>
</template>
</el-table-column>
</el-table-column>
</template>
</template>
<template #empty>
<no-data></no-data>
@ -48,11 +50,25 @@ const props = defineProps({
multiple: {
type: Boolean,
default: false,
}
},
tableRowClassList: {
type: Array as PropType<number[]>,
default: () => [],
},
});
const template_selection = ref('');
const emit = defineEmits(['select']);
// class
const tableRowClassName = computed(() => {
return (data: { row: any }) => {
if (props.tableRowClassList.includes(data.row.data_index)) {
return 'table-error-row'
}
return ''
}
});
//#region
//
const row_click = (row: any) => {
@ -61,6 +77,7 @@ const row_click = (row: any) => {
const new_table_data = JSON.parse(JSON.stringify(props.tableData));
//
template_selection.value = new_table_data.findIndex((item: any) => item[props.type] == row[props.type]).toString();
//
emit('select', [ row ]);
}
};

View File

@ -1,6 +1,6 @@
<template>
<div :style="style_container">
<div :style="style_img_container">
<div class="flex-col" :style="style_img_container">
<div class="oh" :style="tabs_container">
<div class="oh" :style="tabs_img_container">
<tabs-view ref="tabs" :value="article_tabs" :active-index="tabs_active_index"></tabs-view>
@ -15,7 +15,7 @@
</div>
</template>
<script setup lang="ts">
import { background_computer, common_img_computer, common_styles_computer, gradient_computer, margin_computer, padding_computer } from '@/utils';
import { background_computer, common_img_computer, common_styles_computer, gradient_computer, margin_computer, padding_computer, radius_computer } from '@/utils';
import { cloneDeep } from 'lodash';
/**
* @description: 文章选项卡列表 渲染
@ -51,7 +51,7 @@ watch(
background_img_style: new_style.tabs_bg_background_img_style,
background_img: new_style.tabs_bg_background_img,
}
tabs_container.value = gradient_computer(tabs_data);
tabs_container.value = gradient_computer(tabs_data) + radius_computer(new_style.tabs_radius);
tabs_img_container.value = background_computer(tabs_data) + padding_computer(new_style.tabs_padding);
//
const article_content_data = {
@ -60,7 +60,7 @@ watch(
background_img_style: new_style.article_content_background_img_style,
background_img: new_style.article_content_background_img,
}
article_container.value = gradient_computer(article_content_data) + margin_computer(new_style.article_content_margin);
article_container.value = gradient_computer(article_content_data) + margin_computer(new_style.article_content_margin) + radius_computer(new_style.article_content_radius);
article_img_container.value = background_computer(article_content_data) + padding_computer(new_style.article_content_padding);
//
new_data.content.theme = new_data.content.article_theme;
@ -79,7 +79,7 @@ watch(
article_tabs.value = new_data;
style_container.value = common_styles_computer(new_style.common_style);
style_img_container.value = common_img_computer(new_style.common_style);
style_img_container.value = common_img_computer(new_style.common_style) + `gap: ${new_style.article_content_spacing}px;`;
},
{ immediate: true, deep: true }
);

View File

@ -33,6 +33,9 @@
<upload v-model="form.tabs_bg_background_img" :limit="1" @update:model-value="tabs_bg_background_img_change"></upload>
</div>
</el-form-item>
<el-form-item label="圆角">
<radius :value="form.tabs_radius"></radius>
</el-form-item>
<el-form-item label="内边距">
<padding :value="form.tabs_padding"></padding>
</el-form-item>
@ -51,12 +54,18 @@
<upload v-model="form.article_content_background_img" :limit="1" @update:model-value="article_content_background_img_change"></upload>
</div>
</el-form-item>
<el-form-item label="圆角">
<radius :value="form.article_content_radius"></radius>
</el-form-item>
<el-form-item label="外间距">
<margin :value="form.article_content_margin"></margin>
</el-form-item>
<el-form-item label="内间距">
<padding :value="form.article_content_padding"></padding>
</el-form-item>
<el-form-item label="数据间距">
<slider v-model="form.article_content_spacing" :max="100"></slider>
</el-form-item>
</card-container>
<div class="divider-line"></div>
<card-container>

View File

@ -15,6 +15,9 @@
<upload v-model="form.carousel_content_background_img" :limit="1" @update:model-value="carousel_content_background_img_change"></upload>
</div>
</el-form-item>
<el-form-item label="圆角">
<radius :value="form.carousel_content_radius"></radius>
</el-form-item>
<el-form-item label="外间距">
<margin :value="form.carousel_content_margin"></margin>
</el-form-item>

View File

@ -2,15 +2,18 @@
<el-dialog v-model="dialogVisible" class="radius-lg" width="1168" draggable append-to-body :close-on-click-modal="false" :top="dialogPositionTop ? dialogPositionTop + 'px' : ''" @close="close_event">
<template #header>
<div class="title center re">
<div class="tc size-16 fw">{{ config?.popup_title || '' }}</div>
<div class="tc size-16 fw">{{ config?.popup_title || '数据选择' }}</div>
</div>
</template>
<div class="flex-col gap-20 w h pa-20 oh">
<filter-form v-if="dialogVisible" :filter-data="config.filter_form_config" direction="horizontal" :data-interface="default_data" @form-change="filter_form_change"></filter-form>
<table-config v-loading="loading" :table-data="tableData" :multiple="multiple" :table-column-list="config.header" @select="table_select"></table-config>
<div class="flex-row jc-e">
<el-pagination :current-page="pagination_data.page" background :page-size="pagination_data.page_size" :pager-count="5" layout="prev, pager, next" :total="pagination_data.data_total" @current-change="get_list" />
</div>
<filter-form v-if="dialogVisible && !isEmpty(config?.filter_form_config)" :filter-data="config.filter_form_config" direction="horizontal" :data-interface="default_data" @form-change="filter_form_change"></filter-form>
<!-- 表格头部如果传输了数据就渲染表格, 否则就不渲染 -->
<template v-if="!isEmpty(config?.header)">
<table-config v-loading="loading" :table-data="tableData" :multiple="multiple" :table-column-list="config.header" :table-row-class-list="tableRowClassList" @select="table_select"></table-config>
<div class="flex-row jc-e">
<el-pagination :current-page="pagination_data.page" background :page-size="pagination_data.page_size" :pager-count="5" layout="prev, pager, next" :total="pagination_data.data_total" @current-change="get_list" />
</div>
</template>
</div>
<template #footer>
<span class="dialog-footer">
@ -30,6 +33,10 @@ const props = defineProps({
type: Array as PropType<string[]>,
default: () => [],
},
dataListKey: {
type: String,
default: () => '',
},
config: {
type: Object as PropType<any>,
default: () => {},
@ -46,7 +53,20 @@ const props = defineProps({
const dialogVisible = defineModel('dialogVisible', { type: Boolean, default: false });
//#region
const select_data = ref([]);
const tableRowClassList = ref<number[]>([]);
const table_select = (val: any) => {
//
if (val.length > 0) {
const contain_list: number[] = [];
val.forEach((item: any) => {
if (tableRowClassList.value.includes(item.data_index)) {
contain_list.push(item.data_index);
}
});
tableRowClassList.value = contain_list;
} else {
tableRowClassList.value = [];
}
select_data.value = val;
};
const emit = defineEmits(['confirm_event']);
@ -54,8 +74,36 @@ const close_event = () => {
dialogVisible.value = false;
};
const confirm_event = () => {
dialogVisible.value = false;
emit('confirm_event', select_data.value);
if (init_data()) {
//
dialogVisible.value = false;
emit('confirm_event', select_data.value);
}
};
const init_data = () => {
if (select_data.value.length > 0) {
//
const all_length = select_data.value.length;
// data_key
const list = select_data.value.filter((item: any) => item[props.dataListKey] == undefined );
if (list.length == 0) {
return true;
} else {
if (list.length == all_length) {
//
tableRowClassList.value = select_data.value.map((item: any) => item.data_index);
ElMessage.error(`没有${props.dataListKey}对应的数据`);
} else {
//
tableRowClassList.value = list.map((item: any) => item.data_index);
ElMessage.error(`${list.length}个数据没有${props.dataListKey}对应`);
}
return false;
}
} else {
return true;
}
};
//#endregion
//#region
@ -73,22 +121,27 @@ watchEffect(() => {
const staging_data : any = {};
pagination_data.value = {
page: 1,
page_size: props.config?.page_size || 10,
page_size: props?.config?.page_size || '',
data_total: 0,
}
const filter_form_config = props?.config?.filter_form_config || [];
//
// ,
props.config.filter_form_config.forEach((item: any) => {
let value : number | string | Array<any> = '';
if (item.type == 'checkbox' || item.type == 'select' && item.config.is_multiple == '1') { //
value = item.config.default ? item.config.default : [];
} else if (item.type == 'input' && item.config.type == 'number') { //
value = item.config.default ? item.config.default : 0;
} else if (item.type == 'switch') {
value = item.config.default ? item.config.default : "0";
}
staging_data[item.form_name] = value;
})
if (filter_form_config.length > 0) {
// ,
filter_form_config.forEach((item: any) => {
let value : number | string | Array<any> = '';
if (item.type == 'checkbox' || item.type == 'select' && +item?.config?.is_multiple == 1) { //
value = item?.config?.default || [];
} else if (item.type == 'input' && item?.config?.type == 'number') { //
value = item?.config?.default || 0;
} else if (item.type == 'switch') { //
value = item?.config?.default || "0";
} else { //
value = item?.config?.default || '';
}
staging_data[item.form_name] = value;
})
}
//
default_data.value = staging_data;
}
@ -110,7 +163,7 @@ const loading = ref(false);
const get_table_list = (val: any) => {
tableData.value = [];
//
if (!isEmpty(val) && !isEmpty(props.config) && !isEmpty(props.config.data_url)) {
if (!isEmpty(props.config) && !isEmpty(props.config.data_url)) {
//
const data = {
...val,
@ -124,6 +177,8 @@ const get_table_list = (val: any) => {
data //
}).then((res) => {
if (res.data) {
//
tableRowClassList.value = [];
tableData.value = res.data.data_list;
pagination_data.value.data_total = res.data.data_total;
}

View File

@ -11,28 +11,32 @@
</card-container>
<!-- 筛选数据 -->
<template v-if="!isEmpty(default_type_data)">
<div class="divider-line"></div>
<card-container>
<div class="mb-12">显示设置</div>
<el-form-item label="铺满方式">
<el-radio-group v-model="form.data_source_direction">
<el-radio v-for="(item, index) in default_type_data.show_type" :key="index" :value="item">{{ item == 'vertical' ? '' : item == 'vertical-scroll' ? '' : '' }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="['vertical-scroll', 'horizontal'].includes(form.data_source_direction)" label="每屏显示">
<el-radio-group v-model="form.data_source_carousel_col">
<el-radio v-for="(item, index) in default_type_data.show_number" :key="index" :value="item">{{ item }}{{ form.data_source_direction == 'vertical-scroll' ? '' : '' }}</el-radio>
</el-radio-group>
</el-form-item>
</card-container>
<template v-if="!isEmpty(default_type_data.data_type)">
<template v-if="default_type_data?.show_type.length > 0">
<div class="divider-line"></div>
<card-container>
<div class="mb-12">显示设置</div>
<el-form-item label="铺满方式">
<el-radio-group v-model="form.data_source_direction">
<el-radio v-for="(item, index) in default_type_data?.show_type" :key="index" :value="item">{{ item == 'vertical' ? '' : item == 'vertical-scroll' ? '' : '' }}</el-radio>
</el-radio-group>
</el-form-item>
<template v-if="default_type_data?.show_number.length > 0 && ['vertical-scroll', 'horizontal'].includes(form.data_source_direction)">
<el-form-item label="每屏显示">
<el-radio-group v-model="form.data_source_carousel_col">
<el-radio v-for="(item, index) in default_type_data?.show_number" :key="index" :value="item">{{ item }}{{ form.data_source_direction == 'vertical-scroll' ? '' : '' }}</el-radio>
</el-radio-group>
</el-form-item>
</template>
</card-container>
</template>
<template v-if="default_type_data.data_type.length > 0">
<div class="divider-line"></div>
<card-container>
<div class="mb-12">数据设置</div>
<div class="flex-col">
<el-form-item label="读取方式">
<el-radio-group v-model="form.data_source_content.data_type">
<el-radio v-for="(item, index) in default_type_data.data_type" :key="index" :value="item">{{ item === 0 ? '' : '' }}</el-radio>
<el-radio v-for="(item, index) in default_type_data.data_type" :key="index" :value="item">{{ +item === 0 ? '' : '' }}</el-radio>
</el-radio-group>
</el-form-item>
<template v-if="Number(form.data_source_content.data_type) === 0">
@ -83,7 +87,7 @@
</div>
</div>
</Dialog>
<custom-dialog v-model:dialog-visible="url_value_dialog_visible" :config="default_type_data.appoint_config" :multiple="url_value_multiple_bool" @confirm_event="url_value_dialog_call_back"></custom-dialog>
<custom-dialog v-model:dialog-visible="url_value_dialog_visible" :data-list-key="form.data_list_key" :config="default_type_data.appoint_config" :multiple="url_value_multiple_bool" @confirm_event="url_value_dialog_call_back"></custom-dialog>
</div>
</template>
<script setup lang="ts">
@ -173,8 +177,14 @@ const data_processing = () => {
if (type_data.length > 0 && !isEmpty(type_data[0].custom_config)) {
//
form.value.is_custom_data = '1';
//
default_type_data.value = type_data[0].custom_config;
const custom_config = type_data[0].custom_config;
//
default_type_data.value = {
...custom_config,
show_type: custom_config?.show_type || ['vertical', 'vertical-scroll', 'horizontal'],
show_number: custom_config?.show_number || [1, 2, 3, 4],
data_type: custom_config?.data_type || [0, 1],
};
default_data();
}
};
@ -183,19 +193,36 @@ const default_data = () => {
const { show_type = [], show_number = [], data_type = []} = default_type_data.value;
const { data_source_direction, data_source_carousel_col, data_source_content} = form.value;
// ,
if (!isEmpty(show_type) && !show_type.includes(data_source_direction)) {
form.value.data_source_direction = show_type[0];
if (!isEmpty(show_type)) {
if (!show_type.includes(data_source_direction)) {
form.value.data_source_direction = show_type[0];
}
} else {
// show_type
form.value.data_source_direction = 'vertical';
}
// ,
if (!isEmpty(show_number) && !show_number.includes(data_source_carousel_col)) {
form.value.data_source_carousel_col = show_number[0];
if (!isEmpty(show_number)) {
if (!show_number.includes(data_source_carousel_col)) {
form.value.data_source_carousel_col = show_number[0];
}
} else {
// show_number
form.value.data_source_carousel_col = 1;
}
// ,
if (!isEmpty(data_type) && isEmpty(data_source_content.data_type) && !data_type.includes(Number(data_source_content.data_type))) {
form.value.data_source_content.data_type = data_type[0];
if (!isEmpty(data_type)) {
if (isEmpty(data_source_content.data_type) && !data_type.includes(Number(data_source_content.data_type))) {
form.value.data_source_content.data_type = data_type[0];
}
} else if (!isEmpty(data_source_content.data_type) && typeof data_source_content.data_type == 'string') { // 使
form.value.data_source_content.data_type = Number(form.value.data_source_content.data_type);
} else {
// data_type
form.value.data_source_content.data_type = 0;
}
// id
form.value.data_list_key = default_type_data.value?.appoint_config?.show_data?.data_key || 'id';
}
//
const model_data_source = ref<data_list[]>([]);
@ -273,9 +300,16 @@ const changeDataSource = (key: string) => {
//
form.value.is_custom_data = '1';
//
const custom_config = type_data[0].custom_config;
//
form.value.data_source_direction = custom_config.show_type[0];
const custom_config = type_data[0].custom_config
//
default_type_data.value = {
...custom_config,
show_type: custom_config?.show_type || ['vertical', 'vertical-scroll', 'horizontal'],
show_number: custom_config?.show_number || [1, 2, 3, 4],
data_type: custom_config?.data_type || [0, 1],
};
//
default_data();
//
const staging_data : any = {
// id
@ -285,22 +319,19 @@ const changeDataSource = (key: string) => {
//
data_auto_list: [],
//
data_type: custom_config.data_type[0],
data_type: default_type_data.value.data_type.length > 0 ? default_type_data.value.data_type[0] : 0,
};
//
default_type_data.value = custom_config;
default_data();
// id
form.value.data_list_key = default_type_data.value?.appoint_config?.show_data?.data_key || 'id';
// ,
default_type_data.value.filter_config.filter_form_config.forEach((item: any) => {
default_type_data.value?.filter_config?.filter_form_config.forEach((item: any) => {
let value : number | string | Array<any> = '';
if (item.type == 'checkbox' || (item.type == 'select' && item.config.is_multiple == '1')) { //
value = item.config.default ? item.config.default : [];
} else if (item.type == 'input' || item.config.type == 'number') { //
value = item.config.default ? item.config.default : 0;
if (item.type == 'checkbox' || (item.type == 'select' && +item?.config?.is_multiple == 1)) { //
value = item?.config?.default || [];
} else if (item.type == 'input' && item?.config?.type == 'number') { //
value = item?.config?.default || 0;
} else if (item.type == 'switch') {
value = item.config.default ? item.config.default : "0";
value = item?.config?.default || "0";
} else {
value = item?.config?.default || '';
}
staging_data[item.form_name] = value;
})
@ -323,14 +354,18 @@ const data_list_replace = (index: number) => {
};
//
const add = () => {
if (!isEmpty(default_type_data.value?.appoint_config?.data_url)) {
if (isEmpty(default_type_data.value) || isEmpty(default_type_data.value.appoint_config)) {
ElMessage.error('请先配置数据源内容(appoint_config)');
} else if (isEmpty(default_type_data.value.appoint_config.data_url)) {
ElMessage.error('请先配置请求地址(data_url)');
} else if (isEmpty(default_type_data.value.appoint_config.header)) {
ElMessage.error('请先配置表格头(header)');
} else {
// index-1
data_list_replace_index.value = -1;
//
url_value_multiple_bool.value = default_type_data.value.appoint_config.is_multiple.toString() == '1' ? true : false;
url_value_multiple_bool.value = +default_type_data.value.appoint_config?.is_multiple == 1 ? true : false;
url_value_dialog_visible.value = true;
} else {
ElMessage.error('请先配置数据源地址');
}
};
//
@ -385,7 +420,11 @@ let data_source_content_list = computed(() => {
})
//
const get_auto_data = () => {
if (!isEmpty(default_type_data.value) && !isEmpty(default_type_data.value.filter_config) && !isEmpty(default_type_data.value.filter_config.data_url)) {
if (isEmpty(default_type_data.value) || isEmpty(default_type_data.value.filter_config)) {
ElMessage.error('请先配置数据源内容(filter_config)');
} else if (isEmpty(default_type_data.value.filter_config.data_url)) {
ElMessage.error('请先配置请求地址(data_url)');
} else {
const data = omit(cloneDeep(form.value.data_source_content), ['data_ids', 'data_list', 'data_auto_list', 'data_type']);
request({
url: default_type_data.value.filter_config.data_url, //
@ -402,11 +441,6 @@ const get_auto_data = () => {
// ,
form.value.data_source_content.data_auto_list = [];
});
} else if (!isEmpty(default_type_data.value) && !isEmpty(default_type_data.value.filter_config) && isEmpty(default_type_data.value.filter_config.data_url)) {
ElMessage.error('请先配置数据源地址');
} else {
// ,
form.value.data_source_content.data_auto_list = [];
}
};
//
@ -423,7 +457,7 @@ const data_source_content_value = computed(() => {
//
watch(() => data_source_content_value.value, (new_val, old_val) => {
//
if (JSON.stringify(new_val) != JSON.stringify(old_val) && Number(new_val.data_type) !== 0) {
if (JSON.stringify(new_val) != JSON.stringify(old_val) && Number(new_val?.data_type || 0) !== 0) {
get_auto_data();
}
},{ deep: true });

View File

@ -1,6 +1,6 @@
<template>
<div :style="style_container">
<div :style="style_img_container">
<div class="flex-col" :style="style_img_container">
<div class="oh" :style="tabs_container">
<div class="oh" :style="tabs_img_container">
<tabs-view ref="tabs" :value="props.value" :active-index="tabs_active_index"></tabs-view>
@ -15,7 +15,7 @@
</div>
</template>
<script setup lang="ts">
import { background_computer, common_img_computer, common_styles_computer, gradient_computer, margin_computer, padding_computer } from '@/utils';
import { background_computer, common_img_computer, common_styles_computer, gradient_computer, margin_computer, padding_computer, radius_computer } from '@/utils';
import { cloneDeep } from 'lodash';
const props = defineProps({
@ -51,7 +51,7 @@ watch(
background_img_style: new_style.tabs_bg_background_img_style,
background_img: new_style.tabs_bg_background_img,
}
tabs_container.value = gradient_computer(tabs_data);
tabs_container.value = gradient_computer(tabs_data) + radius_computer(new_style.tabs_radius);
tabs_img_container.value = background_computer(tabs_data) + padding_computer(new_style.tabs_padding);
//
const shop_content_data = {
@ -60,7 +60,7 @@ watch(
background_img_style: new_style.shop_content_background_img_style,
background_img: new_style.shop_content_background_img,
}
shop_container.value = gradient_computer(shop_content_data) + margin_computer(new_style.shop_content_margin);
shop_container.value = gradient_computer(shop_content_data) + margin_computer(new_style.shop_content_margin) + radius_computer(new_style.shop_content_radius);
shop_img_container.value = background_computer(shop_content_data) + padding_computer(new_style.shop_content_padding);
//
new_data.content.data_type = new_data.content.tabs_list[tabs_active_index.value].data_type;
@ -76,7 +76,7 @@ watch(
tabs_list.value = new_data;
//
style_container.value += common_styles_computer(new_style.common_style);
style_img_container.value = common_img_computer(new_style.common_style);
style_img_container.value = common_img_computer(new_style.common_style) + `gap: ${new_style.shop_content_spacing}px;`;
},
{ immediate: true, deep: true }
);

View File

@ -33,6 +33,9 @@
<upload v-model="form.tabs_bg_background_img" :limit="1" @update:model-value="tabs_bg_background_img_change"></upload>
</div>
</el-form-item>
<el-form-item label="圆角">
<radius :value="form.tabs_radius"></radius>
</el-form-item>
<el-form-item label="内边距">
<padding :value="form.tabs_padding"></padding>
</el-form-item>
@ -51,12 +54,18 @@
<upload v-model="form.shop_content_background_img" :limit="1" @update:model-value="shop_content_background_img_change"></upload>
</div>
</el-form-item>
<el-form-item label="圆角">
<radius :value="form.shop_content_radius"></radius>
</el-form-item>
<el-form-item label="外间距">
<margin :value="form.shop_content_margin"></margin>
</el-form-item>
<el-form-item label="内间距">
<padding :value="form.shop_content_padding"></padding>
</el-form-item>
<el-form-item label="数据间距">
<slider v-model="form.shop_content_spacing" :max="100"></slider>
</el-form-item>
</card-container>
<div class="divider-line"></div>
<card-container>

View File

@ -15,7 +15,7 @@
</div>
</template>
<script setup lang="ts">
import { common_styles_computer, common_img_computer, padding_computer, gradient_computer, background_computer, margin_computer } from '@/utils';
import { common_styles_computer, common_img_computer, padding_computer, gradient_computer, background_computer, margin_computer, radius_computer } from '@/utils';
import { cloneDeep } from 'lodash';
const props = defineProps({
value: {
@ -47,7 +47,7 @@ watch(
background_img_style: new_style.tabs_bg_background_img_style,
background_img: new_style.tabs_bg_background_img,
}
tabs_container.value = gradient_computer(tabs_data);
tabs_container.value = gradient_computer(tabs_data) + radius_computer(new_style.tabs_radius);
tabs_img_container.value = background_computer(tabs_data) + padding_computer(new_style.tabs_padding);
//
const carousel_content_data = {
@ -56,7 +56,7 @@ watch(
background_img_style: new_style.carousel_content_background_img_style,
background_img: new_style.carousel_content_background_img,
}
carousel_container.value = gradient_computer(carousel_content_data) + margin_computer(new_style.carousel_content_margin);
carousel_container.value = gradient_computer(carousel_content_data) + margin_computer(new_style.carousel_content_margin) + radius_computer(new_style.carousel_content_radius);
carousel_img_container.value = background_computer(carousel_content_data) + padding_computer(new_style.carousel_content_padding);
//
new_data.content.tabs_list = [home_data, ...new_data.content.tabs_list];

View File

@ -34,6 +34,9 @@
<upload v-model="form.tabs_bg_background_img" :limit="1" @update:model-value="tabs_bg_background_img_change"></upload>
</div>
</el-form-item>
<el-form-item label="圆角">
<radius :value="form.tabs_radius"></radius>
</el-form-item>
<el-form-item label="内边距">
<padding :value="form.tabs_padding"></padding>
</el-form-item>

View File

@ -54,13 +54,16 @@ interface DefaultArticleTabs {
tabs_bg_background_img_style: string,
tabs_bg_background_img: string[],
tabs_sign_spacing: number;
tabs_radius: radiusStyle;
tabs_padding: paddingStyle;
article_content_direction: string;
article_content_color_list: color_list[];
article_content_background_img_style: string;
article_content_background_img: string[];
article_content_radius: radiusStyle;
article_content_margin: marginStyle;
article_content_padding: paddingStyle;
article_content_spacing: number;
article_direction: string,
article_color_list: color_list[],
article_background_img_style: string,
@ -141,21 +144,35 @@ const defaultArticleTabs: DefaultArticleTabs = {
tabs_bg_color_list: [{ color: '', color_percentage: undefined }],
tabs_bg_background_img_style: '2',
tabs_bg_background_img: [],
tabs_radius: {
radius: 0,
radius_top_left: 0,
radius_top_right: 0,
radius_bottom_left: 0,
radius_bottom_right: 0,
},
tabs_padding: {
padding: 0,
padding_top: 0,
padding_bottom: 0,
padding_left: 0,
padding_right: 0,
padding: 10,
padding_top: 10,
padding_bottom: 10,
padding_left: 10,
padding_right: 10,
},
// 文章内容设置
article_content_direction: '90deg',
article_content_color_list: [{ color: '', color_percentage: undefined }],
article_content_background_img_style: '2',
article_content_background_img: [],
article_content_radius: {
radius: 0,
radius_top_left: 0,
radius_top_right: 0,
radius_bottom_left: 0,
radius_bottom_right: 0,
},
article_content_margin: {
margin: 0,
margin_top: 10,
margin_top: 0,
margin_bottom: 0,
margin_left: 0,
margin_right: 0,
@ -163,10 +180,11 @@ const defaultArticleTabs: DefaultArticleTabs = {
article_content_padding: {
padding: 0,
padding_top: 0,
padding_bottom: 0,
padding_left: 0,
padding_right: 0,
padding_bottom: 10,
padding_left: 10,
padding_right: 10,
},
article_content_spacing: 0,
// 文章背景设置
article_direction: '90deg',
article_color_list: [{ color: '#fff', color_percentage: undefined }],

View File

@ -57,13 +57,16 @@ interface DefaultProductList {
tabs_bg_color_list: color_list[],
tabs_bg_background_img_style: string,
tabs_bg_background_img: string[],
tabs_radius: radiusStyle;
tabs_padding: paddingStyle;
shop_content_direction: string;
shop_content_color_list: color_list[];
shop_content_background_img_style: string;
shop_content_background_img: string[];
shop_content_radius: radiusStyle;
shop_content_margin: marginStyle;
shop_content_padding: paddingStyle;
shop_content_spacing: number;
shop_direction: string;
shop_color_list: color_list[];
shop_background_img_style: string;
@ -172,21 +175,35 @@ const defaultProductList: DefaultProductList = {
tabs_bg_color_list: [{ color: '', color_percentage: undefined }],
tabs_bg_background_img_style: '2',
tabs_bg_background_img: [],
tabs_radius: {
radius: 0,
radius_top_left: 0,
radius_top_right: 0,
radius_bottom_left: 0,
radius_bottom_right: 0,
},
tabs_padding: {
padding: 0,
padding_top: 0,
padding_bottom: 0,
padding_left: 0,
padding_right: 0,
padding: 10,
padding_top: 10,
padding_bottom: 10,
padding_left: 10,
padding_right: 10,
},
// 商品内容设置
shop_content_direction: '90deg',
shop_content_color_list: [{ color: '', color_percentage: undefined }],
shop_content_background_img_style: '2',
shop_content_background_img: [],
shop_content_radius: {
radius: 0,
radius_top_left: 0,
radius_top_right: 0,
radius_bottom_left: 0,
radius_bottom_right: 0,
},
shop_content_margin: {
margin: 0,
margin_top: 10,
margin_top: 0,
margin_bottom: 0,
margin_left: 0,
margin_right: 0,
@ -194,10 +211,11 @@ const defaultProductList: DefaultProductList = {
shop_content_padding: {
padding: 0,
padding_top: 0,
padding_bottom: 0,
padding_left: 0,
padding_right: 0,
padding_bottom: 10,
padding_left: 10,
padding_right: 10,
},
shop_content_spacing: 0,
// 商品背景设置
shop_direction: '90deg',
shop_color_list: [{ color: '#fff', color_percentage: undefined }],
@ -281,7 +299,7 @@ const defaultProductList: DefaultProductList = {
shop_icon_size: 10,
shop_icon_color: '#fff',
subscript_style: subscriptStyle,
common_style: { ...defaultCommon, padding: 10, padding_top: 10, padding_bottom: 10, padding_left: 10, padding_right: 10 },
common_style: defaultCommon,
},
};

View File

@ -45,11 +45,13 @@ interface defaultTabs {
tabs_bg_color_list: color_list[],
tabs_bg_background_img_style: string,
tabs_bg_background_img: string[],
tabs_radius: radiusStyle;
tabs_padding: paddingStyle;
carousel_content_direction: string;
carousel_content_color_list: color_list[];
carousel_content_background_img_style: string;
carousel_content_background_img: string[];
carousel_content_radius: radiusStyle;
carousel_content_margin: marginStyle;
carousel_content_padding: paddingStyle;
more_icon_class: string;
@ -152,21 +154,35 @@ const defaultTabs: defaultTabs = {
tabs_bg_color_list: [{ color: '', color_percentage: undefined }],
tabs_bg_background_img_style: '2',
tabs_bg_background_img: [],
tabs_radius: {
radius: 0,
radius_top_left: 0,
radius_top_right: 0,
radius_bottom_left: 0,
radius_bottom_right: 0,
},
tabs_padding: {
padding: 0,
padding_top: 0,
padding_bottom: 0,
padding_left: 0,
padding_right: 0,
padding: 10,
padding_top: 10,
padding_bottom: 10,
padding_left: 10,
padding_right: 10,
},
// 轮播内间距设置
carousel_content_direction: '90deg',
carousel_content_color_list: [{ color: '', color_percentage: undefined }],
carousel_content_background_img_style: '2',
carousel_content_background_img: [],
carousel_content_radius: {
radius: 0,
radius_top_left: 0,
radius_top_right: 0,
radius_bottom_left: 0,
radius_bottom_right: 0,
},
carousel_content_margin: {
margin: 0,
margin_top: 10,
margin_top: 0,
margin_bottom: 0,
margin_left: 0,
margin_right: 0,
@ -174,9 +190,9 @@ const defaultTabs: defaultTabs = {
carousel_content_padding: {
padding: 0,
padding_top: 0,
padding_bottom: 0,
padding_left: 0,
padding_right: 0,
padding_bottom: 10,
padding_left: 10,
padding_right: 10,
},
// 更多设置
more_icon_class: 'category-more',

View File

@ -289,4 +289,11 @@ p {
position: absolute;
left: 20px;
}
}
.el-table .table-error-row {
background: #FFEAEA !important;
.el-table__cell {
background: #FFEAEA !important;
}
}