From 42951d01c3aa5aeb00453f6b1adc50ee49dc0082 Mon Sep 17 00:00:00 2001 From: liaoxuezhi <2betop.cn@gmail.com> Date: Thu, 16 Nov 2023 17:15:58 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20envOverwrite=20?= =?UTF-8?q?=E5=AD=98=E5=9C=A8=E5=89=AF=E4=BD=9C=E7=94=A8=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20(#8766)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-core/src/envOverwrite.ts | 35 +++++++++++++++----------- packages/amis-core/src/index.tsx | 2 +- packages/amis-core/src/utils/helper.ts | 35 ++++++++++++++------------ 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/packages/amis-core/src/envOverwrite.ts b/packages/amis-core/src/envOverwrite.ts index 3936ca6e5..8a9545c0b 100644 --- a/packages/amis-core/src/envOverwrite.ts +++ b/packages/amis-core/src/envOverwrite.ts @@ -2,26 +2,31 @@ * @file 用于在移动端或不同语言环境下使用不同配置 */ -import {findObjectsWithKey} from './utils/helper'; +import {JSONValueMap, findObjectsWithKey} from './utils/helper'; +import isPlainObject from 'lodash/isPlainObject'; const isMobile = (window as any).matchMedia?.('(max-width: 768px)').matches ? true : false; // 这里不能用 addSchemaFilter 是因为还需要更深层的替换,比如 select 里的 options export const envOverwrite = (schema: any, locale?: string) => { - if (locale) { - let schemaNodes = findObjectsWithKey(schema, locale); - for (let schemaNode of schemaNodes) { - Object.assign(schemaNode, schemaNode[locale]); - delete schemaNode[locale]; - } - } + return JSONValueMap( + schema, + (value: any) => { + if (!isPlainObject(value)) { + return value; + } - if (isMobile) { - let schemaNodes = findObjectsWithKey(schema, 'mobile'); - for (let schemaNode of schemaNodes) { - Object.assign(schemaNode, schemaNode['mobile']); - delete schemaNode['mobile']; - } - } + if (locale && value[locale]) { + const newValue = Object.assign({}, value, value[locale]); + delete newValue[locale]; + return newValue; + } else if (isMobile && value.mobile) { + const newValue = Object.assign({}, value, value.mobile); + delete newValue.mobile; + return newValue; + } + }, + true + ); }; diff --git a/packages/amis-core/src/index.tsx b/packages/amis-core/src/index.tsx index 0a7fe66aa..ec7e7137f 100644 --- a/packages/amis-core/src/index.tsx +++ b/packages/amis-core/src/index.tsx @@ -308,7 +308,7 @@ function AMISRenderer({ } // 根据环境覆盖 schema,这个要在最前面做,不然就无法覆盖 validations - envOverwrite(schema, locale); + schema = envOverwrite(schema, locale); schema = replaceText(schema, options.replaceText, env.replaceTextIgnoreKeys); return ( diff --git a/packages/amis-core/src/utils/helper.ts b/packages/amis-core/src/utils/helper.ts index e3fc1739c..b4fc9469b 100644 --- a/packages/amis-core/src/utils/helper.ts +++ b/packages/amis-core/src/utils/helper.ts @@ -1954,6 +1954,7 @@ export function JSONValueMap( host: Object, stack: Array ) => any, + deepFirst: boolean = false, stack: Array = [] ) { if (!isPlainObject(json) && !Array.isArray(json)) { @@ -1966,40 +1967,42 @@ export function JSONValueMap( host: any, stack: Array = [] ) => { - let maped: any = mapper(origin, key, host, stack); + if (deepFirst) { + const value = JSONValueMap(origin, mapper, deepFirst, stack); + return mapper(value, key, host, stack) ?? value; + } - if (maped === origin && (isPlainObject(origin) || Array.isArray(origin))) { - return JSONValueMap(origin, mapper, stack); + let maped: any = mapper(origin, key, host, stack) ?? origin; + + // 如果不是深度优先,上层的对象都修改了,就不继续递归进到新返回的对象了 + if (maped === origin) { + return JSONValueMap(origin, mapper, deepFirst, stack); } return maped; }; if (Array.isArray(json)) { - let flag = false; - let mapped = json.map((value, index) => { - let result: any = iterator(value, index, json, [json].concat(stack)); - if (result !== value) { - flag = true; - return result; - } - return value; + let modified = false; + let arr = json.map((value, index) => { + let newValue: any = iterator(value, index, json, [json].concat(stack)); + modified = modified || newValue !== value; + return newValue; }); - return flag ? mapped : json; + return modified ? arr : json; } - let flag = false; + let modified = false; const toUpdate: any = {}; Object.keys(json).forEach(key => { const value: any = json[key]; let result: any = iterator(value, key, json, [json].concat(stack)); if (result !== value) { - flag = true; + modified = true; toUpdate[key] = result; - return; } }); - return flag + return modified ? { ...json, ...toUpdate