数据选项卡内容处理

v1.2.0
于肖磊 2025-02-06 16:16:15 +08:00
parent be17019f41
commit 790a59ebed
19 changed files with 669 additions and 181 deletions

View File

@ -1,44 +0,0 @@
<template>
<div class="data-tabs-style">
<model-article-list-styles :value="form" :content="data" :default-config="defaultConfig" :is-common-style="false" />
</div>
</template>
<script lang="ts" setup>
const props = defineProps({
value: {
type: Object,
default: () => ({}),
},
content: {
type: Object,
default: () => ({}),
},
defaultConfig: {
type: Object,
default: () => ({
//
img_radius_0: 4,
img_radius_1: 0,
}),
},
});
//
const state = reactive({
form: props.value,
data: props.content,
});
// 使toRefs
const { form, data } = toRefs(state);
watch(() => props.value, (value) => {
form.value = value;
},{deep: true, immediate: true });
watch(() => props.content, (value) => {
data.value = value;
},{deep: true, immediate: true });
</script>
<style lang="scss" scoped>
</style>

View File

@ -1,5 +1,5 @@
<template>
<card-container>
<card-container class="card-container">
<div class="mb-12">展示设置</div>
<el-form-item label="选择风格">
<el-radio-group v-model="form.theme" @change="theme_change">
@ -12,8 +12,8 @@
</el-radio-group>
</el-form-item>
</card-container>
<div class="divider-line"></div>
<card-container>
<div class="divider-line data-tabs-line"></div>
<card-container class="card-container">
<div class="mb-12">列表设置</div>
<el-form-item label="是否显示">
<el-checkbox-group v-model="form.field_show">
@ -31,13 +31,13 @@
</el-form-item>
</template>
</card-container>
<div class="divider-line"></div>
<card-container>
<div class="divider-line data-tabs-line"></div>
<card-container class="card-container">
<div class="mb-12">角标设置</div>
<!-- 角标设置 -->
<subscript-content :value="form"></subscript-content>
</card-container>
<div class="divider-line"></div>
<div class="divider-line data-tabs-line"></div>
<!-- 数据筛选组件, 根据数据源类型显示不同的筛选组件 -->
<data-filter type="article" :value="form" :list="form.data_list" :base-list="base_list" @add="add" @data_list_replace="data_list_replace" @data_list_remove="data_list_remove" @data_list_sort="data_list_sort"></data-filter>
<url-value-dialog v-model:dialog-visible="url_value_dialog_visible" :type="['article']" :multiple="url_value_multiple_bool" @update:model-value="url_value_dialog_call_back"></url-value-dialog>

View File

