<script lang="ts" setup>
|
import type { TreeActionItem, TreeActionType } from '@jnpf/ui';
|
|
import { h, onMounted, ref, unref } from 'vue';
|
|
import { BasicTree } from '@jnpf/ui';
|
import { useModal } from '@jnpf/ui/modal';
|
|
import { DeleteOutlined, FormOutlined, PlusOutlined } from '@ant-design/icons-vue';
|
import draggable from 'vuedraggable';
|
|
import { BatchOperate, InterfaceModal } from '#/components/CommonModal';
|
import { useDynamic } from '#/components/FormGenerator/src/hooks/useDynamic';
|
import { useField } from '#/components/FormGenerator/src/hooks/useField';
|
import { SelectInterfaceBtn } from '#/components/Interface';
|
|
import TreeBatchOperate from './TreeBatchOperate.vue';
|
import TreeNodeModal from './TreeNodeModal.vue';
|
|
const props = defineProps(['activeData', 'dicOptions']);
|
const emit = defineEmits(['propsChildrenChange']);
|
const treeRef = ref<Nullable<TreeActionType>>(null);
|
const treeNodeRef = ref(null);
|
const currentNode = ref<any>(null);
|
const { options, debounceOnSearch, onFocus, initFieldData } = useField(props.activeData);
|
const {
|
onDataTypeChange,
|
onDictionaryTypeChange,
|
onPropsUrlChange,
|
dataTypeOptions,
|
valueOptions,
|
addSelectItem,
|
formFieldsOptions,
|
onRelationFieldChange,
|
onBatchOperateConfirm,
|
} = useDynamic(props.activeData, initFieldData);
|
const [registerBatchOperate, { openModal }] = useModal();
|
const [registerTreeBatchOperate, { openModal: openTreeModal }] = useModal();
|
const actionList: TreeActionItem[] = [
|
{
|
render: (node) => {
|
return h(PlusOutlined, {
|
class: 'ml-[4px]',
|
title: '添加',
|
onClick: () => {
|
handleAdd(node);
|
},
|
});
|
},
|
},
|
{
|
render: (node) => {
|
return h(FormOutlined, {
|
class: 'ml-[4px]',
|
title: '编辑',
|
onClick: () => {
|
handleEdit(node);
|
},
|
});
|
},
|
},
|
{
|
render: (node) => {
|
return h(DeleteOutlined, {
|
class: 'ml-[4px]',
|
title: '删除',
|
onClick: () => {
|
handleDelete(node);
|
},
|
});
|
},
|
},
|
];
|
|
function getTree() {
|
const tree = unref(treeRef);
|
if (!tree) {
|
throw new Error('tree is null!');
|
}
|
return tree;
|
}
|
function handleAdd(node: any) {
|
const data = getTree().getSelectedNode(node.id) as any;
|
if (!Reflect.has(data, 'children')) data.children = [];
|
currentNode.value = data.children;
|
(unref(treeNodeRef) as any).openModal();
|
}
|
function handleEdit(node: any) {
|
const data = getTree().getSelectedNode(node.id) as any;
|
currentNode.value = data;
|
(unref(treeNodeRef) as any).openModal(data);
|
}
|
function handleDelete(node: any) {
|
props.activeData.__config__.defaultValue = [];
|
getTree().deleteNodeByKey(node.id);
|
}
|
function addTreeItem() {
|
(unref(treeNodeRef) as any).openModal();
|
currentNode.value = props.activeData.options;
|
}
|
function onTreeNodeConfirm(data, isEdit) {
|
if (!isEdit) return currentNode.value.push(data);
|
getTree().updateNodeByKey(currentNode.value.id, data);
|
}
|
function onPropsChildrenChange() {
|
emit('propsChildrenChange');
|
}
|
|
onMounted(() => initFieldData());
|
</script>
|
<template>
|
<a-divider>数据选项</a-divider>
|
<a-form-item class="flex justify-center">
|
<jnpf-radio
|
v-model:value="activeData.__config__.dataType"
|
:options="dataTypeOptions"
|
option-type="button"
|
button-style="solid"
|
@change="onDataTypeChange" />
|
</a-form-item>
|
<div class="options-list" v-if="activeData.__config__.dataType === 'static'">
|
<template v-if="['treeSelect', 'cascader'].includes(activeData.__config__.jnpfKey)">
|
<BasicTree ref="treeRef" :tree-data="activeData.options" :action-list="actionList" />
|
<div class="add-btn">
|
<a-button type="link" pre-icon="icon-ym icon-ym-btn-add" @click="addTreeItem" class="!px-0">添加父级</a-button>
|
<a-divider type="vertical" />
|
<a-button type="link" @click="openTreeModal(true, { options: activeData.options })" class="!px-0">批量编辑</a-button>
|
</div>
|
</template>
|
<template v-else>
|
<draggable v-model="activeData.options" :animation="300" group="selectItem" handle=".option-drag" item-key="uuid">
|
<template #item="{ element, index }">
|
<div class="select-item">
|
<div class="select-line-icon option-drag">
|
<i class="icon-ym icon-ym-darg"></i>
|
</div>
|
<a-input v-model:value="element.fullName" placeholder="选项名" />
|
<a-input v-model:value="element.id" placeholder="选项值" />
|
<div class="close-btn select-line-icon" @click="activeData.options.splice(index, 1)">
|
<i class="icon-ym icon-ym-btn-clearn"></i>
|
</div>
|
</div>
|
</template>
|
</draggable>
|
<div class="add-btn">
|
<a-button type="link" pre-icon="icon-ym icon-ym-btn-add" @click="addSelectItem" class="!px-0">添加选项</a-button>
|
<a-divider type="vertical" />
|
<a-button type="link" @click="openModal(true, { options: activeData.options })" class="!px-0">批量编辑</a-button>
|
</div>
|
</template>
|
</div>
|
<div v-if="activeData.__config__.dataType === 'dictionary'">
|
<a-form-item label="数据字典">
|
<jnpf-tree-select :options="dicOptions" v-model:value="activeData.__config__.dictionaryType" last-level allow-clear @change="onDictionaryTypeChange" />
|
</a-form-item>
|
<a-form-item label="存储字段">
|
<jnpf-select v-model:value="activeData.props.value" placeholder="请选择" :options="valueOptions" />
|
</a-form-item>
|
</div>
|
<div v-if="activeData.__config__.dataType === 'dynamic'">
|
<a-form-item>
|
<template #label>数据接口<BasicHelp text="支持通过数据接口的参数实现控件之间的联动。" /></template>
|
<InterfaceModal :value="activeData.__config__.propsUrl" :title="activeData.__config__.propsName" popup-title="数据接口" @change="onPropsUrlChange" />
|
</a-form-item>
|
<a-form-item label="存储字段">
|
<a-auto-complete
|
v-model:value="activeData.props.value"
|
placeholder="请输入"
|
:options="options"
|
@focus="onFocus(activeData.props.value)"
|
@search="debounceOnSearch(activeData.props.value)" />
|
</a-form-item>
|
<a-form-item label="回显字段">
|
<a-auto-complete
|
v-model:value="activeData.props.label"
|
placeholder="请输入"
|
:options="options"
|
@focus="onFocus(activeData.props.label)"
|
@search="debounceOnSearch(activeData.props.label)" />
|
</a-form-item>
|
<a-form-item label="子级字段" v-if="['treeSelect', 'cascader'].includes(activeData.__config__.jnpfKey)">
|
<a-input v-model:value="activeData.props.children" placeholder="请输入" @change="onPropsChildrenChange" />
|
</a-form-item>
|
<a-form-item label="是否缓存">
|
<a-switch v-model:checked="activeData.__config__.useCache" />
|
</a-form-item>
|
<a-form-item label="参数设置" v-if="activeData.__config__.templateJson?.length">
|
<SelectInterfaceBtn
|
:template-json="activeData.__config__.templateJson"
|
:field-options="formFieldsOptions"
|
:type="3"
|
@field-change="onRelationFieldChange" />
|
</a-form-item>
|
</div>
|
<a-divider />
|
<BatchOperate @register="registerBatchOperate" @confirm="onBatchOperateConfirm" />
|
<TreeNodeModal ref="treeNodeRef" @confirm="onTreeNodeConfirm" />
|
<TreeBatchOperate @register="registerTreeBatchOperate" @confirm="onBatchOperateConfirm" />
|
</template>
|