import type { ComponentType } from '@jnpf/ui/form';
|
|
import { defineComponent, getCurrentInstance, h, nextTick, onMounted, ref, unref } from 'vue';
|
|
import { componentMap } from '@jnpf/ui/form';
|
|
import { cloneDeep, upperFirst } from 'lodash-es';
|
|
import InputTable from '#/components/InputTable/src/InputTable.vue';
|
|
import { getRealProps } from './transform';
|
|
export default defineComponent({
|
props: {
|
conf: {
|
type: Object,
|
required: true,
|
},
|
formData: {
|
type: Object,
|
default: () => {},
|
},
|
size: {
|
type: String,
|
default: 'default',
|
},
|
relations: Object,
|
},
|
setup(props, { emit, expose }) {
|
const tableRef = ref<any>(null);
|
|
expose({ tableRef });
|
function buildVModel(dataObject, defaultValue) {
|
dataObject.value = defaultValue;
|
const obj = dataObject.on ?? {};
|
obj['update:value'] = (val) => {
|
emit('update:value', val);
|
};
|
dataObject.on = obj;
|
}
|
|
function emitEvents(confClone) {
|
['on', 'nativeOn'].forEach((attr) => {
|
const eventKeyList = Object.keys(confClone[attr] || {});
|
eventKeyList.forEach((key) => {
|
if (typeof key === 'string') {
|
confClone[attr][key] = (...arg) => emit(key, arg);
|
}
|
});
|
});
|
}
|
|
function buildDataObject(confClone, dataObject, formData) {
|
const jnpfKey = confClone.__config__.jnpfKey;
|
Object.keys(confClone).forEach((key) => {
|
const val = confClone[key];
|
if (key === '__vModel__') {
|
buildVModel(dataObject, confClone.__config__.defaultValue);
|
} else if (dataObject[key] === undefined) {
|
dataObject[key] = val;
|
} else {
|
if (dataObject[key] === null || dataObject[key] instanceof RegExp || ['boolean', 'function', 'number', 'string'].includes(typeof dataObject[key])) {
|
dataObject[key] = val;
|
} else if (Array.isArray(dataObject[key])) {
|
dataObject[key] = [...dataObject[key], ...val];
|
} else {
|
dataObject[key] = { ...dataObject[key], ...val };
|
}
|
}
|
});
|
if (['autoComplete', 'barcode', 'calculate', 'dateCalculate', 'popupSelect', 'popupTableSelect', 'qrcode', 'table'].includes(jnpfKey)) {
|
dataObject.formData = formData;
|
}
|
if (['table'].includes(jnpfKey)) {
|
dataObject.relations = props.relations;
|
dataObject.vModel = confClone.__vModel__;
|
dataObject.ref = 'tableRef';
|
}
|
if (['popupSelect', 'relationForm'].includes(jnpfKey)) {
|
dataObject.field = confClone.__config__.tableName
|
? `${confClone.__vModel__}_jnpfTable_${confClone.__config__.tableName}${confClone.__config__.isSubTable ? '0' : '1'}`
|
: confClone.__vModel__;
|
if (confClone.__config__.isSubTable) delete dataObject.extraOptions;
|
}
|
// 清理属性
|
clearAttrs(dataObject);
|
}
|
|
function clearAttrs(dataObject) {
|
delete dataObject.__config__;
|
delete dataObject.__slot__;
|
delete dataObject.__methods__;
|
delete dataObject.on;
|
}
|
onMounted(() => {
|
const instance = getCurrentInstance();
|
nextTick(() => {
|
tableRef.value = unref(instance?.refs?.tableRef);
|
});
|
componentMap.set('InputTable', InputTable);
|
});
|
|
return () => {
|
const dataObject = {};
|
const confClone = cloneDeep(props.conf);
|
// 将字符串类型的事件,发送为消息
|
emitEvents(confClone);
|
// 将json表单配置转化为vue render可以识别的数据对象(dataObject)
|
buildDataObject(confClone, dataObject, props.formData);
|
const jnpfKey = upperFirst(props.conf.__config__.jnpfKey) === 'Table' ? 'InputTable' : upperFirst(props.conf.__config__.jnpfKey);
|
const Comp = componentMap.get(jnpfKey as ComponentType) as ReturnType<typeof defineComponent>;
|
if (!Comp) return null;
|
const realDataObject = getRealProps(dataObject, props.conf.__config__.jnpfKey);
|
return h(Comp, realDataObject as any);
|
};
|
},
|
});
|