@ -0,0 +1,587 @@
<template>
<div class="auxiliary-line custom-data">
<el-form :model="form" label-width="70">
<template v-if="!isSubcomponent">
<common-content-top :value="form.content_top"></common-content-top>
<div class="divider-line data-tabs-line"></div>
</template>
<card-container class="card-container">
<div class="mb-20">数据源</div>
<el-form-item label="动态数据">
<el-select v-model="form.data_source" value-key="id" placeholder="请选择数据源" filterable clearable @change="changeDataSource">
<el-option v-for="item in options" :key="item.type" :label="item.name" :value="item.type" />
</el-select>
</el-form-item>
<template v-if="!isEmpty(form.data_source)">
<el-form-item label="数据循环">
<div class="flex-row gap-10">
<el-radio-group v-model="form.data_source_is_loop">
<el-radio value="1"></el-radio>
<el-radio value="0"></el-radio>
</el-radio-group>
<el-tooltip effect="dark" :show-after="200" :hide-after="200" content="1. 是的情况下,第一层自定义自动循环动态数据,编组可以使用循环项数据或其中的列表数据。<br/>2. 否的情况下,第一层自定义不能使用当前动态数据,只能在编组里面选择使用。" raw-content placement="top">
<icon name="miaosha-hdgz" size="12" color="#999"></icon>
</el-tooltip>
</div>
</el-form-item>
</template>
</card-container>
<!-- 筛选数据 -->
<template v-if="!isEmpty(default_type_data)">
<template v-if="default_type_data?.show_type.length > 0 && form.data_source_is_loop == '1'">
<div class="divider-line data-tabs-line"></div>
<card-container class="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">
<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 data-tabs-line"></div>
<card-container class="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-group>
</el-form-item>
<div v-show="Number(form.data_source_content.data_type) === 0" class="nav-list flex-col gap-20">
<filter-form v-if="!isEmpty(default_type_data?.appoint_config?.filter_form_config || {})" :filter-data="default_type_data?.appoint_config?.filter_form_config || {}" direction="vertical" :title-width="58" :data-interface="form.data_source_content" @form-change="filter_form_change"></filter-form>
<drag-group v-if="!isEmpty(form.data_source_content.data_list)" :list="form.data_source_content.data_list" :img-params="form.show_data?.data_logo || ''" :title-params="form.show_data?.data_name || 'name'" type="custom" @onsort="data_list_sort" @remove="data_list_remove" @replace="data_list_replace"></drag-group>
<el-button class="w" @click="add">+</el-button>
</div>
<div v-show="Number(form.data_source_content.data_type) === 1">
<filter-form :filter-data="default_type_data?.filter_config?.filter_form_config || {}" direction="vertical" :title-width="58" :data-interface="form.data_source_content" @form-change="filter_form_change"></filter-form>
</div>
</div>
</card-container>
</template>
</template>
<div class="divider-line data-tabs-line"></div>
<el-button class="w custom-button size-14" size="large" @click="custom_edit('custom')"><icon name="edit" size="14"></icon>自定义编辑</el-button>
</el-form>
<!-- 自定义内容处理 -->
<custom-config :key="dragkey + 'custom'" v-model:visible="dialogVisible" v-model:width="custom_width" v-model:height="center_height" :config-loop="form.data_source_is_loop" :dragkey="dragkey + 'custom'" :options="model_data_source" :source-list="!isEmpty(data_source_content_list) ? data_source_content_list[0] : {}" :group-source-list="data_source_content_list" :is-custom="form.is_custom_data == '1'" :show-data="form?.show_data || { data_key: 'id', data_name: 'name' }" :custom-list="custom_list" @accomplish="accomplish" @custom_edit="custom_edit"></custom-config>
<!-- 自定义内部数据内容处理 -->
<custom-config :key="drag_group_key + 'custom-group'" v-model:visible="dialogVisible_group" v-model:width="center_group_width" v-model:height="center_group_height" v-model:father-list="custom_group_father_list" config-type="custom-group" config-loop="1" :dragkey="drag_group_key + 'custom-group'" :options="custom_group_option_list" :source-list="!isEmpty(new_group_source_list) ? new_group_source_list : {}" :group-source-list="data_source_content_list" :is-custom="form.is_custom_data == '1'" :is-custom-group="true" :show-data="form?.show_data || { data_key: 'id', data_name: 'name' }" :custom-id="center_group_id" :custom-list="custom_group_list" :custom-group-field-id="custom_group_field_id" @accomplish="accomplish"></custom-config>
<!-- 手动筛选数据弹出框 -->
<custom-dialog v-model:dialog-visible="url_value_dialog_visible" :data-list-key="form.show_data?.data_key || 'id'" :config="default_type_data.appoint_config" :extra-search-data="form.data_source_content" :multiple="url_value_multiple_bool" @confirm_event="url_value_dialog_call_back"></custom-dialog>
</div>
</template>
<script setup lang="ts">
import { isEmpty, cloneDeep, pick } from 'lodash';
import request from '@/utils/request';
import CustomAPI from '@/api/custom';
import { DataSourceStore } from '@/store';
import { get_math, get_nested_property, interface_field_processing } from '@/utils';
const data_source_store = DataSourceStore();
const props = defineProps({
configType: {
type: String,
default: 'custom',
},
value: {
type: Object,
default: () => {},
},
magicWidth: {
type: Number,
default: 390,
},
isSubcomponent: {
type: Boolean,
default: false,
}
});
//
const center_width = ref(props.magicWidth);
//
const custom_width = computed(() => {
// data_source_direction != vertical-scroll
if (form.value.is_custom_data == '1' && form.value.data_source_direction != 'vertical-scroll') {
return center_width.value / form.value.data_source_carousel_col;
} else {
return center_width.value;
}
})
const form = ref(props.value);
//
//
const dragkey = ref('');
const dialogVisible = ref(false);
const custom_list = ref([]);
const center_height = ref(0);
//
//
const dialogVisible_group = ref(false);
//
const custom_group_list = ref([]);
//
const center_group_height = ref(0);
const center_group_width = ref(0);
// id
const center_group_id = ref('');
//
const custom_group_father_list = ref([]);
// key
const drag_group_key = ref('');
// id
const custom_group_field_id = ref('');
//
const custom_group_option_list = ref<any[]>([]);
const new_group_source_list = ref({});
//
const custom_edit = (type: string, id?: string, father_list?: any, list?: any, width?: number, height?: number, data_source_field?: { id: string, option: []}, is_use_parent_data?: string) => {
//
if (type == 'custom') {
dragkey.value = Math.random().toString(36).substring(2);
dialogVisible.value = true;
//
custom_list.value = cloneDeep(form.value.custom_list);
//
center_height.value = cloneDeep(form.value.height);
//
data_source_store.set_is_children_custom(false);
} else {
//
drag_group_key.value = Math.random().toString(36).substring(2);
//
dialogVisible_group.value = true;
//
custom_group_list.value = list;
//
custom_group_father_list.value = father_list;
// id
center_group_id.value = id || '';
//
center_group_width.value = width || 0;
center_group_height.value = height || 0;
//
custom_group_field_id.value = data_source_field?.id || '';
// ,
const is_data_source_id = model_data_source.value.filter((item: any) => item.field == data_source_field?.id);
if (form.value.data_source_is_loop == '1') {
if (is_data_source_id.length > 0) {
custom_group_option_list.value = data_source_field?.option || [];
new_group_source_list.value = new_group_source_list_handle(data_source_field?.id || '');
} else {
custom_group_option_list.value = model_data_source.value;
new_group_source_list.value = !isEmpty(data_source_content_list) ? data_source_content_list.value[0] : {};
}
} else {
// 使
if (is_use_parent_data == '1') {
custom_group_option_list.value = model_data_source.value;
new_group_source_list.value = !isEmpty(data_source_content_list) ? data_source_content_list.value[0] : {};
} else {
custom_group_option_list.value = [];
new_group_source_list.value = {};
}
}
//
data_source_store.set_is_children_custom(true);
}
};
//
const new_group_source_list_handle = (data_source_id: string) => {
const source_list = !isEmpty(data_source_content_list.value) ? data_source_content_list.value[0] : {};
if (!isEmpty(source_list)) {
let list = get_nested_property(source_list, data_source_id);
//
if (source_list.data) {
list = get_nested_property(source_list.data, data_source_id);
}
return list.length > 0 ? list[0] : {};
} else {
return {};
}
}
//
const accomplish = (type: string, list: any) => {
//
data_source_store.set_is_children_custom(false);
//
if (type == 'custom') {
form.value.custom_list = list;
form.value.height = center_height.value;
} else {
//
custom_list.value = list;
}
};
//#endregion
//
interface custom_config {
show_type: string[],
show_number: number[],
data_type: string[],
filter_config: object,
appoint_config: object,
}
interface data_list {
name: string;
field: string;
type: string;
}
interface options_item {
custom_config?: custom_config;
appoint_data?: object;
name: string;
data: data_list[];
type: string;
}
const options = ref<options_item[]>([]);
//#region
const getCustominit = () => {
CustomAPI.getCustominit().then((res) => {
const { data_source } = res.data;
options.value = data_source;
data_source_store.set_data_source(data_source);
//
processing_data(form.value.data_source);
data_processing();
});
};
onBeforeMount(() => {
if (!data_source_store.is_data_source_api) {
data_source_store.set_is_data_source_api(true);
getCustominit();
} else {
options.value = data_source_store.data_source_list;
//
processing_data(form.value.data_source);
data_processing();
}
});
//
const data_processing = () => {
//
const type_data = options.value.filter((item) => item.type == form.value.data_source);
if (type_data.length > 0 && !isEmpty(type_data[0].custom_config)) {
//
form.value.is_custom_data = '1';
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],
};
filter_data_handling('old');
default_data();
}
};
//
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)) {
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)) {
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)) {
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.show_data = default_type_data.value?.appoint_config?.show_data || { data_key: 'id', data_name: 'name' };
}
// data_source_content type old new
const filter_data_handling = (type: string = 'old') => {
//
const data_type = default_type_data.value.data_type.length > 0 ? default_type_data.value.data_type[0] : 0;
//
const staging_data : any = {
// id
data_ids: type == 'old' ? form.value.data_source_content?.data_ids ?? [] : [],
//
data_list: type == 'old' ? form.value.data_source_content?.data_list ?? [] : [],
//
data_auto_list: type == 'old' ? form.value.data_source_content?.data_auto_list ?? [] : [],
// 使使
data_type: type == 'old'? (form.value.data_source_content?.data_type ?? data_type) : data_type,
};
let new_data_field = {};
//
if (staging_data.data_type === 0) {
//
new_data_field = {
...interface_field_processing(default_type_data.value?.filter_config?.filter_form_config, type, form.value?.data_source_content || {}),
...interface_field_processing(default_type_data.value?.appoint_config?.filter_form_config, type, form.value?.data_source_content || {}),
}
} else {
//
new_data_field = {
...interface_field_processing(default_type_data.value?.appoint_config?.filter_form_config, type, form.value?.data_source_content || {}),
...interface_field_processing(default_type_data.value?.filter_config?.filter_form_config, type, form.value?.data_source_content || {}),
}
}
//
form.value.data_source_content = {
...staging_data,
...new_data_field,
};
};
//
const model_data_source = ref<data_list[]>([]);
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 = [];
}
};
//
provide('field_list', computed(() => form.value.field_list));
//#endregion
//#region
//
const url_value_dialog_visible = ref(false);
const default_type_data = ref<any>({})
const url_value_multiple_bool = ref(true);
const emits = defineEmits(['data_source_change']);
const changeDataSource = (key: string) => {
form.value.is_custom_data = '0';
const type_data = options.value.filter((item) => item.type == key);
processing_data(key);
//
form.value.data_source_content = {
// id
data_ids: [],
data_list: [],
//
data_auto_list: [],
}
//
default_type_data.value = {};
form.value.data_source_direction = 'vertical';
// data_list
if (type_data.length > 0 && !isEmpty(type_data[0].appoint_data)) {
emits('data_source_change', type_data[0].name);
form.value.data_source_content.data_list = [ type_data[0].appoint_data ];
} else if (type_data.length > 0 && !isEmpty(type_data[0].custom_config)) {
emits('data_source_change', type_data[0].name);
//
form.value.is_custom_data = '1';
//
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();
//
filter_data_handling('new');
} else {
emits('data_source_change', '')
}
};
const filter_form_change = (val: any) => {
form.value.data_source_content = val;
}
//#endregion
//#region
const data_list_replace_index = ref(0);
const data_list_replace = (index: number) => {
// index
data_list_replace_index.value = index;
//
url_value_multiple_bool.value = false;
url_value_dialog_visible.value = true;
};
//
const add = () => {
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 == 1 ? true : false;
url_value_dialog_visible.value = true;
}
};
//
const data_list_sort = (new_list: any) => {
form.value.data_source_content.data_list = new_list;
data_list_index_update();
};
const data_list_remove = (index: number) => {
form.value.data_source_content.data_list.splice(index, 1);
data_list_index_update();
};
//
const url_value_dialog_call_back = (item: any[]) => {
// data_list_replace_index -1
if (url_value_multiple_bool.value || data_list_replace_index.value == -1) {
item.forEach((item: any) => {
form.value.data_source_content.data_list.push({
id: get_math(),
new_cover: [],
new_title: '',
data: item,
});
});
} else {
form.value.data_source_content.data_list[data_list_replace_index.value] = {
id: get_math(),
new_cover: form.value.data_source_content.data_list[data_list_replace_index.value]?.new_cover || [],
new_title: '',
data: item[0],
};
}
data_list_index_update();
};
const data_list_index_update = () => {
if (form.value.data_source_content.data_list.length > 0) {
form.value.data_source_content.data_list.forEach((item: any, index: number) => {
item.data.data_index = index + 1;
});
}
};
//
const data_source_content_list = computed(() => {
if (form.value.is_custom_data == '1') {
if (Number(form.value.data_source_content.data_type) === 0) {
return form.value.data_source_content.data_list;
} else {
return form.value.data_source_content.data_auto_list;
}
} else {
return form.value.data_source_content.data_list;
}
})
//
const get_auto_data = () => {
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 filter_data = interface_field_processing(default_type_data.value?.filter_config?.filter_form_config, 'new', {}) || {};
// key
const filter_key = Object.keys(filter_data);
// key
const data = pick(cloneDeep(form.value.data_source_content), filter_key);
request({
url: default_type_data.value.filter_config.data_url, //
method: 'post', //
data //
}).then((res) => {
if (res.data) {
form.value.data_source_content.data_auto_list = res.data;
} else {
// ,
form.value.data_source_content.data_auto_list = [];
}
}).catch((err) => {
// ,
form.value.data_source_content.data_auto_list = [];
});
}
};
//
const data_source_content_value = computed(() => {
// 'data_ids', 'data_list', 'data_auto_list'
const data: any = {};
for (const key in form.value.data_source_content) {
if (!['data_ids', 'data_list', 'data_auto_list'].includes(key)) {
data[key] = form.value.data_source_content[key];
}
}
return data;
})
//
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) !== 0) {
get_auto_data();
}
},{ deep: true });
//#endregion
</script>
<style lang="scss" scoped>
:deep(.el-dialog) {
margin-top: 0;
padding: 0;
overflow: hidden;
.el-dialog__header {
padding: 2.3rem 2rem;
.el-dialog__title {
font-size: 16px;
}
.el-dialog__headerbtn {
font-size: 2.4rem;
padding: 2rem;
height: auto;
width: auto;
}
}
.el-dialog__body {
background: #f5f5f5;
height: calc(100% - 15rem);
}
.el-dialog__footer {
padding: 2.4rem 3rem;
}
}
.custom-data {
background: transparent;
}
.custom-button {
position: -webkit-sticky;
position: sticky;
bottom: 0; /* 固定在底部 */
background-color: white; /* 设置背景色以避免按钮看不见 */
z-index: 1000; /* 确保按钮在其他内容之上 */
width: 100%; /* 确保按钮宽度占满父容器 */
padding: 1rem; /* 添加一些内边距 */
}
</style>

