1404 lines
39 KiB
TypeScript
1404 lines
39 KiB
TypeScript
import {
|
|
AppComponentType,
|
|
AppFormSchema,
|
|
AppFormProps,
|
|
} from './../../model/generator/appFormConfig';
|
|
import { ComponentType, SubFormColumn } from '/@/components/Form/src/types';
|
|
import {
|
|
CardComponentProps,
|
|
FormProps,
|
|
FormSchema,
|
|
GridComponentProps,
|
|
TabComponentProps,
|
|
} from '/@/components/Form';
|
|
import { ComponentOptionModel, FormJson } from '/@/model/generator/codeGenerator';
|
|
import { uploadApi } from '/@/api/sys/upload';
|
|
import { camelCaseString, isValidJSON } from '/@/utils/event/design';
|
|
import { ColumnType } from '/@/components/Designer/src/types';
|
|
import { useI18n } from '/@/hooks/web/useI18n';
|
|
import { cloneDeep } from 'lodash-es';
|
|
|
|
const { t } = useI18n();
|
|
export const displayColumn = ['grid', 'form', 'divider'];
|
|
export const replaceColumn = ['select', 'radio', 'checkbox', 'cascader', 'upload'];
|
|
|
|
/**
|
|
*
|
|
* @param json 表单设计json
|
|
* @param convertCamel 是否需要转换 表名和字段名
|
|
* @returns
|
|
*/
|
|
export function buildOption(json: FormJson, convertCamel = true): FormProps {
|
|
const { list, config, hiddenComponent } = json;
|
|
const formSchema = buildFormScheme(list, convertCamel);
|
|
const formProp: FormProps = {
|
|
labelCol: config.labelCol,
|
|
labelAlign: config.labelAlign,
|
|
layout: config.layout,
|
|
size: config.size,
|
|
schemas: formSchema,
|
|
showActionButtonGroup: false,
|
|
buttonLocation: config.buttonLocation ? config.buttonLocation : 'center',
|
|
actionColOptions: {
|
|
span: 24,
|
|
},
|
|
showResetButton: false,
|
|
showSubmitButton: false,
|
|
hiddenComponent,
|
|
};
|
|
|
|
return formProp;
|
|
}
|
|
|
|
export function buildFormScheme(list: ComponentOptionModel[], convertCamel: boolean): FormSchema[] {
|
|
const componentsoptions: FormSchema[] = list.map((item) => {
|
|
if (item.type === 'divider') {
|
|
const dividerSchema: FormSchema = {
|
|
key: item.key,
|
|
field: '',
|
|
label: item.label,
|
|
colProps: {
|
|
span: 24,
|
|
},
|
|
type: item.type,
|
|
component: 'Divider',
|
|
componentProps: {
|
|
dashed: false, //是否虚线
|
|
orientation: item.options!.orientation,
|
|
text: item.options!.defaultValue,
|
|
isShow: item.options!.isShow,
|
|
style: {
|
|
marginTop: item.options!.marginTop + 'px',
|
|
marginBottom: item.options!.marginBottom + 'px',
|
|
},
|
|
},
|
|
};
|
|
return dividerSchema;
|
|
}
|
|
|
|
//如果是栅格布局组件
|
|
if (item.type === 'grid') {
|
|
const gridSchema: FormSchema = {
|
|
key: item.key,
|
|
field: '',
|
|
label: '',
|
|
type: item.type,
|
|
colProps: { span: 24 },
|
|
component: buildComponentType(item.type) as ComponentType,
|
|
children: [],
|
|
componentProps: item.options,
|
|
};
|
|
item.layout?.map((el) => {
|
|
const gridProps: GridComponentProps = {
|
|
span: el.span,
|
|
list: [],
|
|
};
|
|
|
|
gridProps.list = buildFormScheme(el.list, convertCamel);
|
|
gridSchema.children?.push(gridProps);
|
|
});
|
|
return gridSchema;
|
|
}
|
|
//如果是表格布局组件
|
|
if (item.type === 'table-layout') {
|
|
const gridSchema: FormSchema = {
|
|
key: item.key,
|
|
field: '',
|
|
label: '',
|
|
type: item.type,
|
|
colProps: { span: 24 },
|
|
component: buildComponentType(item.type) as ComponentType,
|
|
children: [],
|
|
componentProps: item.options,
|
|
};
|
|
item.layout?.map((el) => {
|
|
const gridProps: any = {
|
|
list: [],
|
|
};
|
|
el.list.map((li) => {
|
|
const gridChild: any = { ...li };
|
|
gridChild.children = buildFormScheme(li.children!, convertCamel);
|
|
gridProps.list.push(gridChild);
|
|
});
|
|
|
|
gridSchema.children?.push(gridProps);
|
|
});
|
|
return gridSchema;
|
|
}
|
|
//如果是子表单布局组件
|
|
if (item.type === 'form') {
|
|
const formSchema: FormSchema = {
|
|
key: item.key,
|
|
label: item.label,
|
|
field: (convertCamel ? camelCaseString(item.bindTable) : item.bindTable) + 'List',
|
|
type: item.type,
|
|
component: buildComponentType(item.type) as ComponentType,
|
|
required: true,
|
|
colProps: { span: 24 },
|
|
};
|
|
const childSchamas = item.children?.map((column) => buildSubFormSchema(column, convertCamel));
|
|
childSchamas?.push({
|
|
title: t('操作'),
|
|
key: 'action',
|
|
fixed: 'right',
|
|
width: '50px',
|
|
});
|
|
formSchema.componentProps = {
|
|
mainKey: (convertCamel ? camelCaseString(item.bindTable) : item.bindTable) + 'List',
|
|
columns: childSchamas,
|
|
...item.options,
|
|
};
|
|
return formSchema;
|
|
}
|
|
|
|
//如果是子表单一对一布局组件
|
|
if (item.type === 'one-for-one') {
|
|
const oneForOneSchema: FormSchema = {
|
|
key: item.key,
|
|
label: item.label,
|
|
field: (convertCamel ? camelCaseString(item.bindTable) : item.bindTable) + 'List',
|
|
type: item.type,
|
|
component: buildComponentType(item.type) as ComponentType,
|
|
colProps: { span: 24 },
|
|
children: [],
|
|
componentProps: {
|
|
isShow: item.options?.isShow,
|
|
},
|
|
};
|
|
|
|
const childSchamas = buildFormScheme(item.children!, convertCamel);
|
|
// const childSchamas = item.children?.map((column) => buildFormScheme(column, convertCamel));
|
|
|
|
oneForOneSchema.componentProps = {
|
|
mainKey: (convertCamel ? camelCaseString(item.bindTable) : item.bindTable) + 'List',
|
|
childSchemas: childSchamas,
|
|
...item.options,
|
|
};
|
|
|
|
return oneForOneSchema;
|
|
}
|
|
|
|
if (item.type === 'tab') {
|
|
const tabSchema: FormSchema = {
|
|
key: item.key,
|
|
field: '',
|
|
label: '',
|
|
type: item.type,
|
|
colProps: { span: 24 },
|
|
component: 'Tab',
|
|
children: [],
|
|
componentProps: {
|
|
tabPosition: item.options!.tabPosition ?? 'top',
|
|
size: item.options!.tabSize ?? 'default',
|
|
type: item.options!.type ?? 'line',
|
|
isShow: item.options!.isShow,
|
|
},
|
|
};
|
|
|
|
item.layout?.map((el) => {
|
|
const tabProps: TabComponentProps = {
|
|
span: el.span,
|
|
name: el.name,
|
|
list: [],
|
|
};
|
|
|
|
tabProps.list = buildFormScheme(el.list, convertCamel);
|
|
tabSchema.children?.push(tabProps);
|
|
});
|
|
return tabSchema;
|
|
}
|
|
|
|
if (item.type === 'upload') {
|
|
const uploadSchema: FormSchema = {
|
|
key: item.key,
|
|
field: convertCamel ? camelCaseString(item.bindField)! : item.bindField!,
|
|
label: item.label,
|
|
type: item.type,
|
|
component: buildComponentType(item.type) as ComponentType,
|
|
colProps: {
|
|
span: 24,
|
|
},
|
|
componentProps: {
|
|
api: uploadApi,
|
|
...item.options,
|
|
},
|
|
};
|
|
return uploadSchema;
|
|
}
|
|
|
|
if (item.type === 'card') {
|
|
const tabSchema: FormSchema = {
|
|
key: item.key,
|
|
field: '',
|
|
label: '',
|
|
type: item.type,
|
|
colProps: { span: 24 },
|
|
component: 'Card',
|
|
children: [],
|
|
componentProps: {
|
|
title: item.options!.title,
|
|
isShow: item.options!.isShow,
|
|
},
|
|
};
|
|
|
|
item.layout?.map((el) => {
|
|
const cardProps: CardComponentProps = {
|
|
span: el.span,
|
|
name: el.name,
|
|
list: [],
|
|
};
|
|
|
|
cardProps.list = buildFormScheme(el.list, convertCamel);
|
|
tabSchema.children?.push(cardProps);
|
|
});
|
|
return tabSchema;
|
|
}
|
|
|
|
if (item.type === 'time-range' || item.type === 'date-range') {
|
|
const rangeSchema: FormSchema = {
|
|
key: item.key,
|
|
field: `${convertCamel ? camelCaseString(item.bindStartTime!) : item.bindStartTime},${
|
|
convertCamel ? camelCaseString(item.bindEndTime!) : item.bindEndTime
|
|
}`,
|
|
label: item.label,
|
|
type: item.type,
|
|
component: buildComponentType(item.type) as ComponentType,
|
|
componentProps: {
|
|
...item.options,
|
|
style: { width: item.options!.width },
|
|
placeholder: [item.options!.startTimePlaceholder, item.options!.endTimePlaceholder],
|
|
},
|
|
colProps: { span: 24 },
|
|
};
|
|
return rangeSchema;
|
|
}
|
|
|
|
if (item.type === 'picker-color') {
|
|
const colorPickerSchema: FormSchema = {
|
|
key: item.key,
|
|
field: convertCamel ? camelCaseString(item.bindField)! : item.bindField,
|
|
label: item.label,
|
|
type: item.type,
|
|
component: buildComponentType(item.type) as ComponentType,
|
|
colProps: {
|
|
span: 24,
|
|
},
|
|
defaultValue: item.options!.defaultValue,
|
|
componentProps: {
|
|
...item.options,
|
|
style: { 'pointer-events': item.options!.disabled ? 'none' : 'auto' },
|
|
},
|
|
};
|
|
return colorPickerSchema;
|
|
}
|
|
|
|
if (item.type === 'button') {
|
|
const options = cloneDeep(item.options);
|
|
camelCaseOptionsField(options, item.type, convertCamel);
|
|
const buttonSchema: FormSchema = {
|
|
key: item.key,
|
|
field: convertCamel ? camelCaseString(item.bindField)! : item.bindField,
|
|
label: item.label,
|
|
type: item.type,
|
|
component: buildComponentType(item.type) as ComponentType,
|
|
colProps: {
|
|
span: 24,
|
|
},
|
|
componentProps: {
|
|
...options,
|
|
width: item.options?.buttonWidth,
|
|
height: item.options?.buttonHeight,
|
|
},
|
|
};
|
|
return buttonSchema;
|
|
}
|
|
|
|
if (item.type === 'hiddenComponent') {
|
|
const hiddenComponentSchema: FormSchema = {
|
|
key: item.key,
|
|
field: convertCamel ? camelCaseString(item.bindField)! : item.bindField!,
|
|
label: item.label,
|
|
type: item.type,
|
|
component: buildComponentType(item.type) as ComponentType,
|
|
colProps: {
|
|
span: 24,
|
|
},
|
|
defaultValue: item.value,
|
|
};
|
|
return hiddenComponentSchema;
|
|
}
|
|
|
|
return buildSchema(item, convertCamel);
|
|
});
|
|
return componentsoptions;
|
|
}
|
|
|
|
export function buildSchema(model: ComponentOptionModel, convertCamel: boolean): FormSchema {
|
|
const componentName = buildComponentType(model.type);
|
|
const options = cloneDeep(model.options);
|
|
camelCaseOptionsField(options, model.type, convertCamel);
|
|
const schema: FormSchema = {
|
|
key: model.key,
|
|
field: (convertCamel ? camelCaseString(model.bindField)! : model.bindField) || '',
|
|
label: model.label,
|
|
type: model.type,
|
|
component: componentName as ComponentType,
|
|
colProps: {
|
|
span: 24,
|
|
},
|
|
defaultValue: model.options?.defaultValue,
|
|
componentProps: {
|
|
...options,
|
|
style: { width: model.options?.width },
|
|
},
|
|
};
|
|
return schema;
|
|
}
|
|
|
|
/**
|
|
* 构建子表单Schema
|
|
* @param model 当前组件配置
|
|
* @returns
|
|
*/
|
|
export function buildSubFormSchema(
|
|
model: ComponentOptionModel,
|
|
convertCamel = true,
|
|
): SubFormColumn {
|
|
if (model.type === 'upload') {
|
|
const uploadSchema: SubFormColumn = {
|
|
key: model.key,
|
|
dataIndex: convertCamel ? camelCaseString(model.bindField) : model.bindField,
|
|
title: model.label,
|
|
componentType: buildComponentType(model.type) as ComponentType,
|
|
componentProps: {
|
|
api: uploadApi,
|
|
...model.options,
|
|
},
|
|
};
|
|
return uploadSchema;
|
|
}
|
|
|
|
if (model.type === 'time-range' || model.type === 'date-range') {
|
|
const rangeSchema: SubFormColumn = {
|
|
key: model.key,
|
|
dataIndex: `${convertCamel ? camelCaseString(model.bindStartTime!) : model.bindStartTime},${
|
|
convertCamel ? camelCaseString(model.bindEndTime!) : model.bindEndTime
|
|
}`,
|
|
title: model.label,
|
|
componentType: buildComponentType(model.type) as ComponentType,
|
|
componentProps: {
|
|
...model.options,
|
|
style: { width: model.options!.width },
|
|
placeholder: [model.options!.startTimePlaceholder, model.options!.endTimePlaceholder],
|
|
},
|
|
};
|
|
return rangeSchema;
|
|
}
|
|
|
|
if (model.type === 'picker-color') {
|
|
const colorPickerSchema: SubFormColumn = {
|
|
key: model.key,
|
|
dataIndex: convertCamel ? camelCaseString(model.bindField) : model.bindField,
|
|
title: model.label,
|
|
componentType: buildComponentType(model.type) as ComponentType,
|
|
defaultValue: model.options!.defaultValue,
|
|
componentProps: {
|
|
...model.options,
|
|
style: { 'pointer-events': model.options!.disabled ? 'none' : 'auto' },
|
|
},
|
|
};
|
|
return colorPickerSchema;
|
|
}
|
|
const options = cloneDeep(model.options);
|
|
camelCaseOptionsField(options, model.type, convertCamel);
|
|
const column: SubFormColumn = {
|
|
key: model.key,
|
|
title: model.label,
|
|
dataIndex: convertCamel ? camelCaseString(model.bindField) : model.bindField,
|
|
componentType: buildComponentType(model.type) as ComponentType,
|
|
defaultValue: model.options!.defaultValue,
|
|
componentProps: options,
|
|
};
|
|
|
|
return column;
|
|
}
|
|
|
|
/**
|
|
* 构建子表单的card tab grid 组件的子级 Schema
|
|
* TODO 暂时搁浅 先不做
|
|
*
|
|
* @param model 当前组件配置
|
|
* @returns
|
|
*/
|
|
export function buildSubFormChildSchema(modelList: ComponentOptionModel[]): SubFormColumn[] {
|
|
const childSchamas = modelList.map((item) => {
|
|
const column: SubFormColumn = {
|
|
title: item.label,
|
|
dataIndex: camelCaseString(item.bindField),
|
|
componentType: buildComponentType(item.type) as ComponentType,
|
|
defaultValue: item.options!.defaultValue,
|
|
};
|
|
|
|
//如果是包含自己的组件
|
|
if (['card', 'tab', 'grid', 'form'].includes(item.type)) {
|
|
if (['card', 'tab', 'grid'].includes(item.type)) {
|
|
if (item.children && item.children.length > 0) {
|
|
column.children = buildSubFormChildSchema(item.children);
|
|
}
|
|
}
|
|
}
|
|
|
|
return column;
|
|
});
|
|
|
|
return childSchamas;
|
|
}
|
|
|
|
export function buildComponentType(type: string): string {
|
|
switch (type) {
|
|
case 'input':
|
|
return 'Input';
|
|
|
|
case 'password':
|
|
return 'InputPassword';
|
|
|
|
case 'textarea':
|
|
return 'InputTextArea';
|
|
|
|
case 'book':
|
|
return 'InputTextArea';
|
|
|
|
case 'number':
|
|
return 'InputNumber';
|
|
|
|
case 'radio':
|
|
return 'ApiRadioGroup';
|
|
|
|
case 'checkbox':
|
|
return 'ApiCheckboxGroup';
|
|
|
|
case 'select':
|
|
return 'XjrSelect';
|
|
|
|
case 'cascader':
|
|
return 'ApiCascader';
|
|
|
|
case 'time':
|
|
return 'TimePicker';
|
|
|
|
case 'date':
|
|
return 'DatePicker';
|
|
|
|
case 'time-range':
|
|
return 'TimeRangePicker';
|
|
|
|
case 'date-range':
|
|
return 'RangePicker';
|
|
case 'rate':
|
|
return 'Rate';
|
|
|
|
case 'switch':
|
|
return 'Switch';
|
|
|
|
case 'slider':
|
|
return 'Slider';
|
|
|
|
case 'divider':
|
|
return 'Divider';
|
|
|
|
case 'upload':
|
|
return 'Upload';
|
|
|
|
case 'richtext-editor':
|
|
return 'RichTextEditor';
|
|
|
|
case 'form':
|
|
return 'SubForm';
|
|
|
|
case 'one-for-one':
|
|
return 'OneForOne';
|
|
|
|
case 'grid':
|
|
return 'Grid';
|
|
|
|
case 'card':
|
|
return 'Card';
|
|
|
|
case 'user':
|
|
return 'User';
|
|
|
|
case 'organization':
|
|
return 'Dept';
|
|
|
|
case 'info':
|
|
return 'Info';
|
|
|
|
case 'area':
|
|
return 'Area';
|
|
|
|
case 'multiple-popup':
|
|
return 'MultiplePopup';
|
|
|
|
case 'associate-popup':
|
|
return 'MultiplePopup';
|
|
|
|
case 'associate-select':
|
|
return 'AssociateSelect';
|
|
|
|
case 'button':
|
|
return 'Button';
|
|
|
|
case 'computational':
|
|
return 'Computation';
|
|
|
|
case 'picker-color':
|
|
return 'ColorPicker';
|
|
|
|
case 'title':
|
|
return 'Title';
|
|
case 'text':
|
|
return 'Text';
|
|
case 'opinion':
|
|
return 'Opinion';
|
|
|
|
case 'image':
|
|
return 'Image';
|
|
|
|
case 'auto-code':
|
|
return 'AutoCodeRule';
|
|
|
|
case 'money-chinese':
|
|
return 'MoneyChineseInput';
|
|
|
|
case 'map':
|
|
return 'SelectMap';
|
|
|
|
case 'qrcode':
|
|
return 'XjrQrcode';
|
|
|
|
case 'auto-complete':
|
|
return 'AutoComplete';
|
|
|
|
case 'form-view':
|
|
return 'FormView';
|
|
|
|
case 'iframe':
|
|
return 'XjrIframe';
|
|
|
|
case 'table-layout':
|
|
return 'TableLayout';
|
|
default:
|
|
return 'Input';
|
|
}
|
|
}
|
|
|
|
export function buildAppComponentType(type: string): AppComponentType {
|
|
switch (type) {
|
|
case 'input':
|
|
return AppComponentType.input;
|
|
|
|
case 'password':
|
|
return AppComponentType.input;
|
|
|
|
case 'textarea':
|
|
return AppComponentType.input;
|
|
|
|
case 'number':
|
|
return AppComponentType.inputNumber;
|
|
|
|
case 'radio':
|
|
return AppComponentType.radio;
|
|
|
|
case 'checkbox':
|
|
return AppComponentType.checkbox;
|
|
|
|
case 'select':
|
|
return AppComponentType.select;
|
|
|
|
case 'area':
|
|
case 'cascader':
|
|
return AppComponentType.cascader;
|
|
|
|
case 'time':
|
|
return AppComponentType.timeRange;
|
|
|
|
case 'date':
|
|
return AppComponentType.dateTime;
|
|
|
|
case 'time-range':
|
|
return AppComponentType.timeRange;
|
|
|
|
case 'date-range':
|
|
return AppComponentType.dateTimeRange;
|
|
|
|
case 'rate':
|
|
return AppComponentType.rate;
|
|
|
|
case 'switch':
|
|
return AppComponentType.switch;
|
|
|
|
case 'slider':
|
|
return AppComponentType.slider;
|
|
|
|
case 'divider':
|
|
return AppComponentType.divider;
|
|
|
|
case 'upload':
|
|
return AppComponentType.upload;
|
|
|
|
case 'richtext-editor':
|
|
return AppComponentType.editor;
|
|
case 'opinion':
|
|
return AppComponentType.opinion;
|
|
|
|
case 'form':
|
|
return AppComponentType.subForm;
|
|
|
|
case 'one-for-one':
|
|
return AppComponentType.singleForm;
|
|
|
|
case 'form-view':
|
|
return AppComponentType.formView;
|
|
|
|
case 'iframe':
|
|
return AppComponentType.iframe;
|
|
|
|
case 'auto-code':
|
|
return AppComponentType.autoCode;
|
|
|
|
case 'image':
|
|
return AppComponentType.image;
|
|
|
|
case 'picker-color':
|
|
return AppComponentType.color;
|
|
|
|
case 'qrcode':
|
|
return AppComponentType.qrcode;
|
|
|
|
case 'title':
|
|
return AppComponentType.title;
|
|
case 'text':
|
|
return AppComponentType.text;
|
|
case 'map':
|
|
return AppComponentType.map;
|
|
|
|
case 'organization':
|
|
return AppComponentType.organization;
|
|
|
|
case 'user':
|
|
return AppComponentType.user;
|
|
|
|
case 'computational':
|
|
return AppComponentType.computation;
|
|
|
|
case 'money-chinese':
|
|
return AppComponentType.moneyChinese;
|
|
|
|
case 'associate-select':
|
|
return AppComponentType.associatePicker;
|
|
|
|
case 'associate-popup':
|
|
return AppComponentType.associatePopup;
|
|
|
|
case 'multiple-popup':
|
|
return AppComponentType.multiplePopup;
|
|
|
|
case 'info':
|
|
return AppComponentType.info;
|
|
case 'button':
|
|
return AppComponentType.button;
|
|
case 'table-layout':
|
|
return AppComponentType.tableLayout;
|
|
default:
|
|
return AppComponentType.input;
|
|
}
|
|
}
|
|
|
|
export function JavaTypeConvertTsType(type: string): ColumnType {
|
|
switch (type) {
|
|
case 'Integer':
|
|
return ColumnType.NUMBER;
|
|
case 'Long':
|
|
return ColumnType.NUMBER;
|
|
case 'Float':
|
|
return ColumnType.NUMBER;
|
|
case 'Double':
|
|
return ColumnType.NUMBER;
|
|
case 'BigDecimal':
|
|
return ColumnType.NUMBER;
|
|
case 'Short':
|
|
return ColumnType.NUMBER;
|
|
case 'Byte':
|
|
return ColumnType.NUMBER;
|
|
case 'Boolean':
|
|
return ColumnType.BOOL;
|
|
case 'LocalDateTime':
|
|
return ColumnType.DATE;
|
|
case 'LocalTime':
|
|
return ColumnType.TIME;
|
|
default:
|
|
return ColumnType.STRING;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 将web端设计json 转换为 手机端所需要form
|
|
*/
|
|
export function buildAppFormProps(json: FormJson, convertCamel = true): AppFormProps {
|
|
const { config, hiddenComponent } = json;
|
|
let list = json.list;
|
|
list = list.concat(hiddenComponent);
|
|
const formSchema = buildAppFormScheme(list, convertCamel);
|
|
const formProp: AppFormProps = {
|
|
validateTrigger: 'submit',
|
|
labelPosition: config.layout === 'vertical' || config.layout === 'inline' ? 'top' : 'left',
|
|
labelWidth: 75,
|
|
labelAlign: !config.labelAlign ? 'center' : config.labelAlign,
|
|
errShowType: 'undertext',
|
|
border: false,
|
|
schemas: formSchema,
|
|
rules: [],
|
|
};
|
|
|
|
return formProp;
|
|
}
|
|
|
|
export function buildAppFormScheme(
|
|
list: ComponentOptionModel[],
|
|
convertCamel: boolean,
|
|
): AppFormSchema[] {
|
|
let schemas: AppFormSchema[] = [];
|
|
|
|
for (const item of list) {
|
|
if (item.type === 'divider') {
|
|
const dividerSchema: AppFormSchema = {
|
|
key: item.key,
|
|
field: item.bindField,
|
|
name: item.label,
|
|
component: AppComponentType.divider,
|
|
componentProps: {
|
|
text: item.options!.defaultValue,
|
|
align: item.options!.orientation,
|
|
isShow: item.options?.isShow,
|
|
},
|
|
};
|
|
schemas.push(dividerSchema);
|
|
|
|
continue;
|
|
}
|
|
if (item.type === 'iframe') {
|
|
const iframeSchema: AppFormSchema = {
|
|
key: item.key,
|
|
field: '',
|
|
name: item.label,
|
|
label: item.label,
|
|
component: AppComponentType.iframe,
|
|
url: item.options?.url,
|
|
};
|
|
schemas.push(iframeSchema);
|
|
|
|
continue;
|
|
}
|
|
//如果是栅格布局组件或者表格布局组件 手机端没有 必须要扁平化
|
|
if (item.type === 'grid') {
|
|
item.layout?.map((el) => {
|
|
schemas = schemas.concat(buildAppFormScheme(el.list, convertCamel));
|
|
});
|
|
continue;
|
|
}
|
|
|
|
if (item.type === 'table-layout') {
|
|
const layoutSchema: AppFormSchema = {
|
|
key: item.key,
|
|
name: item.label,
|
|
component: AppComponentType.tableLayout,
|
|
componentProps: {
|
|
isShow: item.options?.isShow || false,
|
|
},
|
|
layout: [],
|
|
};
|
|
|
|
item.layout?.map((el, index) => {
|
|
const child = {
|
|
name: el.name,
|
|
value: index,
|
|
children: [] as AppFormSchema[],
|
|
};
|
|
el.list?.map((chil) => {
|
|
if (chil.children && chil.children.length > 0) {
|
|
child.children = child.children.concat(buildAppFormScheme(chil.children, convertCamel));
|
|
}
|
|
});
|
|
layoutSchema.layout?.push(child);
|
|
});
|
|
schemas.push(layoutSchema);
|
|
continue;
|
|
}
|
|
//如果是tab组件 转换为手机端配置
|
|
if (item.type === 'tab') {
|
|
const tabSchema: AppFormSchema = {
|
|
key: item.key,
|
|
name: item.label,
|
|
component: AppComponentType.segmented,
|
|
layout: [],
|
|
componentProps: {
|
|
isShow: item.options?.isShow,
|
|
},
|
|
};
|
|
|
|
item.layout?.map((el, index) => {
|
|
const child = {
|
|
name: el.name,
|
|
value: index,
|
|
children: [] as AppFormSchema[],
|
|
};
|
|
child.children = buildAppFormScheme(el.list, convertCamel);
|
|
tabSchema.layout?.push(child);
|
|
});
|
|
schemas.push(tabSchema);
|
|
continue;
|
|
}
|
|
|
|
//如果是tab组件 转换为手机端配置
|
|
if (item.type === 'card') {
|
|
const cardSchema: AppFormSchema = {
|
|
key: item.key,
|
|
name: item.options?.title || item.label,
|
|
component: AppComponentType.collapse,
|
|
componentProps: {
|
|
isShow: item.options?.isShow,
|
|
},
|
|
layout: [],
|
|
};
|
|
|
|
item.layout?.map((el, index) => {
|
|
const child = {
|
|
name: el.name,
|
|
value: index,
|
|
children: [] as AppFormSchema[],
|
|
};
|
|
child.children = buildAppFormScheme(el.list, convertCamel);
|
|
cardSchema.layout?.push(child);
|
|
});
|
|
schemas.push(cardSchema);
|
|
continue;
|
|
}
|
|
|
|
//如果是子表单组件
|
|
if (item.type === 'form' || item.type === 'one-for-one') {
|
|
const formSchema: AppFormSchema = {
|
|
field: (convertCamel ? camelCaseString(item.bindTable) : item.bindTable) + 'List', //字段
|
|
key: item.key,
|
|
name: item.label,
|
|
component: item.type === 'form' ? AppComponentType.subForm : AppComponentType.singleForm,
|
|
columns: [],
|
|
componentProps: {
|
|
isShow: item.options?.isShow,
|
|
},
|
|
};
|
|
if (item.options?.useSelectButton !== undefined) {
|
|
formSchema.useSelectButton = item.options.useSelectButton;
|
|
formSchema.buttonName = item.options.buttonName;
|
|
}
|
|
if (item.options?.preloadType) {
|
|
formSchema.preloadType = item.options.preloadType;
|
|
if (formSchema.preloadType == 'dic') {
|
|
if (item.options.itemId) formSchema.itemId = item.options.itemId;
|
|
if (item.options.dicOptions) {
|
|
formSchema.associateOptions = item.options.dicOptions;
|
|
}
|
|
} else if (formSchema.preloadType == 'api') {
|
|
if (item.options.apiConfig?.path)
|
|
formSchema.apiConfig = setApiConfig(item.options.apiConfig);
|
|
if (item.options.apiConfig?.outputParams) {
|
|
formSchema.associateOptions = item.options.apiConfig.outputParams;
|
|
}
|
|
}
|
|
}
|
|
formSchema.columns = buildAppFormScheme(item.children!, convertCamel);
|
|
schemas.push(formSchema);
|
|
continue;
|
|
}
|
|
|
|
schemas.push(buildAppSchema(item, convertCamel));
|
|
}
|
|
|
|
return schemas;
|
|
}
|
|
|
|
export function buildAppSchema(model: ComponentOptionModel, convertCamel: boolean): AppFormSchema {
|
|
const compType = buildAppComponentType(model.type);
|
|
const params: any = {};
|
|
let field = '';
|
|
if (model.type == 'date-range' || model.type == 'time-range') {
|
|
const start = convertCamel ? camelCaseString(model.bindStartTime!) : model.bindStartTime;
|
|
const end = convertCamel ? camelCaseString(model.bindEndTime!) : model.bindEndTime;
|
|
params.startTimeField = start;
|
|
params.endTimeField = end;
|
|
field = start + ',' + end;
|
|
}
|
|
if (model.options?.prestrainField) {
|
|
params.prestrainField = model.options.prestrainField;
|
|
}
|
|
const rules: any = [];
|
|
if (model.options?.required) {
|
|
rules.push({
|
|
required: model.options.required,
|
|
errorMessage: model.label + '项必填',
|
|
});
|
|
}
|
|
if (model.options?.rules && Array.isArray(model.options.rules)) {
|
|
model.options.rules.forEach((o) => {
|
|
rules.push({
|
|
pattern: o.pattern,
|
|
errorMessage: o.message,
|
|
});
|
|
});
|
|
}
|
|
const schema: AppFormSchema = {
|
|
key: model.key,
|
|
field: field
|
|
? field
|
|
: (convertCamel ? camelCaseString(model.bindField)! : model.bindField) || '',
|
|
label: model.options?.showLabel ? model.label : '',
|
|
component: compType,
|
|
defaultValue:
|
|
model.type == 'hiddenComponent'
|
|
? model.value
|
|
: model.type == 'number'
|
|
? model.options?.defaultValue > 0
|
|
? model.options?.defaultValue
|
|
: 0
|
|
: model.type == 'upload'
|
|
? Array.isArray(model.options?.defaultValue)
|
|
? ''
|
|
: model.options?.defaultValue
|
|
: model.options?.defaultValue || model.options?.defaultSelect,
|
|
componentProps: buildAppComponentProps(model.type, model.options, model.key, model.bindTable),
|
|
required: model.options?.required,
|
|
rules: rules,
|
|
name: model.label,
|
|
ifShow:
|
|
model.type == 'opinion' || model.type == 'hiddenComponent' ? false : model.options?.isShow,
|
|
dynamicDisabled: model.options?.disabled,
|
|
events: model.options?.events,
|
|
...params,
|
|
};
|
|
return schema;
|
|
}
|
|
|
|
export function buildAppComponentProps(type, options, key, bindTable) {
|
|
const params: any = {};
|
|
const defaultParams = { isShow: options.isShow };
|
|
switch (type) {
|
|
case 'input':
|
|
return {
|
|
placeholder: options.placeholder,
|
|
prefixIcon: options.prefix,
|
|
suffixIcon: options.suffix,
|
|
addonBefore: options.addonBefore,
|
|
addonAfter: options.addonAfter,
|
|
clearable: options.allowClear,
|
|
maxlength: options.maxlength || -1,
|
|
...defaultParams,
|
|
};
|
|
|
|
case 'password':
|
|
return {
|
|
type: 'password',
|
|
placeholder: options.placeholder,
|
|
prefixIcon: options.prefix,
|
|
addonBefore: options.addonBefore,
|
|
addonAfter: options.addonAfter,
|
|
clearable: options.allowClear,
|
|
maxlength: options.maxlength || -1,
|
|
...defaultParams,
|
|
};
|
|
|
|
case 'textarea':
|
|
return {
|
|
type: 'textarea',
|
|
placeholder: options.placeholder,
|
|
maxlength: options.maxlength || -1,
|
|
showCount: options.showCount,
|
|
autoHeight: options.autoSize,
|
|
clearable: options.allowClear,
|
|
...defaultParams,
|
|
};
|
|
case 'number':
|
|
return {
|
|
min: options.min,
|
|
placeholder: options.placeholder,
|
|
max: options.max,
|
|
step: options.step,
|
|
maxlength: options.maxlength || -1,
|
|
...defaultParams,
|
|
};
|
|
case 'auto-code':
|
|
return {
|
|
autoCodeRule: options.autoCodeRule,
|
|
placeholder: options.placeholder,
|
|
prefixIcon: options.prefix,
|
|
suffixIcon: options.suffix,
|
|
addonBefore: options.addonBefore,
|
|
addonAfter: options.addonAfter,
|
|
...defaultParams,
|
|
};
|
|
case 'radio':
|
|
case 'checkbox':
|
|
case 'select':
|
|
case 'associate-select':
|
|
case 'multiple-popup':
|
|
case 'associate-popup':
|
|
const remoteComponents = ['associate-select', 'multiple-popup', 'associate-popup'];
|
|
if (options.datasourceType == 'staticData') {
|
|
params.localdata = options.staticOptions;
|
|
params.map = {
|
|
text: options.labelField,
|
|
value: options.valueField,
|
|
};
|
|
} else if (options.datasourceType == 'dic') {
|
|
params.itemId = options.itemId;
|
|
params.map = {
|
|
text: options.labelField,
|
|
value: options.valueField,
|
|
};
|
|
if (remoteComponents.includes(type)) {
|
|
params.associateOptions = [...options.dicOptions];
|
|
}
|
|
} else if (options.datasourceType == 'api') {
|
|
params.apiConfig = setApiConfig(options.apiConfig);
|
|
params.map = {
|
|
text: options.labelField,
|
|
value: options.valueField,
|
|
};
|
|
if (remoteComponents.includes(type) && options.apiConfig?.outputParams) {
|
|
params.associateOptions = [...options.apiConfig.outputParams];
|
|
}
|
|
}
|
|
if (type == 'checkbox') {
|
|
params.multiple = true;
|
|
}
|
|
if (type == 'radio') {
|
|
params.mode = options.optionType;
|
|
}
|
|
return {
|
|
placeholder: options.placeholder,
|
|
...defaultParams,
|
|
...params,
|
|
};
|
|
|
|
case 'area':
|
|
case 'cascader':
|
|
if (type == 'area') {
|
|
params.showFormat = 'all';
|
|
params.split = '/';
|
|
params.selectedConfig = 'any';
|
|
params.type = 'area';
|
|
} else {
|
|
params.apiConfig = setApiConfig(options.apiConfig);
|
|
params.showFormat = options.showFormat;
|
|
params.split = options.separator;
|
|
params.selectedConfig = options.selectedConfig;
|
|
}
|
|
return {
|
|
placeholder: options.placeholder,
|
|
clearIcon: options.allowClear,
|
|
...defaultParams,
|
|
...params,
|
|
};
|
|
case 'slider':
|
|
return {
|
|
step: options.step,
|
|
min: options.min,
|
|
max: options.max,
|
|
...defaultParams,
|
|
};
|
|
case 'switch':
|
|
return {
|
|
checkedText: options.checkedChildren,
|
|
unCheckedText: options.unCheckedChildren,
|
|
checkedColor: options.checkedColor,
|
|
unCheckedColor: options.unCheckedColor,
|
|
...defaultParams,
|
|
};
|
|
case 'date':
|
|
return {
|
|
clearIcon: options.allowClear,
|
|
placeholder: options.placeholder,
|
|
type:
|
|
options.format == 'YYYY-MM-DD HH:mm:ss'
|
|
? 'datetime'
|
|
: options.format == 'YYYY-MM-DD'
|
|
? 'date'
|
|
: 'date',
|
|
formatType:
|
|
options.format == 'YYYY-MM'
|
|
? 'month'
|
|
: options.format == 'YYYY'
|
|
? 'year'
|
|
: options.format == 'YYYY-MM-DD HH:mm:ss'
|
|
? 'datetime'
|
|
: 'date',
|
|
...defaultParams,
|
|
};
|
|
case 'date-range':
|
|
return {
|
|
type: 'daterange',
|
|
startPlaceholder: options.startTimePlaceholder,
|
|
endPlaceholder: options.endTimePlaceholder,
|
|
...defaultParams,
|
|
};
|
|
case 'time':
|
|
return {
|
|
placeholder: options.placeholder,
|
|
clearable: options.allowClear,
|
|
...defaultParams,
|
|
};
|
|
case 'time-range':
|
|
return {
|
|
startTimePlaceholder: options.startTimePlaceholder,
|
|
endTimePlaceholder: options.endTimePlaceholder,
|
|
isRange: true,
|
|
clearable: options.allowClear,
|
|
...defaultParams,
|
|
};
|
|
case 'rate':
|
|
return {
|
|
max: options.count,
|
|
allowHalf: options.allowHalf,
|
|
...defaultParams,
|
|
};
|
|
case 'qrcode':
|
|
if (options.codeType == 'api') {
|
|
params.apiConfig = setApiConfig(options.apiConfig);
|
|
} else {
|
|
params.text = options.defaultValue;
|
|
}
|
|
return {
|
|
codeType: options.codeType,
|
|
codekey: key,
|
|
...params,
|
|
...defaultParams,
|
|
};
|
|
case 'title':
|
|
return {
|
|
color: options.color,
|
|
fontSize: options.fontSize,
|
|
align: options.align,
|
|
title: options.defaultValue,
|
|
...defaultParams,
|
|
};
|
|
case 'map':
|
|
return {
|
|
address: options.address,
|
|
prefixIcon: options.prefix,
|
|
suffixIcon: options.suffix,
|
|
latiAndLong: options.latiAndLong,
|
|
placeholder: options.placeholder,
|
|
bindTable: bindTable + 'List',
|
|
...defaultParams,
|
|
};
|
|
case 'upload':
|
|
return {
|
|
showType: options.listType,
|
|
fileExtname: options.accept ? options.accept.split(',') : [],
|
|
limit: options.maxNumber,
|
|
multiple: options.multiple,
|
|
maxSize: options.maxSize,
|
|
...defaultParams,
|
|
};
|
|
case 'image':
|
|
return {
|
|
showType: 'image',
|
|
fileExtname: ['.png', '.jpg', '.bmp', '.jpeg', '.gif', '.svg'],
|
|
maxSize: 10,
|
|
isUpload: options.isUpload,
|
|
...defaultParams,
|
|
};
|
|
case 'organization':
|
|
return {
|
|
placeholder: options.placeholder,
|
|
...defaultParams,
|
|
};
|
|
|
|
case 'user':
|
|
return {
|
|
placeholder: options.placeholder,
|
|
prefixIcon: options.prefix,
|
|
suffixIcon: options.suffix,
|
|
...defaultParams,
|
|
};
|
|
|
|
case 'computational':
|
|
return {
|
|
placeholder: options.placeholder,
|
|
prefixIcon: options.prefix,
|
|
addonBefore: options.addonBefore,
|
|
addonAfter: options.addonAfter,
|
|
computationalConfig: options.computationalConfig,
|
|
...defaultParams,
|
|
};
|
|
|
|
case 'money-chinese':
|
|
return {
|
|
placeholder: options.placeholder,
|
|
prefixIcon: options.prefix,
|
|
suffixIcon: options.suffix,
|
|
addonBefore: options.addonBefore,
|
|
addonAfter: options.addonAfter,
|
|
computationalConfig: options.computationalConfig,
|
|
...defaultParams,
|
|
};
|
|
case 'info':
|
|
return {
|
|
infoType: options.infoType,
|
|
loadAgain: options.loadAgain,
|
|
...defaultParams,
|
|
};
|
|
case 'button':
|
|
if (options.buttonType === 2) {
|
|
params.tableColumns = options.tableColumns;
|
|
}
|
|
if (options.buttonType === 1 || options.buttonType === 2) {
|
|
params.buttonType = options.buttonType;
|
|
if (options.datasourceType == 'dic') {
|
|
params.itemId = options.itemId;
|
|
params.map = {
|
|
text: options.labelField,
|
|
value: options.valueField,
|
|
};
|
|
params.associateOptions = [...options.dicOptions];
|
|
} else if (options.datasourceType == 'api') {
|
|
params.apiConfig = setApiConfig(options.apiConfig);
|
|
params.map = {
|
|
text: options.labelField,
|
|
value: options.valueField,
|
|
};
|
|
if (options.apiConfig?.outputParams) {
|
|
params.associateOptions = [...options.apiConfig.outputParams];
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
width: options.buttonWidth,
|
|
height: options.buttonHeight,
|
|
prefixIcon: options.prefix,
|
|
suffixIcon: options.suffix,
|
|
name: options.name,
|
|
...params,
|
|
...defaultParams,
|
|
};
|
|
case 'text':
|
|
return {
|
|
fontFamily: options.fontFamily,
|
|
fontSize: options.fontSize + 'px',
|
|
fontWeight: options.fontWeight,
|
|
color: options.color,
|
|
fontStyle: options.fontStyle,
|
|
align: options.align,
|
|
...defaultParams,
|
|
};
|
|
default:
|
|
return { ...defaultParams };
|
|
}
|
|
}
|
|
export function setApiConfig(config) {
|
|
const data: any = {};
|
|
data.method = config.method;
|
|
data.path = config.path;
|
|
data.requestParamsConfigs = [];
|
|
data.requestHeaderConfigs = [];
|
|
data.requestBodyConfigs = [];
|
|
if (config.apiParams) {
|
|
config.apiParams.forEach((o) => {
|
|
if (o.key == 1 && o.tableInfo?.length) {
|
|
o.tableInfo.forEach((element) => {
|
|
data.requestParamsConfigs.push({
|
|
name: element.name, //API入参名称
|
|
dataType: element.dataType, //API入参类型
|
|
assignmentType: element.bindType, //赋值类型
|
|
value: element.value, //值
|
|
config: '', //赋值配置
|
|
});
|
|
});
|
|
} else if (o.key == 2 && o.tableInfo?.length) {
|
|
o.tableInfo.forEach((element) => {
|
|
data.requestHeaderConfigs.push({
|
|
name: element.name, //API入参名称
|
|
dataType: element.dataType, //API入参类型
|
|
assignmentType: element.bindType, //赋值类型
|
|
value: element.value, //值
|
|
config: '', //赋值配置
|
|
});
|
|
});
|
|
} else if (o.key == 3 && o.tableInfo?.length) {
|
|
o.tableInfo.forEach((element) => {
|
|
data.requestBodyConfigs.push({
|
|
name: element.name, //API入参名称
|
|
dataType: element.dataType, //API入参类型
|
|
assignmentType: element.bindType, //赋值类型
|
|
value: element.value, //值
|
|
config: '', //赋值配置
|
|
});
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
function camelCaseOptionsField(options, type, convertCamel) {
|
|
if (convertCamel) {
|
|
if (options.dicOptions && options.dicOptions.length > 0) {
|
|
options.dicOptions.forEach((o) => {
|
|
o.bindField = camelCaseString(o.bindField);
|
|
});
|
|
}
|
|
if (options.tableColumns && options.tableColumns.length > 0) {
|
|
options.tableColumns.forEach((o) => {
|
|
o.bindField = camelCaseString(o.bindField);
|
|
o.bindTable = camelCaseString(o.bindTable);
|
|
});
|
|
}
|
|
if (options.apiConfig) {
|
|
if (options.apiConfig.apiParams?.length > 0) {
|
|
options.apiConfig.apiParams.forEach((o) => {
|
|
if (o.tableInfo?.length > 0) {
|
|
o.tableInfo.forEach((x) => {
|
|
if (x.bindType == 'data') {
|
|
const val = isValidJSON(x.value);
|
|
if (val && val.bindTable) {
|
|
val.bindTable = camelCaseString(val.bindTable);
|
|
}
|
|
if (val && val.bindField) {
|
|
val.bindField = camelCaseString(val.bindField);
|
|
}
|
|
x.value = JSON.stringify(val);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
if (options.apiConfig.outputParams?.length > 0) {
|
|
options.apiConfig.outputParams.forEach((o) => {
|
|
o.bindField = camelCaseString(o.bindField);
|
|
});
|
|
}
|
|
}
|
|
if (options.computationalConfig?.length > 0) {
|
|
options.computationalConfig.forEach((o) => {
|
|
o.bindField = camelCaseString(o.bindField);
|
|
o.bindTable = camelCaseString(o.bindTable);
|
|
});
|
|
}
|
|
if (options.address && type == 'map') {
|
|
options.address = camelCaseString(options.address);
|
|
}
|
|
if (options.latiAndLong && type == 'map') {
|
|
options.latiAndLong = camelCaseString(options.latiAndLong);
|
|
}
|
|
}
|
|
}
|