<script lang="ts" setup>
|
import { computed, defineAsyncComponent, inject, markRaw, nextTick, ref } from 'vue';
|
|
import { DeleteOutlined } from '@ant-design/icons-vue';
|
import { upperFirst } from 'lodash-es';
|
|
import { $t } from '#/locales';
|
|
import CardHeader from '../../Portal/CardHeader/index.vue';
|
import { chartList } from '../helper/dataMap';
|
import AddBtn from './AddBtn.vue';
|
|
defineOptions({ name: 'Parser' });
|
|
const props = defineProps(['item', 'activeId', 'showType', 'detailed']);
|
const allModules: any = import.meta.glob('../../Portal/H*/index.vue');
|
const layouts = ref<any>(null);
|
const emitter: any = inject('emitter');
|
if (props.item.jnpfKey !== 'card') layouts.value = markRaw(defineAsyncComponent(() => getComponents(props.item.jnpfKey)));
|
const useNeedKeyList = new Set(['carousel', 'customEcharts', 'dataBoard', 'image', 'notice', 'tableList', 'text', 'todo', 'video']);
|
|
const activeData = computed(() => {
|
const activeData = props.item;
|
if (!props.detailed) return activeData;
|
if (activeData.titleI18nCode) activeData.title = $t(activeData.titleI18nCode, activeData.title);
|
if (activeData.card.cardRightBtnI18nCode) activeData.card.cardRightBtn = $t(activeData.card.cardRightBtnI18nCode, activeData.card.cardRightBtn);
|
if (activeData.jnpfKey === 'tab') {
|
for (let i = 0; i < activeData.children.length; i++) {
|
if (activeData.children[i].titleI18nCode) activeData.children[i].title = $t(activeData.children[i].titleI18nCode, activeData.children[i].title);
|
}
|
}
|
if (['dataBoard', 'todo'].includes(activeData.jnpfKey)) {
|
for (let i = 0; i < activeData.option.defaultValue.length; i++) {
|
const e = activeData.option.defaultValue[i];
|
if (e.fullNameI18nCode) e.fullName = $t(e.fullNameI18nCode, e.fullName);
|
}
|
}
|
if (activeData.jnpfKey === 'carousel') {
|
for (let i = 0; i < activeData.option.defaultValue.length; i++) {
|
const e = activeData.option.defaultValue[i];
|
if (e.textDefaultValueI18nCode) e.textDefaultValue = $t(e.textDefaultValueI18nCode, e.textDefaultValue);
|
}
|
}
|
if (activeData.jnpfKey === 'text' && activeData.dataType === 'static' && activeData.option.defaultValueI18nCode) {
|
activeData.option.defaultValue = $t(activeData.option.defaultValueI18nCode, activeData.option.defaultValue);
|
}
|
if (activeData.jnpfKey === 'image' && activeData.option.textDefaultValueI18nCode) {
|
activeData.option.textDefaultValue = $t(activeData.option.textDefaultValueI18nCode, activeData.option.textDefaultValue);
|
}
|
if (['notice', 'tableList'].includes(activeData.jnpfKey)) {
|
for (let i = 0; i < activeData.option.columnData.length; i++) {
|
const e = activeData.option.columnData[i];
|
if (e.fullNameI18nCode) e.fullName = $t(e.fullNameI18nCode, e.fullName);
|
}
|
}
|
if (activeData.jnpfKey === 'rankList') {
|
for (let i = 0; i < activeData.option.columnOptions.length; i++) {
|
const e = activeData.option.columnOptions[i];
|
if (e.labelI18nCode) e.label = $t(e.labelI18nCode, e.label);
|
}
|
}
|
if (['mapChart', ...chartList].includes(activeData.jnpfKey)) {
|
if (activeData.option.titleTextI18nCode) activeData.option.titleText = $t(activeData.option.titleTextI18nCode, activeData.option.titleText);
|
if (activeData.option.titleSubtextI18nCode) activeData.option.titleSubtext = $t(activeData.option.titleSubtextI18nCode, activeData.option.titleSubtext);
|
if (activeData.option.xAxisNameI18nCode) activeData.option.xAxisName = $t(activeData.option.xAxisNameI18nCode, activeData.option.xAxisName);
|
if (activeData.option.yAxisNameI18nCode) activeData.option.yAxisName = $t(activeData.option.yAxisNameI18nCode, activeData.option.yAxisName);
|
}
|
return activeData;
|
});
|
|
const getBindValue = computed(() => ({
|
activeData: props.item,
|
key: useNeedKeyList.has(props.item.jnpfKey) ? props.item.renderKey : '',
|
}));
|
|
function getComponents(e: string): Promise<any> {
|
if (chartList.includes(e)) e = 'chart';
|
const name = `H${upperFirst(e)}`;
|
const page = `../../Portal/${name}/index.vue`;
|
return new Promise((resolve, reject) => {
|
let flag = true;
|
for (const path in allModules) {
|
if (path == page) {
|
flag = false;
|
allModules[path]().then((mod) => {
|
resolve(mod);
|
});
|
}
|
}
|
if (flag) reject(new Error(`该文件不存在:${page}`));
|
});
|
}
|
function handleClick(data) {
|
emitter.emit('handlerActive', data);
|
}
|
function handleRemoveItem(i, parent) {
|
parent.splice(i, 1);
|
}
|
function handleAddComponent(val) {
|
emitter.emit('addComponent', { val, item: props.item });
|
}
|
function handleTabClick() {
|
nextTick(() => {
|
const active = props.item.active;
|
const list = props.item.children;
|
for (const element of list) {
|
if (element.name === active && element.children && element.children.length) {
|
element.children.map((ele) => {
|
emitter.emit(`eChart${ele.i}`);
|
return ele;
|
});
|
}
|
}
|
});
|
}
|
</script>
|
<template>
|
<div class="h-full" @click.stop="handleClick(activeData)">
|
<component :is="layouts" v-bind="getBindValue" v-if="activeData.jnpfKey !== 'card' && activeData.jnpfKey !== 'tab'" />
|
<template v-if="activeData.jnpfKey === 'card'">
|
<a-card class="portal-card-box">
|
<template #title v-if="activeData.title">
|
<CardHeader :title="activeData.title" :card="activeData.card" />
|
</template>
|
<div class="portal-card-body flex items-center justify-center p-[15px]">
|
<div
|
v-show="activeData.children && activeData.children.length"
|
class="portal-box-item"
|
v-for="(it, index) in activeData.children"
|
:key="index"
|
@click.stop="handleClick(it)">
|
<Parser :item="it" :class="{ 'active-item': it.i === activeId }" :active-id="activeId" :detailed="detailed" />
|
<div class="drawing-item-action">
|
<a-popconfirm
|
:title="$t('formGenerator.delComponentTip')"
|
class="drawing-item-action-item drawing-item-delete"
|
@confirm="handleRemoveItem(index, activeData.children)"
|
v-if="!detailed">
|
<span :title="$t('common.delText')">
|
<DeleteOutlined />
|
</span>
|
</a-popconfirm>
|
</div>
|
</div>
|
<AddBtn :active-data="activeData" @add-component="handleAddComponent" v-show="!activeData.children?.length && !detailed" />
|
</div>
|
</a-card>
|
</template>
|
<template v-if="activeData.jnpfKey === 'tab'">
|
<a-tabs
|
v-model:active-key="activeData.active"
|
:tab-position="activeData.tabPosition"
|
@tab-click="handleTabClick"
|
:type="activeData.type"
|
class="portal-box-tab h-full bg-white"
|
:class="{ 'portal-eChart-tab-position': activeData.tabPosition == 'left' || activeData.tabPosition == 'right' }">
|
<a-tab-pane v-for="child in activeData.children" :key="child.name">
|
<template #tab>
|
<span class="ml-[4px]"><i :class="child.icon" class="pr-[4px]"></i>{{ child.title }}</span>
|
</template>
|
<div class="portal-tab-body flex h-full items-center justify-center p-[15px]">
|
<div v-show="child.children?.length" class="portal-box-item" v-for="(it, index) in child.children" :key="index" @click.stop="handleClick(it)">
|
<parser :item="it" :class="{ 'active-item': it.i === activeId }" :active-id="activeId" :detailed="detailed" />
|
<div class="drawing-item-action">
|
<a-popconfirm
|
:title="$t('formGenerator.delComponentTip')"
|
class="drawing-item-action-item drawing-item-delete"
|
@confirm="handleRemoveItem(index, child.children)"
|
v-if="!detailed">
|
<span :title="$t('common.delText')">
|
<DeleteOutlined />
|
</span>
|
</a-popconfirm>
|
</div>
|
</div>
|
<AddBtn :active-data="activeData" @add-component="handleAddComponent" v-show="!child.children?.length && !detailed" />
|
</div>
|
</a-tab-pane>
|
</a-tabs>
|
</template>
|
</div>
|
</template>
|
<style lang="scss" scoped>
|
.portal-box-tab {
|
:deep(.ant-tabs-nav) {
|
margin-bottom: unset;
|
}
|
|
:deep(.ant-tabs-content) {
|
height: 100%;
|
}
|
}
|
</style>
|