View File

@ -1,27 +1,29 @@
<template>
<el-form-item label="商品风格">
<el-radio-group v-model="form.theme" @change="change_style">
<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.carousel_col">
<el-radio :value="1">单列展示</el-radio>
<el-radio :value="2">两列展示</el-radio>
<el-radio :value="3">三列展示</el-radio>
<el-radio :value="4">四列展示</el-radio>
</el-radio-group>
</el-form-item>
<div class="divider-line"></div>
<card-container class="card-container">
<el-form-item label="商品风格">
<el-radio-group v-model="form.theme" @change="change_style">
<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.carousel_col">
<el-radio :value="1">单列展示</el-radio>
<el-radio :value="2">两列展示</el-radio>
<el-radio :value="3">三列展示</el-radio>
<el-radio :value="4">四列展示</el-radio>
</el-radio-group>
</el-form-item>
</card-container>
<div class="divider-line data-tabs-line"></div>
<!-- 商品显示的配置信息 -->
<product-show-config :value="form" @change_shop_type="change_shop_type"></product-show-config>
<div class="divider-line"></div>
<card-container>
<div class="divider-line data-tabs-line"></div>
<card-container class="card-container">
<div class="mb-12">角标设置</div>
<!-- 角标设置 -->
<subscript-content :value="form"></subscript-content>
</card-container>
<div class="divider-line"></div>
<div class="divider-line data-tabs-line"></div>
<!-- 数据筛选组件, 根据数据源类型显示不同的筛选组件 -->
<data-filter type="goods" :value="form" :list="form.data_list" :base-list="base_list" @add="product_add" @data_list_replace="data_list_replace" @data_list_remove="goods_list_remove" @data_list_sort="goods_list_sort"></data-filter>
<url-value-dialog v-model:dialog-visible="url_value_dialog_visible" :type="['goods']" :multiple="url_value_multiple_bool" @update:model-value="url_value_dialog_call_back"></url-value-dialog>

