vr-uniapp/src/components/model-custom/model-custom-content.vue

235 lines
7.6 KiB
Vue
Raw Normal View History

<template>
<div class="auxiliary-line">
2024-08-26 03:26:32 +00:00
<el-form :model="form" label-width="70">
2024-08-29 07:18:32 +00:00
<card-container>
<div class="mb-20">数据源</div>
<el-form-item label="动态数据">
2024-08-26 07:13:47 +00:00
<el-select v-model="form.data_source" value-key="id" placeholder="请选择数据源" filterable clearable @change="changeDataSource">
2024-08-20 01:35:57 +00:00
<el-option v-for="item in options" :key="item.type" :label="item.name" :value="item.type" />
</el-select>
2024-09-05 02:43:32 +00:00
<div v-if="!isEmpty(form.data_source_content)" class="flex-row mt-20 gap-20">
2024-08-22 07:05:39 +00:00
<div class="re flex align-c">
2024-09-05 03:05:57 +00:00
<image-empty v-model="form.data_source_content[form.img_key]" style="width: 10rem; height: 10rem"></image-empty>
2024-08-22 07:05:39 +00:00
<div class="plr-15 bg-f abs replace-data size-14" @click="replace_data"></div>
</div>
2024-09-05 03:05:57 +00:00
<div class="flex-1 size-14 text-line-3">{{ form.data_source_content.title || form.data_source_content.name }}</div>
2024-08-22 07:05:39 +00:00
</div>
</el-form-item>
<div class="mb-20">内容设置</div>
<el-button class="w" size="large" @click="custom_edit"><icon name="edit" size="12"></icon>自定义编辑</el-button>
</card-container>
</el-form>
<Dialog ref="dialog" @accomplish="accomplish">
<div class="flex-row h w">
2024-09-05 02:43:32 +00:00
<DragIndex ref="draglist" :key="dragkey" v-model:height="center_height" :source-list="form.data_source_content" :list="custom_list" @right-update="right_update"></DragIndex>
<div class="settings">
<template v-if="diy_data.key === 'img'">
2024-08-20 01:35:57 +00:00
<model-image-style :key="key" v-model:height="center_height" :options="model_data_source" :value="diy_data"></model-image-style>
</template>
<template v-else-if="diy_data.key == 'text'">
2024-08-20 01:35:57 +00:00
<model-text-style :key="key" v-model:height="center_height" :options="model_data_source" :value="diy_data"></model-text-style>
</template>
<template v-else-if="diy_data.key == 'auxiliary-line'">
<model-lines-style :key="key" v-model:height="center_height" :value="diy_data"></model-lines-style>
</template>
2024-08-12 09:12:26 +00:00
<template v-else>
2024-08-16 10:01:59 +00:00
<div class="w h flex align-c bg-f">
<no-data></no-data>
</div>
2024-08-12 09:12:26 +00:00
</template>
</div>
</div>
</Dialog>
2024-09-05 03:05:57 +00:00
<url-value-dialog v-model:dialog-visible="url_value_dialog_visible" :type="[form.data_source]" @update:model-value="url_value_dialog_call_back" @close="url_value_close"></url-value-dialog>
</div>
</template>
<script setup lang="ts">
import Dialog from './components/dialog.vue';
import DragIndex from './components/index.vue';
2024-08-22 07:05:39 +00:00
import { isEmpty, cloneDeep } from 'lodash';
2024-08-20 01:35:57 +00:00
import CustomAPI from '@/api/custom';
2024-08-19 10:19:42 +00:00
import { DataSourceStore } from '@/store';
2024-08-22 07:05:39 +00:00
const data_source_store = DataSourceStore();
2024-08-19 10:19:42 +00:00
const props = defineProps({
value: {
type: Object,
default: () => {},
},
});
const dialog = ref<expose | null>(null);
2024-08-12 08:10:56 +00:00
const draglist = ref<diy_data | null>(null);
const form = reactive(props.value);
// 弹出框里的内容
let custom_list = reactive([]);
const center_height = ref(0);
2024-09-05 02:43:32 +00:00
const options = ref<data_source_content[]>([]);
2024-08-22 07:05:39 +00:00
//#region 初始化数据处理
2024-08-20 01:35:57 +00:00
interface data_list {
name: string;
field: string;
type: string;
2024-09-05 03:05:57 +00:00
}
2024-09-05 02:43:32 +00:00
interface data_source_content {
2024-08-20 01:35:57 +00:00
name: string;
data: data_list[];
type: string;
2024-09-05 03:05:57 +00:00
}
2024-08-22 07:05:39 +00:00
const getCustominit = () => {
2024-08-20 01:35:57 +00:00
CustomAPI.getCustominit().then((res) => {
const { data_source } = res.data;
options.value = data_source;
2024-08-22 07:05:39 +00:00
data_source_store.set_data_source(data_source);
2024-08-26 08:51:20 +00:00
// 数据处理
processing_data(form.data_source);
2024-08-20 01:35:57 +00:00
});
2024-09-05 03:05:57 +00:00
};
2024-08-20 01:35:57 +00:00
onBeforeMount(() => {
2024-08-22 07:05:39 +00:00
if (!data_source_store.is_data_source_api) {
data_source_store.set_is_data_source_api(true);
getCustominit();
2024-08-20 01:35:57 +00:00
} else {
2024-08-22 07:05:39 +00:00
options.value = data_source_store.data_source_list;
// 如果历史的值出现,根据历史选中的值处理一下传递的数据结构
processing_data(form.data_source);
2024-08-20 01:35:57 +00:00
}
});
2024-08-22 07:05:39 +00:00
// 处理显示的图片和传递到下去的数据结构
2024-09-05 03:05:57 +00:00
const model_data_source = ref<data_list[]>([]);
2024-08-22 07:05:39 +00:00
const processing_data = (key: string) => {
2024-09-05 03:05:57 +00:00
const list = options.value.filter((item) => item.type == key);
2024-08-22 07:05:39 +00:00
if (list.length > 0) {
model_data_source.value = list[0].data;
// 从中取出包含图片的内容
2024-09-05 03:05:57 +00:00
const field_list = list[0].data.filter((item) => item.type == 'images');
2024-08-22 07:05:39 +00:00
// 取出图片的key
if (field_list.length > 0) {
2024-08-26 08:51:20 +00:00
form.img_key = field_list[0].field;
2024-08-22 07:05:39 +00:00
}
} else {
model_data_source.value = [];
}
};
//#endregion
//#region 自定义编辑的内部处理逻辑
const diy_data = ref<diy>({
key: '',
location: {
x: 0,
y: 0,
2024-08-16 10:01:59 +00:00
record_x: 0,
record_y: 0,
staging_y: 0,
},
com_data: {},
});
const key = ref('');
const dragkey = ref('');
const right_update = (item: any) => {
diy_data.value = item;
// 生成随机id
key.value = Math.random().toString(36).substring(2);
};
2024-08-22 07:05:39 +00:00
// 自定义编辑的逻辑
const custom_edit = () => {
if (!dialog.value) return;
dialog.value.dialogVisible = true;
dragkey.value = Math.random().toString(36).substring(2);
custom_list = cloneDeep(form.custom_list);
center_height.value = cloneDeep(form.height);
};
2024-08-22 07:05:39 +00:00
// 点击完成的处理逻辑
const accomplish = () => {
2024-08-12 08:10:56 +00:00
if (!draglist.value) {
return;
} else {
form.custom_list = draglist.value.diy_data;
}
form.height = center_height.value;
};
2024-08-22 07:05:39 +00:00
//#endregion
//#region 数据源更新逻辑处理
// 打开弹出框
const url_value_dialog_visible = ref(false);
const changeDataSource = (key: string) => {
processing_data(key);
2024-09-05 02:43:32 +00:00
form.data_source_content = {};
2024-08-22 07:05:39 +00:00
if (!isEmpty(key)) {
url_value_dialog_visible.value = true;
}
2024-09-05 03:05:57 +00:00
};
2024-08-22 07:05:39 +00:00
// 弹出框选择的内容
const url_value_dialog_call_back = (item: any[]) => {
if (item.length > 0) {
2024-09-05 02:43:32 +00:00
form.data_source_content = item[0];
2024-08-20 01:35:57 +00:00
} else {
2024-09-05 02:43:32 +00:00
form.data_source_content = {};
2024-08-22 07:05:39 +00:00
}
};
// 弹出框关闭
const url_value_close = () => {
2024-09-05 02:43:32 +00:00
if (isEmpty(form.data_source_content)) {
2024-08-22 07:05:39 +00:00
form.data_source = '';
2024-08-20 01:35:57 +00:00
}
2024-09-05 03:05:57 +00:00
};
2024-08-22 07:05:39 +00:00
// 替换数据
const replace_data = () => {
2024-08-26 08:51:20 +00:00
if (!isEmpty(form.data_source)) {
2024-08-22 07:05:39 +00:00
url_value_dialog_visible.value = true;
}
2024-09-05 03:05:57 +00:00
};
2024-08-22 07:05:39 +00:00
//#endregion
</script>
<style lang="scss" scoped>
.card.mb-8 {
.el-form-item:last-child {
margin-bottom: 0;
}
}
.settings {
width: 46rem;
overflow: auto;
display: flex;
flex-direction: column;
}
2024-08-30 10:48:27 +00:00
@media screen and (max-width: 1560px) {
.settings {
width: 40rem;
}
}
:deep(.el-dialog) {
margin-top: 0;
padding: 0;
overflow: hidden;
.el-dialog__header {
2024-09-05 03:05:57 +00:00
padding: 2.3rem 2rem;
.el-dialog__title {
font-size: 16px;
}
.el-dialog__headerbtn {
font-size: 2.4rem;
2024-09-05 03:05:57 +00:00
padding: 2rem;
height: auto;
width: auto;
}
}
.el-dialog__body {
background: #f5f5f5;
2024-09-05 03:05:57 +00:00
height: calc(100% - 15rem);
}
.el-dialog__footer {
padding: 2.4rem 3rem;
}
}
2024-08-22 07:05:39 +00:00
.replace-data {
bottom: 1rem;
left: 0.5rem;
border-radius: 2rem;
border: 1px solid #ccc;
}
</style>