修改自定义历史记录逻辑处理
parent
ffbead8c02
commit
0e8077e1fe
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -5,6 +5,34 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "43087330",
|
||||
"name": "箭头左",
|
||||
"font_class": "left-arrow",
|
||||
"unicode": "e7b4",
|
||||
"unicode_decimal": 59316
|
||||
},
|
||||
{
|
||||
"icon_id": "43087331",
|
||||
"name": "历史记录",
|
||||
"font_class": "historical-records",
|
||||
"unicode": "e7b9",
|
||||
"unicode_decimal": 59321
|
||||
},
|
||||
{
|
||||
"icon_id": "43087329",
|
||||
"name": "箭头右",
|
||||
"font_class": "right-arrow",
|
||||
"unicode": "e7ba",
|
||||
"unicode_decimal": 59322
|
||||
},
|
||||
{
|
||||
"icon_id": "42958997",
|
||||
"name": "编组",
|
||||
"font_class": "grouping",
|
||||
"unicode": "e7d6",
|
||||
"unicode_decimal": 59350
|
||||
},
|
||||
{
|
||||
"icon_id": "42773571",
|
||||
"name": "更多四块",
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -15,11 +15,9 @@
|
|||
<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>
|
||||
<div class="bg-f5 divider-line" />
|
||||
<card-container>
|
||||
<div class="mb-20">自定义设置</div>
|
||||
<el-button class="w" size="large" @click="custom_edit"><icon name="edit" size="12"></icon>自定义编辑</el-button>
|
||||
<el-form-item label="滚动条">
|
||||
<el-switch v-model="form.is_scroll_bar" active-value="1" inactive-value="0" @change="operation_end" />
|
||||
</el-form-item>
|
||||
</card-container>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
|
@ -47,10 +45,7 @@ const group_change = () => {
|
|||
}
|
||||
};
|
||||
|
||||
const emit = defineEmits(['custom_edit', 'operation_end']);
|
||||
const custom_edit = () => {
|
||||
emit('custom_edit', form.value.data_source_field);
|
||||
};
|
||||
const emit = defineEmits(['operation_end']);
|
||||
// 操作结束触发事件
|
||||
const operation_end = () => {
|
||||
emit('operation_end');
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ const get_nested_property = (obj: any, path: string) => {
|
|||
}
|
||||
// #endregion
|
||||
// 公共样式
|
||||
const style_container = computed(() => common_styles_computer(new_style.value.common_style) + 'overflow: auto;');
|
||||
const style_container = computed(() => common_styles_computer(new_style.value.common_style) + (form.value.is_scroll_bar == '1' ? 'overflow: auto;' : ''));
|
||||
const style_img_container = computed(() => common_img_computer(new_style.value.common_style));
|
||||
// 内容样式
|
||||
const style_content_container = computed(() => common_styles_computer(new_style.value.data_content_style));
|
||||
|
|
|
|||
|
|
@ -17,12 +17,14 @@
|
|||
<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" :options="options" @custom_edit="custom_edit" @operation_end="operation_end"></custom-tabs-content>
|
||||
<custom-tabs-content :value="form" :options="options" @operation_end="operation_end"></custom-tabs-content>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="样式设置" name="styles">
|
||||
<model-custom-styles :value="form.data_style" :content="form" :is-floating-up="false" @operation_end="operation_end"></model-custom-styles>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div class="bg-f5 divider-line" />
|
||||
<el-button class="w custom-button size-14" size="large" @click="custom_edit"><icon name="edit" size="14"></icon>自定义编辑</el-button>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -49,7 +51,8 @@ const { diy_data } = toRefs(state);
|
|||
const form = ref(diy_data.value.com_data);
|
||||
//#region 自定义组的编辑功能
|
||||
const emit = defineEmits(['custom_edit', 'operation_end']);
|
||||
const custom_edit = (data_source_field: any[]) => {
|
||||
const custom_edit = () => {
|
||||
const data_source_field = form.value.data_source_field;
|
||||
const { custom_list, com_width, custom_height } = form.value;
|
||||
// 计算宽度
|
||||
const width = form.value.data_source_direction != 'vertical-scroll' ? com_width / form.value.data_source_carousel_col : com_width; // 可拖拽区域的宽度
|
||||
|
|
@ -99,4 +102,13 @@ watch(
|
|||
width: 100%;
|
||||
}
|
||||
}
|
||||
.custom-button {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
bottom: 0; /* 固定在底部 */
|
||||
background-color: white; /* 设置背景色以避免按钮看不见 */
|
||||
z-index: 1000; /* 确保按钮在其他内容之上 */
|
||||
width: 100%; /* 确保按钮宽度占满父容器 */
|
||||
padding: 1rem; /* 添加一些内边距 */
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
<el-radio value="italic">倾斜</el-radio>
|
||||
</el-radio-group>
|
||||
<el-form-item label="字号" label-width="50" class="mb-0 w">
|
||||
<slider v-model="form.text_size" :max="100" @update:model-value="text_size_change"></slider>
|
||||
<slider v-model="form.text_size" :max="100" @update:model-value="text_size_change" @operation_end="operation_end"></slider>
|
||||
</el-form-item>
|
||||
<el-form-item label="行间距" label-width="50" class="mb-0 w">
|
||||
<slider v-model="form.line_text_size" :max="200" @operation_end="operation_end"></slider>
|
||||
|
|
@ -187,7 +187,6 @@ const text_link_change = (key: string) => {
|
|||
// 文字大小变化时,同步更新行间距
|
||||
const text_size_change = (size: number) => {
|
||||
form.value.line_text_size = size;
|
||||
operation_end();
|
||||
};
|
||||
const mult_color_picker_event = (arry: color_list[], type: number) => {
|
||||
form.value.color_list = arry;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<Dialog v-model:visible="dialogVisible" :title="configType == 'custom' ? '编辑自定义' : '编辑自定义组'" @accomplish="accomplish">
|
||||
<div class="flex-row h w">
|
||||
<!-- 左侧和中间区域 -->
|
||||
<DragIndex ref="draglist" :key="dragkey" v-model:height="center_height" v-model:width="center_width" :config-type="configType" :source-list="sourceList" :custom-group-field-id="customGroupFieldId" :is-custom="configType == 'custom'? isCustom : false" :show-data="showData" :list="customList" @right-update="right_update"></DragIndex>
|
||||
<DragIndex ref="draglist" :key="dragkey" v-model:height="center_height" v-model:width="center_width" :config-type="configType" :source-list="sourceList" :custom-group-field-id="customGroupFieldId" :is-custom="configType == 'custom'? isCustom : false" :show-data="showData" :list="new_list" @right-update="right_update" @operation_end="operation_end"></DragIndex>
|
||||
<!-- 右侧配置区域 -->
|
||||
<div class="settings">
|
||||
<template v-if="diy_data.key === 'img'">
|
||||
|
|
@ -35,6 +35,11 @@
|
|||
<script lang="ts" setup>
|
||||
import Dialog from '@/components/model-custom/components/dialog.vue';
|
||||
import DragIndex from '@/components/model-custom/components/index.vue';
|
||||
import { DataSourceStore } from '@/store';
|
||||
import { formatDate } from '@/utils';
|
||||
import { cloneDeep, isEqual } from "lodash";
|
||||
const data_source_store = DataSourceStore();
|
||||
|
||||
const props = defineProps({
|
||||
configType: {
|
||||
type: String,
|
||||
|
|
@ -73,6 +78,7 @@ const props = defineProps({
|
|||
default: () => [],
|
||||
},
|
||||
});
|
||||
const new_list = ref(cloneDeep(props.customList))
|
||||
// 自定义组的父组件数据
|
||||
const custom_father_list = defineModel('fatherList', { type: Array, default: () => [] });
|
||||
// 中间区域的宽高
|
||||
|
|
@ -109,8 +115,14 @@ const accomplish = () => {
|
|||
} else {
|
||||
// 如果是自定点击完成,需要将数据传递给父组件
|
||||
if (props.configType == 'custom') {
|
||||
// 点击完成的时候,清除历史数据
|
||||
data_source_store.set_custom_records([]);
|
||||
data_source_store.set_custom_records_index(-1);
|
||||
emits('accomplish', props.configType, draglist.value.diy_data);
|
||||
} else {
|
||||
// 点击完成的时候,清除历史数据
|
||||
data_source_store.set_custom_group_records([]);
|
||||
data_source_store.set_custom_group_records_index(-1);
|
||||
// 如果是自定义组点击完成,需要将值赋值给对应的父组件数据中,再将完整的数据渲染出来
|
||||
custom_father_list.value.forEach((item: any) => {
|
||||
if (item.id == props.customId) {
|
||||
|
|
@ -130,8 +142,86 @@ const custom_edit = (id: string, list: diy, width: number, height: number, data_
|
|||
}
|
||||
emits('custom_edit', 'custom-group', id, father_list, list, width, height, data_source_field);
|
||||
};
|
||||
const operation_end = () => {
|
||||
console.log('操作结束');
|
||||
// 初始化的时候默认生成一条新数据,避免用户无法回到最初的记录
|
||||
onBeforeMount(() => {
|
||||
const new_data = [{ name: formatDate('HH点mm分ss秒'), height: center_height.value, value: props.customList }];
|
||||
if (props.configType == 'custom') {
|
||||
// 传递给store进行存储
|
||||
data_source_store.set_custom_records(new_data);
|
||||
// 操作之后更新数据
|
||||
data_source_store.set_custom_records_index(0);
|
||||
} else {
|
||||
// 传递给store进行存储
|
||||
data_source_store.set_custom_group_records(new_data);
|
||||
// 操作之后更新数据
|
||||
data_source_store.set_custom_group_records_index(0);
|
||||
}
|
||||
})
|
||||
// 操作结束触发事件
|
||||
const operation_end = (is_compare: boolean = true) => {
|
||||
// 如果没有数据,直接返回
|
||||
if (!draglist.value) {
|
||||
return;
|
||||
} else {
|
||||
// 历史数据和新数据进行对比,如果新数据跟历史数据不相同就设置历史数据记录, is_compare = false的值是代表着不需要进行判断就要保存的记录
|
||||
let old_index = 0;
|
||||
let old_compare_data = {};
|
||||
if (props.configType == 'custom') {
|
||||
old_index = data_source_store.custom_records_index;
|
||||
old_compare_data = cloneDeep(data_source_store.custom_records[old_index].value) || {};
|
||||
} else {
|
||||
old_index = data_source_store.custom_group_records_index;
|
||||
old_compare_data = cloneDeep(data_source_store.custom_group_records[old_index].value) || {};
|
||||
}
|
||||
// 新的数据
|
||||
const new_compare_data = cloneDeep(draglist.value.diy_data);
|
||||
|
||||
if (!is_compare || !isEqual(old_compare_data, new_compare_data)) {
|
||||
// 如果是自定点击完成,需要将数据传递给父组件
|
||||
if (props.configType == 'custom') {
|
||||
// 获取历史数据
|
||||
const new_data = old_data_handle(data_source_store?.custom_records || [], data_source_store?.custom_records_index || -1);
|
||||
// 新增一条新数据
|
||||
new_data.unshift({ name: formatDate('HH点mm分ss秒'), height: center_height.value, value: new_compare_data });
|
||||
// 传递给store进行存储
|
||||
data_source_store.set_custom_records(new_data);
|
||||
// 操作之后更新数据
|
||||
data_source_store.set_custom_records_index(0);
|
||||
} else {
|
||||
// 获取历史数据
|
||||
const new_data = old_data_handle(data_source_store?.custom_group_records || [], data_source_store?.custom_group_records_index || -1);
|
||||
// 新增一条新数据
|
||||
new_data.unshift({ name: formatDate('HH点mm分ss秒'), height: center_height.value, value: new_compare_data });
|
||||
// 更改自定义组的内容
|
||||
data_source_store.set_custom_group_records(new_data);
|
||||
// 更改自定义组的历史记录值
|
||||
data_source_store.set_custom_group_records_index(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 处理旧数据以生成新数据数组
|
||||
* 此函数用于根据当前选中的历史记录索引,对旧数据进行克隆和更新
|
||||
* 主要目的是维护一个最多包含10条记录的历史数据列表
|
||||
*
|
||||
* @param old_data 任何类型的旧数据数组,包含历史记录
|
||||
* @param index 当前选中的历史记录的索引,用于决定如何更新数据
|
||||
* @returns 返回更新后的新数据数组
|
||||
*/
|
||||
const old_data_handle = (old_data: any, index: number) => {
|
||||
// 克隆旧数据数组以避免直接修改原始数据
|
||||
const new_data = cloneDeep(old_data);
|
||||
// 判断当前选中的历史记录是不是最新的,如果不是,更新之后清除当前数据
|
||||
if (index !== 0 && index !== -1) {
|
||||
// 先判断index是为了确保10条数据更新的时候不会出现数据问题
|
||||
new_data.splice(index, 1);
|
||||
} else if (new_data.length == 10) {
|
||||
// 如果历史数据已经是10条了,那就删除最后一条数据, 否则的话就可以正常添加
|
||||
new_data.splice(new_data.length - 1, 1);
|
||||
}
|
||||
// 返回处理后的新数据数组
|
||||
return new_data;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -224,6 +224,7 @@ const custom_group_com_data = {
|
|||
custom_height: 100, // 自定义高度
|
||||
data_source_direction: 'vertical', // 铺满方式
|
||||
data_source_carousel_col: 1, // 铺满数量
|
||||
is_scroll_bar: false, // 是否需要滚动条
|
||||
data_style: {
|
||||
...defaultCustom.style
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
</card-container>
|
||||
<card-container class="mb-8">
|
||||
<div class="mb-12">内容设置</div>
|
||||
<slider v-model="center_height" :max="1000">组件高度</slider>
|
||||
<slider v-model="center_height" :max="1000" @operation_end="operation_end(false)">组件高度</slider>
|
||||
</card-container>
|
||||
<card-container class="h selected">
|
||||
<div class="flex-col gap-10 drawer-container">
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
</template>
|
||||
</div>
|
||||
<div class="abs draggable-icon" :style="item.show_tabs == '1' ? 'opacity: 1;' : 'opacity: 0.5;'">
|
||||
<el-icon class="iconfont icon-commodity-edit size-16 cr-primary do-not-trigger two-click" @click="on_edit(index)" />
|
||||
<el-icon class="iconfont icon-edit size-16 cr-primary do-not-trigger two-click" @click="on_edit(index)" />
|
||||
<el-icon class="iconfont icon-close-round-o size-16" @click.stop="del(index)" />
|
||||
</div>
|
||||
</li>
|
||||
|
|
@ -62,12 +62,13 @@
|
|||
<right-side-operation v-if="typeof select_index === 'number' && !isNaN(select_index) && diy_data.length > 0" v-model:index="select_index" v-model:data-length="diy_data.length" @del="del" @copy="copy" @previous_layer="previous_layer" @underlying_layer="underlying_layer" @top_up="top_up" @bottom_up="bottom_up"></right-side-operation>
|
||||
<!-- 拖拽区 -->
|
||||
<div class="model-drag">
|
||||
<top-side-operation class="model-top-wall" :config-type="props.configType" @back="back" @forward="forward" @handle-history="handle_history"></top-side-operation>
|
||||
<div class="model-wall">
|
||||
<div ref="imgBoxRef" class="drag-area re dropzone" @dragover.prevent @dragenter.prevent @drop="drop">
|
||||
<div class="w h" @mousedown.prevent="start_drag" @mousemove.prevent="move_drag" @mouseup.prevent="end_drag">
|
||||
<DraggableContainer v-if="draggable_container" style="z-index:0" :reference-line-visible="true" :disabled="false" reference-line-color="#ddd" @selectstart.prevent @contextmenu.prevent @dragstart.prevent>
|
||||
<!-- @mouseover="on_choose(index)" -->
|
||||
<Vue3DraggableResizable v-for="(item, index) in diy_data" :key="item.id" v-model:w="item.com_data.com_width" v-model:h="item.com_data.com_height" :min-w="0" :min-h="0" :class="{'plug-in-show-component-line': is_show_component_line, 'plug-in-show-tabs': item.show_tabs == '1', 'vdr-handle-z-index': item.com_data.bottom_up == '1' }" :style="{ 'z-index': (diy_data.length - 1) - index }" :init-w="item.com_data.com_width" :init-h="item.com_data.com_height" :x="item.location.x" :y="item.location.y" :parent="true" :draggable="is_draggable" @mousedown.stop="on_choose(index, item.show_tabs)" @click.stop="on_choose(index, item.show_tabs)" @drag-end="dragEndHandle($event, index)" @resizing="resizingHandle($event, item.key, index)" @resize-end="resizingHandle($event, item.key, index)">
|
||||
<Vue3DraggableResizable v-for="(item, index) in diy_data" :key="item.id" v-model:w="item.com_data.com_width" v-model:h="item.com_data.com_height" :min-w="0" :min-h="0" :class="{'plug-in-show-component-line': is_show_component_line, 'plug-in-show-tabs': item.show_tabs == '1', 'vdr-handle-z-index': item.com_data.bottom_up == '1' }" :style="{ 'z-index': (diy_data.length - 1) - index }" :init-w="item.com_data.com_width" :init-h="item.com_data.com_height" :x="item.location.x" :y="item.location.y" :parent="true" :draggable="is_draggable" @mousedown.stop="on_choose(index, item.show_tabs)" @click.stop="on_choose(index, item.show_tabs)" @drag-end="dragEndHandle($event, index)" @resizing="resizingHandle($event, item.key, index, 'resizing')" @resize-end="resizingHandle($event, item.key, index, 'resizeEnd')">
|
||||
<div :class="['main-content flex-row', { 'plug-in-border': item.show_tabs == '1' }]">
|
||||
<template v-if="item.key == 'text'">
|
||||
<model-text :key="item.id" :value="item.com_data" :source-list="props.sourceList" :is-custom="isCustom" :custom-group-field-id="customGroupFieldId" :title-params="showData?.data_name || 'name'"></model-text>
|
||||
|
|
@ -110,7 +111,7 @@
|
|||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { cloneDeep, isEmpty, property } from 'lodash';
|
||||
import { cloneDeep, isEmpty, property, isEqual } from 'lodash';
|
||||
import { get_math, adjustPosition, getPlatform } from '@/utils';
|
||||
import { defaultComData, isRectangleIntersecting } from "./index-default";
|
||||
import { SortableEvent, VueDraggable } from 'vue-draggable-plus';
|
||||
|
|
@ -119,7 +120,7 @@ const common_store = commonStore();
|
|||
// 删除
|
||||
const app = getCurrentInstance();
|
||||
//#region 传递参数和传出数据的处理
|
||||
const emits = defineEmits(['rightUpdate']);
|
||||
const emits = defineEmits(['rightUpdate', 'operation_end']);
|
||||
interface Props {
|
||||
configType: string;
|
||||
list: diy_content[];
|
||||
|
|
@ -203,6 +204,7 @@ const on_sort = (item: SortableEvent) => {
|
|||
let index = item?.newIndex || 0;
|
||||
// 设置对应的位置为显示
|
||||
set_show_tabs(index);
|
||||
operation_end();
|
||||
};
|
||||
//#endregion
|
||||
//#region 中间区域的处理逻辑
|
||||
|
|
@ -237,8 +239,12 @@ const on_edit = (index: number) => {
|
|||
// 判断点击的是否是可以点击的区域,其他区域隐藏掉编辑属性
|
||||
const outerClick = (e: any) => {
|
||||
if ((!isEmpty(e.target.className) && !e.target.className.includes('do-not-trigger')) && (!isEmpty(e.target.parentNode.className) && !e.target.parentNode.className.includes('do-not-trigger'))) {
|
||||
edit_close_processing(edit_index.value);
|
||||
edit_index.value = -1;
|
||||
// 点击区域结束的时候触发事件, 为-1的时候,证明没有触发事件
|
||||
if (edit_index.value !== -1) {
|
||||
edit_close_processing(edit_index.value);
|
||||
edit_index.value = -1;
|
||||
operation_end();
|
||||
}
|
||||
}
|
||||
};
|
||||
// 双击事件
|
||||
|
|
@ -275,6 +281,7 @@ const copy = (index: null | number) => {
|
|||
// 在当前位置下插入数据
|
||||
diy_data.value.splice(index, 0, new_data);
|
||||
set_show_tabs(index + 1);
|
||||
operation_end();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -305,6 +312,7 @@ const del = (index: null | number) => {
|
|||
diy_data.value.splice(index, 1);
|
||||
}
|
||||
select_index.value = diy_data.value.length > 0 ? select_index.value : null;
|
||||
operation_end();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -345,6 +353,7 @@ const moveItem = (index: number, newIndex: number) => {
|
|||
// 将数据插入新位置
|
||||
diy_data.value.splice(newIndex, 0, old_data);
|
||||
set_show_tabs(newIndex);
|
||||
operation_end();
|
||||
} catch (error) {
|
||||
console.error('Error moving item:', error);
|
||||
}
|
||||
|
|
@ -410,6 +419,8 @@ const center_width = defineModel('width', { type: Number, default: 390 });
|
|||
|
||||
const drag_area_height = computed(() => center_height.value + 'px');
|
||||
const drag_area_width = computed(() => center_width.value + 'px');
|
||||
// 头部页面显示内容
|
||||
const drag_area_top_width = computed(() => center_width.value > 170 ? center_width.value + 'px' : '170px');
|
||||
|
||||
const draggable_container = ref(true);
|
||||
let data = reactive<diy_content[]>([]);
|
||||
|
|
@ -490,7 +501,7 @@ const drop = (event: any) => {
|
|||
// 组装新数据
|
||||
const newItem = {
|
||||
...draggedItem.value,
|
||||
new_name: list.length > 0 ? draggedItem.value.name + list.length : draggedItem.value.name, // 默认添加别名
|
||||
new_name: list.length > 0 ? draggedItem.value.name + list.length : '', // 默认添加别名
|
||||
location: {
|
||||
x: adjustedX,
|
||||
y: adjustedY,
|
||||
|
|
@ -503,15 +514,22 @@ const drop = (event: any) => {
|
|||
diy_data.value.unshift(newItem);
|
||||
// 因为是添加到头部,所以默认选中第0个
|
||||
set_show_tabs(0);
|
||||
operation_end();
|
||||
}
|
||||
};
|
||||
//#endregion
|
||||
//#region 区域内拖拽显示
|
||||
const dragEndHandle = (item: any, index: number) => {
|
||||
diy_data.value[index].location = { x: item.x, y: item.y, record_x: item.x, record_y: item.y, staging_y: item.y };
|
||||
const old_location = diy_data.value[index].location;
|
||||
const new_location = { x: item.x, y: item.y, record_x: item.x, record_y: item.y, staging_y: item.y };
|
||||
// 对数组进行比较,确定跟之前的是否有变化
|
||||
if (!isEqual(old_location, new_location)) {
|
||||
operation_end();
|
||||
}
|
||||
diy_data.value[index].location = new_location;
|
||||
};
|
||||
// 拖拽结束时触发的事件 {x: number, y: number, w: number, h: number}
|
||||
const resizingHandle = (new_location: any, key: string, index: number) => {
|
||||
const resizingHandle = (new_location: any, key: string, index: number, type: string) => {
|
||||
const { x, y, w, h } = new_location;
|
||||
// 对应位置的定位修改为当前更新的位置
|
||||
diy_data.value[index].location = { x, y, record_x: x, record_y: y, staging_y: y };
|
||||
|
|
@ -531,6 +549,9 @@ const resizingHandle = (new_location: any, key: string, index: number) => {
|
|||
com_data.line_width = line_width;
|
||||
com_data.line_size = line_size;
|
||||
}
|
||||
if (type == 'resizeEnd') {
|
||||
operation_end();
|
||||
}
|
||||
};
|
||||
// 图片大小的计算
|
||||
const handleImg = (com_data: any, w: number, h: number ) => {
|
||||
|
|
@ -683,6 +704,7 @@ const start_drag_area_box = (index: number, event: MouseEvent) => {
|
|||
item.location.record_y = y;
|
||||
}
|
||||
});
|
||||
operation_end();
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -804,7 +826,6 @@ const rect_style = computed(() => {
|
|||
const platform = getPlatform();
|
||||
// 缓存内容,用于回退
|
||||
const data_source_store = DataSourceStore();
|
||||
const pressedKeys = new Set(); // 使用 Set 记录按下的按键
|
||||
const handle_keydown = (e: KeyboardEvent) => {
|
||||
// 排除默认事件
|
||||
const default_list = ['textarea', 'input'];
|
||||
|
|
@ -812,22 +833,90 @@ const handle_keydown = (e: KeyboardEvent) => {
|
|||
if (e.target instanceof HTMLElement && default_list.includes(e.target?.localName)) {
|
||||
return;
|
||||
}
|
||||
// 使用 key 或 code 属性代替 keyCode
|
||||
const key = e.key.toLowerCase(); // 将按键转换为小写,确保一致性
|
||||
// 添加按键到 Set 中
|
||||
pressedKeys.add(key);
|
||||
// 检查 A 和 B 键是否同时按下
|
||||
if ((pressedKeys.has('control') && pressedKeys.has('z') && platform == 'Windows') || (pressedKeys.has('meta') && pressedKeys.has('z') && platform == 'Mac')) {
|
||||
if ((e.ctrlKey && e.key === 'z' && platform == 'Windows') || (e.metaKey && e.key === 'z' && platform == 'Mac')) {
|
||||
// 监听开启的是全局监听,为了避免全局监听的同时也监听了子组件的回退事件,所以需要判断当前是全局监听还是子组件监听
|
||||
if (!data_source_store.is_children_custom && props.configType == 'custom') {
|
||||
console.log('同时按下了A和B键', props.configType); // 执行相应的操作
|
||||
back(data_source_store.custom_records_index, props.configType);
|
||||
} else if (data_source_store.is_children_custom && props.configType == 'custom-group') {
|
||||
console.log('同时按下了A和B键', props.configType); // 执行相应的操作
|
||||
back(data_source_store.custom_group_records_index, props.configType);
|
||||
}
|
||||
} else if ((e.ctrlKey && e.key === 'y' && platform == 'Windows') || (e.metaKey && e.key === 'y' && platform == 'Mac')) {
|
||||
// 监听开启的是全局监听,为了避免全局监听的同时也监听了子组件的回退事件,所以需要判断当前是全局监听还是子组件监听
|
||||
if (!data_source_store.is_children_custom && props.configType == 'custom') {
|
||||
forward(data_source_store.custom_records_index, props.configType);
|
||||
} else if (data_source_store.is_children_custom && props.configType == 'custom-group') {
|
||||
forward(data_source_store.custom_group_records_index, props.configType);
|
||||
}
|
||||
}
|
||||
// 阻止默认事件
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
// 提取公共逻辑
|
||||
const getRecordsList = (type: string) => {
|
||||
if (type === 'custom') {
|
||||
return data_source_store.custom_records;
|
||||
} else if (type === 'custom-group') {
|
||||
return data_source_store.custom_group_records;
|
||||
}
|
||||
throw new Error('Invalid type');
|
||||
};
|
||||
// 设置新的选中值
|
||||
const setIndex = (type: string, index: number) => {
|
||||
if (type === 'custom') {
|
||||
data_source_store.set_custom_records_index(index);
|
||||
} else if (type === 'custom-group') {
|
||||
data_source_store.set_custom_group_records_index(index);
|
||||
}
|
||||
};
|
||||
// 数据回退
|
||||
const back = (index: number, type: string) => {
|
||||
const list = getRecordsList(type);
|
||||
if (!list || list.length === 0) return;
|
||||
let new_index = index + 1;
|
||||
if (new_index < list.length) {
|
||||
setIndex(type, new_index);
|
||||
const data = list[new_index];
|
||||
if (!isEmpty(data)) {
|
||||
diy_data.value = data.value;
|
||||
center_height.value = data?.height || center_height.value;
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
};
|
||||
// 数据前进
|
||||
const forward = (index: number, type: string) => {
|
||||
const list = getRecordsList(type);
|
||||
if (!list || list.length === 0) return;
|
||||
|
||||
let new_index = Math.max(0, index - 1);
|
||||
if (new_index >= 0 && new_index < list.length) {
|
||||
setIndex(type, new_index);
|
||||
const data = list[new_index];
|
||||
if (!isEmpty(data)) {
|
||||
diy_data.value = data.value;
|
||||
center_height.value = data?.height || center_height.value;
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
};
|
||||
// 跳转到指定数据
|
||||
const handle_history = (index: number, type: string) => {
|
||||
const list = getRecordsList(type);
|
||||
if (!list || list.length === 0 || index === -1) return;
|
||||
|
||||
if (index >= 0 && index < list.length) {
|
||||
setIndex(type, index);
|
||||
const data = list[index];
|
||||
if (!isEmpty(data)) {
|
||||
diy_data.value = data.value;
|
||||
center_height.value = data?.height || center_height.value;
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeyUp = (e: KeyboardEvent) => {
|
||||
// 排除默认事件
|
||||
const default_list = ['textarea', 'input'];
|
||||
|
|
@ -850,24 +939,20 @@ const handleKeyUp = (e: KeyboardEvent) => {
|
|||
}
|
||||
// 监听开启的是全局监听,为了避免全局监听的同时也监听了子组件的回退事件,所以需要判断当前是全局监听还是子组件监听
|
||||
if (!data_source_store.is_children_custom && props.configType == 'custom') {
|
||||
// 移除按键
|
||||
const key = e.key.toLowerCase();
|
||||
pressedKeys.delete(key);
|
||||
// 阻止默认事件
|
||||
e.preventDefault();
|
||||
// 只有是点击上下左右的时候才会生效
|
||||
if (key_code.includes(e.key)) {
|
||||
data_handling(x, y);
|
||||
operation_end();
|
||||
}
|
||||
} else if (data_source_store.is_children_custom && props.configType == 'custom-group') {
|
||||
// 移除按键
|
||||
const key = e.key.toLowerCase();
|
||||
pressedKeys.delete(key);
|
||||
// 阻止默认事件
|
||||
e.preventDefault();
|
||||
// 只有是点击上下左右的时候才会生效
|
||||
if (key_code.includes(e.key)) {
|
||||
data_handling(x, y);
|
||||
operation_end();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -938,11 +1023,15 @@ onMounted(() => {
|
|||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('keyup', handleKeyUp);
|
||||
document.removeEventListener('keydown', handle_keydown);
|
||||
// 移除监听事件
|
||||
document.removeEventListener('keyup', handleKeyUp);
|
||||
});
|
||||
//#endregion
|
||||
//#endregion
|
||||
// 用户操作结束触发事件
|
||||
const operation_end = (is_compare: boolean = true) => {
|
||||
emits('operation_end', is_compare);
|
||||
}
|
||||
// 暴露出去的数据,避免跟外部数据双向绑定,点击保存的时候才会保存数据
|
||||
defineExpose({
|
||||
diy_data,
|
||||
|
|
@ -953,6 +1042,11 @@ defineExpose({
|
|||
@import 'index.scss';
|
||||
.model-drag {
|
||||
overflow-y: scroll;
|
||||
.model-top-wall {
|
||||
width: v-bind(drag_area_top_width);
|
||||
margin: 0 auto;
|
||||
z-index: 999;
|
||||
}
|
||||
.model-wall {
|
||||
width: v-bind(drag_area_width);
|
||||
background-image: linear-gradient(45deg, #e5e5e5 25%, transparent 25%), linear-gradient(135deg, #e5e5e5 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #e5e5e5 75%), linear-gradient(135deg, transparent 75%, #e5e5e5 75%);
|
||||
|
|
@ -962,7 +1056,7 @@ defineExpose({
|
|||
.drag-area {
|
||||
height: v-bind(drag_area_height);
|
||||
width: 100%;
|
||||
margin: 0.5rem 0; // 用于将上边框和下边框显示出来
|
||||
margin: 1.4rem 0; // 用于将上边框和下边框显示出来
|
||||
user-select: none;
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,192 @@
|
|||
<template>
|
||||
<div v-if="typeof records_index === 'number' && !isNaN(records_index)" class="sticky-top">
|
||||
<div class="acticons">
|
||||
<el-tooltip effect="dark" :show-after="200" :hide-after="200" content="回退" placement="top">
|
||||
<el-icon :class="['iconfont icon-left-arrow tooltip-icon', { 'disabled': records_index == history_list.length - 1 }]" @click.stop="back(records_index, records_index < history_list.length - 1)" />
|
||||
</el-tooltip>
|
||||
<div class="icon_border"></div>
|
||||
<el-tooltip effect="dark" :show-after="200" :hide-after="200" content="前进" placement="top">
|
||||
<el-icon :class="['iconfont icon-right-arrow tooltip-icon', { 'disabled': records_index <= 0 }] " @click.stop="forward(records_index, records_index > 0)" />
|
||||
</el-tooltip>
|
||||
<div class="icon_border"></div>
|
||||
<el-tooltip effect="dark" :show-after="200" :hide-after="200" content="历史记录" placement="top">
|
||||
<el-icon :class="['iconfont icon-historical-records tooltip-icon', { 'disabled': history_list.length === 0 }]" @click.stop="open_history(history_list.length !== 0)" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<el-dialog v-model="dialogVisible" class="history-dialog" :style="{ top: '80px', left: dialog_left + 'px' }" title="历史记录" width="200" draggable show-close :modal="false" :close-on-click-modal="false" :close-on-press-escape="false">
|
||||
<div ref="historyDialog" class="history-dialog-content flex-col gap-14">
|
||||
<div v-for="(item, index1) in history_list" :key="index1" :class="[`history-dialog-item ${props.configType}`, {'active': records_index == index1, }]" @click="handleHistory(index1, records_index !== index1)">
|
||||
<div class="history-dialog-item-title">{{ item.name }}</div>
|
||||
<el-icon v-if="records_index == index1" class="iconfont icon-checked size-14" />
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { DataSourceStore } from '@/store';
|
||||
const dataSourceStore = DataSourceStore();
|
||||
const props = defineProps({
|
||||
configType: {
|
||||
type: String,
|
||||
default: 'custom',
|
||||
}
|
||||
});
|
||||
const records_index = ref(-1);
|
||||
const history_list = ref<any[]>([]);
|
||||
const historyDialog = ref<HTMLElement | null>(null);
|
||||
onMounted(() => {
|
||||
handleResize();
|
||||
window.addEventListener('resize', handleResize);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
});
|
||||
const dialog_left = ref(0);
|
||||
const handleResize = () => {
|
||||
// 处理一半区域的大小
|
||||
let width = (window.innerWidth - 200) / 2;
|
||||
// 减去右侧的宽度
|
||||
if (window.innerWidth <= 1560) {
|
||||
width = width - 410;
|
||||
} else {
|
||||
width = width - 470;
|
||||
}
|
||||
// 设置dialog的left
|
||||
dialog_left.value = width;
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
if (props.configType == 'custom') {
|
||||
history_list.value = dataSourceStore.custom_records;
|
||||
records_index.value = dataSourceStore.custom_records_index;
|
||||
} else {
|
||||
history_list.value = dataSourceStore.custom_group_records;
|
||||
records_index.value = dataSourceStore.custom_group_records_index;
|
||||
}
|
||||
// 获取当前选中的内容 --中间区域的滚动效果
|
||||
const activeCard: HTMLElement | null = document.querySelector(`.history-dialog-item.active.${props.configType}`);
|
||||
if (activeCard) {
|
||||
// 获取选中内容的位置
|
||||
const scrollY = activeCard.offsetTop;
|
||||
if (historyDialog.value) {
|
||||
// 选中的滚动到指定位置
|
||||
historyDialog.value.scrollTo({ top: scrollY - 100, behavior: 'smooth' });
|
||||
}
|
||||
}
|
||||
});
|
||||
const emits = defineEmits(['back', 'forward', 'handleHistory']);
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
//回退
|
||||
const back = (index: number, is_click: boolean) => {
|
||||
if (is_click) {
|
||||
emits('back', index, props.configType);
|
||||
}
|
||||
}
|
||||
// 前进
|
||||
const forward = (index: number, is_click: boolean) => {
|
||||
if (is_click) {
|
||||
emits('forward', index, props.configType)
|
||||
}
|
||||
}
|
||||
const handleHistory = (index: number, is_click: boolean) => {
|
||||
// 判断是否可点击数据
|
||||
if (is_click) {
|
||||
emits('handleHistory', index, props.configType);
|
||||
}
|
||||
}
|
||||
const open_history = (is_click: boolean) => {
|
||||
// 判断是否可点击数据
|
||||
if (is_click) {
|
||||
dialogVisible.value = !dialogVisible.value;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.sticky-top{
|
||||
position: sticky;
|
||||
top: 1rem;
|
||||
z-index: 1;
|
||||
height: 4rem;
|
||||
.acticons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: 16rem;
|
||||
background: #fff;
|
||||
}
|
||||
.icon_border {
|
||||
border-right: 1px solid #eeeeee;
|
||||
height: 1.6rem;
|
||||
}
|
||||
.tooltip-icon {
|
||||
font-size: 2rem;
|
||||
width: 5.7rem;
|
||||
height: 100%;
|
||||
padding: 0.8rem 1.6rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
.tooltip-icon.disabled {
|
||||
cursor: default !important;
|
||||
}
|
||||
}
|
||||
:deep(.el-dialog) {
|
||||
// transform: translate(238px, 159px);
|
||||
.el-dialog__header{
|
||||
padding: 1.2rem 1.4rem !important;
|
||||
}
|
||||
.el-dialog__header .el-dialog__headerbtn {
|
||||
padding: 1.3rem 1.4rem 0.7rem !important;
|
||||
font-size: 1.6rem !important;
|
||||
}
|
||||
.el-dialog__title {
|
||||
font-size: 1.2rem !important;
|
||||
line-height: 1.2rem !important;
|
||||
}
|
||||
}
|
||||
// 实现dialog可拖拽且底层可点击
|
||||
:deep(:has(> .el-overlay-dialog .history-dialog)) {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
|
||||
:deep(.el-overlay-dialog) {
|
||||
pointer-events: none !important;
|
||||
|
||||
.history-dialog {
|
||||
.el-dialog__header,
|
||||
.el-dialog__body,
|
||||
.el-dialog__footer {
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.history-dialog-content {
|
||||
overflow: auto;
|
||||
height: 23rem;
|
||||
padding: 1rem 0.8rem;
|
||||
background: #fff;
|
||||
.history-dialog-item {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0.6rem 1rem;
|
||||
}
|
||||
.history-dialog-item-title {
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
line-height: 20px;
|
||||
font-style: normal;
|
||||
}
|
||||
.history-dialog-item.active {
|
||||
background: #F4f4f4;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.icon-checked{
|
||||
color: #2A94FF;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="auxiliary-line">
|
||||
<div class="auxiliary-line custom-data">
|
||||
<el-form :model="form" label-width="70">
|
||||
<card-container>
|
||||
<div class="mb-20">数据源</div>
|
||||
|
|
@ -54,10 +54,7 @@
|
|||
</template>
|
||||
</template>
|
||||
<div class="divider-line"></div>
|
||||
<card-container>
|
||||
<div class="mb-20">内容设置</div>
|
||||
<el-button class="w" size="large" @click="custom_edit('custom')"><icon name="edit" size="12"></icon>自定义编辑</el-button>
|
||||
</card-container>
|
||||
<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" :dragkey="dragkey + 'custom'" :options="model_data_source" :source-list="!isEmpty(data_source_content_list) ? data_source_content_list[0] : {}" :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>
|
||||
|
|
@ -538,4 +535,16 @@ watch(() => data_source_content_value.value, (new_val, old_val) => {
|
|||
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>
|
||||
|
|
|
|||
|
|
@ -273,34 +273,34 @@ const default_list = {
|
|||
** @return {Array}
|
||||
*/
|
||||
const commodity_list = (list: any[], num: number, data_content: any, data_style: any) => {
|
||||
if (list.length > 0) {
|
||||
// 深拷贝一下,确保不会出现问题
|
||||
const goods_list = cloneDeep(list).map((item: any) => ({
|
||||
...item.data,
|
||||
title: !isEmpty(item.new_title) ? item.new_title : item.data.title,
|
||||
new_cover: item.new_cover,
|
||||
}));
|
||||
// 存储数据显示
|
||||
let nav_list: { split_list: any[] }[] = [];
|
||||
// 如果是滑动,需要根据每行显示的个数来区分来拆分数据 translation 表示的是平移
|
||||
if (data_style.rolling_fashion != 'translation') {
|
||||
// 拆分的数量
|
||||
const split_num = Math.ceil(goods_list.length / num);
|
||||
for (let i = 0; i < split_num; i++) {
|
||||
nav_list.push({ split_list: goods_list.slice(i * num, (i + 1) * num) });
|
||||
}
|
||||
return nav_list;
|
||||
} else {
|
||||
return rotation_calculation(goods_list, num, data_content, data_style)
|
||||
if (list.length > 0) {
|
||||
// 深拷贝一下,确保不会出现问题
|
||||
const goods_list = cloneDeep(list).map((item: any) => ({
|
||||
...item.data,
|
||||
title: !isEmpty(item.new_title) ? item.new_title : item.data.title,
|
||||
new_cover: item.new_cover,
|
||||
}));
|
||||
// 存储数据显示
|
||||
let nav_list: { split_list: any[] }[] = [];
|
||||
// 如果是滑动,需要根据每行显示的个数来区分来拆分数据 translation 表示的是平移
|
||||
if (data_style.rolling_fashion != 'translation') {
|
||||
// 拆分的数量
|
||||
const split_num = Math.ceil(goods_list.length / num);
|
||||
for (let i = 0; i < split_num; i++) {
|
||||
nav_list.push({ split_list: goods_list.slice(i * num, (i + 1) * num) });
|
||||
}
|
||||
return nav_list;
|
||||
} else {
|
||||
const list = Array(num).fill(default_list);
|
||||
if (data_style.rolling_fashion != 'translation') {
|
||||
return [{ split_list: list }];
|
||||
} else {
|
||||
return rotation_calculation(list, num, data_content, data_style)
|
||||
}
|
||||
return rotation_calculation(goods_list, num, data_content, data_style)
|
||||
}
|
||||
} else {
|
||||
const list = Array(num).fill(default_list);
|
||||
if (data_style.rolling_fashion != 'translation') {
|
||||
return [{ split_list: list }];
|
||||
} else {
|
||||
return rotation_calculation(list, num, data_content, data_style)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rotation_calculation = (list: Array<any>, num: number, data_content: any, data_style: any) => {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
<el-radio-group v-model="form.button_jump">
|
||||
<el-radio value="link">页面链接</el-radio>
|
||||
<el-radio value="customer_service">客服入口</el-radio>
|
||||
<el-radio value="quick_nav">快捷导航</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="上传图片">
|
||||
|
|
|
|||
|
|
@ -18,6 +18,12 @@ export const DataSourceStore = defineStore('dataSource', () => {
|
|||
const is_data_source_api = ref(false);
|
||||
// 数据源
|
||||
const data_source_list = ref<data_source_content[]>([]);
|
||||
// 自定义历史记录
|
||||
const custom_records_index = ref<number>(-1);
|
||||
const custom_records = ref<any[]>([]);
|
||||
// 自定义组历史记录
|
||||
const custom_group_records_index = ref<number>(-1);
|
||||
const custom_group_records = ref<any[]>([]);
|
||||
// 存储上传分类列表
|
||||
const set_data_source = (data_source_content: data_source_content[]) => {
|
||||
data_source_list.value = data_source_content;
|
||||
|
|
@ -31,13 +37,34 @@ export const DataSourceStore = defineStore('dataSource', () => {
|
|||
const set_is_children_custom = (bool: boolean) => {
|
||||
is_children_custom.value = bool;
|
||||
};
|
||||
|
||||
// 设置自定义的历史数据
|
||||
const set_custom_records_index = (index: number) => {
|
||||
custom_records_index.value = index;
|
||||
};
|
||||
const set_custom_records = (records: any[]) => {
|
||||
custom_records.value = records;
|
||||
};
|
||||
// 设置自定义组的历史数据
|
||||
const set_custom_group_records_index = (index: number) => {
|
||||
custom_group_records_index.value = index;
|
||||
};
|
||||
const set_custom_group_records = (records: any[]) => {
|
||||
custom_group_records.value = records;
|
||||
};
|
||||
return {
|
||||
custom_records,
|
||||
custom_group_records,
|
||||
custom_records_index,
|
||||
custom_group_records_index,
|
||||
is_children_custom,
|
||||
data_source_list,
|
||||
is_data_source_api,
|
||||
set_data_source,
|
||||
set_is_data_source_api,
|
||||
set_is_children_custom,
|
||||
set_custom_records,
|
||||
set_custom_records_index,
|
||||
set_custom_group_records,
|
||||
set_custom_group_records_index,
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -835,4 +835,29 @@ export const getPlatform = () => {
|
|||
}
|
||||
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期为指定格式的时间字符串
|
||||
*
|
||||
* @param date 日期对象
|
||||
* @param format 格式化字符串,默认为 'YYYY-MM-DD HH:mm:ss'
|
||||
* @returns 格式化后的时间字符串
|
||||
*/
|
||||
export function formatDate(format: string = 'YYYY-MM-DD HH:mm:ss'): string {
|
||||
const date = new Date();
|
||||
const year = String(date.getFullYear());
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||
|
||||
return format
|
||||
.replace('YYYY', year)
|
||||
.replace('MM', month)
|
||||
.replace('DD', day)
|
||||
.replace('HH', hours)
|
||||
.replace('mm', minutes)
|
||||
.replace('ss', seconds);
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
<el-radio-button class="radio-item" value="2">样式</el-radio-button>
|
||||
</el-radio-group>
|
||||
</card-container>
|
||||
<div class="setting-content">
|
||||
<div class="setting-content" :style="value.key == 'custom' ? '' : 'background-color: #fff;'">
|
||||
<!-- 基础组件 -->
|
||||
<!-- 页面设置 -->
|
||||
<template v-if="value.key == 'page-settings'">
|
||||
|
|
@ -155,7 +155,6 @@ const radio = ref('1'); // 创建一个响应式的数字变量,初始值为0
|
|||
.setting-content {
|
||||
height: calc(100vh - 14.8rem);
|
||||
overflow: auto;
|
||||
background-color: #fff;
|
||||
}
|
||||
:deep(.el-input-number) {
|
||||
width: 100%;
|
||||
|
|
|
|||
Loading…
Reference in New Issue