View File

@ -1,44 +0,0 @@
<template>
<div class="data-tabs-style">
<model-goods-list-styles :value="form" :content="data" :default-config="defaultConfig" :is-common-style="false" />
</div>
</template>
<script lang="ts" setup>
const props = defineProps({
value: {
type: Object,
default: () => ({}),
},
content: {
type: Object,
default: () => ({}),
},
defaultConfig: {
type: Object,
default: () => ({
//
img_radius_0: 4,
img_radius_1: 0,
}),
},
});
//
const state = reactive({
form: props.value,
data: props.content,
});
// 使toRefs
const { form, data } = toRefs(state);
watch(() => props.value, (value) => {
form.value = value;
},{deep: true, immediate: true });
watch(() => props.content, (value) => {
data.value = value;
},{deep: true, immediate: true });
</script>
<style lang="scss" scoped>
</style>

View File

@ -1,5 +1,5 @@
<template>
<card-container>
<card-container class="card-container">
<div class="mb-12">显示内容</div>
<el-form-item label="是否显示">
<el-checkbox-group v-model="form.is_show">
@ -15,8 +15,8 @@
<el-switch v-model="form.is_price_solo" active-value="1" inactive-value="0"></el-switch>
</el-form-item>
</card-container>
<div class="bg-f5 divider-line" />
<card-container>
<div class="divider-line data-tabs-line" />
<card-container class="card-container">
<div class="mb-12">购物车设置</div>
<el-form-item label="是否显示">
<el-switch v-model="form.is_shop_show" active-value="1" inactive-value="0" ></el-switch>

