mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-02 03:58:07 +08:00
fix: 模型表单无法编辑数据源配置; chore: 修复Form使用场景兼容逻辑执行环节错误问题
This commit is contained in:
parent
90ec85977d
commit
4e968e8e91
@ -1,11 +1,10 @@
|
||||
import cx from 'classnames';
|
||||
import flatten from 'lodash/flatten';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import {isObject, getRendererByName} from 'amis-core';
|
||||
import {isObject, getRendererByName, setVariable} from 'amis-core';
|
||||
import {
|
||||
BasePlugin,
|
||||
tipedLabel,
|
||||
getI18nEnabled,
|
||||
ChangeEventContext,
|
||||
BaseEventContext,
|
||||
PluginEvent,
|
||||
@ -31,6 +30,7 @@ import {
|
||||
import {FormOperatorMap} from '../../builder/constants';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import {FieldSetting} from '../../renderer/FieldSetting';
|
||||
import {_isModelComp} from '../../util';
|
||||
|
||||
import type {FormSchema} from 'amis/lib/Schema';
|
||||
import type {
|
||||
@ -591,6 +591,29 @@ export class FormPlugin extends BasePlugin {
|
||||
this._dynamicControls = {...this._dynamicControls, ...controls};
|
||||
}
|
||||
|
||||
/** 获取可能的使用场景 */
|
||||
guessDSFeatFromSchema(schema: Record<string, any>): FormPluginFeat {
|
||||
const validFeat = [
|
||||
DSFeatureEnum.Insert,
|
||||
DSFeatureEnum.Edit,
|
||||
DSFeatureEnum.BulkEdit,
|
||||
DSFeatureEnum.View
|
||||
];
|
||||
if (schema.hasOwnProperty('feat')) {
|
||||
return validFeat.includes(schema.feat)
|
||||
? schema.feat
|
||||
: DSFeatureEnum.Insert;
|
||||
}
|
||||
|
||||
if (schema.initApi != null && schema.api != null) {
|
||||
return DSFeatureEnum.Edit;
|
||||
} else if (schema.initApi != null && schema.api == null) {
|
||||
return DSFeatureEnum.View;
|
||||
} else {
|
||||
return DSFeatureEnum.Insert;
|
||||
}
|
||||
}
|
||||
|
||||
panelBodyCreator = (context: BaseEventContext) => {
|
||||
const dc = this.dynamicControls;
|
||||
const builder = this.dsManager.getBuilderBySchema(context.schema);
|
||||
@ -611,25 +634,8 @@ export class FormPlugin extends BasePlugin {
|
||||
justify: true
|
||||
}
|
||||
});
|
||||
const i18nEnabled = getI18nEnabled();
|
||||
const schema = context?.node?.schema ?? context?.schema;
|
||||
/** 是否是模型表单 */
|
||||
const isModelForm =
|
||||
((typeof schema?.api === 'string'
|
||||
? schema.api
|
||||
: typeof schema?.api?.url === 'string'
|
||||
? schema.api.url
|
||||
: ''
|
||||
).startsWith('model://') ||
|
||||
(typeof schema?.initApi === 'string'
|
||||
? schema.initApi
|
||||
: typeof schema?.initApi?.url === 'string'
|
||||
? schema.initApi.url
|
||||
: ''
|
||||
).startsWith('model://')) &&
|
||||
!schema.api.strategy;
|
||||
|
||||
/** 数据源控件 */
|
||||
/** 新版数据源控件 */
|
||||
const generateDSControls = () => {
|
||||
const dsTypeSelector = this.dsManager.getDSSelectorSchema(
|
||||
{
|
||||
@ -714,14 +720,71 @@ export class FormPlugin extends BasePlugin {
|
||||
return [dsTypeSelector, ...dsSettings];
|
||||
};
|
||||
|
||||
return [
|
||||
getSchemaTpl('tabs', [
|
||||
/** 数据源 */
|
||||
const generateDSCollapse = () => {
|
||||
if (isCRUDFilter) {
|
||||
/** CRUD查询表头数据源交给CRUD托管 */
|
||||
return null;
|
||||
} else if (_isModelComp(schema)) {
|
||||
/** 模型组件使用旧版数据源配置 */
|
||||
return {
|
||||
title: '数据源',
|
||||
body: [
|
||||
getSchemaTpl('apiControl', {
|
||||
label: '保存接口',
|
||||
sampleBuilder: () => {
|
||||
return `{\n "status": 0,\n "msg": "",\n // 可以不返回,如果返回了数据将被 merge 进来。\n data: {}\n}`;
|
||||
}
|
||||
}),
|
||||
getSchemaTpl('apiControl', {
|
||||
name: 'asyncApi',
|
||||
label: tipedLabel(
|
||||
'异步检测接口',
|
||||
'设置此属性后,表单提交发送保存接口后,还会继续轮询请求该接口,直到返回 finished 属性为 true 才 结束'
|
||||
),
|
||||
visibleOn: 'data.asyncApi != null'
|
||||
}),
|
||||
getSchemaTpl('apiControl', {
|
||||
name: 'initAsyncApi',
|
||||
label: tipedLabel(
|
||||
'异步检测接口',
|
||||
'设置此属性后,表单请求 initApi 后,还会继续轮询请求该接口,直到返回 finished 属性为 true 才 结束'
|
||||
),
|
||||
visibleOn: 'data.initAsyncApi != null'
|
||||
}),
|
||||
getSchemaTpl('apiControl', {
|
||||
name: 'initApi',
|
||||
label: '初始化接口',
|
||||
sampleBuilder: () => {
|
||||
const data = {};
|
||||
const schema = context?.schema;
|
||||
|
||||
if (Array.isArray(schema?.body)) {
|
||||
schema.body.forEach((control: any) => {
|
||||
if (
|
||||
control.name &&
|
||||
!~['combo', 'input-array', 'form'].indexOf(control.type)
|
||||
) {
|
||||
setVariable(data, control.name, 'sample');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return JSON.stringify(
|
||||
{
|
||||
title: '属性',
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
isCRUDFilter || isModelForm
|
||||
? null
|
||||
: {
|
||||
status: 0,
|
||||
msg: '',
|
||||
data: data
|
||||
},
|
||||
null,
|
||||
2
|
||||
);
|
||||
}
|
||||
})
|
||||
]
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
title: '数据源',
|
||||
body: [
|
||||
{
|
||||
@ -736,15 +799,9 @@ export class FormPlugin extends BasePlugin {
|
||||
let feat = value;
|
||||
|
||||
if (!value) {
|
||||
feat =
|
||||
formStore?.data?.initApi != null
|
||||
? DSFeatureEnum.Edit
|
||||
: DSFeatureEnum.Insert;
|
||||
feat = this.guessDSFeatFromSchema(formStore?.data);
|
||||
}
|
||||
|
||||
/** 存量数据可能未设置过feat, 需要在数据域中 set 一下 */
|
||||
formStore.setValueByName('feat', feat);
|
||||
|
||||
return feat;
|
||||
},
|
||||
onChange: (
|
||||
@ -768,7 +825,18 @@ export class FormPlugin extends BasePlugin {
|
||||
},
|
||||
...generateDSControls()
|
||||
]
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return [
|
||||
getSchemaTpl('tabs', [
|
||||
{
|
||||
title: '属性',
|
||||
body: getSchemaTpl(
|
||||
'collapseGroup',
|
||||
[
|
||||
generateDSCollapse(),
|
||||
{
|
||||
title: '基本',
|
||||
body: [
|
||||
@ -817,13 +885,16 @@ export class FormPlugin extends BasePlugin {
|
||||
items: {
|
||||
type: 'input-text',
|
||||
placeholder: '请输入字段名',
|
||||
options: flatten(schema?.body ?? schema?.controls ?? [])
|
||||
options: flatten(
|
||||
schema?.body ?? schema?.controls ?? []
|
||||
)
|
||||
.map((item: Record<string, any>) => {
|
||||
const isFormItem = getRendererByName(
|
||||
item?.type
|
||||
)?.isFormItem;
|
||||
|
||||
return isFormItem && typeof item?.name === 'string'
|
||||
return isFormItem &&
|
||||
typeof item?.name === 'string'
|
||||
? {label: item.name, value: item.name}
|
||||
: false;
|
||||
})
|
||||
@ -993,11 +1064,15 @@ export class FormPlugin extends BasePlugin {
|
||||
body: [
|
||||
getSchemaTpl('switch', {
|
||||
name: 'debug',
|
||||
label: tipedLabel('开启调试', '在表单顶部显示当前表单的数据')
|
||||
label: tipedLabel(
|
||||
'开启调试',
|
||||
'在表单顶部显示当前表单的数据'
|
||||
)
|
||||
})
|
||||
]
|
||||
}
|
||||
])
|
||||
].filter(Boolean)
|
||||
)
|
||||
},
|
||||
{
|
||||
title: '外观',
|
||||
@ -1184,7 +1259,11 @@ export class FormPlugin extends BasePlugin {
|
||||
* 为了让 form 的按钮可以点击编辑
|
||||
*/
|
||||
patchSchema(schema: Schema, info: RendererConfig, props: any) {
|
||||
let shouldUpdateSchema = false;
|
||||
let patchedSchema: Schema = {...schema};
|
||||
|
||||
if (
|
||||
!(
|
||||
Array.isArray(schema.actions) ||
|
||||
schema.wrapWithPanel === false ||
|
||||
(Array.isArray(schema.body) &&
|
||||
@ -1197,23 +1276,38 @@ export class FormPlugin extends BasePlugin {
|
||||
(item as any).type
|
||||
)
|
||||
))
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
...schema,
|
||||
shouldUpdateSchema = true;
|
||||
patchedSchema = {
|
||||
...patchedSchema,
|
||||
actions: [
|
||||
{
|
||||
type: 'submit',
|
||||
label:
|
||||
props?.translate(props?.submitText) || schema.submitText || '提交',
|
||||
props?.translate(props?.submitText) ||
|
||||
schema.submitText ||
|
||||
'提交',
|
||||
primary: true
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
if (!_isModelComp(schema)) {
|
||||
/** 存量数据可能未设置过feat, 需要添加一下 */
|
||||
if (!schema.feat) {
|
||||
shouldUpdateSchema = true;
|
||||
patchedSchema = {
|
||||
...patchedSchema,
|
||||
feat: this.guessDSFeatFromSchema(schema)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return shouldUpdateSchema ? patchedSchema : undefined;
|
||||
}
|
||||
|
||||
async getAvailableContextFields(
|
||||
scopeNode: EditorNodeType,
|
||||
target: EditorNodeType,
|
||||
|
@ -80,3 +80,39 @@ export function escapeFormula(conf: any, keys: string[] = ['tpl']) {
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断给定的 schema 是否为 model 组件
|
||||
*
|
||||
* @param schema schema 对象
|
||||
* @returns 如果给定的 schema 是 model 组件则返回 true,否则返回 false
|
||||
*/
|
||||
export function _isModelComp(schema: Record<string, any>): boolean {
|
||||
if (!schema) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
schema.hasOwnProperty('$$m') &&
|
||||
(schema.$$m?.type === 'list' || schema.$$m?.type === 'form')
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const extraEvaluation = ['source', 'api', 'initApi'].some(key => {
|
||||
if (schema?.[key] && typeof schema[key] === 'string') {
|
||||
return schema?.[key].startsWith('model://');
|
||||
}
|
||||
|
||||
if (schema?.[key]?.url && typeof schema[key].url === 'string') {
|
||||
return (
|
||||
schema[key].url.startsWith('model://') &&
|
||||
!schema[key].hasOwnProperty('strategy')
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
return extraEvaluation;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user