<script lang="ts" setup>
|
import { computed, inject, nextTick, onMounted } from 'vue';
|
|
import { useMessage } from '@jnpf/hooks';
|
import { useModal } from '@jnpf/ui/modal';
|
import { buildBitUUID } from '@jnpf/utils';
|
|
import { cloneDeep } from 'lodash-es';
|
import draggable from 'vuedraggable';
|
|
import ComplexHeaderModal from '#/components/ColumnDesign/src/components/ComplexHeaderModal.vue';
|
import { inputComponents, selectComponents, systemComponents } from '#/components/FormGenerator/src/helper/componentMap';
|
import { noTableAllowList } from '#/components/FormGenerator/src/helper/config';
|
import { useGeneratorStore } from '#/store';
|
|
import BtnConfigModal from './BtnConfigModal.vue';
|
|
defineOptions({ inheritAttrs: false });
|
const props = defineProps(['activeData', 'formInfo']);
|
const emit = defineEmits(['addTableComponent', 'activeFormItem']);
|
const defaultAddTableConf = {
|
popupTitle: '选择数据',
|
popupType: 'dialog',
|
popupWidth: '800px',
|
dataSource: 'dynamic',
|
modelId: '',
|
interfaceId: '',
|
interfaceName: '',
|
templateJson: [],
|
hasPage: true,
|
pageSize: 20,
|
columnOptions: [],
|
relationOptions: [],
|
executeType: 2,
|
executeFunc: '({ data, onlineUtils }) => {\r\n \r\n}',
|
executeInterfaceId: '',
|
executeInterfaceName: '',
|
executeTemplateJson: [],
|
executeUseConfirm: false,
|
executeConfirmTitle: '此操作将通过接口处理',
|
};
|
const layoutTypeOptions = [
|
{ id: 'table', fullName: '表格' },
|
{ id: 'list', fullName: '平铺' },
|
];
|
|
const generatorStore = useGeneratorStore();
|
const { createMessage } = useMessage();
|
const [registerModal, { openModal }] = useModal();
|
const [registerComplexHeaderModal, { openModal: openComplexHeaderModal }] = useModal();
|
const defaultColumnBtnsList = [
|
{ value: 'copy', label: '复制', labelI18nCode: 'common.copyText', show: true, btnType: 'primary', btnIcon: 'icon-ym icon-ym-btn-edit' },
|
{
|
value: 'remove',
|
label: '删除',
|
labelI18nCode: 'common.delText',
|
show: true,
|
btnType: 'danger',
|
btnIcon: 'icon-ym icon-ym-btn-clearn',
|
showConfirm: true,
|
},
|
];
|
const defaultFooterBtnsList = [
|
{ value: 'add', label: '添加', labelI18nCode: 'common.add1Text', show: true, btnType: 'primary', btnIcon: 'icon-ym icon-ym-btn-add' },
|
{
|
value: 'batchRemove',
|
label: '批量删除',
|
labelI18nCode: 'common.batchDelText',
|
show: true,
|
btnType: 'danger',
|
btnIcon: 'icon-ym icon-ym-btn-clearn',
|
showConfirm: true,
|
},
|
];
|
const pageSizeOptions = [
|
{ id: 10, fullName: '10条' },
|
{ id: 20, fullName: '20条' },
|
{ id: 30, fullName: '30条' },
|
{ id: 50, fullName: '50条' },
|
];
|
|
const childrenList = computed(() => {
|
const list = props.activeData.__config__.children.filter(
|
(o) => ['calculate', 'input', 'inputNumber'].includes(o.__config__.jnpfKey) && o.__vModel__ && !o.useMask,
|
);
|
return list.map((o) => ({ id: o.__vModel__, fullName: o.__config__.label }));
|
});
|
const getInputComponents = computed(() => inputComponents.filter((o) => !noTableAllowList.includes(o.__config__.jnpfKey)));
|
const getSelectComponents = computed(() => selectComponents.filter((o) => !noTableAllowList.includes(o.__config__.jnpfKey)));
|
const getSystemComponents = computed(() => systemComponents.filter((o) => !noTableAllowList.includes(o.__config__.jnpfKey)));
|
|
const getShowType: (() => string | undefined) | undefined = inject('getShowType');
|
const showType = computed(() => (getShowType as () => string | undefined)());
|
|
function handleComplexHeader() {
|
let columnOptions = props.activeData.__config__.children.map((o) => ({
|
fullName: o.__config__.label,
|
id: o.__vModel__,
|
...o,
|
}));
|
columnOptions = columnOptions.filter((o) => o.__config__.tableFixed !== 'left' && o.__config__.tableFixed !== 'right' && o.id);
|
openComplexHeaderModal(true, { list: props.activeData.__config__.complexHeaderList, columnOptions });
|
}
|
function updateConf(data) {
|
props.activeData.columnBtnsList = props.activeData.columnBtnsList.map((o) => (data.value == o.value ? data : o));
|
props.activeData.footerBtnsList = props.activeData.footerBtnsList.map((o) => (data.value == o.value ? data : o));
|
const list: [] = props.activeData.footerBtnsList.filter((o) => data.value == o.value);
|
if (!['add', 'batchRemove', 'copy', 'remove'].includes(data.value) && !list.length) props.activeData.footerBtnsList.push(data);
|
}
|
function updateComplexHeaderList(data) {
|
props.activeData.__config__.complexHeaderList = data;
|
}
|
function addComponent(item) {
|
if (generatorStore.getHasTable && !props.activeData.__config__.tableName) return createMessage.warning(`子表请先关联数据表`);
|
const activeItem = cloneDeep(item);
|
activeItem.__config__.isSubTable = true;
|
activeItem.__config__.parentVModel = props.activeData.__vModel__;
|
if (generatorStore.getHasTable) activeItem.__config__.relationTable = props.activeData.__config__.tableName;
|
emit('addTableComponent', activeItem, props.activeData.__config__.children);
|
}
|
function handleActiveFormItem(item) {
|
emit('activeFormItem', item);
|
}
|
function addBtn() {
|
const config = {
|
value: `custom${buildBitUUID()}`,
|
label: '',
|
labelI18nCode: '',
|
show: true,
|
btnType: '',
|
btnIcon: '',
|
actionType: 1,
|
actionConfig: cloneDeep(defaultAddTableConf),
|
};
|
openModal(true, { config, children: props.activeData.__config__.children });
|
}
|
function editBtnConfig(item) {
|
const config = cloneDeep(item);
|
if (!['add', 'batchRemove', 'copy', 'remove'].includes(item.value)) {
|
config.actionConfig = { ...defaultAddTableConf, ...config.actionConfig };
|
}
|
openModal(true, { config, children: props.activeData.__config__.children });
|
}
|
function onNumLimitBlur(e) {
|
if (!e.target.value) nextTick(() => (props.activeData.numLimit = 1000));
|
}
|
|
onMounted(() => {
|
if (!props.activeData.columnBtnsList?.length) props.activeData.columnBtnsList = cloneDeep(defaultColumnBtnsList);
|
if (!props.activeData.footerBtnsList?.length) props.activeData.footerBtnsList = cloneDeep(defaultFooterBtnsList);
|
});
|
</script>
|
<template>
|
<a-form-item label="合计设置">
|
<a-switch v-model:checked="activeData.showSummary" />
|
</a-form-item>
|
<a-form-item label="合计字段" v-if="activeData.showSummary">
|
<jnpf-select v-model:value="activeData.summaryField" placeholder="请选择" :options="childrenList" allow-clear show-search multiple />
|
</a-form-item>
|
<a-form-item label="条数限制">
|
<a-switch v-model:checked="activeData.isNumLimit" />
|
</a-form-item>
|
<a-form-item label="最多添加" v-if="activeData.isNumLimit">
|
<jnpf-input-number v-model:value="activeData.numLimit" placeholder="请输入" :min="1" addon-after="条" @blur="onNumLimitBlur" />
|
</a-form-item>
|
<template v-if="showType === 'pc'">
|
<a-form-item>
|
<template #label>布局设置<BasicHelp text="平铺布局不支持子表内的控件冻结和批量删除按钮操作" /></template>
|
<jnpf-radio
|
v-model:value="activeData.layoutType"
|
:options="layoutTypeOptions"
|
option-type="button"
|
button-style="solid"
|
@change="activeData.hasPage = false" />
|
</a-form-item>
|
<template v-if="activeData.layoutType == 'table'">
|
<a-form-item>
|
<template #label>分页设置<BasicHelp text="不支持代码生成、平铺布局和移动端" /></template>
|
<a-switch v-model:checked="activeData.hasPage" />
|
</a-form-item>
|
<a-form-item label="分页条数" v-if="activeData.hasPage">
|
<jnpf-radio v-model:value="activeData.pageSize" :options="pageSizeOptions" option-type="button" button-style="solid" class="right-radio" />
|
</a-form-item>
|
</template>
|
<a-form-item label="复杂表头" v-show="activeData.layoutType === 'table'">
|
<a-button block @click="handleComplexHeader">{{ activeData.__config__.complexHeaderList?.length ? '编辑复杂表头' : '复杂表头配置' }}</a-button>
|
</a-form-item>
|
<a-form-item label="默认展开" v-show="activeData.layoutType === 'list'">
|
<a-switch v-model:checked="activeData.defaultExpandAll" />
|
</a-form-item>
|
</template>
|
<a-divider>子表字段</a-divider>
|
<div class="custom-draggable-list">
|
<draggable v-model="activeData.__config__.children" :animation="300" group="selectItem" handle=".option-drag" item-key="value">
|
<template #item="{ element, index }">
|
<div class="custom-draggable-item">
|
<div class="custom-line-icon option-drag">
|
<i class="icon-ym icon-ym-darg"></i>
|
</div>
|
<p class="custom-line-value" @click="handleActiveFormItem(element)">{{ element.__config__.label }}</p>
|
<div class="close-btn custom-line-icon" @click="activeData.__config__.children.splice(index, 1)">
|
<i class="icon-ym icon-ym-btn-clearn"></i>
|
</div>
|
</div>
|
</template>
|
</draggable>
|
<div class="add-btn">
|
<a-dropdown :trigger="['click']" destroy-popup-on-hide>
|
<a-button type="link" pre-icon="icon-ym icon-ym-btn-add">添加字段</a-button>
|
<template #overlay>
|
<a-menu class="custom-draggable-dropdown-menu">
|
<a-menu-item v-for="(item, index) in getInputComponents" :key="index" @click="addComponent(item)">
|
<i :class="item.__config__.tagIcon"></i>
|
{{ item.__config__.label }}
|
</a-menu-item>
|
<a-menu-divider />
|
<a-menu-item v-for="(item, index) in getSelectComponents" :key="index" @click="addComponent(item)">
|
<i :class="item.__config__.tagIcon"></i>
|
{{ item.__config__.label }}
|
</a-menu-item>
|
<a-menu-divider />
|
<a-menu-item v-for="(item, index) in getSystemComponents" :key="index" @click="addComponent(item)">
|
<i :class="item.__config__.tagIcon"></i>
|
{{ item.__config__.label }}
|
</a-menu-item>
|
</a-menu>
|
</template>
|
</a-dropdown>
|
</div>
|
</div>
|
<a-divider>操作列按钮</a-divider>
|
<draggable v-model="activeData.columnBtnsList" :animation="300" group="selectItem" handle=".option-drag" item-key="value" class="custom-draggable-list">
|
<template #item="{ element }">
|
<div class="custom-draggable-item">
|
<div class="custom-line-icon option-drag">
|
<i class="icon-ym icon-ym-darg"></i>
|
</div>
|
<p class="custom-line-value">{{ element.label }}</p>
|
<div class="edit-btn custom-line-icon" @click="editBtnConfig(element)">
|
<i class="icon-ym icon-ym-btn-edit"></i>
|
</div>
|
</div>
|
</template>
|
</draggable>
|
<a-divider>底部按钮</a-divider>
|
<div class="custom-draggable-list">
|
<draggable v-model="activeData.footerBtnsList" :animation="300" group="selectItem" handle=".option-drag" item-key="value">
|
<template #item="{ element, index }">
|
<div class="custom-draggable-item">
|
<div class="custom-line-icon option-drag">
|
<i class="icon-ym icon-ym-darg"></i>
|
</div>
|
<p class="custom-line-value">{{ element.label }}</p>
|
<div class="close-btn custom-line-icon" @click="activeData.footerBtnsList.splice(index, 1)" v-if="index > 1">
|
<i class="icon-ym icon-ym-btn-clearn"></i>
|
</div>
|
<div class="edit-btn custom-line-icon ml-[10px]" @click="editBtnConfig(element)">
|
<i class="icon-ym icon-ym-btn-edit"></i>
|
</div>
|
</div>
|
</template>
|
</draggable>
|
<div class="add-btn" v-if="activeData.footerBtnsList?.length < 5">
|
<a-button type="link" pre-icon="icon-ym icon-ym-btn-add" @click="addBtn()">添加按钮</a-button>
|
</div>
|
</div>
|
<BtnConfigModal @register="registerModal" @confirm="updateConf" />
|
<ComplexHeaderModal @register="registerComplexHeaderModal" @confirm="updateComplexHeaderList" />
|
</template>
|