View File

@ -1,5 +1,5 @@
<template>
<card-container>
<card-container class="card-container">
<div v-if="props.type != 'nav-group'" class="mb-12"></div>
<el-form-item label="角标位置">
<div class="flex-col gap-10">

View File

@ -1,7 +1,7 @@
<template>
<div class="styles">
<el-form :model="form" label-width="70">
<card-container>
<card-container class="card-container">
<div class="mb-12">列表样式</div>
<el-form-item v-if="theme != '3'" label="文章背景">
<background-common v-model:color_list="form.article_color_list" v-model:direction="form.article_direction" v-model:img_style="form.article_background_img_style" v-model:img="form.article_background_img" @mult_color_picker_event="mult_color_picker_event" />
@ -80,8 +80,8 @@
</template>
</card-container>
<template v-if="theme == '4'">
<div class="divider-line"></div>
<card-container>
<div class="divider-line data-tabs-line"></div>
<card-container class="card-container">
<div class="mb-12">轮播设置</div>
<el-form-item label="自动轮播">
<el-switch v-model="form.is_roll" :active-value="1" :inactive-value="0" />
@ -101,12 +101,12 @@
</template>
<!-- 角标 -->
<template v-if="data.seckill_subscript_show == '1'">
<div class="divider-line"></div>
<div class="divider-line data-tabs-line"></div>
<subscript-styles :value="form.subscript_style" :data="data"></subscript-styles>
</template>
</el-form>
<template v-if="isCommonStyle">
<div class="divider-line"></div>
<div class="divider-line data-tabs-line"></div>
<common-styles :value="form.common_style" @update:value="common_style_update" />
</template>
</div>

