<script lang="ts" setup>
|
import { computed, inject, ref, unref } from 'vue';
|
|
import { useModal } from '@jnpf/ui/modal';
|
import { buildBitUUID } from '@jnpf/utils';
|
|
import { TreeSelect } from 'ant-design-vue';
|
import { cloneDeep } from 'lodash-es';
|
import draggable from 'vuedraggable';
|
|
import { useGeneratorStore } from '#/store';
|
|
import BusinessKeyCfgModal from './BusinessKeyCfgModal.vue';
|
import CustomBtnCfg from './CustomBtnCfg.vue';
|
import DetailExtraModal from './DetailExtraModal.vue';
|
import FormScript from './FormScript.vue';
|
import StyleScript from './StyleScript.vue';
|
|
const props = defineProps(['activeData', 'formConf', 'drawingList', 'formInfo', 'dbType', 'printTplOptions', 'toggleVmodelCase']);
|
const sizeOptions = [
|
{ id: 'large', fullName: '较大' },
|
{ id: 'middle', fullName: '中等' },
|
{ id: 'small', fullName: '较小' },
|
];
|
const defaultLabelPositionOptions = [
|
{ id: 'left', fullName: '左对齐', disabled: false },
|
{ id: 'right', fullName: '右对齐', disabled: false },
|
{ id: 'top', fullName: '顶部对齐', disabled: false },
|
];
|
const popupTypeOptions = [
|
{ id: 'general', fullName: '居中弹窗' },
|
{ id: 'drawer', fullName: '右侧弹窗' },
|
{ id: 'fullScreen', fullName: '全屏弹窗' },
|
];
|
const formStyleOptions = [
|
{ id: '', fullName: '默认风格' },
|
{ id: 'word-form', fullName: '公文风格' },
|
];
|
const policyOptions = [
|
{ id: 1, fullName: '雪花ID' },
|
{ id: 2, fullName: '自增长ID' },
|
];
|
const generalWidthOptions = ['600px', '800px', '1000px', '40%', '50%', '60%', '70%', '80%'];
|
const fullScreenWidthOptions = ['800px', '1000px', '1200px', '1400px', '50%', '60%', '70%', '80%', '90%', '100%'];
|
|
const getShowType: (() => string | undefined) | undefined = inject('getShowType');
|
const showType = computed(() => (getShowType as () => string | undefined)());
|
const [registerScriptModal, { openModal: openScriptModal }] = useModal();
|
const [registerStyleScriptModal, { openModal: openStyleScriptModal }] = useModal();
|
const [registerBusinessKeyCfgModal, { openModal: openBusinessKeyCfgModal }] = useModal();
|
const [registerCustomBtnCfgModal, { openModal: openCustomBtnCfgModal }] = useModal();
|
const [registerDetailExtraModal, { openModal: openDetailExtraModal }] = useModal();
|
const activeFunc = ref('');
|
const generatorStore = useGeneratorStore();
|
|
const labelPositionOptions = computed(() => {
|
const options = cloneDeep(defaultLabelPositionOptions);
|
options[2].disabled = props.formConf.formStyle === 'word-form';
|
return options;
|
});
|
const getClassNameOptions = computed(() => unref(props.formConf).classNames.map((o) => ({ id: o, fullName: o })));
|
const getHasTable = computed(() => generatorStore.getHasTable);
|
|
function editFunc(funcName) {
|
activeFunc.value = funcName;
|
openScriptModal(true, { text: unref(props.formConf).funcs[funcName] });
|
}
|
function updateScript(data) {
|
props.formConf.funcs[activeFunc.value] = data;
|
}
|
function editStyle() {
|
openStyleScriptModal(true, { text: unref(props.formConf).classJson });
|
}
|
function updateStyleScript(data) {
|
props.formConf.classJson = data;
|
props.formConf.classNames = spiltByDoc(data);
|
}
|
function spiltByDoc(str) {
|
str = str.trim();
|
const arr: any[] = [];
|
const cut = str.split('}');
|
cut.forEach((item) => {
|
if (item) {
|
const afterCut = item.split('{');
|
const classObject = { key: '', value: '' };
|
let name: string = '';
|
name = afterCut[0].split(' ').length > 1 ? afterCut[0].split(' ')[0] : afterCut[0];
|
if (name.split('.').length > 1) {
|
name = name.split('.')[1] || '';
|
}
|
name = name.split(':')[0] || '';
|
const matching = /^[a-z].*$/i;
|
if (matching.test(name)) {
|
classObject.key = name.replaceAll(/\r|\n/g, '').trim();
|
classObject.value = `${item.replaceAll(/\r|\n/g, '')}}`;
|
arr.push(classObject);
|
}
|
}
|
});
|
return arr.map((o) => o.key);
|
}
|
function editBusinessKeyCfg() {
|
openBusinessKeyCfgModal(true, {
|
businessKeyList: props.formConf.businessKeyList,
|
businessKeyTip: props.formConf.businessKeyTip,
|
drawingList: props.drawingList,
|
});
|
}
|
function updateBusinessKeyCfg(data) {
|
props.formConf.businessKeyList = data.businessKeyList;
|
props.formConf.businessKeyTip = data.businessKeyTip;
|
}
|
function addCustomBtn() {
|
const data = {
|
value: `btn_${buildBitUUID()}`,
|
label: '',
|
labelI18nCode: '',
|
show: true,
|
actionConfig: {},
|
};
|
editCustomBtn(data);
|
}
|
function editCustomBtn(data) {
|
openCustomBtnCfgModal(true, {
|
showType: unref(showType),
|
drawingList: props.drawingList,
|
data: cloneDeep(data),
|
});
|
}
|
function updateCustomBtnCfg(data) {
|
const customBtns = unref(showType) == 'pc' ? 'customBtns' : 'appCustomBtns';
|
const list: any[] = props.formConf[customBtns].filter((o) => data.value == o.value);
|
if (list.length) {
|
props.formConf[customBtns] = props.formConf[customBtns].map((o) => (data.value == o.value ? data : o));
|
} else {
|
props.formConf[customBtns].push(data);
|
}
|
}
|
function onDataLogChange(val) {
|
if (val) props.formConf.popupType = 'fullScreen';
|
}
|
function editDetailExtra() {
|
openDetailExtraModal(true, { drawingList: props.drawingList, detailExtraList: props.formConf.detailExtraList || [] });
|
}
|
function onDetailExtraConfirm(data) {
|
props.formConf.detailExtraList = data || [];
|
}
|
function onTableNameChange(val) {
|
if (val) props.formConf.tableName = props.toggleVmodelCase(val);
|
}
|
</script>
|
<template>
|
<a-form :colon="false" layout="vertical" class="right-board-form">
|
<a-form-item v-if="!getHasTable">
|
<template #label>数据库表<BasicHelp text="发布后,主表的数据库表名不支持修改" /></template>
|
<jnpf-input v-model:value="formConf.tableName" placeholder="请输入" allow-clear :maxlength="30" @change="onTableNameChange" />
|
</a-form-item>
|
<a-form-item label="表单尺寸">
|
<jnpf-radio v-model:value="formConf.size" :options="sizeOptions" option-type="button" button-style="solid" />
|
</a-form-item>
|
<a-form-item label="标签对齐">
|
<jnpf-radio v-model:value="formConf.labelPosition" :options="labelPositionOptions" option-type="button" button-style="solid" class="right-radio" />
|
</a-form-item>
|
<a-form-item label="标题宽度">
|
<jnpf-input-number v-model:value="formConf.labelWidth" placeholder="请输入" :min="0" />
|
</a-form-item>
|
<a-form-item label="标题后缀">
|
<a-input v-model:value="formConf.labelSuffix" placeholder="请输入" />
|
</a-form-item>
|
<a-form-item label="栅格间隔">
|
<jnpf-input-number v-model:value="formConf.gutter" placeholder="请输入" :min="0" />
|
</a-form-item>
|
<a-form-item label="弹窗类型">
|
<jnpf-select v-model:value="formConf.popupType" :options="popupTypeOptions" :disabled="formConf.dataLog" />
|
</a-form-item>
|
<a-form-item label="页签管理" v-if="formConf.popupType === 'fullScreen'">
|
<a-button block @click="editDetailExtra()">设置</a-button>
|
</a-form-item>
|
<a-form-item label="表单样式">
|
<a-select v-model:value="formConf.formStyle" :options="formStyleOptions" :field-names="{ value: 'id', label: 'fullName' }" />
|
</a-form-item>
|
<a-form-item label="表单宽度" v-if="formConf.popupType === 'general'">
|
<a-select v-model:value="formConf.generalWidth">
|
<a-select-option v-for="item in generalWidthOptions" :key="item" :value="item">{{ item }}</a-select-option>
|
</a-select>
|
</a-form-item>
|
<a-form-item label="表单宽度" v-if="formConf.popupType === 'fullScreen'">
|
<a-select v-model:value="formConf.fullScreenWidth">
|
<a-select-option v-for="item in fullScreenWidthOptions" :key="item" :value="item">{{ item }}</a-select-option>
|
</a-select>
|
</a-form-item>
|
<a-form-item label="表单宽度" v-if="formConf.popupType === 'drawer'">
|
<a-select v-model:value="formConf.drawerWidth">
|
<a-select-option v-for="item in generalWidthOptions" :key="item" :value="item">{{ item }}</a-select-option>
|
</a-select>
|
</a-form-item>
|
<a-form-item>
|
<template #label>表单Css<BasicHelp text="不支持代码生成" /></template>
|
<a-button block @click="editStyle()">编写样式</a-button>
|
</a-form-item>
|
<a-form-item>
|
<template #label>表单Class<BasicHelp text="不支持代码生成" /></template>
|
<jnpf-select v-model:value="formConf.className" multiple allow-clear :options="getClassNameOptions" show-search />
|
</a-form-item>
|
<a-form-item label="主键策略">
|
<jnpf-select v-model:value="formConf.primaryKeyPolicy" :options="policyOptions" :disabled="!!formInfo.id" />
|
</a-form-item>
|
<a-form-item>
|
<template #label>并发锁定<BasicHelp text="并发提交表单时候,加乐观锁机制以保证数据提交准确性" /></template>
|
<a-switch v-model:checked="formConf.concurrencyLock" />
|
</a-form-item>
|
<a-form-item>
|
<template #label>逻辑删除<BasicHelp text="表单是否增加删除标志、删除时间和删除用户字段" /></template>
|
<a-switch v-model:checked="formConf.logicalDelete" />
|
</a-form-item>
|
<a-form-item>
|
<template #label>修改记录<BasicHelp text="启用后,编辑/详情页显示表单修改记录;不支持代码生成" /></template>
|
<a-switch v-model:checked="formConf.dataLog" @change="onDataLogChange" />
|
</a-form-item>
|
<a-form-item>
|
<template #label>业务主键<BasicHelp text="若表单中一个或多个字段的值与已提交的数据有重复时,不允许提交" /></template>
|
<a-switch v-model:checked="formConf.useBusinessKey" />
|
</a-form-item>
|
<a-form-item label="校验规则" v-if="formConf.useBusinessKey">
|
<a-button block @click="editBusinessKeyCfg()">规则设置</a-button>
|
</a-form-item>
|
<a-divider>表单按钮</a-divider>
|
<div class="btn-config-list">
|
<div class="btn-cell">
|
<a-checkbox v-model:checked="formConf.hasConfirmBtn" disabled>确定</a-checkbox>
|
<jnpf-i18n-input v-model:value="formConf.confirmButtonText" v-model:i18n="formConf.confirmButtonTextI18nCode" placeholder="请输入" />
|
</div>
|
<div class="btn-cell">
|
<a-checkbox v-model:checked="formConf.hasCancelBtn" disabled>取消</a-checkbox>
|
<jnpf-i18n-input v-model:value="formConf.cancelButtonText" v-model:i18n="formConf.cancelButtonTextI18nCode" placeholder="请输入" />
|
</div>
|
<div class="btn-cell" v-if="showType == 'pc'">
|
<a-checkbox v-model:checked="formConf.hasPrintBtn">打印<BasicHelp text="启用流程后,操作按钮以流程节点为准" /></a-checkbox>
|
<jnpf-i18n-input v-model:value="formConf.printButtonText" v-model:i18n="formConf.printButtonTextI18nCode" placeholder="请输入" />
|
</div>
|
<a-form-item v-if="formConf.hasPrintBtn && showType == 'pc'" class="!pl-[100px]">
|
<jnpf-tree-select
|
v-model:value="formConf.printId"
|
placeholder="请选择"
|
multiple
|
:options="printTplOptions"
|
last-level
|
:show-checked-strategy="TreeSelect.SHOW_CHILD" />
|
</a-form-item>
|
<div class="btn-cell" v-if="showType == 'pc'">
|
<a-checkbox class="!w-full" v-model:checked="formConf.hasConfirmAndAddBtn">
|
确定并继续操作<BasicHelp text="选中后显示“确定并新增”、“确定并继续”、“上一条”、“下一条”按钮" />
|
</a-checkbox>
|
</div>
|
</div>
|
<a-divider>{{ showType == 'pc' ? 'PC' : 'APP' }}自定义按钮<BasicHelp text="不支持代码生成" /></a-divider>
|
<div class="custom-draggable-list">
|
<draggable v-model="formConf.customBtns" :animation="300" group="selectItem" handle=".option-drag" item-key="value" v-if="showType == 'pc'">
|
<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="formConf.customBtns.splice(index, 1)">
|
<i class="icon-ym icon-ym-btn-clearn"></i>
|
</div>
|
<div class="edit-btn custom-line-icon ml-[10px]" @click="editCustomBtn(element)">
|
<i class="icon-ym icon-ym-btn-edit"></i>
|
</div>
|
</div>
|
</template>
|
</draggable>
|
<draggable v-model="formConf.appCustomBtns" :animation="300" group="selectItem" handle=".option-drag" item-key="value" v-else>
|
<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="formConf.appCustomBtns.splice(index, 1)">
|
<i class="icon-ym icon-ym-btn-clearn"></i>
|
</div>
|
<div class="edit-btn custom-line-icon ml-[10px]" @click="editCustomBtn(element)">
|
<i class="icon-ym icon-ym-btn-edit"></i>
|
</div>
|
</div>
|
</template>
|
</draggable>
|
<div class="add-btn" v-if="formConf[showType == 'pc' ? 'customBtns' : 'appCustomBtns']?.length < 5">
|
<a-button type="link" pre-icon="icon-ym icon-ym-btn-add" @click="addCustomBtn()">添加按钮</a-button>
|
</div>
|
</div>
|
<template v-if="formConf.funcs">
|
<a-divider>脚本事件<BasicHelp text="不支持代码生成" /></a-divider>
|
<a-form-item label="onLoad">
|
<a-button block @click="editFunc('onLoad')">表单加载触发</a-button>
|
</a-form-item>
|
<a-form-item label="beforeSubmit">
|
<a-button block @click="editFunc('beforeSubmit')">提交前置触发</a-button>
|
</a-form-item>
|
<a-form-item label="afterSubmit">
|
<a-button block @click="editFunc('afterSubmit')">提交后置触发</a-button>
|
</a-form-item>
|
</template>
|
<FormScript type="form" @register="registerScriptModal" :tree-title="formInfo.fullName" :drawing-list="drawingList" @confirm="updateScript" />
|
<StyleScript @register="registerStyleScriptModal" @confirm="updateStyleScript" />
|
<BusinessKeyCfgModal @register="registerBusinessKeyCfgModal" @confirm="updateBusinessKeyCfg" />
|
<CustomBtnCfg @register="registerCustomBtnCfgModal" @confirm="updateCustomBtnCfg" />
|
<DetailExtraModal @register="registerDetailExtraModal" @confirm="onDetailExtraConfirm" />
|
</a-form>
|
</template>
|