View File

@ -89,12 +89,9 @@ const props = defineProps({
});
//
const state = reactive({
form: props.value.content,
new_style: props.value.style,
});
// 使toRefs
const { form, new_style } = toRefs(state);
const form = computed(() => props.value?.content || {});
const new_style = computed(() => props.value?.style || {});
// ,
provide('field_list', computed(() => form.value?.field_list || []));
onBeforeMount(() => {

View File

@ -1,11 +1,11 @@
<template>
<div class="auxiliary-line custom-data">
<el-form :model="form" label-width="70">
<template v-if="!isDataMagic">
<template v-if="!isSubcomponent">
<common-content-top :value="form.content_top"></common-content-top>
<div class="divider-line"></div>
<div class="divider-line data-tabs-line"></div>
</template>
<card-container>
<card-container class="card-container">
<div class="mb-20">数据源</div>
<el-form-item label="动态数据">
<el-select v-model="form.data_source" value-key="id" placeholder="请选择数据源" filterable clearable @change="changeDataSource">
@ -29,8 +29,8 @@
<!-- 筛选数据 -->
<template v-if="!isEmpty(default_type_data)">
<template v-if="default_type_data?.show_type.length > 0 && form.data_source_is_loop == '1'">
<div class="divider-line"></div>
<card-container>
<div class="divider-line data-tabs-line"></div>
<card-container class="card-container">
<div class="mb-12">显示设置</div>
<el-form-item label="铺满方式">
<el-radio-group v-model="form.data_source_direction">
@ -47,8 +47,8 @@
</card-container>
</template>
<template v-if="default_type_data.data_type.length > 0">
<div class="divider-line"></div>
<card-container>
<div class="divider-line data-tabs-line"></div>
<card-container class="card-container">
<div class="mb-12">数据设置</div>
<div class="flex-col">
<el-form-item label="读取方式">
@ -70,7 +70,7 @@
</card-container>
</template>
</template>
<div class="divider-line"></div>
<div class="divider-line data-tabs-line"></div>
<el-button class="w custom-button size-14" size="large" @click="custom_edit('custom')"><icon name="edit" size="14"></icon>自定义编辑</el-button>
</el-form>
<!-- 自定义内容处理 -->
@ -102,7 +102,7 @@ const props = defineProps({
type: Number,
default: 390,
},
isDataMagic: {
isSubcomponent: {
type: Boolean,
default: false,
}

View File

@ -2,7 +2,7 @@
<div class="w">
<el-form :model="form" label-width="70">
<template v-if="['vertical-scroll', 'horizontal'].includes(data.data_source_direction)">
<card-container>
<card-container class="card-container">
<div class="mb-12">轮播设置</div>
<el-form-item label="自动轮播">
<el-switch v-model="form.is_roll" active-value="1" inactive-value="0" @change="operation_end"/>
@ -19,13 +19,13 @@
</el-form-item>
</template>
</card-container>
<div class="bg-f5 divider-line" />
<card-container>
<div class="divider-line data-tabs-line" />
<card-container class="card-container">
<carousel-indicator :value="form" @operation_end="operation_end"></carousel-indicator>
</card-container>
<div class="bg-f5 divider-line" />
<div class="divider-line data-tabs-line" />
</template>
<card-container>
<card-container class="card-container">
<div class="mb-12">数据样式</div>
<el-form-item label="背景">
<background-common v-model:color_list="form.data_style.color_list" v-model:direction="form.data_style.direction" v-model:img_style="form.data_style.background_img_style" v-model:img="form.data_style.background_img" @mult_color_picker_event="mult_color_picker_event" @operation_end="operation_end" />
@ -54,8 +54,8 @@
<!-- 阴影配置 -->
<shadow-config v-model="form.data_style" @operation_end="operation_end"></shadow-config>
</card-container>
<div class="bg-f5 divider-line" />
<card-container>
<div class="divider-line data-tabs-line" />
<card-container class="card-container">
<div class="mb-12">内容样式</div>
<el-form-item label="背景">
<background-common v-model:color_list="form.data_content_style.color_list" v-model:direction="form.data_content_style.direction" v-model:img_style="form.data_content_style.background_img_style" v-model:img="form.data_content_style.background_img" @mult_color_picker_event="mult_content_color_picker_event" @operation_end="operation_end" />
@ -75,8 +75,10 @@
<shadow-config v-model="form.data_content_style" @operation_end="operation_end"></shadow-config>
</card-container>
</el-form>
<div class="bg-f5 divider-line" />
<common-styles :value="form.common_style" :is-floating-up="isFloatingUp" @operation_end="operation_end"/>
<template v-if="isCommonStyle">
<div class="divider-line data-tabs-line" />
<common-styles :value="form.common_style" :is-floating-up="isFloatingUp" @operation_end="operation_end"/>
</template>
</div>
</template>
<script setup lang="ts">
@ -93,6 +95,10 @@ const props = defineProps({
type: Boolean,
default: true,
},
isCommonStyle: {
type: Boolean,
default: true,
}
});
const state = reactive({
form: props.value,

View File

@ -105,7 +105,7 @@
</template>
<template v-else-if="form.data_type == 'custom'">
<div class="bg-f5 divider-line" />
<model-custom-content :key="key" :value="form" :magic-width="form.width" :is-data-magic="true" @data_source_change="data_source_change"></model-custom-content>
<model-custom-content :key="key" :value="form" :magic-width="form.width" :is-subcomponent="true" @data_source_change="data_source_change"></model-custom-content>
</template>
<template v-else>
<div class="bg-f5 divider-line" />

View File

@ -15,7 +15,7 @@
<model-article-list :value="tabs_list" :is-common-style="false"></model-article-list>
</template>
<template v-else-if="tabs_data_type == 'custom'">
<model-custom :value="tabs_list" :is-common-style="false"></model-custom>
<model-custom :value="tabs_list" :outer_container_padding="outer_container_width" :is-common-style="false"></model-custom>
</template>
</div>
</div>
@ -46,6 +46,8 @@ const tabs_img_container = ref('');
//
const data_container = ref('');
const data_img_container = ref('');
//
const outer_container_width = ref(0);
watch(
() => props.value,
(val) => {
@ -62,7 +64,7 @@ watch(
}
tabs_container.value = gradient_computer(tabs_data) + radius_computer(new_style.tabs_radius) + margin_computer(new_style.tabs_margin) + border_computer(new_style.tabs_content) + box_shadow_computer(new_style.tabs_content);
tabs_img_container.value = background_computer(tabs_data) + padding_computer(new_style.tabs_padding);
//
//
const data_content = {
color_list: new_style.data_content_color_list,
direction: new_style.data_content_direction,
@ -71,6 +73,9 @@ watch(
}
data_container.value = gradient_computer(data_content) + margin_computer(new_style.data_content_margin) + radius_computer(new_style.data_content_radius) + border_computer(new_style.data_content) + box_shadow_computer(new_style.data_content);
data_img_container.value = background_computer(data_content) + padding_computer(new_style.data_content_padding);
const common_style = new_style.common_style;
//
outer_container_width.value = common_style.margin_left + common_style.margin_right + common_style.padding_left + common_style.padding_right + new_style.data_content_margin.margin_left + new_style.data_content_margin.margin_right + new_style.data_content_padding.padding_left + new_style.data_content_padding.padding_right;
//
const tabs_data_list = new_data.content.tabs_list[tabs_active_index.value] || {};
tabs_data_type.value = tabs_data_list?.tabs_data_type || '';
@ -83,7 +88,7 @@ watch(
}
//
style_container.value += common_styles_computer(new_style.common_style);
style_img_container.value = common_img_computer(new_style.common_style) + `gap: ${new_style.shop_content_spacing}px;`;
style_img_container.value = common_img_computer(new_style.common_style) + `gap: ${new_style.data_content_spacing}px;`;
},
{ immediate: true, deep: true }
);

View File

@ -66,7 +66,7 @@
<data-article-content :value="row.article_config.content" :tab-style="row.article_config.style"></data-article-content>
</div>
<div v-show="row.tabs_data_type == 'custom'" class="data-tabs-style">
<data-goods-content :value="row.goods_config.content" :tab-style="row.goods_config.style"></data-goods-content>
<data-custom-content :value="row.custom_config.content" :is-subcomponent="true"></data-custom-content>
</div>
</el-tab-pane>
<el-tab-pane label="样式设置" name="styles">
@ -77,7 +77,7 @@
<model-article-list-styles :value="row.article_config.style" :content="row.article_config.content" :is-common-style="false" />
</div>
<div v-show="row.tabs_data_type == 'custom'" class="data-tabs-style">
<data-goods-style :value="row.goods_config.style" :content="row.goods_config.content"></data-goods-style>
<model-custom-styles :value="row.custom_config.style" :content="row.custom_config.content" :is-common-style="false"></model-custom-styles>
</div>
</el-tab-pane>
</el-tabs>

View File

@ -113,6 +113,7 @@
<shadow-config v-model="form.data_content"></shadow-config>
</card-container>
</el-form>
<div class="divider-line"></div>
<common-styles :value="form.common_style" @update:value="common_style_update" />
</div>
</template>
@ -149,25 +150,6 @@ const state = reactive({
});
// 使toRefs
const { form, data } = toRefs(state);
const theme = computed(() => data.value.theme);
if (['0', '4'].includes(theme.value)) {
if (form.value.shop_img_radius.radius == props.defaultConfig.img_radius_0 || (form.value.shop_img_radius.radius_bottom_left == props.defaultConfig.img_radius_1 && form.value.shop_img_radius.radius_bottom_right == props.defaultConfig.img_radius_1 && form.value.shop_img_radius.radius_top_left == props.defaultConfig.img_radius_1 && form.value.shop_img_radius.radius_top_right == props.defaultConfig.img_radius_1)) {
form.value.shop_img_radius.radius = props.defaultConfig.img_radius_0;
form.value.shop_img_radius.radius_bottom_left = props.defaultConfig.img_radius_0;
form.value.shop_img_radius.radius_bottom_right = props.defaultConfig.img_radius_0;
form.value.shop_img_radius.radius_top_left = props.defaultConfig.img_radius_0;
form.value.shop_img_radius.radius_top_right = props.defaultConfig.img_radius_0;
}
} else {
if (form.value.shop_img_radius.radius == props.defaultConfig.img_radius_0 || (form.value.shop_img_radius.radius_bottom_left == props.defaultConfig.img_radius_1 && form.value.shop_img_radius.radius_bottom_right == props.defaultConfig.img_radius_1 && form.value.shop_img_radius.radius_top_left == props.defaultConfig.img_radius_1 && form.value.shop_img_radius.radius_top_right == props.defaultConfig.img_radius_1)) {
form.value.shop_img_radius.radius = props.defaultConfig.img_radius_1;
form.value.shop_img_radius.radius_bottom_left = props.defaultConfig.img_radius_1;
form.value.shop_img_radius.radius_bottom_right = props.defaultConfig.img_radius_1;
form.value.shop_img_radius.radius_top_left = props.defaultConfig.img_radius_1;
form.value.shop_img_radius.radius_top_right = props.defaultConfig.img_radius_1;
}
}
const common_style_update = (value: any) => {
form.value.common_style = value;
};

View File

@ -1,7 +1,7 @@
<template>
<div class="w">
<el-form :model="form" label-width="70">
<card-container>
<card-container class="card-container">
<div class="mb-12">商品样式</div>
<el-form-item v-if="theme != '6'" label="商品背景">
<background-common v-model:color_list="form.shop_color_list" v-model:direction="form.shop_direction" v-model:img_style="form.shop_background_img_style" v-model:img="form.shop_background_img" @mult_color_picker_event="mult_color_picker_event" />
@ -90,8 +90,8 @@
</template>
</card-container>
<template v-if="theme == '5'">
<div class="divider-line"></div>
<card-container>
<div class="divider-line data-tabs-line"></div>
<card-container class="card-container">
<div class="mb-12">轮播设置</div>
<el-form-item label="自动轮播">
<el-switch v-model="form.is_roll" active-value="1" inactive-value="0" />
@ -111,12 +111,12 @@
</template>
<!-- 秒杀角标 -->
<template v-if="data.seckill_subscript_show == '1'">
<div class="divider-line"></div>
<div class="divider-line data-tabs-line"></div>
<subscript-styles :value="form.subscript_style" :data="data"></subscript-styles>
</template>
<template v-if="data.is_shop_show == '1'">
<div class="divider-line"></div>
<card-container>
<div class="divider-line data-tabs-line"></div>
<card-container class="card-container">
<div class="mb-12">购物车按钮</div>
<el-form-item label="按钮颜色" class="topic">
<flex-gradients-create :color-list="form.shop_button_color" default-color="#FF3D53"></flex-gradients-create>
@ -135,7 +135,7 @@
</template>
</el-form>
<template v-if="isCommonStyle">
<div class="divider-line"></div>
<div class="divider-line data-tabs-line"></div>
<common-styles :value="form.common_style" @update:value="common_style_update" />
</template>
</div>

View File

@ -317,17 +317,14 @@ p {
}
.data-tabs-style {
.card {
.card-container {
padding: 0 !important;
// .el-form-item:last-child {
// margin-bottom: 1.8rem;
// }
.flex-row.is-newline {
flex-direction: column !important;
align-items: flex-start;
}
}
.divider-line {
.data-tabs-line {
height: 0.1rem !important;
margin-bottom: 1rem;
margin-top: 1rem;