From 9e1d9a92f7347f83ae8228674f4805c6a258ba64 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Fri, 21 Feb 2025 11:36:04 +0800 Subject: [PATCH 001/153] =?UTF-8?q?feature:=201=E3=80=81=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E7=AE=80=E5=8C=96=E7=89=88ButtonGroup=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=EF=BC=9B2=E3=80=81=E8=A1=A5=E5=85=85=E6=A0=B8=E5=BF=83?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E7=9A=84Schema=E5=92=8CPropResolver=EF=BC=9B?= =?UTF-8?q?3=E3=80=81=E5=AE=9E=E7=8E=B0DynamicView=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + .ls-lint.yml | 1 + .../components/button-group/index.ts | 19 ++ .../src/button-group.component.tsx | 42 +++ .../button-group/src/button-group.props.ts | 39 +++ .../button-group/src/button-group.scss | 9 + .../src/schema/button-group.schema.json | 53 +++ .../button-group/src/schema/schema-mapper.ts | 5 + .../src/schema/schema-resolver.ts | 5 + .../mobile-ui-vue/components/button/index.ts | 15 +- .../components/button/src/button.props.ts | 11 + .../button/src/schema/button.schema.json | 57 ++++ .../button/src/schema/schema-mapper.ts | 6 + .../button/src/schema/schema-resolver.ts | 5 + .../components/component/index.ts | 35 ++ .../component/src/component.component.tsx | 25 ++ .../component/src/component.props.ts | 41 +++ .../src/schema/component.schema.json | 63 ++++ .../component/src/schema/schema-mapper.ts | 5 + .../component/src/schema/schema-resolver.ts | 5 + .../components/content-container/index.ts | 21 ++ .../src/content-container.component.tsx | 27 ++ .../src/content-container.props.ts | 21 ++ .../src/content-container.scss | 0 .../src/schema/content-container.schema.json | 41 +++ .../src/schema/schema-mapper.ts | 5 + .../src/schema/schema-resolver.ts | 5 + .../designer-canvas/src/components/maps.ts | 4 +- .../src/composition/use-type-resolver.ts | 17 +- .../components/dynamic-view/index.ts | 1 - .../dynamic-view/src/callback-deliver.ts | 10 - .../dynamic-view/src/components/maps.ts | 20 -- .../dynamic-view/src/composition/index.ts | 3 - .../src/composition/use-binding-data.ts | 20 -- .../src/composition/use-component-manager.ts | 51 --- .../src/composition/use-entity-resolver.ts | 69 ---- .../src/composition/use-entity-state.ts | 32 -- .../src/composition/use-entity.ts | 34 -- .../src/composition/use-field-resolver.ts | 50 --- .../src/composition/use-form-schema.ts | 11 - .../src/dynamic-view.component.tsx | 312 +++--------------- .../dynamic-view/src/dynamic-view.props.ts | 20 +- .../dynamic-view/src/event-dispatcher.ts | 16 - .../components/dynamic-view/src/types.ts | 83 ----- .../components/float-container/index.ts | 20 ++ .../src/float-container.component.tsx | 23 ++ .../src/float-container.props.ts | 20 ++ .../float-container/src/float-container.scss | 5 + .../src/schema/float-container.schema.json | 41 +++ .../src/schema/schema-mapper.ts | 5 + .../src/schema/schema-resolver.ts | 5 + .../components/form-item/index.ts | 12 +- .../form-item/src/form-item.props.ts | 14 +- .../form-item/src/form.component.tsx | 19 +- .../components/form-item/src/form.props.ts | 20 +- .../components/form-item/src/form.scss | 4 + .../src/schema/form-item-schema-mapper.ts | 5 + .../src/schema/form-item-schema-resolver.ts | 5 + .../src/schema/form-item.schema.json | 46 +++ .../src/schema/form-schema-mapper.ts | 5 + .../src/schema/form-schema-resolver.ts | 5 + .../form-item/src/schema/form.schema.json | 41 +++ .../mobile-ui-vue/components/form/index.ts | 33 +- packages/mobile-ui-vue/components/index.scss | 2 + packages/mobile-ui-vue/components/index.ts | 56 ++-- .../components/input-group/index.ts | 13 +- .../input-group/src/input-group.props.ts | 12 +- .../src/schema/input-group.schema.json | 48 +++ .../input-group/src/schema/schema-mapper.ts | 6 + .../input-group/src/schema/schema-resolver.ts | 5 + .../components/list-view/index.ts | 10 +- .../list-view/src/list-view.props.ts | 2 +- .../src/schema/list-view.schema.json | 78 +---- .../list-view/src/schema/schema-mapper.ts | 4 +- .../mobile-ui-vue/components/navbar/index.ts | 7 + .../navbar/src/navbar.component.tsx | 4 +- .../components/navbar/src/navbar.props.ts | 12 + .../navbar/src/schema/navbar.schema.json | 45 +++ .../navbar/src/schema/schema-mapper.ts | 5 + .../navbar/src/schema/schema-resolver.ts | 5 + .../components/page-body-container/index.ts | 26 +- .../src/page-body-container.component.tsx | 2 +- .../schema/page-body-container.schema.json | 18 - .../components/page-container/index.ts | 31 +- .../src/schema/page-container.schema.json | 18 - .../components/page-footer-container/index.ts | 31 +- .../components/page-header-container/index.ts | 32 +- .../schema/page-header-container.schema.json | 18 - packages/mobile-ui-vue/components/register.ts | 45 +++ packages/mobile-ui-vue/package.json | 5 +- 90 files changed, 1252 insertions(+), 932 deletions(-) create mode 100644 packages/mobile-ui-vue/components/button-group/index.ts create mode 100644 packages/mobile-ui-vue/components/button-group/src/button-group.component.tsx create mode 100644 packages/mobile-ui-vue/components/button-group/src/button-group.props.ts create mode 100644 packages/mobile-ui-vue/components/button-group/src/button-group.scss create mode 100644 packages/mobile-ui-vue/components/button-group/src/schema/button-group.schema.json create mode 100644 packages/mobile-ui-vue/components/button-group/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/button-group/src/schema/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/button/src/schema/button.schema.json create mode 100644 packages/mobile-ui-vue/components/button/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/button/src/schema/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/component/index.ts create mode 100644 packages/mobile-ui-vue/components/component/src/component.component.tsx create mode 100644 packages/mobile-ui-vue/components/component/src/component.props.ts create mode 100644 packages/mobile-ui-vue/components/component/src/schema/component.schema.json create mode 100644 packages/mobile-ui-vue/components/component/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/component/src/schema/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/content-container/index.ts create mode 100644 packages/mobile-ui-vue/components/content-container/src/content-container.component.tsx create mode 100644 packages/mobile-ui-vue/components/content-container/src/content-container.props.ts create mode 100644 packages/mobile-ui-vue/components/content-container/src/content-container.scss create mode 100644 packages/mobile-ui-vue/components/content-container/src/schema/content-container.schema.json create mode 100644 packages/mobile-ui-vue/components/content-container/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/content-container/src/schema/schema-resolver.ts delete mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/callback-deliver.ts delete mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/components/maps.ts delete mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/index.ts delete mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/use-binding-data.ts delete mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/use-component-manager.ts delete mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-resolver.ts delete mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-state.ts delete mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity.ts delete mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/use-field-resolver.ts delete mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/use-form-schema.ts delete mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/event-dispatcher.ts delete mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/types.ts create mode 100644 packages/mobile-ui-vue/components/float-container/index.ts create mode 100644 packages/mobile-ui-vue/components/float-container/src/float-container.component.tsx create mode 100644 packages/mobile-ui-vue/components/float-container/src/float-container.props.ts create mode 100644 packages/mobile-ui-vue/components/float-container/src/float-container.scss create mode 100644 packages/mobile-ui-vue/components/float-container/src/schema/float-container.schema.json create mode 100644 packages/mobile-ui-vue/components/float-container/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/float-container/src/schema/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/form-item/src/form.scss create mode 100644 packages/mobile-ui-vue/components/form-item/src/schema/form-item-schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/form-item/src/schema/form-item-schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/form-item/src/schema/form-item.schema.json create mode 100644 packages/mobile-ui-vue/components/form-item/src/schema/form-schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/form-item/src/schema/form-schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/form-item/src/schema/form.schema.json create mode 100644 packages/mobile-ui-vue/components/input-group/src/schema/input-group.schema.json create mode 100644 packages/mobile-ui-vue/components/input-group/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/input-group/src/schema/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/navbar/src/schema/navbar.schema.json create mode 100644 packages/mobile-ui-vue/components/navbar/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/navbar/src/schema/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/register.ts diff --git a/.gitignore b/.gitignore index f7117ac51eb..cf124b19a13 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ dist-ssr /packages/ui-binding/package /packages/logger/package /packages/ui-vue/theme-default +/packages/mobile-ui-vue/package +/packages/mobile-command-services/package diff --git a/.ls-lint.yml b/.ls-lint.yml index 8136c908ed8..f3d8f63766f 100644 --- a/.ls-lint.yml +++ b/.ls-lint.yml @@ -104,6 +104,7 @@ ignore: - packages/mobile-command-services/public - packages/mobile-command-services/src - packages/mobile-command-services/lib + - packages/mobile-command-services/package - packages/mobile-command-services/test # cli - packages/cli/.vscode diff --git a/packages/mobile-ui-vue/components/button-group/index.ts b/packages/mobile-ui-vue/components/button-group/index.ts new file mode 100644 index 00000000000..3f23dc6f68c --- /dev/null +++ b/packages/mobile-ui-vue/components/button-group/index.ts @@ -0,0 +1,19 @@ +import { Plugin } from 'vue'; +import { withInstall } from '@components/common'; +import ButtonGroupInstallless from './src/button-group.component'; +import { propsResolver } from './src/button-group.props'; + +const BUTTON_GROUP_REGISTERED_NAME = 'button-group'; + +const ButtonGroup = withInstall(ButtonGroupInstallless); +ButtonGroup.register = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[BUTTON_GROUP_REGISTERED_NAME] = ButtonGroup; + propsResolverMap[BUTTON_GROUP_REGISTERED_NAME] = propsResolver; +}; + +export * from './src/button-group.props'; +export { ButtonGroup }; +export default ButtonGroup as typeof ButtonGroup & Plugin; diff --git a/packages/mobile-ui-vue/components/button-group/src/button-group.component.tsx b/packages/mobile-ui-vue/components/button-group/src/button-group.component.tsx new file mode 100644 index 00000000000..3fb47cbd965 --- /dev/null +++ b/packages/mobile-ui-vue/components/button-group/src/button-group.component.tsx @@ -0,0 +1,42 @@ +import { defineComponent } from 'vue'; +import { useBem } from '@components/common'; +import FButton from '@components/button'; +import { BUTTON_GROUP_NAME, ButtonItem, ButtonGroupProps, buttonGroupProps } from './button-group.props'; + +export default defineComponent({ + name: BUTTON_GROUP_NAME, + props: buttonGroupProps, + emits: ['click'], + setup(props: ButtonGroupProps, context) { + const { bem } = useBem(BUTTON_GROUP_NAME); + const buttonGroupClass = { + [bem()]: true + }; + const buttonItemClass = { + [bem('item')]: true + }; + + const buttonItems = props.items || []; + + /** + * 渲染按钮集合 + */ + const renderItem = (buttonItem: ButtonItem) => { + return ( +
+ {buttonItem.text} +
+ ); + }; + + return () => ( +
+ {buttonItems.map((buttonItem) => renderItem(buttonItem))} +
+ ); + } +}); diff --git a/packages/mobile-ui-vue/components/button-group/src/button-group.props.ts b/packages/mobile-ui-vue/components/button-group/src/button-group.props.ts new file mode 100644 index 00000000000..a62c4adbf71 --- /dev/null +++ b/packages/mobile-ui-vue/components/button-group/src/button-group.props.ts @@ -0,0 +1,39 @@ +import { ExtractPropTypes, PropType } from 'vue'; +import { createPropsResolver } from '@components/dynamic-resolver'; +import { ButtonProps } from '@components/button/src/button.props'; +import buttonSchema from './schema/button-group.schema.json'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; + +/** + * 组件名称 + */ +export const BUTTON_GROUP_NAME = 'fm-button-group'; + +/** + * 按钮项类型 + */ +export type ButtonItem = ButtonProps & { text: string, onClick: ()=>void }; + +/** + * 按钮组属性 + */ +export const buttonGroupProps = { + + /** + * 按钮项集合 + */ + items: { type: Array, default: [] } +}; + +/** + * 按钮组属性处理器 + */ +export const propsResolver = createPropsResolver( + buttonGroupProps, + buttonSchema, + schemaMapper, + schemaResolver +); + +export type ButtonGroupProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/button-group/src/button-group.scss b/packages/mobile-ui-vue/components/button-group/src/button-group.scss new file mode 100644 index 00000000000..223cc0a8fe6 --- /dev/null +++ b/packages/mobile-ui-vue/components/button-group/src/button-group.scss @@ -0,0 +1,9 @@ +.fm-button-group { + display: flex; + padding: 8px 16px; + + &__item { + display: flex; + flex: 1; + } +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/button-group/src/schema/button-group.schema.json b/packages/mobile-ui-vue/components/button-group/src/schema/button-group.schema.json new file mode 100644 index 00000000000..995a80cd08c --- /dev/null +++ b/packages/mobile-ui-vue/components/button-group/src/schema/button-group.schema.json @@ -0,0 +1,53 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/button-group.schema.json", + "title": "button-group", + "description": "", + "type": "object", + "properties": { + "id": { + "description": "唯一标志", + "type": "string" + }, + "type": { + "description": "组件类型", + "type": "string", + "default": "button-group" + }, + "appearance": { + "description": "外观", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "items": { + "description": "按钮项集合", + "type": "array", + "items": { + "type": "object", + "properties": { + "text": { + "type": "string" + }, + "onClick": { + "type": "string" + } + }, + "events": [ + "onClick" + ] + } + } + }, + "required": [ + "id", + "type" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/button-group/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/button-group/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..47415f8117f --- /dev/null +++ b/packages/mobile-ui-vue/components/button-group/src/schema/schema-mapper.ts @@ -0,0 +1,5 @@ +import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance], +]); diff --git a/packages/mobile-ui-vue/components/button-group/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/button-group/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..c1bf8da88a0 --- /dev/null +++ b/packages/mobile-ui-vue/components/button-group/src/schema/schema-resolver.ts @@ -0,0 +1,5 @@ +import { DynamicResolver } from "../../../dynamic-resolver"; + +export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { + return schema; +} diff --git a/packages/mobile-ui-vue/components/button/index.ts b/packages/mobile-ui-vue/components/button/index.ts index dac023b9dc6..f211334c44a 100644 --- a/packages/mobile-ui-vue/components/button/index.ts +++ b/packages/mobile-ui-vue/components/button/index.ts @@ -1,7 +1,18 @@ -import { withInstall } from '@components/common'; +import { Plugin } from 'vue'; +import { withInstall, } from '@components/common'; import ButtonInstallless from './src/button.component'; +import { propsResolver } from './src/button.props'; + +const BUTTON_REGISTERED_NAME = 'button'; const Button = withInstall(ButtonInstallless); +Button.register = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[BUTTON_REGISTERED_NAME] = Button; + propsResolverMap[BUTTON_REGISTERED_NAME] = propsResolver; +}; export { Button }; -export default Button; +export default Button as typeof Button & Plugin; diff --git a/packages/mobile-ui-vue/components/button/src/button.props.ts b/packages/mobile-ui-vue/components/button/src/button.props.ts index 4638cdb4869..e1e378f497a 100644 --- a/packages/mobile-ui-vue/components/button/src/button.props.ts +++ b/packages/mobile-ui-vue/components/button/src/button.props.ts @@ -1,4 +1,8 @@ import { ExtractPropTypes, PropType } from 'vue'; +import { createPropsResolver } from '../../dynamic-resolver'; +import buttonSchema from './schema/button.schema.json'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; type ButtonType = 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info'; type SizeType = 'large' | 'normal' | 'small' | 'mini'; @@ -53,3 +57,10 @@ export const buttonProps = { }; export type ButtonProps = ExtractPropTypes; + +export const propsResolver = createPropsResolver( + buttonProps, + buttonSchema, + schemaMapper, + schemaResolver +); diff --git a/packages/mobile-ui-vue/components/button/src/schema/button.schema.json b/packages/mobile-ui-vue/components/button/src/schema/button.schema.json new file mode 100644 index 00000000000..3109eabb1fb --- /dev/null +++ b/packages/mobile-ui-vue/components/button/src/schema/button.schema.json @@ -0,0 +1,57 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/button.schema.json", + "title": "button", + "description": "", + "type": "object", + "properties": { + "id": { + "description": "唯一标志", + "type": "string" + }, + "type": { + "description": "组件类型", + "type": "string", + "default": "button" + }, + "displayType": { + "description": "显示类型", + "type": "string", + "default": "default" + }, + "icon": { + "description": "图标", + "type": "string", + "default": null + }, + "round": { + "description": "是否为圆形", + "type": "boolean", + "default": false, + "isEvent": true + }, + "appearance": { + "description": "外观", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "onClick": { + "type": "string" + } + }, + "events": [ + "onClick" + ], + "required": [ + "id", + "type" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/button/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/button/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..1a9e31c13af --- /dev/null +++ b/packages/mobile-ui-vue/components/button/src/schema/schema-mapper.ts @@ -0,0 +1,6 @@ +import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance], + ['displayType', 'type'] +]); diff --git a/packages/mobile-ui-vue/components/button/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/button/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..c1bf8da88a0 --- /dev/null +++ b/packages/mobile-ui-vue/components/button/src/schema/schema-resolver.ts @@ -0,0 +1,5 @@ +import { DynamicResolver } from "../../../dynamic-resolver"; + +export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { + return schema; +} diff --git a/packages/mobile-ui-vue/components/component/index.ts b/packages/mobile-ui-vue/components/component/index.ts new file mode 100644 index 00000000000..cba22460cb6 --- /dev/null +++ b/packages/mobile-ui-vue/components/component/index.ts @@ -0,0 +1,35 @@ + +/** + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import type { Plugin } from 'vue'; +import { withInstall } from '@components/common'; +import ComponentInstallless from './src/component.component'; +import { propsResolver } from './src/component.props'; + +const COMPONENT_REGISTERED_NAME = 'component'; + +const Component = withInstall(ComponentInstallless); +Component.register = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[COMPONENT_REGISTERED_NAME] = Component; + propsResolverMap[COMPONENT_REGISTERED_NAME] = propsResolver; +}; + +export * from './src/component.props'; +export { Component }; +export default Component as typeof Component & Plugin; diff --git a/packages/mobile-ui-vue/components/component/src/component.component.tsx b/packages/mobile-ui-vue/components/component/src/component.component.tsx new file mode 100644 index 00000000000..33388fa3006 --- /dev/null +++ b/packages/mobile-ui-vue/components/component/src/component.component.tsx @@ -0,0 +1,25 @@ +import { SetupContext, defineComponent, onBeforeMount, computed } from 'vue'; +import { COMPONENT_NAME, ComponentPropsType, componentProps } from './component.props'; + +export default defineComponent({ + name: COMPONENT_NAME, + props: componentProps, + emits: ['init'], + setup(props: ComponentPropsType, context: SetupContext) { + + onBeforeMount(() => { + context.emit('init', props.id); + }); + + const componentClass = computed(() => ({ + ['fm-page']: props.componentType === 'Page', + [props.customClass || '']: true, + })); + + return () => ( +
+ {context.slots.default && context.slots.default()} +
+ ); + } +}); diff --git a/packages/mobile-ui-vue/components/component/src/component.props.ts b/packages/mobile-ui-vue/components/component/src/component.props.ts new file mode 100644 index 00000000000..ab01ca66a48 --- /dev/null +++ b/packages/mobile-ui-vue/components/component/src/component.props.ts @@ -0,0 +1,41 @@ + +import { ExtractPropTypes } from 'vue'; +import { createPropsResolver } from '../../dynamic-resolver'; +import { schemaMapper } from './schema/schema-mapper'; +import componentSchema from './schema/component.schema.json'; +import { schemaResolver } from './schema/schema-resolver'; + +export const COMPONENT_NAME = 'fm-component'; + +/** + * 组件属性 + */ +export const componentProps = { + + /** 组件ID */ + id: { type: String }, + + /** 组件类型 */ + componentType: { type: String, default: '' }, + + /** 组件自定class */ + customClass: { type: String, default: '' }, + + /** 组件自定义样式 */ + customStyle: { type: String, default: '' } + +} as Record; + +/** + * 组件属性类型 + */ +export type ComponentPropsType = ExtractPropTypes; + +// 属性处理器 +export const propsResolver = createPropsResolver(componentProps, componentSchema, schemaMapper, schemaResolver); + +// 设计时属性 +export const componentDesignProps = Object.assign({}, componentProps, { componentId: { type: String, default: '' } }); +export type ComponentDesignPropsType = ExtractPropTypes; + + diff --git a/packages/mobile-ui-vue/components/component/src/schema/component.schema.json b/packages/mobile-ui-vue/components/component/src/schema/component.schema.json new file mode 100644 index 00000000000..915b307ce36 --- /dev/null +++ b/packages/mobile-ui-vue/components/component/src/schema/component.schema.json @@ -0,0 +1,63 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/component.schema.json", + "title": "component", + "description": "A Farris Visual Component", + "type": "object", + "properties": { + "id": { + "description": "组件唯一标志", + "type": "string" + }, + "type": { + "description": "组件类型", + "type": "string", + "default": "component" + }, + "componentType": { + "description": "组件具体类型", + "type": "string" + }, + "viewModel": { + "description": "组件对应的视图模型", + "type": "string" + }, + "appearance": { + "description": "组件外观", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "contents": { + "description": "组件下级节点", + "type": "array", + "default": [] + }, + "onInit": { + "description": "初始化事件", + "type": "string", + "default": "" + }, + "onLoadData": { + "description": "取数事件", + "type": "string", + "default": "" + } + }, + "events": [ + "onInit", + "onLoadData" + ], + "required": [ + "id", + "type", + "contents" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/component/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/component/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..90dc1493e55 --- /dev/null +++ b/packages/mobile-ui-vue/components/component/src/schema/schema-mapper.ts @@ -0,0 +1,5 @@ +import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance] +]); diff --git a/packages/mobile-ui-vue/components/component/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/component/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..c1bf8da88a0 --- /dev/null +++ b/packages/mobile-ui-vue/components/component/src/schema/schema-resolver.ts @@ -0,0 +1,5 @@ +import { DynamicResolver } from "../../../dynamic-resolver"; + +export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { + return schema; +} diff --git a/packages/mobile-ui-vue/components/content-container/index.ts b/packages/mobile-ui-vue/components/content-container/index.ts new file mode 100644 index 00000000000..c1fbc4d9104 --- /dev/null +++ b/packages/mobile-ui-vue/components/content-container/index.ts @@ -0,0 +1,21 @@ +import { App, Plugin } from 'vue'; +import FContentContainer from './src/content-container.component'; +import { propsResolver } from './src/content-container.props'; + +const CONTENT_CONTAINER_REGISTERED_NAME = 'content-container'; + +FContentContainer.install = (app: App) => { + app.component(FContentContainer.name as string, FContentContainer); +}; + +FContentContainer.register = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[CONTENT_CONTAINER_REGISTERED_NAME] = FContentContainer; + propsResolverMap[CONTENT_CONTAINER_REGISTERED_NAME] = propsResolver; +}; + +export * from './src/content-container.props'; +export { FContentContainer }; +export default FContentContainer as typeof FContentContainer & Plugin; diff --git a/packages/mobile-ui-vue/components/content-container/src/content-container.component.tsx b/packages/mobile-ui-vue/components/content-container/src/content-container.component.tsx new file mode 100644 index 00000000000..b1376f278cd --- /dev/null +++ b/packages/mobile-ui-vue/components/content-container/src/content-container.component.tsx @@ -0,0 +1,27 @@ +import { SetupContext, defineComponent, computed } from 'vue'; +import { CONTENT_CONTAINER_NAME, ContentContainerProps, contentContainerProps } from './content-container.props'; +import { useBem } from '../../common/index'; + +export default defineComponent({ + name: CONTENT_CONTAINER_NAME, + props: contentContainerProps, + emits: [], + setup(props: ContentContainerProps, context: SetupContext) { + const { bem } = useBem(CONTENT_CONTAINER_NAME); + + const containerClass = computed(() => ({ + [bem()]: true, + [props.customClass || '']: true, + })); + + const customStyle = computed(() => { + return props.customStyle; + }); + + return () => ( +
+ {context.slots.default && context.slots.default()} +
+ ); + } +}); diff --git a/packages/mobile-ui-vue/components/content-container/src/content-container.props.ts b/packages/mobile-ui-vue/components/content-container/src/content-container.props.ts new file mode 100644 index 00000000000..b356d338f5d --- /dev/null +++ b/packages/mobile-ui-vue/components/content-container/src/content-container.props.ts @@ -0,0 +1,21 @@ +import { ExtractPropTypes } from 'vue'; +import { createPropsResolver } from '../../dynamic-resolver'; +import contentContainerSchema from './schema/content-container.schema.json'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; + +export const CONTENT_CONTAINER_NAME = 'fm-content-container'; + +export const contentContainerProps = { + customClass: { type: String, default: '' }, + customStyle: { type: String, default: '' }, +}; + +export type ContentContainerProps = ExtractPropTypes; + +export const propsResolver = createPropsResolver( + contentContainerProps, + contentContainerSchema, + schemaMapper, + schemaResolver +); diff --git a/packages/mobile-ui-vue/components/content-container/src/content-container.scss b/packages/mobile-ui-vue/components/content-container/src/content-container.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/mobile-ui-vue/components/content-container/src/schema/content-container.schema.json b/packages/mobile-ui-vue/components/content-container/src/schema/content-container.schema.json new file mode 100644 index 00000000000..a082e40914e --- /dev/null +++ b/packages/mobile-ui-vue/components/content-container/src/schema/content-container.schema.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/content-container.schema.json", + "title": "content-container", + "description": "", + "type": "object", + "properties": { + "id": { + "description": "ID", + "type": "string" + }, + "type": { + "description": "类型", + "type": "string", + "default": "content-container" + }, + "appearance": { + "description": "外观", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "contents": { + "description": "子组件集合", + "type": "array", + "default": [] + } + }, + "required": [ + "id", + "type", + "contents" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/content-container/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/content-container/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..90dc1493e55 --- /dev/null +++ b/packages/mobile-ui-vue/components/content-container/src/schema/schema-mapper.ts @@ -0,0 +1,5 @@ +import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance] +]); diff --git a/packages/mobile-ui-vue/components/content-container/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/content-container/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..c1bf8da88a0 --- /dev/null +++ b/packages/mobile-ui-vue/components/content-container/src/schema/schema-resolver.ts @@ -0,0 +1,5 @@ +import { DynamicResolver } from "../../../dynamic-resolver"; + +export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { + return schema; +} diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/components/maps.ts b/packages/mobile-ui-vue/components/designer-canvas/src/components/maps.ts index bf45989af28..1a5e6de142d 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/components/maps.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/components/maps.ts @@ -23,8 +23,8 @@ function loadDesignerRegisterByComponents(components:any[]) { if (!hasLoaded) { hasLoaded = true; components.forEach(component => { - component.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter) - }) + component.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + }); } } diff --git a/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts b/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts index a76465116e5..2845948f29e 100644 --- a/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts @@ -1,29 +1,20 @@ import FInputGroup from '../../../input-group/src/input-group.component'; import { EditorType, EditorConfig } from "../types"; import { UseTypeResolver } from "./types"; -import { componentMap, componentPropsConverter, loadRegister } from '../../../dynamic-view/src/components/maps'; + +import { componentMap, propsConverterMap, registerComponents } from '../../../register'; export function useTypeResolver(): UseTypeResolver { - loadRegister(); + registerComponents(); function resolveEditorType(type: EditorType) { return componentMap[type] || FInputGroup; } function resolveEditorProps(type: EditorType, config: EditorConfig): Record { - const propsConverter = componentPropsConverter[type]; + const propsConverter = propsConverterMap[type]; const viewProps = propsConverter ? propsConverter(config) : {}; - // const Component = resolveEditorType(type); - // const componentPropertyProps = Object.keys(Component?.props || {}); - // const componentEventProps = (Component?.emits as string[] || []).map((eventName: string) => `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`); - // const currentComponentProps = componentPropertyProps.concat(componentEventProps); - // const componentProps = Object.keys(viewProps).reduce((props: Record, propertyName: string) => { - // if (currentComponentProps.indexOf(propertyName) !== -1) { - // props[propertyName] = viewProps[propertyName]; - // } - // return props; - // }, {}); return viewProps; } diff --git a/packages/mobile-ui-vue/components/dynamic-view/index.ts b/packages/mobile-ui-vue/components/dynamic-view/index.ts index 7b3e294e2e8..76d301e4aa9 100644 --- a/packages/mobile-ui-vue/components/dynamic-view/index.ts +++ b/packages/mobile-ui-vue/components/dynamic-view/index.ts @@ -2,7 +2,6 @@ import type { App } from 'vue'; import FDynamicView from './src/dynamic-view.component'; export * from './src/dynamic-view.props'; - export { FDynamicView }; export default { diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/callback-deliver.ts b/packages/mobile-ui-vue/components/dynamic-view/src/callback-deliver.ts deleted file mode 100644 index 77070fdc522..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-view/src/callback-deliver.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Caller } from "../../dynamic-resolver"; - -export function createCallbackDeliver(callback: (type: string, args: any[]) => any): Caller { - function call(methodName: string, payloads: any[]): any { - return callback(methodName, payloads); - } - return { - call - }; -} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/components/maps.ts b/packages/mobile-ui-vue/components/dynamic-view/src/components/maps.ts deleted file mode 100644 index d053ec61421..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-view/src/components/maps.ts +++ /dev/null @@ -1,20 +0,0 @@ - -// import FExternalContainer from '@/components/external-container'; - -const componentMap: Record = {}; -const componentPropsConverter: Record = {}; -const componentPropertyConfigConverter: Record = {}; -const resolverMap: Record = {}; - -let hasLoaded = false; - -// jumphere -function loadRegister() { - if (!hasLoaded) { - hasLoaded = true; - // FAvatar.register(componentMap, componentPropsConverter, componentPropertyConfigConverter, resolverMap); - - } -} - -export { componentMap, componentPropsConverter, loadRegister, resolverMap }; diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/index.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/index.ts deleted file mode 100644 index 9828d143ccb..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-view/src/composition/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './use-form-schema'; -export * from './use-binding-data'; -export * from './use-component-manager'; diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-binding-data.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-binding-data.ts deleted file mode 100644 index f569b2703ee..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-binding-data.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { BindingData } from "../../../dynamic-resolver"; -import { Ref, SetupContext } from "vue"; - -export function useBindingData(modelValue: Ref>, setupContext: SetupContext): BindingData { - function getValue(elementId: string) { - return modelValue.value && modelValue.value[elementId]; - } - - function setValue(elementId: string, field: string, value: any) { - if (modelValue.value) { - modelValue.value[elementId] = value; - } - setupContext.emit('update:modelValue', { elementId, field, value, modelValue: modelValue.value }); - } - - return { - getValue, - setValue - }; -} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-component-manager.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-component-manager.ts deleted file mode 100644 index 620a2057382..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-component-manager.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { UseComponentInstanceManager } from "../types"; - -export function useComponentManager(): UseComponentInstanceManager { - const instances: Map = new Map(); - - function register(id: string, instance: any) { - instances.set(id, instance); - } - - function get(id: string) { - const instance = instances.get(id); - if (!instance) { - console.warn(`Instance with id ${id} not found`); - return null; - } - return instance; - } - - function remove(id: string) { - instances.delete(id); - } - - function update(id: string, instance: any) { - if (!instances.has(id)) { - console.warn(`Instance with id ${id} not found`); - return; - } - instances.set(id, instance); - } - - function has(id: string): boolean { - return instances.has(id); - } - - function getAll(): Map { - return new Map(instances); - } - - function clear() { - instances.clear(); - } - return { - register, - get, - remove, - update, - has, - getAll, - clear - }; -} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-resolver.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-resolver.ts deleted file mode 100644 index 95169ec23fe..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-resolver.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* eslint-disable no-use-before-define */ -import { ResolvedEntity, EntitySchema, UseEntityResolver } from "../types"; -import { useFormSchema } from "./use-form-schema"; - -export function useEntityResolver(schema: Record): UseEntityResolver { - const { getSchemaEntity } = useFormSchema(schema); - function resolveEntityByDataSource(dataSource: string): ResolvedEntity | null { - const entity = getSchemaEntity(); - const entityInfo = resolveEntity(entity, dataSource); - return entityInfo; - } - function resolveEntities(entitySchema: EntitySchema): ResolvedEntity[] { - const result: ResolvedEntity[] = []; - function traverse(entity: EntitySchema, path: string[]) { - const currentPath = [...path, entity.label]; - const primary = entitySchema?.type?.primary || null; - if (primary) { - result.push({ - bindingPaths: currentPath, - primaryKey: entity.type.primary, - label: entity.label - }); - } - entity.type.entities.forEach(childEntity => { - traverse(childEntity, currentPath); - }); - } - const primary = entitySchema?.type?.primary || null; - if (!primary) { - return result; - } - result.push({ - bindingPaths: [], - primaryKey: entitySchema.type.primary, - label: entitySchema.label - }); - const childEntities = entitySchema?.type?.entities || []; - childEntities.forEach((entity) => { - traverse(entity, []); - }); - return result; - } - function resolveEntity(entity: Record, entityLabel: string, isRoot: boolean = true): ResolvedEntity | null { - const currentPath = isRoot ? [] : [entity.label]; - if (entity.label === entityLabel) { - return { - bindingPaths: currentPath, - primaryKey: entity.type.primary, - label: entity.label - }; - } - for (const childEntity of entity.type.entities) { - const result = resolveEntity(childEntity, entityLabel, false); - if (result) { - return { - bindingPaths: [...currentPath, ...result.bindingPaths], - primaryKey: result.primaryKey, - label: result.label - }; - } - } - return null; - } - return { - resolveEntityByDataSource, - resolveEntity, - resolveEntities - }; -} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-state.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-state.ts deleted file mode 100644 index 1255c85431e..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-state.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { EntityState, ResolvedEntity } from "../types"; -import { useEntityResolver } from "./use-entity-resolver"; -import { useFormSchema } from "./use-form-schema"; - -export function useEntityState(schema: Record) { - const bindingContexts: Record = {}; - const { getSchemaEntity } = useFormSchema(schema); - const { resolveEntities } = useEntityResolver(schema); - - function setup() { - const schemaEntity = getSchemaEntity(); - const entities = resolveEntities(schemaEntity); - entities.forEach((entity: ResolvedEntity) => { - const bindingPath = '/' + entity.bindingPaths.join('/'); - const { primaryKey } = entity; - const bindingContext: EntityState = { primaryKey, bindingPath, label: entity.label, currentId: null }; - bindingContexts[bindingPath] = bindingContext; - }); - } - function get(bindingPath: string | string[]): EntityState { - if (Array.isArray(bindingPath)) { - bindingPath = '/' + bindingPath.join('/'); - } else { - bindingPath = '/' + bindingPath.split('/').filter((item: any) => item).join('/'); - } - return bindingContexts[bindingPath]; - } - return { - setup, - get - }; -} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity.ts deleted file mode 100644 index bb3ba43b275..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { EntityState, ResolvedEntity } from "../types"; -import { useEntityResolver } from "./use-entity-resolver"; -import { useFormSchema } from "./use-form-schema"; - -export function useEntity(schema: Record) { - const bindingDataContexts: Record = {}; - const { getSchemaEntity } = useFormSchema(schema); - const { resolveEntities } = useEntityResolver(schema); - - function setup() { - const schemaEntity = getSchemaEntity(); - const entities = resolveEntities(schemaEntity); - entities.forEach((entity: ResolvedEntity) => { - const bindingPath = '/' + entity.bindingPaths.join('/'); - const { primaryKey } = entity; - const bindingContext: EntityState = { primaryKey, bindingPath, currentId: null, label: entity.label }; - // jumphere by sagi - bindingContext['dataSource'] = entity.label; - bindingDataContexts[bindingPath] = bindingContext; - }); - } - function get(bindingPath: string | string[]): EntityState { - if (Array.isArray(bindingPath)) { - bindingPath = '/' + bindingPath.join('/'); - } else { - bindingPath = '/' + bindingPath.split('/').filter((item: any) => item).join('/'); - } - return bindingDataContexts[bindingPath]; - } - return { - setup, - get - }; -} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-field-resolver.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-field-resolver.ts deleted file mode 100644 index 29206d38d88..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-field-resolver.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* eslint-disable no-use-before-define */ - -import { ResolvedEntityField, UseFieldResolver } from "../types"; -import { useFormSchema } from "./use-form-schema"; - -export function useFieldResolver(schema: Record): UseFieldResolver { - const { getSchemaEntity } = useFormSchema(schema); - function resolveFieldById(fieldId: string): ResolvedEntityField | null { - const entity = getSchemaEntity(); - const fieldInfo = resolveField(entity, fieldId); - return fieldInfo; - } - - function resolveField(entitySchema: Record, fieldId: string): ResolvedEntityField | null { - const { fields } = entitySchema.type; - for (const field of fields) { - if (field.id === fieldId) { - return { - id: field.id, - bindingPath: field.bindingPath, - require: field.require, - readonly: field.readonly, - multiLanguage: field.multiLanguage, - label: field.label, - dataSource: entitySchema.label - }; - } - if (field.type && field.type.fields) { - const result = resolveField({ type: field.type, label: entitySchema.label }, fieldId); - if (result) { - return result; - } - } - } - const { entities } = entitySchema.type; - if (!entities || entities.length < 1) { - return null; - } - for (const entity of entities) { - const result = resolveField(entity, fieldId); - if (result) { - return result; - } - } - return null; - } - return { - resolveFieldById - }; -} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-form-schema.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-form-schema.ts deleted file mode 100644 index f39c41aef55..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-form-schema.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { EntitySchema } from "../types"; - -export function useFormSchema(schema: Record) { - function getSchemaEntity(): EntitySchema { - return schema?.module?.entity[0]?.entities[0] || {}; - } - - return { - getSchemaEntity - }; -} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx b/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx index 2bf3634cc82..4f1569d3c01 100644 --- a/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx +++ b/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx @@ -1,291 +1,67 @@ -/* eslint-disable @typescript-eslint/no-unsafe-function-type */ -/* eslint-disable no-use-before-define */ -import { SetupContext, defineComponent, ref, watch, inject, createVNode, VNode } from 'vue'; -import { merge } from 'lodash-es'; -import { dynamicViewProps, DynamicViewProps } from './dynamic-view.props'; -import { componentMap, componentPropsConverter, loadRegister, resolverMap } from './components/maps'; -import { createEventsResolver, createFormBindingResolver, EditorResolver, SelectionItemResolver, UpdateColumnsResolver } from '../../dynamic-resolver'; -import { createEventDispatcher } from './event-dispatcher'; -import { useComponentManager } from './composition/use-component-manager'; -import { useBindingData } from './composition/use-binding-data'; -import { useEntityState } from './composition/use-entity-state'; -import { createCallbackDeliver } from './callback-deliver'; + +import { SetupContext, defineComponent, ref, watch, createVNode } from 'vue'; +import { componentMap, registerComponents, propsConverterMap } from '@components/register'; +import { DYNAMIC_VIEW_NAME, dynamicViewProps, DynamicViewProps } from './dynamic-view.props'; + +registerComponents(); const FDynamicView = defineComponent({ - name: 'FDynamicView', + name: DYNAMIC_VIEW_NAME, props: dynamicViewProps, - emits: ['update:modelValue', 'event', 'componentReady'], + emits: [], setup(props: DynamicViewProps, setupContext: SetupContext) { - const schema = ref(props.schema); - const modelValue = ref(props.modelValue); - const callback = ref(props.callback); - const schemaMap: Map = new Map(); - const dataSourceMap: Map = new Map(); - loadRegister(); - const componentManager = useComponentManager(); - const bindingData = useBindingData(modelValue, setupContext); - const entityState = useEntityState(schema.value); - entityState.setup(); - - function resolveModels(viewSchema: Record) { - const componentType = viewSchema.type; - const { dataSource, binding } = viewSchema; - if (!dataSource && !binding) { - return {}; - } - if (dataSource) { - dataSourceMap.set(dataSource, viewSchema); - } - const resolver = resolverMap[componentType]; - const bindingResolver = resolver && resolver.bindingResolver ? resolver.bindingResolver : createFormBindingResolver(); - return bindingResolver.resolve(viewSchema, bindingData); - } - - function renderSlots(slots?: Record) { - const result: Record = {}; - if (!slots) { - return result; - } - Object.entries(slots).forEach(([name, schema]) => { - result[name] = () => { - if (Array.isArray(schema)) { - return schema.map((schema: Record) => render(schema)); - } - return render(schema); - }; - }); - return result; - } - - function resolveCallbacks(viewSchema: Record) { - const componentKey = viewSchema.type; - const resolvers = resolverMap[componentKey]; - if (!resolvers || Object.keys(resolvers).length < 1) { - return {}; - } - const { callbackResolver } = resolvers; - if (!callbackResolver) { - return {}; - } - const callbackDeliver = createCallbackDeliver(callback.value); - return callbackResolver.resolve(viewSchema, callbackDeliver); - } - function resolveEvents(viewSchema: Record) { - const componentKey = viewSchema.type; - const eventDispatcher = createEventDispatcher(setupContext, viewSchema); - const Component = componentMap[componentKey]; - const eventResolver = createEventsResolver(); - const resolver = resolverMap[componentKey]; - const editorResolver: EditorResolver = resolver ? resolver.editorResolver : null; - if (editorResolver) { - const editor = editorResolver.resolve(viewSchema); - const componentType = editor.type; - const Editor = componentMap[componentType]; - const eventProps = eventResolver ? eventResolver(Editor, viewSchema, eventDispatcher) : {}; - return eventProps; - } - const eventProps = eventResolver ? eventResolver(Component, viewSchema, eventDispatcher) : {}; - return eventProps; - } - - function resolveExtraProps(viewSchema: Record) { - // const componentKey = viewSchema.type; - // const resolver = resolverMap[componentKey]; - // const extraPropsResolver: ExtraPropsResolver | null = resolver ? resolver.extraPropsResolver : null; - // if (!extraPropsResolver) { - // return {}; - // } - // return extraPropsResolver.resolve(viewSchema); - return {}; - } + const viewConfig = ref(props.config); - function resolveProps(viewSchema: Record) { - const componentKey = viewSchema.type; - const propsConverter = componentPropsConverter[componentKey]; - const componentProps: Record = propsConverter ? propsConverter(viewSchema) : {}; - // const Component = componentMap[componentKey]; - // const componentPropertyProps = Object.keys(Component?.props || {}); - // const componentEventProps = (Component?.emits as string[] || []).map((eventName: string) => `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`); - // const currentComponentProps = componentPropertyProps.concat(componentEventProps); - // const componentProps = Object.keys(componentSchema).reduce((props: Record, propertyName: string) => { - // if (currentComponentProps.indexOf(propertyName) !== -1) { - // props[propertyName] = componentSchema[propertyName]; - // } - // return props; - // }, {}); - const eventProps = { - ...resolveEvents(viewSchema) - }; - const viewProps = { - ...componentProps, - ...resolveModels(viewSchema), - ...resolveExtraProps(viewSchema), - ...resolveCallbacks(viewSchema) - }; - const props = { - ...viewProps, - key: viewSchema.id, - ref: (componentRef: any) => { - if (componentRef && viewSchema.id && !componentManager.has(viewSchema.id)) { - componentManager.register(viewSchema.id, componentRef); - setupContext.emit('componentReady', { ref: ref(componentRef), id: viewSchema.id, type: viewSchema.type }); - } - } - }; - return { props, eventProps }; - } - - function render(viewSchema: Record) { - const componentKey = viewSchema.type; - - if (componentKey === 'component-ref') { - const componentSchema = schema.value?.module?.components - .find((component: any) => component.id === viewSchema.component); - if (componentSchema) { - return render(componentSchema); - } - } - - if (viewSchema.id) { - schemaMap.set(viewSchema.id, viewSchema); - } - const Component = componentMap[componentKey]; + function renderComponent(componentConfig: any) { + const componentType = componentConfig.type; + const Component = componentMap[componentType]; if (!Component) { return null; } - const { props, eventProps } = resolveProps(viewSchema); - - const renderChildren = () => { - if (!viewSchema.contents) { - return null; - } - if (typeof viewSchema.contents === 'string') { - return viewSchema.contents; - } - return viewSchema.contents.map((schema: Record) => render(schema)); - }; - const resolver = resolverMap[componentKey]; - const editorResolver: EditorResolver = resolver ? resolver.editorResolver : null; - if (editorResolver) { - const editor = editorResolver.resolve(viewSchema); - Object.assign(editor, eventProps); - } else { - Object.assign(props, eventProps); - } - const createNode = (componentType: any, props: Record, children?: null | undefined | any[]) => { - if (children && children.length > 0) { - return createVNode(componentType, { ...props }, children); - } else { - return createVNode(componentType, { ...props }, null); - } - }; - if (viewSchema.contents && viewSchema.contents.length > 0) { - return createNode(Component, props, [renderChildren()]); - } else if (viewSchema.slots) { - return createNode(Component, props, [...Object.values(renderSlots(viewSchema.slots))]); - } else { - return createNode(Component, props); - } - } - function rerender(component: any) { - if (component.$forceUpdate) { - component.$forceUpdate(); - } - } + const componentPropsConverter = propsConverterMap[componentType]; + const componentProps = componentPropsConverter ? componentPropsConverter(componentConfig) : {}; - function getSchema(id: string) { - return schemaMap.get(id); - } + const renderChildComponents = () => { + const { editor, contents } = componentConfig; + let childComponentConfigs: any[]; - function setSchema(id: string, partialSchema: Record) { - const elementSchema = schemaMap.get(id); - if (!elementSchema) { - return; - } - const componentInstance = componentManager.get(id); - if (!componentInstance) { - return; - } - merge(elementSchema, partialSchema); - const componentKey = elementSchema.type; - const resolver = resolverMap[componentKey]; - const updateColumnsResolver: UpdateColumnsResolver = resolver ? resolver.updateColumnsResolver : null; - if (updateColumnsResolver) { - updateColumnsResolver.updateColumns(componentInstance, elementSchema); - } - rerender(componentInstance); - } - - function getProps(id: string): Record { - const instance = componentManager.get(id); - return instance.$props || {}; - } - - function setProps(id: string, props: Record) { - const componentInstance = componentManager.get(id); - if (!componentInstance) { - return; - } - const elementSchema = schemaMap.get(id); - if (!elementSchema) { - return; - } - merge(elementSchema, props); - rerender(componentInstance); - } + if (editor) { + childComponentConfigs = [editor]; + } else if (Array.isArray(contents)) { + childComponentConfigs = componentConfig.contents; + } else { + childComponentConfigs = []; + } - function invoke(id: string, method: string, ...args: any[]): any { - const componentInstance = componentManager.get(id); - if (!componentInstance) { - return; - } - if (!componentInstance || typeof componentInstance[method] !== 'function') { - throw new Error(`Method ${method} not found on instance ${id}`); - } - return componentInstance[method](...args); - } + return childComponentConfigs.map((childComponentConfig: any) => { + return renderComponent(childComponentConfig); + }); + }; - function selectItemById(bindingPath: string, id: string) { - const bindingEntityState = entityState.get(bindingPath); - if (!bindingEntityState) { - return; - } - const entityLabel = bindingEntityState.label; - const viewSchema = dataSourceMap.get(entityLabel); - if (!viewSchema) { - return; - } - const componentType = viewSchema.type; - const resolver = resolverMap[componentType]; - const selectionMethodResolver: SelectionItemResolver | null = resolver ? resolver.selectionItemResolver : null; - if (selectionMethodResolver) { - const Component = componentManager.get(viewSchema.id); - selectionMethodResolver.selectItemById(Component, id); - } + return createVNode( + Component, + { ...componentProps }, + { + default: renderChildComponents + } + ); } watch( - [() => props.modelValue, () => props.schema], - ([newModelValue, newSchema]) => { - modelValue.value = newModelValue; - schema.value = newSchema; + [() => props.config], + ([newViewConfig]) => { + viewConfig.value = newViewConfig; } ); - setupContext.expose({ componentManager, rerender, getProps, invoke, setProps, getSchema, setSchema, selectItemById }); + setupContext.expose({}); - return () => { - const components: Record[] = schema.value?.module?.components; - if (!components || components.length < 1) { - return null; - } - const frameComponent = components.find((component: Record) => component.componentType && component.componentType.toLowerCase() === 'frame'); - if (!frameComponent) { - return null; - } - return render(frameComponent); - }; + return () => ( +
+ {renderComponent(viewConfig.value)} +
+ ); } }); export default FDynamicView; diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.props.ts b/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.props.ts index 116990adad7..478f218c5c9 100644 --- a/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.props.ts +++ b/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.props.ts @@ -1,17 +1,11 @@ -import { ExtractPropTypes, PropType } from 'vue'; +import { ExtractPropTypes } from 'vue'; + +export const DYNAMIC_VIEW_NAME = 'fm-dynamic-view'; export const dynamicViewProps = { - /** - * schema - */ - schema: { type: Object, default: null }, - /** - * 组件值 - */ - modelValue: { type: Object as PropType>, default: null }, - /** - * 回调 - */ - callback: { type: Function as PropType<(type: string, ...args: unknown[]) => any>, default: () => { } } + + /** 视图配置 */ + config: { type: Object, default: null }, }; + export type DynamicViewProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/event-dispatcher.ts b/packages/mobile-ui-vue/components/dynamic-view/src/event-dispatcher.ts deleted file mode 100644 index 37b0c47fa49..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-view/src/event-dispatcher.ts +++ /dev/null @@ -1,16 +0,0 @@ - -import { SetupContext } from "vue"; -import { createEventHandlerResolver, EventDispatcher } from "../../dynamic-resolver"; -import { resolverMap } from "./components/maps"; - -export function createEventDispatcher(context: SetupContext, schema: Record): EventDispatcher { - function dispatch(token: string, eventName: string, type: string, payloads: any[]) { - const resolver = resolverMap[type]; - const eventHandlerResolver = resolver && resolver.eventHandlerResolver ? resolver.eventHandlerResolver : createEventHandlerResolver(); - const eventHandler = eventHandlerResolver.resolve(schema, { token, name: eventName, type, payloads }); - context.emit('event', { token, name: eventName, type, payloads, handler: eventHandler, schema }); - } - return { - dispatch - }; -} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/types.ts b/packages/mobile-ui-vue/components/dynamic-view/src/types.ts deleted file mode 100644 index 07c3f181906..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-view/src/types.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* eslint-disable no-use-before-define */ -export interface EntityState { - primaryKey: string; - bindingPath: string; - currentId: string | null; - label: string; -} - -export interface UseBindingContext { - setup(); - get(bindingPath: string | string[]): EntityState; -} - -export interface EntityFieldSchema { - id: string; - require: any; - multiLanguage: boolean; - defaultValue: any; - readonly: any; - bindingPath: string; - label: string; - type: Record; - name: string; -} - -export interface EntityTypeSchema { - entities: EntitySchema[]; - primary: string; - displayName: string; - fields: EntityFieldSchema[]; - name: string; -} -export interface EntitySchema { - id: string; - label: string; - code: string; - type: EntityTypeSchema; - name: string; -} - -export interface ResolvedEntity { - bindingPaths: string[]; - primaryKey: string; - label: string; -} - -export interface ResolvedEntityField { - id: string; - bindingPath: string; - require: any; - readonly: any; - multiLanguage: boolean; - label: string; - dataSource: string; -} - -export interface UseEntityResolver { - resolveEntityByDataSource(dataSource: string): ResolvedEntity | null; - resolveEntities(entitySchema: EntitySchema): ResolvedEntity[]; - resolveEntity(entity: Record, entityLabel: string, isRoot?: boolean): ResolvedEntity | null; -} - -export interface UseFieldResolver { - resolveFieldById(fieldId: string): ResolvedEntityField | null; -} - -// export interface UseBindingData { -// currentId: ComputedRef; -// primaryKey: ComputedRef; -// bindingList: ComputedRef; -// currentItem: ComputedRef; -// setValueByPath(bindingPath: string, value: any); -// } - -export interface UseComponentInstanceManager { - register(id: string, instance: any): void; - get(id: string): any | null; - remove(id: string): void; - update(id: string, instance: any): void; - has(id: string): boolean; - getAll(): Map; - clear(): void; -} diff --git a/packages/mobile-ui-vue/components/float-container/index.ts b/packages/mobile-ui-vue/components/float-container/index.ts new file mode 100644 index 00000000000..47454ca63a9 --- /dev/null +++ b/packages/mobile-ui-vue/components/float-container/index.ts @@ -0,0 +1,20 @@ +import { Plugin } from 'vue'; +import { withInstall } from '@components/common'; +import { propsResolver } from './src/float-container.props'; +import FloatContainerInstallless from './src/float-container.component'; + +const FLOAT_CONTAINER_REGISTERED_NAME = 'float-container'; + +const FloatContainer = withInstall(FloatContainerInstallless); + +FloatContainer.register = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[FLOAT_CONTAINER_REGISTERED_NAME] = FloatContainer; + propsResolverMap[FLOAT_CONTAINER_REGISTERED_NAME] = propsResolver; +}; + +export * from './src/float-container.props'; +export { FloatContainer }; +export default FloatContainer as typeof FloatContainer & Plugin; diff --git a/packages/mobile-ui-vue/components/float-container/src/float-container.component.tsx b/packages/mobile-ui-vue/components/float-container/src/float-container.component.tsx new file mode 100644 index 00000000000..ebb255014a8 --- /dev/null +++ b/packages/mobile-ui-vue/components/float-container/src/float-container.component.tsx @@ -0,0 +1,23 @@ +import { SetupContext, defineComponent, computed } from 'vue'; +import { useBem } from '@components/common/index'; +import { FLOAT_CONTAINER_NAME, floatContainerProps, FloatContainerProps } from './float-container.props'; + +export default defineComponent({ + name: FLOAT_CONTAINER_NAME, + props: floatContainerProps, + emits: [], + setup(props: FloatContainerProps, context: SetupContext) { + const { bem } = useBem(FLOAT_CONTAINER_NAME); + + const containerClass = computed(() => ({ + [bem()]: true, + [props.customClass || '']: true, + })); + + return () => ( +
+ {context.slots.default?.()} +
+ ); + } +}); diff --git a/packages/mobile-ui-vue/components/float-container/src/float-container.props.ts b/packages/mobile-ui-vue/components/float-container/src/float-container.props.ts new file mode 100644 index 00000000000..e3d5c77dd14 --- /dev/null +++ b/packages/mobile-ui-vue/components/float-container/src/float-container.props.ts @@ -0,0 +1,20 @@ +import { ExtractPropTypes } from 'vue'; +import { createPropsResolver } from '../../dynamic-resolver'; +import floatContainerSchema from './schema/float-container.schema.json'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; + +export const FLOAT_CONTAINER_NAME = 'fm-float-container'; + +export const floatContainerProps = { + customClass: { type: String, default: '' }, +}; + +export type FloatContainerProps = ExtractPropTypes; + +export const propsResolver = createPropsResolver( + floatContainerProps, + floatContainerSchema, + schemaMapper, + schemaResolver +); diff --git a/packages/mobile-ui-vue/components/float-container/src/float-container.scss b/packages/mobile-ui-vue/components/float-container/src/float-container.scss new file mode 100644 index 00000000000..ccd9b255496 --- /dev/null +++ b/packages/mobile-ui-vue/components/float-container/src/float-container.scss @@ -0,0 +1,5 @@ +.fm-float-container { + position: absolute !important; + bottom: 60px; + right: 30px; +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/float-container/src/schema/float-container.schema.json b/packages/mobile-ui-vue/components/float-container/src/schema/float-container.schema.json new file mode 100644 index 00000000000..473930001e2 --- /dev/null +++ b/packages/mobile-ui-vue/components/float-container/src/schema/float-container.schema.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/float-container.schema.json", + "title": "float-container", + "description": "", + "type": "object", + "properties": { + "id": { + "description": "", + "type": "string" + }, + "type": { + "description": "", + "type": "string", + "default": "float-container" + }, + "appearance": { + "description": "", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "contents": { + "description": "", + "type": "array", + "default": [] + } + }, + "required": [ + "id", + "type", + "contents" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/float-container/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/float-container/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..90dc1493e55 --- /dev/null +++ b/packages/mobile-ui-vue/components/float-container/src/schema/schema-mapper.ts @@ -0,0 +1,5 @@ +import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance] +]); diff --git a/packages/mobile-ui-vue/components/float-container/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/float-container/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..c1bf8da88a0 --- /dev/null +++ b/packages/mobile-ui-vue/components/float-container/src/schema/schema-resolver.ts @@ -0,0 +1,5 @@ +import { DynamicResolver } from "../../../dynamic-resolver"; + +export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { + return schema; +} diff --git a/packages/mobile-ui-vue/components/form-item/index.ts b/packages/mobile-ui-vue/components/form-item/index.ts index 0cc8aac1007..af7481fd11f 100644 --- a/packages/mobile-ui-vue/components/form-item/index.ts +++ b/packages/mobile-ui-vue/components/form-item/index.ts @@ -1,9 +1,19 @@ import { withInstall } from '@components/common'; +import { propsResolver } from './src/form-item.props'; import FormItemInstallless from './src/form-item.component'; -export * from './src/form-item.props'; +const FORM_REGISTERED_NAME = 'form-item'; const FormItem = withInstall(FormItemInstallless); +FormItem.register = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[FORM_REGISTERED_NAME] = FormItem; + propsResolverMap[FORM_REGISTERED_NAME] = propsResolver; +}; + +export * from './src/form-item.props'; export { FormItem }; export default FormItem; diff --git a/packages/mobile-ui-vue/components/form-item/src/form-item.props.ts b/packages/mobile-ui-vue/components/form-item/src/form-item.props.ts index 9a07479795f..a50759b8f7a 100644 --- a/packages/mobile-ui-vue/components/form-item/src/form-item.props.ts +++ b/packages/mobile-ui-vue/components/form-item/src/form-item.props.ts @@ -1,12 +1,13 @@ import { ExtractPropTypes, PropType } from 'vue'; +import { createPropsResolver } from '@components/dynamic-resolver'; +import formItemSchema from './schema/form-item.schema.json'; +import { schemaMapper } from './schema/form-item-schema-mapper'; +import { schemaResolver } from './schema/form-item-schema-resolver'; import { ValidationRule } from './validation/index'; import { LabelAlign, ContentAlign } from './types'; export const FORM_ITEM_NAME = 'FmFormItem'; -/** - * 表单项属性 - */ export const formItemProps = { /** 名称 */ @@ -39,3 +40,10 @@ export const formItemProps = { }; export type FormItemProps = ExtractPropTypes; + +export const propsResolver = createPropsResolver( + formItemProps, + formItemSchema, + schemaMapper, + schemaResolver +); diff --git a/packages/mobile-ui-vue/components/form-item/src/form.component.tsx b/packages/mobile-ui-vue/components/form-item/src/form.component.tsx index d6bb80b1b75..cd74b2d15d2 100644 --- a/packages/mobile-ui-vue/components/form-item/src/form.component.tsx +++ b/packages/mobile-ui-vue/components/form-item/src/form.component.tsx @@ -15,21 +15,20 @@ */ import { defineComponent, SetupContext } from 'vue'; -import { preventDefault, useChildrenContexts } from '@components/common'; -import { useFormValidation, useFormContext } from './composition'; -import { FORM_KEY } from './consts'; +import { useBem, preventDefault, useChildrenContexts } from '@components/common'; +import { useFormValidation, useFormContext } from '@components/form-item/src/composition'; +import { FORM_KEY } from '@components/form-item/src/consts'; -import { FormContext, FormItemContext } from './types'; -import { formProps, FormProps } from './form.props'; - -const name = 'fm-form'; +import { FormContext, FormItemContext } from '@components/form-item/src/types'; +import { FORM_NAME, formProps, FormProps } from './form.props'; export default defineComponent({ - name, + name: FORM_NAME, props: formProps, emits: [], setup(props: FormProps, context: SetupContext) { const { slots, expose } = context; + const { bem } = useBem(FORM_NAME); const formContext = useFormContext(props, context); const { childContexts } = useChildrenContexts( @@ -39,7 +38,7 @@ export default defineComponent({ const { validate, clearValidate } = useFormValidation(childContexts); const formClass = { - [name]: true + [bem()]: true }; const onSubmit = (e: Event) => { preventDefault(e); @@ -52,7 +51,7 @@ export default defineComponent({ return () => (
- {slots?.default()} + {slots.default && slots.default()}
); } diff --git a/packages/mobile-ui-vue/components/form-item/src/form.props.ts b/packages/mobile-ui-vue/components/form-item/src/form.props.ts index ff833d8e325..f5000a12301 100644 --- a/packages/mobile-ui-vue/components/form-item/src/form.props.ts +++ b/packages/mobile-ui-vue/components/form-item/src/form.props.ts @@ -1,10 +1,13 @@ import { ExtractPropTypes, PropType } from 'vue'; -import { LabelAlign, ContentAlign, FormData } from './types'; -import { ValidationRules } from './validation'; +import { LabelAlign, ContentAlign, FormData } from '@components/form-item/src/types'; +import { ValidationRules } from '@components/form-item/src/validation'; +import { createPropsResolver } from '@components/dynamic-resolver'; +import formSchema from './schema/form.schema.json'; +import { schemaMapper } from './schema/form-schema-mapper'; +import { schemaResolver } from './schema/form-schema-resolver'; + +export const FORM_NAME = 'fm-form'; -/** - * 表单属性 - */ export const formProps = { /** 绑定数据 */ @@ -34,3 +37,10 @@ export const formProps = { }; export type FormProps = ExtractPropTypes; + +export const propsResolver = createPropsResolver( + formProps, + formSchema, + schemaMapper, + schemaResolver +); diff --git a/packages/mobile-ui-vue/components/form-item/src/form.scss b/packages/mobile-ui-vue/components/form-item/src/form.scss new file mode 100644 index 00000000000..f634f3441bd --- /dev/null +++ b/packages/mobile-ui-vue/components/form-item/src/form.scss @@ -0,0 +1,4 @@ +.fm-form { + display: flex; + flex-direction: column; +} diff --git a/packages/mobile-ui-vue/components/form-item/src/schema/form-item-schema-mapper.ts b/packages/mobile-ui-vue/components/form-item/src/schema/form-item-schema-mapper.ts new file mode 100644 index 00000000000..90dc1493e55 --- /dev/null +++ b/packages/mobile-ui-vue/components/form-item/src/schema/form-item-schema-mapper.ts @@ -0,0 +1,5 @@ +import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance] +]); diff --git a/packages/mobile-ui-vue/components/form-item/src/schema/form-item-schema-resolver.ts b/packages/mobile-ui-vue/components/form-item/src/schema/form-item-schema-resolver.ts new file mode 100644 index 00000000000..b02bdf93eec --- /dev/null +++ b/packages/mobile-ui-vue/components/form-item/src/schema/form-item-schema-resolver.ts @@ -0,0 +1,5 @@ +import { DynamicResolver } from "../../../dynamic-resolver"; + +export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { + return schema; +} diff --git a/packages/mobile-ui-vue/components/form-item/src/schema/form-item.schema.json b/packages/mobile-ui-vue/components/form-item/src/schema/form-item.schema.json new file mode 100644 index 00000000000..cf3da7f92db --- /dev/null +++ b/packages/mobile-ui-vue/components/form-item/src/schema/form-item.schema.json @@ -0,0 +1,46 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/form-item.schema.json", + "title": "form-item", + "description": "", + "type": "object", + "properties": { + "id": { + "description": "", + "type": "string" + }, + "type": { + "description": "", + "type": "string", + "default": "form-item" + }, + "appearance": { + "description": "", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "label": { + "description": "", + "type": "string", + "default": "" + }, + "editor": { + "description": "", + "type": "obejct", + "default": null + } + }, + + "required": [ + "id", + "type" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/form-item/src/schema/form-schema-mapper.ts b/packages/mobile-ui-vue/components/form-item/src/schema/form-schema-mapper.ts new file mode 100644 index 00000000000..90dc1493e55 --- /dev/null +++ b/packages/mobile-ui-vue/components/form-item/src/schema/form-schema-mapper.ts @@ -0,0 +1,5 @@ +import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance] +]); diff --git a/packages/mobile-ui-vue/components/form-item/src/schema/form-schema-resolver.ts b/packages/mobile-ui-vue/components/form-item/src/schema/form-schema-resolver.ts new file mode 100644 index 00000000000..b02bdf93eec --- /dev/null +++ b/packages/mobile-ui-vue/components/form-item/src/schema/form-schema-resolver.ts @@ -0,0 +1,5 @@ +import { DynamicResolver } from "../../../dynamic-resolver"; + +export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { + return schema; +} diff --git a/packages/mobile-ui-vue/components/form-item/src/schema/form.schema.json b/packages/mobile-ui-vue/components/form-item/src/schema/form.schema.json new file mode 100644 index 00000000000..1052a2fc034 --- /dev/null +++ b/packages/mobile-ui-vue/components/form-item/src/schema/form.schema.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/form.schema.json", + "title": "form", + "description": "", + "type": "object", + "properties": { + "id": { + "description": "", + "type": "string" + }, + "type": { + "description": "", + "type": "string", + "default": "form" + }, + "appearance": { + "description": "", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "contents": { + "description": "", + "type": "array", + "default": [] + } + }, + "required": [ + "id", + "type", + "contents" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/form/index.ts b/packages/mobile-ui-vue/components/form/index.ts index 70c1c6508c7..c62036c1587 100644 --- a/packages/mobile-ui-vue/components/form/index.ts +++ b/packages/mobile-ui-vue/components/form/index.ts @@ -1,9 +1,36 @@ + +/** + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Plugin } from 'vue'; import { withInstall } from '@components/common'; -import FormInstallless from '../form-item/src/form.component'; +import { propsResolver } from '@components/form-item/src/form.props'; +import FormInstallless from '@components/form-item/src/form.component'; -export * from '../form-item/src/form.props'; +const FORM_REGISTERED_NAME = 'form'; const Form = withInstall(FormInstallless); +Form.register = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[FORM_REGISTERED_NAME] = Form; + propsResolverMap[FORM_REGISTERED_NAME] = propsResolver; +}; + +export * from '@components/form-item/src/form.props'; export { Form }; -export default Form; +export default Form as typeof Form & Plugin; diff --git a/packages/mobile-ui-vue/components/index.scss b/packages/mobile-ui-vue/components/index.scss index 1ab754cc207..ecef13826c3 100644 --- a/packages/mobile-ui-vue/components/index.scss +++ b/packages/mobile-ui-vue/components/index.scss @@ -1,6 +1,7 @@ @use './common/src/common.scss'; @use './button/src/button.scss'; @use './button-edit/src/button-edit.scss'; +@use './button-group/src/button-group.scss'; @use './cell/src/cell.scss'; @use './checkbox-group/src/checkbox-group.scss'; @use './checkbox/src/checkbox.scss'; @@ -34,3 +35,4 @@ @use './page-body-container/src/page-body-container.scss'; @use './page-header-container/src/page-header-container.scss'; @use './page-footer-container/src/page-footer-container.scss'; +@use './float-container/src/float-container.scss'; diff --git a/packages/mobile-ui-vue/components/index.ts b/packages/mobile-ui-vue/components/index.ts index 657cb330b5c..b1536a66140 100644 --- a/packages/mobile-ui-vue/components/index.ts +++ b/packages/mobile-ui-vue/components/index.ts @@ -14,9 +14,10 @@ * limitations under the License. */ -import { App } from 'vue'; +import { App, Plugin } from 'vue'; import Button from './button'; import ButtonEdit from './button-edit'; +import ButtonGroup from './button-group'; import Cell from './cell'; import Icon from './icon'; import InputGroup from './input-group'; @@ -55,23 +56,26 @@ import Tab from './tab'; import Tabs from './tabs'; import Tag from './tag'; import * as Utils from './common/src/utils'; -// import PageContainer from './page-container'; -// import PageBodyContainer from './page-body-container'; -// import PageHeaderContainer from './page-header-container'; -// import PageFooterContainer from './page-footer-container'; -// import Component from './component'; -// import ContentContainerfrom './content-container'; -// import FloatContainer from './float-container'; - +import PageContainer from './page-container'; +import PageBodyContainer from './page-body-container'; +import PageHeaderContainer from './page-header-container'; +import PageFooterContainer from './page-footer-container'; +import Component from './component'; +import ContentContainer from './content-container'; +import FloatContainer from './float-container'; import Common from './common'; import Modal from './modal'; import DynamicView from './dynamic-view'; import FDesignerCanvas from './designer-canvas'; + +export * from './register'; export * from './designer'; +export { schemaMap } from './dynamic-resolver'; const components = [ Button, ButtonEdit, + ButtonGroup, Cell, Checkbox, CheckboxGroup, @@ -108,14 +112,16 @@ const components = [ Tabs, Tab, Tag, - // PageContainer, - // PageBodyContainer, - // PageHeaderContainer, - // PageFooterContainer, Overlay, - // Component, - // ContentContainer, - // FloatContainer, + + PageContainer, + PageBodyContainer, + PageHeaderContainer, + PageFooterContainer, + Component, + ContentContainer, + FloatContainer, + Common, Modal, DynamicView, @@ -124,12 +130,14 @@ const components = [ const install = (app: App): void => { components.forEach((component) => { - app.use(component); + app.use(component as Plugin); }); }; + export { Button, ButtonEdit, + ButtonGroup, Cell, Checker, Checkbox, @@ -167,14 +175,14 @@ export { Tab, Tag, Overlay, - // PageContainer, - // PageBodyContainer, - // PageHeaderContainer, - // PageFooterContainer, + Component, + PageContainer, + PageBodyContainer, + PageHeaderContainer, + PageFooterContainer, + ContentContainer, + FloatContainer, Utils, - // Component, - // ContentContainer, - // FloatContainer, Common, Modal, DynamicView, diff --git a/packages/mobile-ui-vue/components/input-group/index.ts b/packages/mobile-ui-vue/components/input-group/index.ts index 78ae8fa99f0..6217bc10ace 100644 --- a/packages/mobile-ui-vue/components/input-group/index.ts +++ b/packages/mobile-ui-vue/components/input-group/index.ts @@ -1,10 +1,19 @@ import { withInstall } from '@components/common'; +import { propsResolver } from './src/input-group.props'; import InputGroupInstallless from './src/input-group.component'; -export * from './src/input-group.props'; -export * from './src/types'; +const INPUT_GROUP_REGISTERED_NAME = 'input-group'; const InputGroup = withInstall(InputGroupInstallless); +InputGroup.register = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[INPUT_GROUP_REGISTERED_NAME] = InputGroup; + propsResolverMap[INPUT_GROUP_REGISTERED_NAME] = propsResolver; +}; +export * from './src/input-group.props'; +export * from './src/types'; export { InputGroup }; export default InputGroup; diff --git a/packages/mobile-ui-vue/components/input-group/src/input-group.props.ts b/packages/mobile-ui-vue/components/input-group/src/input-group.props.ts index 7b05859e4f1..8116d20d776 100644 --- a/packages/mobile-ui-vue/components/input-group/src/input-group.props.ts +++ b/packages/mobile-ui-vue/components/input-group/src/input-group.props.ts @@ -1,7 +1,11 @@ import { ExtractPropTypes, PropType } from 'vue'; import { InputTextAlign, InputTextAlignMap, InputType, InputTypeMap, InputUpdateOn } from "./types"; +import { createPropsResolver } from '../../dynamic-resolver'; +import inputGroupSchema from './schema/input-group.schema.json'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; -export const INPUT_NAME = 'FmInputGroup'; +export const INPUT_NAME = 'fm-input-group'; export const inputCommonProps = { modelValue: { type: [String, Number], default: '' }, @@ -63,3 +67,9 @@ export const inputProps = { export type InputCommonProps = ExtractPropTypes; export type InputProps = ExtractPropTypes; +export const propsResolver = createPropsResolver( + inputProps, + inputGroupSchema, + schemaMapper, + schemaResolver +); diff --git a/packages/mobile-ui-vue/components/input-group/src/schema/input-group.schema.json b/packages/mobile-ui-vue/components/input-group/src/schema/input-group.schema.json new file mode 100644 index 00000000000..4801efdefbc --- /dev/null +++ b/packages/mobile-ui-vue/components/input-group/src/schema/input-group.schema.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/input-group.schema.json", + "title": "input-group", + "description": "", + "type": "object", + "properties": { + "id": { + "description": "", + "type": "string" + }, + "type": { + "description": "", + "type": "string", + "default": "input-group" + }, + "appearance": { + "description": "", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "binding": { + "description": "", + "type": "object", + "default": {} + }, + "onUpdate:modelValue": { + "description": "值变化事件", + "type": "string", + "default": "" + } + }, + "events": [ + "onUpdate:modelValue" + ], + "required": [ + "id", + "type" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/input-group/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/input-group/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..f7d510235fb --- /dev/null +++ b/packages/mobile-ui-vue/components/input-group/src/schema/schema-mapper.ts @@ -0,0 +1,6 @@ +import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance], + ['binding', 'modelValue'] +]); diff --git a/packages/mobile-ui-vue/components/input-group/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/input-group/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..b02bdf93eec --- /dev/null +++ b/packages/mobile-ui-vue/components/input-group/src/schema/schema-resolver.ts @@ -0,0 +1,5 @@ +import { DynamicResolver } from "../../../dynamic-resolver"; + +export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { + return schema; +} diff --git a/packages/mobile-ui-vue/components/list-view/index.ts b/packages/mobile-ui-vue/components/list-view/index.ts index 17cc4085dab..5e571fa8982 100644 --- a/packages/mobile-ui-vue/components/list-view/index.ts +++ b/packages/mobile-ui-vue/components/list-view/index.ts @@ -3,7 +3,7 @@ import ListViewInstallless from './src/list-view.component'; import ListViewDesignInstallless from './src/designer/list-view.design.component'; import { propsResolver } from './src/list-view.props'; -const COMPONENT_TYPE = 'list-view'; +const LIST_VIEW_REGISTER_NAME = 'list-view'; const ListView = withInstall(ListViewInstallless); const ListViewDesign = withInstall(ListViewDesignInstallless); @@ -13,11 +13,11 @@ export { ListView, ListViewDesign }; export default { register(componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void { - componentMap[COMPONENT_TYPE] = ListView; - propsResolverMap[COMPONENT_TYPE] = propsResolver; + componentMap[LIST_VIEW_REGISTER_NAME] = ListView; + propsResolverMap[LIST_VIEW_REGISTER_NAME] = propsResolver; }, registerDesigner(componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void { - componentMap[COMPONENT_TYPE] = ListViewDesign; - propsResolverMap[COMPONENT_TYPE] = propsResolver; + componentMap[LIST_VIEW_REGISTER_NAME] = ListViewDesign; + propsResolverMap[LIST_VIEW_REGISTER_NAME] = propsResolver; } }; diff --git a/packages/mobile-ui-vue/components/list-view/src/list-view.props.ts b/packages/mobile-ui-vue/components/list-view/src/list-view.props.ts index 057171439f7..229a5883e35 100644 --- a/packages/mobile-ui-vue/components/list-view/src/list-view.props.ts +++ b/packages/mobile-ui-vue/components/list-view/src/list-view.props.ts @@ -62,7 +62,7 @@ export const listViewProps = { error: { type: Boolean, default: false }, /** 是否加载完成,加载完成后将在列表下方显示加载完成提示文本,且不会再触发加载事件 */ - finished: { type: Boolean, default: false }, + finished: { type: Boolean, default: true }, /** 列表属性(除了`loading`、`error`、`finished`之外的其它列表组件属性) */ listProps: { type: Object as PropType, default: {} }, diff --git a/packages/mobile-ui-vue/components/list-view/src/schema/list-view.schema.json b/packages/mobile-ui-vue/components/list-view/src/schema/list-view.schema.json index 776afb26bb5..3ae41f52561 100644 --- a/packages/mobile-ui-vue/components/list-view/src/schema/list-view.schema.json +++ b/packages/mobile-ui-vue/components/list-view/src/schema/list-view.schema.json @@ -32,79 +32,25 @@ "type": "array", "default": [] }, - "visible": { - "description": "", - "type": "boolean", - "default": true - }, - "data": { - "description": "", - "type": "array", - "default": [] - }, - "idField": { - "description": "", - "type": "string" - }, - "textField": { - "description": "", - "type": "string" - }, - "disableField": { - "description": "", - "type": "string" - }, - "childField": { - "description": "", - "type": "string" - }, - "selectedValues": { - "description": "", - "type": "array", - "default": [] - }, "loading": { - "description": "", - "type": "boolean" - }, - "error": { - "description": "", - "type": "boolean" - }, - "finished": { - "description": "", - "type": "boolean" - }, - "enablePullRefresh": { - "description": "", - "type": "boolean", - "default": true - }, - "enableMultiSelect": { - "description": "", + "description": "加载中状态", "type": "boolean", - "default": true + "default": "false" }, - "multiSelect": { + "dataSource": { "description": "", - "type": "boolean", - "default": false - }, - "fill": { - "description": "", - "type": "boolean", - "default": true - }, - "split": { - "description": "", - "type": "boolean", - "default": true + "type": "string", + "default": "" }, - "emptyMessage": { - "description": "", - "type": "string" + "onItemClick": { + "description": "行点击事件", + "type": "string", + "default": "" } }, + "events": [ + "onItemClick" + ], "required": [ "id", "type", diff --git a/packages/mobile-ui-vue/components/list-view/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/list-view/src/schema/schema-mapper.ts index 90dc1493e55..ac06d37022a 100644 --- a/packages/mobile-ui-vue/components/list-view/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/list-view/src/schema/schema-mapper.ts @@ -1,5 +1,7 @@ import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; export const schemaMapper = new Map([ - ['appearance', resolveAppearance] + ['appearance', resolveAppearance], + ['dataSource', 'data'], + ['onItemClick', 'onClickItem'] ]); diff --git a/packages/mobile-ui-vue/components/navbar/index.ts b/packages/mobile-ui-vue/components/navbar/index.ts index b7dff96f627..2e20484d4c5 100644 --- a/packages/mobile-ui-vue/components/navbar/index.ts +++ b/packages/mobile-ui-vue/components/navbar/index.ts @@ -1,7 +1,14 @@ import { withInstall } from '@components/common'; +import { propsResolver } from './src/navbar.props'; import NavbarInstallless from './src/navbar.component'; +const NAVBAR_REGISTERED_NAME = 'navigation-bar'; + const Navbar = withInstall(NavbarInstallless); +Navbar.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { + componentMap[NAVBAR_REGISTERED_NAME] = Navbar; + propsResolverMap[NAVBAR_REGISTERED_NAME] = propsResolver; +}; export { Navbar }; export default Navbar; diff --git a/packages/mobile-ui-vue/components/navbar/src/navbar.component.tsx b/packages/mobile-ui-vue/components/navbar/src/navbar.component.tsx index 35447389e2d..3b0436073a5 100644 --- a/packages/mobile-ui-vue/components/navbar/src/navbar.component.tsx +++ b/packages/mobile-ui-vue/components/navbar/src/navbar.component.tsx @@ -15,10 +15,10 @@ */ import { SetupContext, defineComponent } from 'vue'; -import { NavbarProps, navbarProps } from './navbar.props'; +import { NAVBAR_NAME, NavbarProps, navbarProps } from './navbar.props'; export default defineComponent({ - name: 'fm-navbar', + name: NAVBAR_NAME, props: navbarProps, emits: ['click-left', 'click-right'], setup(props: NavbarProps, context: SetupContext) { diff --git a/packages/mobile-ui-vue/components/navbar/src/navbar.props.ts b/packages/mobile-ui-vue/components/navbar/src/navbar.props.ts index fb07cb23650..bd3add9711b 100644 --- a/packages/mobile-ui-vue/components/navbar/src/navbar.props.ts +++ b/packages/mobile-ui-vue/components/navbar/src/navbar.props.ts @@ -14,6 +14,12 @@ * limitations under the License. */ import { ExtractPropTypes } from 'vue'; +import { createPropsResolver } from '../../dynamic-resolver'; +import navbarSchema from './schema/navbar.schema.json'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; + +export const NAVBAR_NAME = 'fm-navbar'; export const navbarProps = { title: { @@ -39,4 +45,10 @@ export const navbarProps = { } }; +export const propsResolver = createPropsResolver( + navbarProps, + navbarSchema, + schemaMapper, + schemaResolver +); export type NavbarProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/navbar/src/schema/navbar.schema.json b/packages/mobile-ui-vue/components/navbar/src/schema/navbar.schema.json new file mode 100644 index 00000000000..4a06ab6f5e7 --- /dev/null +++ b/packages/mobile-ui-vue/components/navbar/src/schema/navbar.schema.json @@ -0,0 +1,45 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/navbar.schema.json", + "title": "navigation-bar", + "description": "页面导航组件", + "type": "object", + "properties": { + "id": { + "description": "唯一标志", + "type": "string" + }, + "type": { + "description": "组件类型", + "type": "string", + "default": "navbar" + }, + "appearance": { + "description": "导航条自定义样式", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "title": { + "description": "标题", + "type": "string", + "default": "" + }, + "leftArrow": { + "description": "是否显示左侧返回按钮", + "type": "boolean", + "default": "true" + } + }, + "required": [ + "id", + "type" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/navbar/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/navbar/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..bc768d5bab9 --- /dev/null +++ b/packages/mobile-ui-vue/components/navbar/src/schema/schema-mapper.ts @@ -0,0 +1,5 @@ +import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance] +]); diff --git a/packages/mobile-ui-vue/components/navbar/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/navbar/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..b02bdf93eec --- /dev/null +++ b/packages/mobile-ui-vue/components/navbar/src/schema/schema-resolver.ts @@ -0,0 +1,5 @@ +import { DynamicResolver } from "../../../dynamic-resolver"; + +export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { + return schema; +} diff --git a/packages/mobile-ui-vue/components/page-body-container/index.ts b/packages/mobile-ui-vue/components/page-body-container/index.ts index 70ac8daa20d..c6cfd478abb 100644 --- a/packages/mobile-ui-vue/components/page-body-container/index.ts +++ b/packages/mobile-ui-vue/components/page-body-container/index.ts @@ -1,4 +1,4 @@ - + /** * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. * @@ -19,21 +19,21 @@ import PageBodyContainerInstallless from './src/page-body-container.component'; import PageBodyContainerDesignInstallless from './src/designer/page-body-container.design.component'; import { propsResolver } from './src/page-body-container.props'; -const COMPONENT_TYPE = 'page-body-container'; +const PAGE_BODY_CONTAINER_REGISTER_NAME = 'page-body-container'; + const PageBodyContainer = withInstall(PageBodyContainerInstallless); +PageBodyContainer.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void => { + componentMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = PageBodyContainer; + propsResolverMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = propsResolver; +}; + const PageBodyContainerDesign = withInstall(PageBodyContainerDesignInstallless); +PageBodyContainerDesign.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void => { + componentMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = PageBodyContainerDesign; + propsResolverMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = propsResolver; +}; export * from './src/page-body-container.props'; - export { PageBodyContainer, PageBodyContainerDesign }; +export default PageBodyContainer; -export default { - register(componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void { - componentMap[COMPONENT_TYPE] = PageBodyContainer; - propsResolverMap[COMPONENT_TYPE] = propsResolver; - }, - registerDesigner(componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void { - componentMap[COMPONENT_TYPE] = PageBodyContainerDesign; - propsResolverMap[COMPONENT_TYPE] = propsResolver; - } -}; diff --git a/packages/mobile-ui-vue/components/page-body-container/src/page-body-container.component.tsx b/packages/mobile-ui-vue/components/page-body-container/src/page-body-container.component.tsx index 63732258fa0..b1f6a581a47 100644 --- a/packages/mobile-ui-vue/components/page-body-container/src/page-body-container.component.tsx +++ b/packages/mobile-ui-vue/components/page-body-container/src/page-body-container.component.tsx @@ -16,7 +16,7 @@ export default defineComponent({ return () => (
- {context.slots.default?.()} + {context.slots.default && context.slots.default()}
); } diff --git a/packages/mobile-ui-vue/components/page-body-container/src/schema/page-body-container.schema.json b/packages/mobile-ui-vue/components/page-body-container/src/schema/page-body-container.schema.json index 1783df370e4..10acd01e8f2 100644 --- a/packages/mobile-ui-vue/components/page-body-container/src/schema/page-body-container.schema.json +++ b/packages/mobile-ui-vue/components/page-body-container/src/schema/page-body-container.schema.json @@ -31,24 +31,6 @@ "description": "", "type": "array", "default": [] - }, - "size": { - "description": "", - "type": "object", - "properties": { - "width": { - "type": "number" - }, - "height": { - "type": "number" - } - }, - "default": null - }, - "visible": { - "description": "", - "type": "boolean", - "default": true } }, "required": [ diff --git a/packages/mobile-ui-vue/components/page-container/index.ts b/packages/mobile-ui-vue/components/page-container/index.ts index ea6d3a23c31..00d8d010d3f 100644 --- a/packages/mobile-ui-vue/components/page-container/index.ts +++ b/packages/mobile-ui-vue/components/page-container/index.ts @@ -1,4 +1,4 @@ - + /** * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. * @@ -19,21 +19,24 @@ import PageContainerInstallless from './src/page-container.component'; import PageContainerDesignInstallless from './src/designer/page-container.design.component'; import { propsResolver } from './src/page-container.props'; -const COMPONENT_TYPE = 'page-container'; +const PAGE_CONTAINER_REGISTERED_NAME = 'page-container'; + const PageContainer = withInstall(PageContainerInstallless); +PageContainer.register = ( + componentMap: Record, propsResolverMap: Record, configResolverMap: Record +): void => { + componentMap[PAGE_CONTAINER_REGISTERED_NAME] = PageContainer; + propsResolverMap[PAGE_CONTAINER_REGISTERED_NAME] = propsResolver; +}; + const PageContainerDesign = withInstall(PageContainerDesignInstallless); +PageContainerDesign.registerDesigner = ( + componentMap: Record, propsResolverMap: Record, configResolverMap: Record +): void => { + componentMap[PAGE_CONTAINER_REGISTERED_NAME] = PageContainerDesign; + propsResolverMap[PAGE_CONTAINER_REGISTERED_NAME] = propsResolver; +}; export * from './src/page-container.props'; - export { PageContainer, PageContainerDesign }; - -export default { - register(componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void { - componentMap[COMPONENT_TYPE] = PageContainer; - propsResolverMap[COMPONENT_TYPE] = propsResolver; - }, - registerDesigner(componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void { - componentMap[COMPONENT_TYPE] = PageContainerDesign; - propsResolverMap[COMPONENT_TYPE] = propsResolver; - } -}; +export default PageContainer; diff --git a/packages/mobile-ui-vue/components/page-container/src/schema/page-container.schema.json b/packages/mobile-ui-vue/components/page-container/src/schema/page-container.schema.json index 2b1f6161733..245b02ce929 100644 --- a/packages/mobile-ui-vue/components/page-container/src/schema/page-container.schema.json +++ b/packages/mobile-ui-vue/components/page-container/src/schema/page-container.schema.json @@ -31,24 +31,6 @@ "description": "", "type": "array", "default": [] - }, - "size": { - "description": "", - "type": "object", - "properties": { - "width": { - "type": "number" - }, - "height": { - "type": "number" - } - }, - "default": null - }, - "visible": { - "description": "", - "type": "boolean", - "default": true } }, "required": [ diff --git a/packages/mobile-ui-vue/components/page-footer-container/index.ts b/packages/mobile-ui-vue/components/page-footer-container/index.ts index cdf30a2226f..1f3f9fcbbc2 100644 --- a/packages/mobile-ui-vue/components/page-footer-container/index.ts +++ b/packages/mobile-ui-vue/components/page-footer-container/index.ts @@ -1,4 +1,4 @@ - + /** * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. * @@ -20,20 +20,25 @@ import PageFooterContainerDesignInstallless from './src/designer/page-footer-con import { propsResolver } from './src/page-footer-container.props'; const COMPONENT_TYPE = 'page-footer-container'; + const PageFooterContainer = withInstall(PageFooterContainerInstallless); +PageFooterContainer.register = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record +): void => { + componentMap[COMPONENT_TYPE] = PageFooterContainer; + propsResolverMap[COMPONENT_TYPE] = propsResolver; +}; + const PageFooterContainerDesign = withInstall(PageFooterContainerDesignInstallless); +PageFooterContainerDesign.registerDesigner = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record +): void => { + componentMap[COMPONENT_TYPE] = PageFooterContainerDesign; + propsResolverMap[COMPONENT_TYPE] = propsResolver; +}; export * from './src/page-footer-container.props'; - export { PageFooterContainer, PageFooterContainerDesign }; - -export default { - register(componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void { - componentMap[COMPONENT_TYPE] = PageFooterContainer; - propsResolverMap[COMPONENT_TYPE] = propsResolver; - }, - registerDesigner(componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void { - componentMap[COMPONENT_TYPE] = PageFooterContainerDesign; - propsResolverMap[COMPONENT_TYPE] = propsResolver; - } -}; +export default PageFooterContainer; diff --git a/packages/mobile-ui-vue/components/page-header-container/index.ts b/packages/mobile-ui-vue/components/page-header-container/index.ts index 59e9675dc4f..92ddae7dab1 100644 --- a/packages/mobile-ui-vue/components/page-header-container/index.ts +++ b/packages/mobile-ui-vue/components/page-header-container/index.ts @@ -1,4 +1,4 @@ - + /** * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. * @@ -19,21 +19,25 @@ import PageHeaderContainerInstallless from './src/page-header-container.componen import PageHeaderContainerDesignInstallless from './src/designer/page-header-container.design.component'; import { propsResolver } from './src/page-header-container.props'; -const COMPONENT_TYPE = 'page-header-container'; +const PAGE_HEADER_CONTAINER_REGISTERED_NAME = 'page-header-container'; + const PageHeaderContainer = withInstall(PageHeaderContainerInstallless); +PageHeaderContainer.register = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record +): void => { + componentMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = PageHeaderContainer; + propsResolverMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = propsResolver; +}; + const PageHeaderContainerDesign = withInstall(PageHeaderContainerDesignInstallless); +PageHeaderContainerDesign.registerDesigner = ( + componentMap: Record, propsResolverMap: Record, configResolverMap: Record +): void => { + componentMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = PageHeaderContainerDesign; + propsResolverMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = propsResolver; +}; export * from './src/page-header-container.props'; - export { PageHeaderContainer, PageHeaderContainerDesign }; - -export default { - register(componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void { - componentMap[COMPONENT_TYPE] = PageHeaderContainer; - propsResolverMap[COMPONENT_TYPE] = propsResolver; - }, - registerDesigner(componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void { - componentMap[COMPONENT_TYPE] = PageHeaderContainerDesign; - propsResolverMap[COMPONENT_TYPE] = propsResolver; - } -}; +export default PageHeaderContainer; diff --git a/packages/mobile-ui-vue/components/page-header-container/src/schema/page-header-container.schema.json b/packages/mobile-ui-vue/components/page-header-container/src/schema/page-header-container.schema.json index f137b8bb4df..e5066b03bab 100644 --- a/packages/mobile-ui-vue/components/page-header-container/src/schema/page-header-container.schema.json +++ b/packages/mobile-ui-vue/components/page-header-container/src/schema/page-header-container.schema.json @@ -31,24 +31,6 @@ "description": "", "type": "array", "default": [] - }, - "size": { - "description": "", - "type": "object", - "properties": { - "width": { - "type": "number" - }, - "height": { - "type": "number" - } - }, - "default": null - }, - "visible": { - "description": "", - "type": "boolean", - "default": true } }, "required": [ diff --git a/packages/mobile-ui-vue/components/register.ts b/packages/mobile-ui-vue/components/register.ts new file mode 100644 index 00000000000..7138d16210d --- /dev/null +++ b/packages/mobile-ui-vue/components/register.ts @@ -0,0 +1,45 @@ +import PageContainer from './page-container'; +import PageHeaderContainer from './page-header-container'; +import PageBodyContainer from './page-body-container'; +import PageFooterContainer from './page-footer-container'; +import Component from './component'; +import ContentContainer from './content-container'; +import FloatContainer from './float-container'; + +import Navbar from './navbar'; +import Button from './button'; +import ButtonGroup from './button-group'; +import Listview from './list-view'; + +import Form from './form'; +import FormItem from './form-item'; +import InputGroup from './input-group'; + +const componentMap: Record = {}; +const propsConverterMap: Record = {}; +const propConfigsConverterMap: Record = {}; +const resolverMap: Record = {}; + +let componentsRegistered = false; + +/** + * 注册组件 + */ +function registerComponents() { + if (componentsRegistered) { + return; + } + componentsRegistered = true; + + const componentsToRegister = [ + Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, + ContentContainer, FloatContainer, + Navbar, Button, ButtonGroup, Listview, + Form, FormItem, InputGroup + ]; + componentsToRegister.forEach((componentToRegister) => { + componentToRegister.register(componentMap, propsConverterMap, propConfigsConverterMap, resolverMap); + }); +} + +export { componentMap, propsConverterMap, propConfigsConverterMap, resolverMap, registerComponents }; diff --git a/packages/mobile-ui-vue/package.json b/packages/mobile-ui-vue/package.json index 4a8a9c589c2..44ae2193fd5 100644 --- a/packages/mobile-ui-vue/package.json +++ b/packages/mobile-ui-vue/package.json @@ -2,8 +2,10 @@ "name": "@farris/mobile-ui-vue", "private": true, "version": "0.0.1-beta.2", + "type": "module", "main": "./package/index.umd.js", "module": "./package/index.esm.js", + "types": "./package/types/index.d.ts", "scripts": { "dev": "farris-cli dev", "prod": "farris-cli build", @@ -16,7 +18,8 @@ "docs:build": "node ./scripts/index.js docs:build" }, "dependencies": { - "vue": "^3.2.37" + "vue": "^3.2.37", + "bignumber.js": "^9.1.2" }, "devDependencies": { "@commitlint/cli": "^17.1.0", -- Gitee From 16f308e9e3b626ce21b0b942ab2d768409db03db Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Fri, 21 Feb 2025 11:44:12 +0800 Subject: [PATCH 002/153] =?UTF-8?q?feature:=20MobileCommandServices?= =?UTF-8?q?=E6=8F=90=E4=BE=9BToastService=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=89=93=E5=8C=85=E6=9C=BA=E5=88=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scripts/commands/build-vite-config.cjs | 2 +- packages/devkit/lib/index.ts | 1 + .../lib/data-services/base-data.service.ts | 6 ++ .../lib/data-services/cancel-data.service.ts | 3 + .../lib/data-services/create-data.service.ts | 2 + .../lib/data-services/load-data.service.ts | 5 +- .../lib/data-services/save-data.service.ts | 8 ++- .../lib/data-services/validator.service.ts | 6 ++ .../lib/devkit-services/command-service.ts | 2 +- .../mobile-command-services/lib/providers.ts | 5 +- .../lib/ui-services/index.ts | 1 + .../lib/ui-services/toast.service.ts | 56 +++++++++++++++++++ packages/mobile-command-services/package.json | 17 +++++- .../mobile-command-services/rollup.config.mjs | 47 ++++++++++++++++ .../scripts/commands/build-vite-config.js | 6 +- .../scripts/commands/build.js | 4 +- .../scripts/commands/create-package.js | 2 +- .../src/configs/config-build-util.ts | 0 .../mobile-command-services/tsconfig.json | 2 +- 19 files changed, 161 insertions(+), 14 deletions(-) create mode 100644 packages/mobile-command-services/lib/ui-services/index.ts create mode 100644 packages/mobile-command-services/lib/ui-services/toast.service.ts create mode 100644 packages/mobile-command-services/rollup.config.mjs delete mode 100644 packages/mobile-command-services/src/configs/config-build-util.ts diff --git a/packages/bef/scripts/commands/build-vite-config.cjs b/packages/bef/scripts/commands/build-vite-config.cjs index ceacb74bb19..ceaab300dab 100644 --- a/packages/bef/scripts/commands/build-vite-config.cjs +++ b/packages/bef/scripts/commands/build-vite-config.cjs @@ -24,7 +24,7 @@ module.exports = function (options) { // external: ["vue", "@vueuse/core", "@vue/shared", "dayjs"], external: (id) => { const items = [ - "@farris/bef-vue" + "@farris/devkit-vue" ]; return items.find((item) => id.indexOf(item) === 0); }, diff --git a/packages/devkit/lib/index.ts b/packages/devkit/lib/index.ts index 92d11ef169e..81f717446cd 100644 --- a/packages/devkit/lib/index.ts +++ b/packages/devkit/lib/index.ts @@ -1,4 +1,5 @@ export * from './common/index'; +export * from './condition/index'; export * from './http/index'; export * from './store/index'; diff --git a/packages/mobile-command-services/lib/data-services/base-data.service.ts b/packages/mobile-command-services/lib/data-services/base-data.service.ts index b56f600e46b..dcbfd55bda9 100644 --- a/packages/mobile-command-services/lib/data-services/base-data.service.ts +++ b/packages/mobile-command-services/lib/data-services/base-data.service.ts @@ -1,5 +1,6 @@ import { Entity, EntityState, EntityStore, ViewModelState, ViewModel } from '@farris/devkit-vue'; import { BefRepository } from '@farris/bef-vue'; +import { ToastService } from '../ui-services/index'; /** * 基础数据服务 @@ -21,6 +22,10 @@ class BaseDataService { */ protected entityStore: EntityStore>; + /** + * 轻提示服务 + */ + protected toastService: ToastService; /** * 构造函数 @@ -29,6 +34,7 @@ class BaseDataService { this.viewModel = viewModel; this.repository = viewModel.repository as BefRepository; this.entityStore = viewModel.entityStore as EntityStore>; + this.toastService = this.getService(ToastService); } /** diff --git a/packages/mobile-command-services/lib/data-services/cancel-data.service.ts b/packages/mobile-command-services/lib/data-services/cancel-data.service.ts index c9a9ff8b7ea..4dbe8a90cb2 100644 --- a/packages/mobile-command-services/lib/data-services/cancel-data.service.ts +++ b/packages/mobile-command-services/lib/data-services/cancel-data.service.ts @@ -18,7 +18,10 @@ class CancelDataService extends BaseDataService { * 取消方法 */ public cancel(): Promise { + this.toastService.showLoading('取消中'); return this.repository.cancelEntityChanges().then(() => { + this.toastService.hideLoading(); + this.toastService.success('取消成功'); const updateService = this.getService(UpdateDataService); const currentEntity = this.entityStore.getCurrentEntity(); return updateService.update(currentEntity.idValue); diff --git a/packages/mobile-command-services/lib/data-services/create-data.service.ts b/packages/mobile-command-services/lib/data-services/create-data.service.ts index 64752e0553e..905c464853e 100644 --- a/packages/mobile-command-services/lib/data-services/create-data.service.ts +++ b/packages/mobile-command-services/lib/data-services/create-data.service.ts @@ -17,7 +17,9 @@ class CreateDataService extends BaseDataService { * 新增数据 */ public create(): Promise { + this.toastService.showLoading('新增中'); const createPromise = this.repository.createEntity().then((entity: Entity) => { + this.toastService.hideLoading(); this.entityStore.loadEntities([entity]); return entity; }); diff --git a/packages/mobile-command-services/lib/data-services/load-data.service.ts b/packages/mobile-command-services/lib/data-services/load-data.service.ts index d19f41d8cdc..ddd67d5325e 100644 --- a/packages/mobile-command-services/lib/data-services/load-data.service.ts +++ b/packages/mobile-command-services/lib/data-services/load-data.service.ts @@ -30,9 +30,10 @@ class LoadDataService extends BaseDataService { sorts = JSON.parse(sorts); } + this.toastService.showLoading('加载中'); const loadPromise = this.repository.getEntities(filters, sorts, pageSize, pageIndex).then((entities: Entity[]) => { + this.toastService.hideLoading(); this.entityStore.loadEntities(entities); - return entities; }); @@ -43,7 +44,9 @@ class LoadDataService extends BaseDataService { *加载实体 */ public loadForCard(id: string): Promise { + this.toastService.showLoading('加载中'); const loadPromise = this.repository.getEntityById(id).then((entity: Entity) => { + this.toastService.hideLoading(); this.entityStore.loadEntities([entity]); return entity; }); diff --git a/packages/mobile-command-services/lib/data-services/save-data.service.ts b/packages/mobile-command-services/lib/data-services/save-data.service.ts index bb9ff258963..acdd7dcd69b 100644 --- a/packages/mobile-command-services/lib/data-services/save-data.service.ts +++ b/packages/mobile-command-services/lib/data-services/save-data.service.ts @@ -17,7 +17,13 @@ class SaveDataService extends BaseDataService { * 保存成功 */ public save() { - return this.repository.saveEntityChanges(); + this.toastService.showLoading('保存中'); + const savePromise = this.repository.saveEntityChanges().then(() => { + this.toastService.hideLoading(); + this.toastService.success('保存成功'); + }); + + return savePromise; } diff --git a/packages/mobile-command-services/lib/data-services/validator.service.ts b/packages/mobile-command-services/lib/data-services/validator.service.ts index cc3720778e7..b83c96d54a4 100644 --- a/packages/mobile-command-services/lib/data-services/validator.service.ts +++ b/packages/mobile-command-services/lib/data-services/validator.service.ts @@ -13,6 +13,12 @@ class ValidatorService extends BaseDataService { super(viewModel); } + /** + * 处理字段验证 + */ + public handleValidateFields(): boolean { + return true; + } /** * 重置验证状态 */ diff --git a/packages/mobile-command-services/lib/devkit-services/command-service.ts b/packages/mobile-command-services/lib/devkit-services/command-service.ts index 84f68909037..f57a1346ce4 100644 --- a/packages/mobile-command-services/lib/devkit-services/command-service.ts +++ b/packages/mobile-command-services/lib/devkit-services/command-service.ts @@ -22,7 +22,7 @@ class CommandService { * 设置当前实体 */ public execute(commandName: string, viewModelId: string): any { - let viewModel = this.viewModel; + let viewModel = this.viewModel as any; if (viewModelId) { const module = viewModel.getModule(); const targetViewModel = module.getViewModel(viewModelId); diff --git a/packages/mobile-command-services/lib/providers.ts b/packages/mobile-command-services/lib/providers.ts index 87d37d8c7ae..d781e64014d 100644 --- a/packages/mobile-command-services/lib/providers.ts +++ b/packages/mobile-command-services/lib/providers.ts @@ -6,6 +6,8 @@ import { LoadDataService, CreateDataService, RemoveDataService, SaveDataService, CancelDataService, UpdateDataService, ValidatorService } from './data-services/index'; +import { ToastService } from './ui-services/index'; + import { ExceptionService } from './exception/index'; import { ROUTER_TOKEN, RouterService} from './router.service'; @@ -25,7 +27,8 @@ const commandServiceViewModelProviders: StaticProvider[] = [ { provide: EntityStateService, useClass: EntityStateService, deps: [ViewModel] }, { provide: StateMachineService, useClass: StateMachineService, deps: [ViewModel] }, { provide: CommandService, useClass: CommandService, deps: [ViewModel] }, - { provide: RouterService, useClass:RouterService, deps: [ViewModel, ROUTER_TOKEN] } + { provide: RouterService, useClass:RouterService, deps: [ViewModel, ROUTER_TOKEN] }, + { provide: ToastService, useClass: ToastService, deps: [] } ]; diff --git a/packages/mobile-command-services/lib/ui-services/index.ts b/packages/mobile-command-services/lib/ui-services/index.ts new file mode 100644 index 00000000000..cf513ecdf9e --- /dev/null +++ b/packages/mobile-command-services/lib/ui-services/index.ts @@ -0,0 +1 @@ +export * from './toast.service'; \ No newline at end of file diff --git a/packages/mobile-command-services/lib/ui-services/toast.service.ts b/packages/mobile-command-services/lib/ui-services/toast.service.ts new file mode 100644 index 00000000000..ce5d11760ff --- /dev/null +++ b/packages/mobile-command-services/lib/ui-services/toast.service.ts @@ -0,0 +1,56 @@ +import { Toast } from '@farris/mobile-ui-vue'; + +/** + * 轻提示服务 + */ +class ToastService { + + /** + * 构造函数 + */ + constructor() { + } + + /** + * 消息提示 + */ + public info(message: string): void { + Toast.info(message); + } + + /** + * 成功提示 + */ + public success(message: string): void { + Toast.success(message); + } + + /** + * 警告提示 + */ + public warning(message: string): void { + Toast.warning(message); + } + + /** + * 失败提示 + */ + public error(message: string): void { + Toast.error(message); + } + + /** + * 显示加载提示 + */ + public showLoading(message: string): void { + Toast.loading({ message }); + } + + /** + * 关闭加载提示 + */ + public hideLoading(): void { + Toast.clear(); + } +} +export { ToastService }; diff --git a/packages/mobile-command-services/package.json b/packages/mobile-command-services/package.json index 9ab0da6eadb..d2ac3449ed3 100644 --- a/packages/mobile-command-services/package.json +++ b/packages/mobile-command-services/package.json @@ -19,7 +19,8 @@ "build:lib": "node ./scripts/index.js build", "preview": "vite preview", "test": "jest --config jest.config.js", - "vitest": "vitest" + "vitest": "vitest", + "rollup": "rollup -c rollup.config.mjs" }, "dependencies": { "vue": "^3.2.37", @@ -69,6 +70,16 @@ "vue-tsc": "^1.2.0", "tslib": "^2.7.0", "@farris/mobile-ui-vue": "latest", - "axios": "^1.7.2" - } + "axios": "^1.7.2", + "rollup-plugin-typescript2": "^0.36.0", + "rollup-plugin-visualizer": "^5.12.0", + "rollup-plugin-vue": "^6.0.0", + "@rollup/plugin-babel": "^6.0.4", + "@rollup/plugin-commonjs": "^28.0.1", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-terser": "^0.4.4" + }, + "typings": "package/mobile-command-services-vue/types/index.d.ts", + "module": "package/mobile-command-services-vue/mobile-command-services-vue.esm.js" } \ No newline at end of file diff --git a/packages/mobile-command-services/rollup.config.mjs b/packages/mobile-command-services/rollup.config.mjs new file mode 100644 index 00000000000..2b0526fbe74 --- /dev/null +++ b/packages/mobile-command-services/rollup.config.mjs @@ -0,0 +1,47 @@ +import typescript from 'rollup-plugin-typescript2'; +import vue from 'rollup-plugin-vue'; +import resolve from "@rollup/plugin-node-resolve"; +import commonjs from '@rollup/plugin-commonjs'; +import babel from '@rollup/plugin-babel'; +import json from '@rollup/plugin-json'; +import { visualizer } from "rollup-plugin-visualizer"; + +export default { + input: 'lib/index.ts', + external: ["@farris/devkit-vue", "@farris/devkit-bef",], + output: [{ + file: `dist-rollup/@farris/mobile-command-services-vue.js`, + format: 'system', + exports: 'auto' + }], + plugins: [ + json(), + vue(), + resolve({ + extensions: ['.js', '.ts', '.vue'], + preferBuiltins: true + }), + commonjs(), + typescript({ + tsconfigOverride: { + compilerOptions: { + module: 'esnext', + target: 'es5' + } + }, + exclude: ['./src/**/*'] + }), + babel({ + presets: [ + [ + "@babel/preset-env" + ] + ], + babelHelpers: 'bundled', + }), + visualizer({ + template: "sunburst", + filename: process.cwd() + `/dist-rollup/@farris/mobile-command-services-vue.html`, + }) + ], +}; diff --git a/packages/mobile-command-services/scripts/commands/build-vite-config.js b/packages/mobile-command-services/scripts/commands/build-vite-config.js index ea795dd081c..46ef05069cc 100644 --- a/packages/mobile-command-services/scripts/commands/build-vite-config.js +++ b/packages/mobile-command-services/scripts/commands/build-vite-config.js @@ -25,7 +25,8 @@ module.exports = function (options) { external: (id) => { const items = [ "@farris/devkit-vue", - "@farris/bef-vue" + "@farris/bef-vue", + "@farris/mobile-ui-vue" ]; return items.find((item) => id.indexOf(item) === 0); }, @@ -34,7 +35,8 @@ module.exports = function (options) { globals: (id) => { const map = { "@farris/devkit-vue": "FarrisDevkitVue", - "@farris/bef-vue": "FarrisBefVue" + "@farris/bef-vue": "FarrisBefVue", + "@farris/mobile-ui-vue": "FarrisMobileUIVue" }; return map[id]; } diff --git a/packages/mobile-command-services/scripts/commands/build.js b/packages/mobile-command-services/scripts/commands/build.js index 7e2e38d508a..2d1165d6f82 100644 --- a/packages/mobile-command-services/scripts/commands/build.js +++ b/packages/mobile-command-services/scripts/commands/build.js @@ -19,13 +19,13 @@ exports.build = async () => { }; // 输出配置 - const outDir = resolve(CWD, "./dist/mobile-command-services-vue"); + const outDir = resolve(CWD, "./package/mobile-command-services-vue"); // 插件配置 const plugins = [ dts({ entryRoot: "./lib", - outputDir: resolve(CWD, "./dist/mobile-command-services-vue/types"), + outputDir: resolve(CWD, "./package/mobile-command-services-vue/types"), include: [ "./lib/**/*.ts", "./lib/**/*.tsx", diff --git a/packages/mobile-command-services/scripts/commands/create-package.js b/packages/mobile-command-services/scripts/commands/create-package.js index 4e3841c1b1f..99c0f85a444 100644 --- a/packages/mobile-command-services/scripts/commands/create-package.js +++ b/packages/mobile-command-services/scripts/commands/create-package.js @@ -31,7 +31,7 @@ const createPackageJson = async (version) => { 2 ); await fsExtra.outputFile( - resolve(CWD, "./dist/mobile-command-services-vue", `package.json`), + resolve(CWD, "./package/mobile-command-services-vue", `package.json`), fileStr, "utf-8" ); diff --git a/packages/mobile-command-services/src/configs/config-build-util.ts b/packages/mobile-command-services/src/configs/config-build-util.ts deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/packages/mobile-command-services/tsconfig.json b/packages/mobile-command-services/tsconfig.json index bcb316126f8..8bb0215fdc2 100644 --- a/packages/mobile-command-services/tsconfig.json +++ b/packages/mobile-command-services/tsconfig.json @@ -40,4 +40,4 @@ "path": "./tsconfig.node.json" } ] -} \ No newline at end of file +} -- Gitee From 9a9916691e7445cf544a0b26be29c79dfbb84e9c Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Mon, 3 Mar 2025 20:38:53 +0800 Subject: [PATCH 003/153] =?UTF-8?q?chore:=20=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E8=A7=A6=E5=8F=91=E5=8F=8A=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Conflicts: # .gitignore # pnpm-lock.yaml --- packages/renderer/farris.config.mjs | 1 - packages/renderer/package.json | 3 +- .../renderer/src/change-handler/readme.md | 1 + .../renderer/src/change-observer/types.ts | 4 + .../ui-state-change-observer.ts | 17 +- packages/renderer/src/composition/index.ts | 1 + .../src/composition/use-expression.ts | 6 + .../src/composition/use-form-injector.ts | 4 +- .../comment-expression-dependency-resolver.ts | 24 +++ .../entity-expression-dependency-resolver.ts | 85 ++++++++++ ...expression-dependency-resolver-registry.ts | 10 ++ .../expression-dependency-resolver/index.ts | 1 + .../expression-dependency-resolver/types.ts | 9 + ...ui-state-expression-dependency-resolver.ts | 23 +++ .../src/expression/expression-engine.ts | 13 ++ .../expression/expression-event-emitter.ts | 38 +++++ packages/renderer/src/expression/index.ts | 3 + packages/renderer/src/expression/providers.ts | 8 + packages/renderer/src/expression/types.ts | 154 ++++++++++++++++++ packages/renderer/src/preview.vue | 3 +- 20 files changed, 396 insertions(+), 12 deletions(-) create mode 100644 packages/renderer/src/change-handler/readme.md create mode 100644 packages/renderer/src/composition/use-expression.ts create mode 100644 packages/renderer/src/expression-dependency-resolver/comment-expression-dependency-resolver.ts create mode 100644 packages/renderer/src/expression-dependency-resolver/entity-expression-dependency-resolver.ts create mode 100644 packages/renderer/src/expression-dependency-resolver/expression-dependency-resolver-registry.ts create mode 100644 packages/renderer/src/expression-dependency-resolver/index.ts create mode 100644 packages/renderer/src/expression-dependency-resolver/types.ts create mode 100644 packages/renderer/src/expression-dependency-resolver/ui-state-expression-dependency-resolver.ts create mode 100644 packages/renderer/src/expression/expression-engine.ts create mode 100644 packages/renderer/src/expression/expression-event-emitter.ts create mode 100644 packages/renderer/src/expression/index.ts create mode 100644 packages/renderer/src/expression/providers.ts create mode 100644 packages/renderer/src/expression/types.ts diff --git a/packages/renderer/farris.config.mjs b/packages/renderer/farris.config.mjs index 88cb371efac..7b27e66514b 100644 --- a/packages/renderer/farris.config.mjs +++ b/packages/renderer/farris.config.mjs @@ -32,7 +32,6 @@ export default { compress: { keep_classnames: true, keep_fnames: true, - drop_console: true, drop_debugger: true, }, mangle: false, diff --git a/packages/renderer/package.json b/packages/renderer/package.json index acf38ffa722..0bc20599798 100644 --- a/packages/renderer/package.json +++ b/packages/renderer/package.json @@ -39,7 +39,8 @@ "@farris/bef-vue":"workspace:^", "@farris/ui-binding-vue":"workspace:^", "axios": "^1.7.2", - "vue-router":"^4.4.5" + "vue-router":"^4.4.5", + "rxjs": "^7.4.0" }, "devDependencies": { "vite-plugin-dts": "^2.1.0", diff --git a/packages/renderer/src/change-handler/readme.md b/packages/renderer/src/change-handler/readme.md new file mode 100644 index 00000000000..7e60fb18546 --- /dev/null +++ b/packages/renderer/src/change-handler/readme.md @@ -0,0 +1 @@ +# 表达式变更处理器 \ No newline at end of file diff --git a/packages/renderer/src/change-observer/types.ts b/packages/renderer/src/change-observer/types.ts index 3ed6c8ec4e5..09e3ad6c10a 100644 --- a/packages/renderer/src/change-observer/types.ts +++ b/packages/renderer/src/change-observer/types.ts @@ -9,4 +9,8 @@ export enum ChangeSource { export interface Change { source: ChangeSource; detail: StateChange; + /** + * 视图模型id,仅变量变更场景有效 + */ + viewModelId?: string; } diff --git a/packages/renderer/src/change-observer/ui-state-change-observer.ts b/packages/renderer/src/change-observer/ui-state-change-observer.ts index 63d231f2536..996c1dc3585 100644 --- a/packages/renderer/src/change-observer/ui-state-change-observer.ts +++ b/packages/renderer/src/change-observer/ui-state-change-observer.ts @@ -1,4 +1,4 @@ -import { Module, StateChange, UIState, UIStore } from "@farris/devkit-vue"; +import { Module, StateChange, UIState, ViewModel, ViewModelState } from "@farris/devkit-vue"; import { Callable } from "../common"; import { ChangeObserver } from "./change-observer"; import { Change, ChangeSource } from "./types"; @@ -13,19 +13,20 @@ export class UIStateChangeObserver extends ChangeObserver { if (!this.module) { return; } - const uiStateStores = this.module.getUIStores(); - if (!uiStateStores || uiStateStores.length < 1) { - return; - } - uiStateStores.forEach((uiStore: UIStore) => { + const viewModels = this.module.getViewModels(); + viewModels.forEach((viewModel: ViewModel) => { + const { uiStore } = viewModel; + if (!uiStore) { + return; + } uiStore.watchChange((change: StateChange) => { const stateMachineChange: Change> = { source: ChangeSource.UIState, - detail: change + detail: change, + viewModelId: viewModel.id }; callback(stateMachineChange); }); }); - } } diff --git a/packages/renderer/src/composition/index.ts b/packages/renderer/src/composition/index.ts index bb5ef61216b..a7e808b5d38 100644 --- a/packages/renderer/src/composition/index.ts +++ b/packages/renderer/src/composition/index.ts @@ -23,3 +23,4 @@ export * from './use-module-config'; export * from './use-model-value'; export * from './use-session'; export * from './use-callback-handler-registry'; +export * from './use-expression'; diff --git a/packages/renderer/src/composition/use-expression.ts b/packages/renderer/src/composition/use-expression.ts new file mode 100644 index 00000000000..dbf2b7e3a74 --- /dev/null +++ b/packages/renderer/src/composition/use-expression.ts @@ -0,0 +1,6 @@ +import { Injector } from "@farris/devkit-vue"; +import { ExpressionEngine } from "../expression/expression-engine"; + +export function useExpression(injector: Injector) { + const expressionEngine = injector.get(ExpressionEngine); +} diff --git a/packages/renderer/src/composition/use-form-injector.ts b/packages/renderer/src/composition/use-form-injector.ts index 3e8c0179155..714f9e1cd4a 100644 --- a/packages/renderer/src/composition/use-form-injector.ts +++ b/packages/renderer/src/composition/use-form-injector.ts @@ -14,6 +14,7 @@ import { eventHanderProviders } from "../event-handler"; import { resolverProviders } from "../resolvers"; import { Ref } from "vue"; import { callbackHandlerProviders } from "../callback-handler"; +import { expressionProviders } from '../expression'; export function useFormInjector(metadata: Ref, module: Module, moduleConfigId: string) { const providers: StaticProvider[] = [ @@ -31,7 +32,8 @@ export function useFormInjector(metadata: Ref, module: Module, moduleConfigId: s ...serviceProviders, ...eventHanderProviders, ...resolverProviders, - ...callbackHandlerProviders + ...callbackHandlerProviders, + ...expressionProviders ]; const formInjector = createInjector({ providers, diff --git a/packages/renderer/src/expression-dependency-resolver/comment-expression-dependency-resolver.ts b/packages/renderer/src/expression-dependency-resolver/comment-expression-dependency-resolver.ts new file mode 100644 index 00000000000..0cb0db86ecc --- /dev/null +++ b/packages/renderer/src/expression-dependency-resolver/comment-expression-dependency-resolver.ts @@ -0,0 +1,24 @@ +import { Resolver } from "./types"; + +export class CommentExpressionDependencyResolver implements Resolver { + public resolve(expr: string): string[] { + const dependencies: string[] = []; + if (!expr || expr.length < 1) { + return dependencies; + } + const defineRegex = /\/\*\*\s*__define__\((.*)\)\s*\*\//; + const defineMatchArray: RegExpMatchArray | null = expr.match(defineRegex); + if (defineMatchArray && defineMatchArray.length === 2) { + const defineString: string = defineMatchArray[1].trim(); + let defineObject = null; + try { + defineObject = JSON.parse(defineString); + } catch (e) { console.warn(`自定义依赖解析失败:${defineString}`); } + // eslint-disable-next-line no-prototype-builtins + if (defineObject && defineObject.hasOwnProperty('deps') && Array.isArray(defineObject['deps'])) { + dependencies.push(...defineObject['deps']); + } + } + return dependencies; + } +} diff --git a/packages/renderer/src/expression-dependency-resolver/entity-expression-dependency-resolver.ts b/packages/renderer/src/expression-dependency-resolver/entity-expression-dependency-resolver.ts new file mode 100644 index 00000000000..149b0f7a475 --- /dev/null +++ b/packages/renderer/src/expression-dependency-resolver/entity-expression-dependency-resolver.ts @@ -0,0 +1,85 @@ +import { ENTITY_TEMPLATE, Resolver } from './types'; + +export class EntityDependencyResolver implements Resolver { + constructor() { + + } + /** + * 解析用户表达式中的实体依赖 + * @param expr 用户配置的完整表达式 + * @returns + */ + public resolve(expr: string): string[] { + const groupFunctionDependencies = ExpressionUtil.getGroupFunctionDependency(expr, this.repository.entityTypeInfo); + const entityDependencies = this.getEntityDependency(expr); + // 去除错误的到子表的依赖 + if (groupFunctionDependencies && groupFunctionDependencies.length > 0 && entityDependencies && entityDependencies.length > 0) { + groupFunctionDependencies.forEach((dep: string) => { + const index = entityDependencies.findIndex((item) => dep.startsWith(item)); + if (index !== -1) { + entityDependencies.splice(index, 1); + } + }); + } + // 去重 + const merged = [...groupFunctionDependencies, ...entityDependencies]; + const deps = [...new Set(merged)]; + return deps; + } + /** + * 获取合法的实体属性表达式 + * @param entityPropertyExpression 实体属性表达式 + * @returns + */ + private getValidEntityPropertyExpression(entityPropertyExpression: string): string[] | null { + const propPaths = entityPropertyExpression.split('.'); + let propInfo = null; + try { + propInfo = this.entityTypeInfo.getPropInfoByPath(propPaths); + } catch (e) { /* empty */ } + if (!propInfo) { + if (propPaths.length > 1) { + propPaths.pop(); + return this.getValidEntityPropertyExpression(propPaths.join('.')); + } else { + return null; + } + } else { + return entityPropertyExpression.split('.'); + } + } + /** + * 获取所有实体依赖 + * @param expression 表达式字符串 + * @returns + */ + private getEntityDependency(expression: string): string[] { + const dependencies: string[] = []; + if (this.entityTypeInfo) { + // 使用正则匹配出所有实体 + const regex = new RegExp(`[\\'\\"]?\\s*(${this.entityTypeInfo.entityInfo.nodeCode}|${this.entityTypeInfo.entityInfo.originalCode})[\\.\\[\\]a-zA-Z0-9_]+\\s*[\\'\\"]?`, 'g'); + const entityPropertyExpressions: RegExpMatchArray | null = expression.match(regex); + if (Array.isArray(entityPropertyExpressions) && entityPropertyExpressions.length > 0) { + // 解析出所有实体相关的字符串,以主实体名字开头,包含主实体属性或子表 + entityPropertyExpressions.forEach((item: string) => { + if (item.indexOf('.') === -1) { + return; + } + // 去空格 + item = item.trim().replace(/"/g, ''); + const paths = ExpressionUtil.convertToNodeCode(item, this.repository.entityTypeInfo); + item = paths.join('.'); + // 截去主实体及点 + item = item.substr(item.indexOf('.') + 1); + const dep = this.getValidEntityPropertyExpression(item); + if (dep && Array.isArray(dep) && dep.length > 0) { + // 此处必须加上主实体的名字来区分依赖的是实体还是其他类型的数据 + dep.splice(0, 0, ENTITY_TEMPLATE); + dependencies.push(dep.join('/')); + } + }); + } + } + return dependencies; + } +} diff --git a/packages/renderer/src/expression-dependency-resolver/expression-dependency-resolver-registry.ts b/packages/renderer/src/expression-dependency-resolver/expression-dependency-resolver-registry.ts new file mode 100644 index 00000000000..d1fb35e4c6b --- /dev/null +++ b/packages/renderer/src/expression-dependency-resolver/expression-dependency-resolver-registry.ts @@ -0,0 +1,10 @@ +import { Injector } from "@farris/devkit-vue"; +import { Resolver, RESOLVER_TOKEN } from "./types"; + + +export class ExpressionDependencyResolverRegistry { + public resolvers: Array; + constructor(private injector: Injector) { + this.resolvers = this.injector.get(RESOLVER_TOKEN); + } +} diff --git a/packages/renderer/src/expression-dependency-resolver/index.ts b/packages/renderer/src/expression-dependency-resolver/index.ts new file mode 100644 index 00000000000..fcb073fefcd --- /dev/null +++ b/packages/renderer/src/expression-dependency-resolver/index.ts @@ -0,0 +1 @@ +export * from './types'; diff --git a/packages/renderer/src/expression-dependency-resolver/types.ts b/packages/renderer/src/expression-dependency-resolver/types.ts new file mode 100644 index 00000000000..2478d52180d --- /dev/null +++ b/packages/renderer/src/expression-dependency-resolver/types.ts @@ -0,0 +1,9 @@ +import { InjectionToken } from "@farris/devkit-vue"; + +export interface Resolver { + resolve(expression: string): string[]; +} +export const RESOLVER_TOKEN = new InjectionToken('@farris_resolver_token'); +export const ENTITY_TEMPLATE = 'ENTITY~'; +export const STATE_TEMPLATE = 'STATE~'; +export const GROUP_FUNCTIONS = ['SumByProp', 'CountByProp', 'AvgByProp', 'MaxByProp', 'MinByProp', 'IsExistRecord', 'ListContains', 'ListGreaterThan', 'ListLessThan', 'ListStartWith', 'ListEndWith', 'MultiplyChildNumber', 'SortChildData', 'IsContainMatch', 'MinValueOfPeriod', 'MaxValueOfPeriod', 'AvgValueOfPeriod']; diff --git a/packages/renderer/src/expression-dependency-resolver/ui-state-expression-dependency-resolver.ts b/packages/renderer/src/expression-dependency-resolver/ui-state-expression-dependency-resolver.ts new file mode 100644 index 00000000000..6ee56859fe0 --- /dev/null +++ b/packages/renderer/src/expression-dependency-resolver/ui-state-expression-dependency-resolver.ts @@ -0,0 +1,23 @@ +import { Resolver } from "./types"; +const CONTEXT_FUNCTIONS = ['GetContextParameter', 'GetSessionValue']; +export class UIStateExpressionDependencyResolver implements Resolver { + public resolve(expression: string): string[] { + const dependencies: string[] = []; + const regex = new RegExp(`DefaultFunction\\.(${CONTEXT_FUNCTIONS.join('|')})\\s*\\([^\\r\\n\\)]*\\)`, 'g'); + const contextFunctions: RegExpMatchArray | null = expression.match(regex); + if (contextFunctions && contextFunctions.length > 0) { + // todo: 使用正则匹配时可能会因为参数中有逗号导致问题,后续使用ast解析 + const argumentsRegex = /\(([^\r\n)]*)\)/; + contextFunctions.forEach((groupFunction: string) => { + const argumentMatchResult = groupFunction.match(argumentsRegex); + if (argumentMatchResult && argumentMatchResult.length === 2) { + const argument = argumentMatchResult[1].trim().replace(/"/g, ''); + const dep = ['STATE~']; + dep.push(argument); + dependencies.push(dep.join('/')); + } + }); + } + return dependencies; + } +} diff --git a/packages/renderer/src/expression/expression-engine.ts b/packages/renderer/src/expression/expression-engine.ts new file mode 100644 index 00000000000..83f3261854b --- /dev/null +++ b/packages/renderer/src/expression/expression-engine.ts @@ -0,0 +1,13 @@ +import { Change } from "../change-observer"; +import { ExpressionEventEmitter } from "./expression-event-emitter"; + +export class ExpressionEngine { + constructor(private expressionEventEmitter: ExpressionEventEmitter) { + + } + private attachEvent(){ + this.expressionEventEmitter.attach().subscribe((changes: Change[])=>{ + console.log(changes); + }); + } +} diff --git a/packages/renderer/src/expression/expression-event-emitter.ts b/packages/renderer/src/expression/expression-event-emitter.ts new file mode 100644 index 00000000000..09f99865616 --- /dev/null +++ b/packages/renderer/src/expression/expression-event-emitter.ts @@ -0,0 +1,38 @@ +import { Injector } from "@farris/devkit-vue"; +import { BehaviorSubject, Observable } from 'rxjs'; +import { Change, ChangeObserver, ChangeObserverRegistry } from "../change-observer"; + +/** + * 监听所有表单事件并暂存,待有消费者时一次返回给消费者 + */ +export class ExpressionEventEmitter { + private onEvent: BehaviorSubject>> | undefined; + private events: Array>; + constructor(private injector: Injector) { + const changeObserverRegistry = this.injector.get(ChangeObserverRegistry); + this.events = new Array>(); + changeObserverRegistry.observers.forEach((observer: ChangeObserver) => { + observer.observe((change: Change) => { + if (this.onEvent && this.onEvent.observers.length > 0) { + let events: any[] = []; + if (this.events.length > 0) { + events = [...this.events]; + } + events.push(change); + this.events = []; + this.onEvent.next(events); + } else { + this.events.push(change); + } + }); + }); + } + public attach(): Observable>> { + if (!this.onEvent) { + const events = Array.from(this.events); + this.events = []; + this.onEvent = new BehaviorSubject>>(events); + } + return this.onEvent.asObservable(); + } +} diff --git a/packages/renderer/src/expression/index.ts b/packages/renderer/src/expression/index.ts new file mode 100644 index 00000000000..abbc03d39da --- /dev/null +++ b/packages/renderer/src/expression/index.ts @@ -0,0 +1,3 @@ +export * from './types'; +export * from './expression-event-emitter'; +export * from './providers'; diff --git a/packages/renderer/src/expression/providers.ts b/packages/renderer/src/expression/providers.ts new file mode 100644 index 00000000000..fadf1a95610 --- /dev/null +++ b/packages/renderer/src/expression/providers.ts @@ -0,0 +1,8 @@ +import { Injector, StaticProvider } from '@farris/devkit-vue'; +import { ExpressionEventEmitter } from './expression-event-emitter'; +import { ExpressionEngine } from './expression-engine'; + +export const expressionProviders: StaticProvider[] = [ + { provide: ExpressionEventEmitter, useClass: ExpressionEventEmitter, deps: [Injector] }, + { provide: ExpressionEngine, useClass: ExpressionEngine, deps: [ExpressionEventEmitter] } +]; diff --git a/packages/renderer/src/expression/types.ts b/packages/renderer/src/expression/types.ts new file mode 100644 index 00000000000..3eda7f2351e --- /dev/null +++ b/packages/renderer/src/expression/types.ts @@ -0,0 +1,154 @@ + +/** + * 表达式绑定字段类型(表达式绑定到实体、UIState?) + */ +export enum ExpressionBindingType { + State = 'State', + Field = 'Field', + Button = 'Button', + Container = 'Container' +} +/** + * 表达式类型 + */ +export enum ExpressionType { + /** + * 必填表达式 + */ + Required = 'require', + /** + * 只读表达式 + */ + Readonly = 'readonly', + /** + * 计算表达式 + */ + Compute = 'compute', + /** + * 依赖表达式 + */ + Dependency = 'dependency', + /** + * 是否可见 + */ + Visible = 'visible', + /** + * 关联表达式 + */ + Relative = 'relative', + /** + * 校验表达式 + */ + Validate = 'validate', + /** + * 帮助前 + */ + DataPicking = 'dataPicking', + /** + * 禁用 + */ + Disable = 'disable', +} +/** + * 表达式对象 + */ +export interface ExpressionObject { + /** + * 表达式唯一标识 + */ + id?: string; + /** + * 表达式绑定的路径 + */ + path: string; + /** + * 表达式绑定类型State|Entity|Element + */ + bindingType: ExpressionBindingType; + /** + * 表达式类型 + */ + type: ExpressionType; + /** + * 表达式 + */ + expression: string; + /** + * 表达式依赖 + */ + deps: Array; + /** + * 表达式namespace + */ + ns: string; + /** + * 表达式计算结果 + */ + result?: any; + /** + * 结果作用路径 + */ + effectPaths?: string[], + /** + * 提示信息 + */ + message?: string; + /** + * 提示消息类型 + */ + messageType?: 'error' | 'info' | 'warning'; + /** + * 表达式计算函数 + */ + factory?: any; +} + +/** + * 表达式执行器 + */ +export interface IExecutor { + compile(expressionObject: ExpressionObject, context?: { [prop: string]: any; }): any; +} + +export enum MessageType { + error = 'error', + info = 'info', + warning = 'warning' +} + +export interface EffectOptions { + /** + * 指定行 + */ + path?: string[]; + /** + * frameId + */ + frameId?: string; + /** + * 消息 + */ + message?: string; + /** + * 消息提示类型 + */ + messageType?: MessageType | 'error' | 'info' | 'warning'; + /** + * 表达式id + */ + expressionId?: string; +} +/** + * 作用器 + */ +export interface Effector { + /** + * namespace + */ + ns: string; + /** + * 作用 + * @param expressionObject + */ + effect(path: string, value: any, options: EffectOptions): void; +} diff --git a/packages/renderer/src/preview.vue b/packages/renderer/src/preview.vue index 080ffac49fb..f9477606874 100644 --- a/packages/renderer/src/preview.vue +++ b/packages/renderer/src/preview.vue @@ -2,7 +2,7 @@ + + diff --git a/packages/mobile-render/package.json b/packages/mobile-render/package.json new file mode 100644 index 00000000000..7d46764b8fe --- /dev/null +++ b/packages/mobile-render/package.json @@ -0,0 +1,80 @@ +{ + "name": "@farris/mobile-renderer", + "private": true, + "version": "0.0.1", + "license": "Apache-2.0", + "description": "Render schema to mobile page with farris mobile ui.", + "keywords": [ + "farris", + "mobile-renderer" + ], + "homepage": "https://farris-design.gitee.io/farris-vue/", + "repository": { + "type": "git", + "url": "git@gitee.com:ubml/farris-vue.git" + }, + "scripts": { + "dev": "vite", + "build": "vue-tsc --noEmit && vite build", + "preview": "vite preview", + "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", + "format": "prettier --write src/" + }, + "dependencies": { + "axios": "^1.7.2", + "@farris/devkit-vue": "workspace:^", + "@farris/bef-vue": "workspace:^", + "@farris/mobile-ui-vue": "workspace:^", + "@farris/mobile-command-services-vue": "workspace:^", + "vue": "^3.4.29", + "vue-router": "^4.3.0" + }, + "devDependencies": { + "@farris/cli": "workspace:^", + "@rushstack/eslint-patch": "^1.8.0", + "@vue/eslint-config-prettier": "^9.0.0", + "@vue/eslint-config-typescript": "^13.0.0", + "@vue/tsconfig": "^0.5.1", + "eslint": "^8.57.0", + "eslint-plugin-vue": "^9.23.0", + "prettier": "^3.2.5", + "vite-plugin-dts": "^2.1.0", + "@babel/parser": "^7.19.0", + "@babel/preset-env": "^7.19.0", + "@babel/preset-typescript": "^7.18.0", + "@babel/traverse": "^7.19.0", + "@commitlint/cli": "^17.1.0", + "@commitlint/config-conventional": "^17.1.0", + "@testing-library/vue": "^7.0.0", + "@types/jest": "^26.0.24", + "@typescript-eslint/eslint-plugin": "^7.15.0", + "@typescript-eslint/parser": "^7.15.0", + "@vitejs/plugin-vue": "^4.0.0", + "@vitejs/plugin-vue-jsx": "^3.0.0", + "@vue/babel-plugin-jsx": "^1.1.1", + "@vue/compiler-sfc": "^3.2.0", + "@vue/test-utils": "^2.0.0", + "@vuedx/typecheck": "^0.7.5", + "@vuedx/typescript-plugin-vue": "^0.7.5", + "babel-jest": "^29.0.3", + "chalk": "^5.0.0", + "commander": "^9.4.0", + "conventional-changelog-cli": "^2.2.2", + "happy-dom": "^8.9.0", + "inquirer": "^9.1.1", + "jest": "^29.0.0", + "ora": "^6.1.2", + "patch-vue-directive-ssr": "^0.0.1", + "sass": "^1.32.2", + "shelljs": "^0.8.4", + "typescript": "^4.6.4", + "vite": "^4.1.4", + "vite-plugin-md": "^0.20.0", + "vite-plugin-banner": "^0.8.0", + "vite-svg-loader": "^4.0.0", + "vitepress": "1.0.0-alpha.8", + "vitepress-theme-demoblock": "1.4.2", + "vitest": "^0.29.2", + "vue-tsc": "^1.2.0" + } +} \ No newline at end of file diff --git a/packages/mobile-render/scripts/build.sh b/packages/mobile-render/scripts/build.sh new file mode 100644 index 00000000000..1c7ef9ce164 --- /dev/null +++ b/packages/mobile-render/scripts/build.sh @@ -0,0 +1,30 @@ + +# # devkit +# cd ../devkit +# npm run build:lib +# npm run rollup +# cp -r -p ./dist-rollup/@farris/devkit-vue.js ../mobile-render/public/devkit-vue.js + +# # bef +# cd ../bef +# npm run build:lib +# npm run rollup +# cp -r -p ./dist-rollup/@farris/bef-vue.js ../mobile-render/public/bef-vue.js + + +# mobile-ui +# cd ../mobile-ui-vue +# npm run build +# cp -r -p ./package/index.systemjs.js ../mobile-render/public/mobile-ui-vue.js +# cp -r -p ./package/index.css ../mobile-render/public/mobile-ui-vue.css + + +# # mobile-command-services +# cd ../mobile-command-services +# npm run build:lib +# npm run rollup +# cp -r -p ./dist-rollup/@farris/mobile-command-services-vue.js ../mobile-render/public/mobile-command-services-vue.js + +# mobile-render +cd ../mobile-render +npm run build diff --git a/packages/mobile-render/src/app.vue b/packages/mobile-render/src/app.vue new file mode 100644 index 00000000000..cc8c75d340f --- /dev/null +++ b/packages/mobile-render/src/app.vue @@ -0,0 +1,5 @@ + + diff --git a/packages/mobile-render/src/assets/fonts/farris-mobile-icon.ttf b/packages/mobile-render/src/assets/fonts/farris-mobile-icon.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7d450d9876c7df282718db3dab7ab1c38a21b725 GIT binary patch literal 52124 zcmd?ScYqwlnKxY3IZW>9$$55WHmBL0QQDv!R#_kf0!d^664@Y8`G>uI{ROQa#U8 zwTv^yOg7C#Hn?)j@k?^Im9Aur&qMBU8@3D#*P^TM#r5sD-gWxkQ!m`!^GF9{(hMGY z_3S-YoOM?DJt!Yq%h-p%zWdBm&**5L_aw^VKCA6UhV~gbgY@A)1C`XKXw0QzZhmL@GazBz4z387xM4(exze4pF985y=Mj|3RmMSK_2nBd&TC*b^PUSL7znsN>NGIq$hcJCW(kc~58*^0HtG2fn3 zFFl_nm|MMje{P!ZIp^$CQNMeKqa5Ak$l*+B=Sq^u?`AUEdW-ONX zocU~e?(?%{XV1>_e|5k4sJwPN=H|`5Yi=H;9rzp0&7;3-wtV~j7!T(?v**L#eYlR- z_1&Aj2X*9~djEK&pAY>R?`_SwZl_=WeEa?E&|lo|oV}iN29+GC=l??*6nM<%oqNY> z>)hw&e)rsbN>e*$@6XmXr;O9Lv-xw+vt?$VoxPrWcFMQMaBlwG^dXG1^84LYAOBB+JGbkJR68~3RhgbkP!c1>NZwxj@8uiA4#(Nu|Jp{@Jh3O5mG2Ey% z<~NRSJV|-4`{8*0T>L)6KE+;O`}tbj-_Kq|`g!Dhl0Cj+2iOzrarPK{KYJg0ls&@U%^qg&W$$6{V((-Rv3IZs*#qo;b|1T! z-NWu?RhD9DmSI_zV|i9!Mb^PetjsE`lXbDn*jw18>=M?^df0{RB6cym0IfZfoyE>( zyV*JT%JbMBwwImHPG@JZ)7S{>WBqIZTy2OAvr)Ey)!95Y#&)osY!^F~)!0I|h|LGj zn_!b{F|}Nd_+*mBSe*HoAAN5!5A!k|yf6TM8)6m{fOgyPe&^?qqkd%h^751-p`6#ja-8u(z^n!2*f5{{Q{QLmi-js-2%t z6CS%ja(MFg9bm09s=+5f?ypY$oag=#R}n-yi@bvYEIGph-59 zZ~@fGW|A&|PT5S#1yC%TNxJ~rWi!xy2tdVbChG#|na$)}0A;h8ybGXlHdAl`)Xrv# zE`aXYOot2L0Bok@0(b$NDZ2o!z-B5gfIqOAP8Yx_*i4rT;2CVD+XZkBHq+w*_z0Wn zbpad&9L@#s7S_NR5rE6E2F8Z~{Dw6!Mg-tItbs8i01sjfj1d9L;fygN0AFGaj1K`g z6l-9N2*9gY17k!0uEiP{BLeU**1#AMfRnKX#)tqsjWsYv1mGmBf$<>#pJNS-5dkmDV0DvR227MC% zyqPuVn*iX_tU>PpfM2slp9|pJtkLfRcsOeexBza>8iOu?ud~Lm3*hjqLE{PluV)Rq z27v3cM$HBAf7YnG07<|a^Id>UV2uSXKsvC-@h(74u*OywATe0u1Q#GXSYw+DkRq&c zq6?5GtZ|YHkSwgR-37=P);QS(whQM|T!7qR4JrqK1Y!*;2Y@VM4JrqKRALP(2Y`HH z4Qew0l8QB`UjUF((V3RnX=>p^!YtT3WAkkQZ#t8t~#u_wE07yC3pm72~-mwOa z69AHrHE5gwkb$g0;{<>-WDOc80OTTT&^Q4gAz6d)1^`*f8iZ#6NKMutJOe;}vIgN9 z0Fsn72wwq^sjNYG41jcH4Z?2#tjSAbVM3p9_$}tZ{`4kjJcXr3;YE ztZ|hKkkPDhwF{8etZ|JCklU>BRu>$)yB28xWI1b0y8x-q8rQi1`OX^Gy8ubg8gFv} zGM_cx?gFGgYuw-h^Z?el(FJG(tZ|bI&<$AQW*49(u*NMekgnFa)dgq{tZ|zQ&>>jk zb{C*cu*MxOK(AnpJ6(W=!5VkD09}JM?skD@d5wEqfd0W6_qqU0gf;GS0Xhk5-0uRk z6V`aZ1?VZP@t_OPSXkp7E-)46hg^Ub!y4~&fo6M+cez0NXye^3K*wQ?_qYIUhc({o z0`wl%c+v$%{rwLvKo??-54u3Jy~c-JfPTapA9ewn5^H?K1?Wty@sBP*dt!}`x&S?j zH9qD7G%D73$_40FtnqOdpk=Yf(=I^YVvSF@0L_avo^b&>7;8N10<uErYAy8x|?HC}K5`WtJ!=mIo3*4Xa?bUN1fv)+lTCPmNDqJayyLfwjuoU26}l%dFe6?y_}vu6t?y z;QA}q-?{!v>wmpr$A%X+4sX&nUA*a|o4>i`UB@jr?hD6XdVGU081tyl;bejmiV)?) zk+4$C7s?~GDnCYAygQsqg%8fqQOv!0dOFpa!XKYJ`b@6_1s$3e|3jR{8#}@K!JVBq z^>ES0ReJXT7mLmp$jGp*XoipT`lvYC&#Ps{&qX^U)as)auEjZ@D1OXNrR7kxt18&0Rgt(WO2{3O+xZtm`!FO78S z!b9oK)OWZYP+K?20h>nx3co@Lgt_f^a-ux!=0y1Asjd|Mm~`mSp=&YmxeolX5A9md zm|Upz^GbQ7j_j7m2yEza=N@r)~&Xae3>qv6<6=$EZaBOVh8E5}tHZkZ8g}nSOI<|J+ zqe!wh7?2;+w8!K?&?`&I^y}+zt6O$dB~ESpN1;Rrf7!>CV89d=<#{cpJ+COD83=+c z;_uKj+B^+D9fZ7~+3X<3vsh5lygFJfRfi*KUK}kVr#!~1c2%wp*T#6!E^@Tg9tvZ; zM~6oEWHVJ+_eVbMoLcUwebtb`L5jI?8)Zz zt|RG3ceM`SQB*KAs`R<90c1V7L%D?|v1YzM)z99Wj+ zc3ANX01i^C)JK4bK(+}!Is(Eg17Rn4tv(=>C-}G+CF~62DU>F>#nV9IFrh4EqVKozfFrqN-}NYWL=S-0MR|;z^Gn%f6s#%YvHA>m8~})kYHG zR4&n%FZm3Ci;C>^?OR|&ts=hd^0!XMRs>Cv4+9$rowy7L5?=X$3j;hjGQdkf3Q!za zUscW*fjwys^pObzgM&J}JO8Ig0f&y@lWMY;U`hz!VbHL6zBO1)B# z9+S;qvuF3%#KhR{J^wwMSkv+4FVFso$KdJJqn>ac{aeRZ+{eDs@nwAb(Q<18%^v=~ zuNOy0NSf7a;2=dX47-YJuvFXO6DlM@bhy?J{8uvkn60~V_nC{v#ulBq`%klpU4Bn= z)JSig+C0!d9!t*~9*LNN373P&crq8m$;tG`PvC$m+r6I{@G)x zeP31F2czv$?b6O;RF){f`7O2IK(sO2ZAU+&x&_702w-6n7X(4m1HnYP9Ev1LrGfrh zRX5Fm-||~NJDKU~8Xl+*)O!YtrRGhdpn?IaB7RIyB-Y{a2O^PFJd;Sr5+U1w2Mb)l zA53eiW(LBsbb()Gn#p7(*Oe`X1yNSKfq1}<7m9toqt%7=@%a<;l|tXt=JWZhisBE( z;@NCRv9r`w>gw=^g0XwV)nARI(%qGzp5ac9qA9wfa{izsnf`D*)6qSsnO@6^Co&no6;3A# zseB?6vQYi-5|Ll6 z57(=9)b{Zn4t=u65o*PL4qYWubqb=;aILNmN20b`tT-YLssp5`4>}DML`@_M?XZu} zUW3`;3e{9d9@fR7<`ZhNQ(eZnlusBu*_RY*T6s{+miTJDcfTB2)uo4g7}P}YF(Dh7 zwo^|AV?rpZcdoE;^SG(VW<}%Tt)i-k{0u!HE|Zq_=SFkTm^D!~vbBjCr2{6<)^bD3 zgk^%{)5VHVNWQFxi{nwP_1EJ3JecB|VJ`9L+FtF?@oeidz1YR&R|GlT^*9uTLiAy= zFa3(bh29d!t-i`jx_X}^-K`p&3pJndYjtp}uplo9oHA6uOF{!2N{I84>Z~S0DiSmtydOvLQ;KAA zA(3Af=&ql7av%_lB?dF8sDyRDKfKED^!2T-E=$M?7rlWV!?5zbo}6$c z-}%VO4gHeGqpQN{7i5yYkwV1N+@(jtnws#Yyi)8qy$BiXek@(hA?%ntB>0Zf~=o;H_ZX{P(x@glvug3@qymb{n^Z0T;BnJ!? zQgd<0Hv7lB`uPc>AsMBft-B-pHfh&95!-Ye_iJV-(^*>_u(R_Qnc>l)ss2T1r=WCY zM@7C-Q1TnRy(4)s8NMAkTDDJ^rJy%b6ww#-L<>Y&6`oMyn+FU#0FudA&x^(Q z?Mf{7ylkb!aKh-{80B(e)4QzZU?CnT;DOAA+wmADwtMa|POwrZ>c zY0KL&wg#znf*jQO6Gmr0mwD?|w0q#iM3D>S#IsU0&jVZ$s@)v7tG%t3q5gv;J+67U zaD(5|`m@$CFI!$xmSi1T6Zh+t#bsP7lCDcW0~frwsKRwwHyxe*5zJF|!B&1e+3j@F zoM__PPo0PPA9^q!%oiM$$_E^UIt7j1$~b%m7+Wcm=*VzjKk514HpGeWSaoKd1I^eMcXoq~#1DrU-TD#~RjD-b`yCGeL>K8HP7Zpi`cKf0k3kbTj`+GgB zdd13$o?G3Ar_1xCYFYoDP`gju)%tDo6Q#Q3RN*%jA;%d`N8W>b2meNOQr*|cvYF82 zYZNgY)1~EIE015(FFKEou3I1pTkZp|KrF$b$DrAtPBwWiR%nVp${mG)Lw5*A(6DHv zR=1F)a-RUKiJ+M<5`5s(PkB=MCVs097H_onYSFBD&4EBs{*mNQ_ztetO|I*o^rnKE z_bQP$vwJnk+;JU$+DwH6v$ah3{>~p3JojF1cthgx-l(p$&JqLRpmdg|#!@Qm63$pn zi(kb2R)&QHNRP3?Ur7$irJzc)A~^`Wq#=U3OUxb`ZmAZ5@AHeTg{_4+Ud3zO@+sJ%o9fd2x}oqg~NvU$sf1Y{OCvgxqdUEiTAg@?+rPF*Lgn` zH*`sO@IeI@QIuteo)n)3e}#<`Ts27Q7O;q{C!@fYYF^lN>aNB4{{DP(5so?j|L~8k zU(Y`@kURKtZeSoMhI0d`2UbhiV%+xSW?LttpXHJ>4oV~{2SKkSHc5ESwoBC2xTp2Y z)-M&)Rs>Nqd4vn$Sdd51&bbZRVrt5R4+@fQP)W2%@%RPUCOYpIHJD-DcKlEzFEcBV zeZ>7$F{z-ojL}pOzhpnL)w*Laakx4N0%jG`p?H~YR%^45I(izau@5U@Sxjw(TLLSK zQ^Va+pCSv_0oM52im${eX z5b)&7`Th?pf?=7r_2-58`To`yUEAH+9q;8w1f+?Yhg` zM#>eL>~>`0E6yhJvxzr;v=~14vW)q-B1=zxlRx4nTUWVF_;|Y|4_oPUC6#*9mQ3Qw z=9lTYcfAWqVZN*hf1BGZH;uNDJ;kLfKWtfjbK2GJZEBASN<(|lm^wy)XrBl$SW$!G zX-6nd_+oPr-b3&Ef^%*xo}8S%PCRig3DTDxZk!m#CoXQib7X{{-LiJ?=D&65^P}Ro z#VzpBz^V>i7Wym?+tKzsBn#6H*?36hsXIEALiR=5wIhykm|*Ca6de&n1;qLgnQKszq)TOFLKuhkL>d)6gp&2c^kqlz2D0JU5!?9+(!fXutIU!wZjxcB z>`*5T{5Dfp!ZA$BdE6J`D9;0A>&$vFKNoyizrSP6P|qMw+v2#LhAF`p?;c)bMNW(^V2UJ?Y+NM;r++u0!sn9)dne=e^2p%z1>#JotCq3h^r6@^7lK7aa> ztjDj4AYR45qxb?r^~r%sAOtcLx!m1V>R43C1Z3mjPk1g{Srkb{R*4%?OpXOL1=^k+ z&*XiznqnpA_v?{jG@iG)rooKl$tBnKrO0p$@{dQm<2kP=DJl#_+1^YvK9TpED(s|Q zyT1@J%}Op8NvJ||x1{@W-MMrrW!N#(6!2ZDsgI2M!&V?}Y6k310*o;}Zz!p$h2e17 zOP?(Wil!wjHPn+W^yQ%12NH%MnQ<$rg)P659kt>HCTbyvZ%m6HMPy_I*t>*0gce4? z(TIsL`ngVXRxr*e#thj4@zA!qjbV&d3N(|+2*cxoV-JKVAT=#R(;I=bjM0&C;pgji zpLOQ$4d(iEDi&YkY5lPELpQl#Njw&|$IbtG%}sbFwjQ^2+w$Lg>pN=M`BR&w=4TTz zJ-M`+s)p4-$nLDBN|R-~QWd>Z$wWLcWo|rg_c?nvdt2Y(y_DRuCAaLPZ6|GC>1j5X zZg&!k6Y-F>a4oN&Qtw(bKZ|NROUqJ5B0FY>wGfP2BNZE!(rH${{WJQ*rpN){a~qG* z)^<-!aJk?U&}Pz}W*f~Vy#4I+)@@ATXCpPxP06sCP7EgcHw@4z64qlAqIX>)k8V zD0Xx}4;iv)##aTsf~X==SCnb`MC7EHs-~DFRaf+|XJyzM)Pm5h1kp5ANOt-a4aIMY z;=-sm#{-pvQOcG|Ov9l3)abnykq|#n!^7L2G~!S+{kAKVZtL?1$XJyTz04RunEJffJg9%gY{f82x}{xTRQCDD!}k)GXJqhH$nrV9D;=j{1%3x zh$#;EV1lTHW`ES4i^if#Xq=sc#cecpu~-Vu!D3k)RAh~? zSPBsqlfQtl_`^X}38_MxbbDnZ)cH0^QtlzD)f6Rwj~9W24$&?Y1#W6yS-CuOt`YaF zD*1Jghw!$vrQYf*fzUMQ-Kr(M83JocNpUgQ7s&d8$19ss|QUP z6f3-}!2I@fVh0ErKdmbTk8-&uYea&YcrNMQ0_Mt(fR&w%SepXP*TBJjydpx^;c?8=277#KTi*!Titp_QyvcxgYBuG5!?hBJ49hwG)d(=0zM`K9 z0dqE*eL_BryE35^X`4kMLg3zk9KwWIAY+H%IERn}brr%l58DOQ>3)uT&_RTMk+~vD z&uUS)-WBbFRv;LU2l=ZPXsQDDk@l=2Hs8)oI~q1K^Hz5X7uUAeDAByLbM?H88IIa8 zhK^)~i*dkT^G+Q2eMSWHyJranQN{W3V*G-3{m;qTzj?wQ{B5YLnU_IjZbek(TKC3U zx2D+|ow1m9eBTv{oWnfq=oz>(Cv(~ooYTItJdB|lf!m*>nHVbZ`@v{Oycv%di*Y^^ zj7Ed4TzRsLKj9bU#pPHl7Bu%VP;Z=x&cikO2z_G zl~AS&hgvjWi`e1^m%nf>Sm=T#pRV+VZq(mSZh@*dw03c)zZ9wyAez* zJU=WdXFRodUcsmFT5G2D5kuis*vLncS;^GHVR)nKeNyYna=l*WZ|6~d<3+I!N$QAQ zR4czvNGHlevZ91-Q5Q3DJL3uQ50`7>WMel}XTEm;I5mlA3edL|B_)YI8(txhwu;(7 zVU8q2Ge9sSoljR5EZgXp4c}>gBIGj^RnwCF!ymb;(zbI!+TV;XP$<4nu86#Xx6RHCDrF+_C?<1- zr!N$De5(1I&k9cjROpeRa1y8(GIxHiw_o~L>$}27KGXcemxL!n`Jm5lh2o*OAsagn z^pTsi&A()E7cdU-G2~f;!3-?G;UN|o)G(w2bd6!93F)W>YbV-D)+a<&(2 z8g{ipt^_$+%nD*%$U|q8-_E6U9@>ViK9>`7NzJPm#vguXdNjMJLnh{)vjiKy8~JTo zCZvU0Kl@!W|Hm9uljm9o19AE762DFM23iNX@Hs&&D&jV%Y5LDbJj3E56xCZ4wJvm%Kl*R$f1oU)t1#T21oGMj*tySO~DkHR7bH;k}p z?z8PQVhnx!MDFvZ%B`Q4Yqc`Zm+Ol?28f8>497UE5T0PmPKCqi@Go>|tvU~1@j%((M`<2k+qJT6)_fea1?!511pb^9b?#u?W#I`>I?*GLOoF$8?y3>q>JJ2 z;LqC{)jx#m)_bjbxE7jcebGwiV`3_n7Za9p@aM6-seGZZ4V)q@y{EXnaE+*mVxhSx zGn&bajycuD^7(;$USyeSrui@q_!CaUq4k8<`#gd={M>t`mnbQpkA5XO>fu-Bqpcop z3RgyjSXq)j8I5igU>nXw^A}{Qi>Lw|p3Dv8@CV!^o3N{USny@TUl%>xGqd_EFLI)F zVCfM>7DTMtb5+6$q1a(girzsNI~<%kvkq0H{)>ro$H&i|5Qg1z^8!&sTm%%s9p%YV zE(PO4Z?3sN+b4_sP#lqQ@ae%*)7-D9K@Z<7tGpPWp8NbaQIB}LU@goypDvAebc~mT z_4$PsCLe;@`gW$LC&T+;Io(l;zt^c^iYyYXXFWkxes7|KqwQp`ng)(cBUV2Sdm=ET zO5wB|=OMC*y;9kO4R zhG0hUdsXpFqkmlB%eDCxZ}T}5;k$xYGqm_7GiVF4H?$C9FylO#FX;$n>F9kJ>hNFr88yhN_Aea4n`XpgNxEGO$SAOdn^u>io01Su!EO#c(C-Cbr04ko z+!KC~M3ALbE?dcxmE5*+{YW^e1rmH@^VE*HcXmu|8s&+A=Ia<)x8kFcXc#_kJ`#zP zl2I{WmX8}6UB6OP!#$~iWKTF9NPBf%Rb&|!VBL$$a8Gg|)e~05mFq``jw`E%Ax4uW zJfDYY%uvf)hDSz*x6H~Yn)h0)f)xwv5FPdwthsoP%QZpSWWWI_IP==74AOXgUI_z@ zFh~T{lD6ecLS$t5NvUwM5C=I@7TY`+6ocAa9vpRwK`nHPkpf7B*nUBKE?uQkPW_<3 zcK!Ucd@Yx&Dt`H>iuj3m^tbM-==3mPgL_G*9Z6gHExj10NbX_0e}nrO8zMPTMuFC4(cXLr z34SXMlPJ)-%q_uhjpQbg_j0bD;|Kz!cG3OA-xeXB?eHz}#~7{$3EfD1pxh7%G7#Ez_3b>-l6n}(QQ|A{ke$e=!5sIdM!VRmJoj)PG z)fH#WPWNo{{=W4aPT9J4%?>S`3b(%9F%k(4uUIu=2S++6HvojONye9e|{dK&hhe6le|NY4N;b z20Q`3j>*zZV808uoYa}_?9C)7S~=u_iPDeBXd$uIN+hgIuzz6Hx?Qn^@1pHn=hZ^l zP$CwJpL73KIqEwp6px2a3VSd4SV!{*2;~TAV^@r8Ayd@&>ifB;yMn2j;Y&rj<6R>+ z-53b;F6#h;mZf+knavG$Me`BeZ^HJjR(g`5XRO3YYt{{oz{NP+zh&bY3F{M~1V8SU z?LlvlCpr>55P9f=y-LV0$z5Ht=(l8!87yKiuxkm;&pntW=bUvOi?IfjVh!CXlRGg3 zRYTbUk)sz%g)kB$Mfpt&z&tivz#^4v47~^11%|0`%D~%3mN6o9khVMhfJzB=K}rJ! zO+#&f$RJfB%`*a65PyrI{s~Ns4qW~dp~jyO8*jA^3BsQQq4l>nxoz=K`}SX(nabkI zuxKW`x{{hlEtQv4gqM(2ri^lB@xf1Yri7PLo&5_J_IIY5nN(-TqK=M5{58DNYZzq< z%SDo*ysADwCnI4YqxFgIRo(v_;)6>Dx$r#F_lCJW9u8Y7>f2m#>5%>aa5GK3; zVvPi!2S(pl1G=z)>msbV&0Ac(<^P6WlIwT$l0*a|w()s}A!P*N*%T=Y;>WDjCt}S9@dR2B0-=K06s77lgy7MPl_sy_Q0pAV zKu<%31>vI{lo1eqd&LMO8zKWpFNCSnT?T?;P)*Rc6$I`;1R@Z#AI?RnBWl6Np+FCh zb69~@ApK#@Quy#mt29~iDV52x8Q>vAMVaNvisF-GZPiJJt;SZYUlCJnV@@%I86B&b zD)d}>S)XUHI|R=|Scxp@g2pR|-7BJ+?b9XRHDDbn5y)&>=%?F@wsv^w-is6GPE4Hp zRys`dtnTh!y_F8)j@-Cvn;q+x^(y$f9XpHwS9_PPE8*+Lb8uN^^7#xr8&t|DQ7IlU zcI?26PU&5?uERX4)JmZ@pXl<0GhVTKYuQ_>V;qNu6K1u;Q$D^s$aA)i63H%;N-TQI ziI&8NhvPhO{3T=lT;%ET^WI7miMO6NzPe}iR!EIiTUYlu^B8yi2I((kv3{c<#7Ye} z><~i)2IEYOE27KGb#NOezD+zHUhV$%1I?}OS@=+MYkpATy;za)AvdwYlMQi9KVN9Q z;FUrNFj<7T9rXwvJsuAn{bcJkQ%+{E!sEBxGKxu6m3|8+2j-~{fc_`34xOw5yRkRG zTi_48p4O~7^CmK+K=TD+(sCkNe1MZHxEw(RJjVQw>?n{~6fI0>PCV6W_kino ztOI_G{WJS-@ZkbFdYrfhI%;;oA~+{qWDo-YD?LXMCpHyiA0=N9uACcK!%4P+2&N}6 z&DihI_GIfPrSq$qK|{c!C_AHMJ_8NrG%Wp z<3N9B6&zR_*5eQdqs)-vf#KUGPY&@J=^FV1yVt+i9sxDo%H2#Qe_~b|I+JahlBx3Im*B8`m*=Nd$ zrCTd&Qbss!SOZi^JOtDG;K+bATg!&om;HmH#Fws~Tcu=psmg_;cG|MivvnRyrBqm= zR5UWVKe=*c4d;h7YRn^O+iJAz#Z;>G)l`xi`C=)NC{Z^YUD_W}A4#Tkc+t?r7t@(c z+DL|VG!U&s6HAtb@3T|JBdLrqKZRD}!>XwiTIn<7hwVtDi`usz37guTNVTAG80oO# zR1sggG){>}47ZBIuh}V6*`w>zxl^H?TDvyoRtVjKVj1rcUlT8B>vGG%VHi2)XnszU z1y^UovJZE9;D{y>Y8v!1S3u3`Wu&sf;0PU!*v1Iv?T%8`HkI+8ue*M#T$b=|r}XD(Q9=Dsr)Ei522(B~XlFZx0uA773PWWk^q4Ep(l zzL0py$}8>~U(}I#`?F`{OoXmy_UznVpSR+Qd#+g7>aOp&Xh+>Sw0Z)`0REnGPxpE0 zA^<<2<4bep0IgM9Msff+KD#pce_X3(Id(n;L3Ij6GC%=9@px;m5sHKil>Artfp?I{n4YG#AG%ijPuQI{;A_dj4890$4BWR)+|J=-s>A*0 z8a5-R2u6>1A7x=Y9c7QEh-5#S&4+{HyPkrlbwPIH2^+IwS0-NJFIa=4gH|jQh_%-F zN=YyOxCbUxPtnub5DobwQfOd!AjqGsq#;d&%=+UuWLoRy*>)&YGrP~kI z|Deay+MCVivr^aI3%dD!D;&0BOP3~E%YDhRmp|>vdqosk8=ahtOGNAZ*{<{Ubcrgd zQ>|6=)~%UZzrfQo*x$|XH?v;YYMp+V7E9;{-~d(!u~xZkg9_d8gjLwD$VqC(*pbNj}~M9gFKJNZb7 zhNp4BPB7e-qa`lqM@terICFCA3&I!pqJvD#@!TTm(HXvLW)TV>?&B!!m;?@vh)##A z&2_U`q@#$>A5-I7^7Xdj>&ahWH=T>T6F zw6#ln@<)>V?RQ;&%KFZju1CAppK?9Vw69{FxVo!2JiKCfxY)m;zkkEYbl}tTMm7yh zObl!qndhX&2RDthR&8H$UcKM4`s?Q{+1^eM)R5-irRP@+A7bt2Q3*QoP!nwwh3jaa zB=VhNy4wD2H)^((ZrnQT?J%P{Dr*FB^buIIp!r4W$U>BH#&;<^C?8I@-NOPh)|J zuB!U3YT{zMEJyv9==vr8s36Ie@Fm5r6Md;J|CVG5acp{Ln-5Go@knDN0p#J1dJ+AA zVBNMinT&U|Cc9XGI%5^pva?tl8p?2;0L!;4?W}0Tg2|I6QqCh3nkWPw;rgnb^LCzh z*OxAt&gaIi-2d@&PFp=WQ4a3f7S5k`<+fAy9CzjlZR96=2Gmuo2( zob~nOT57M+sE-Sn4G4}bBZDnQnQ$2i7pV)1OZX(5TMu?E@1(?*wQJ_r#v~pKs{CAB zTs)D_Ui@I|{k%Bb(J@^7=Ij}1S_6e$_ zwKG;M4k2#qs1vcfSsx?q9n()7?3g>ph)4E|sYb?yinAn2#MS{(Rbc1rJoygVAO^no ze?5{s=kl}9TrdWw{@GV-d+eH}oOXG+{JH9{epSVu0Y?{gpAui7!mrX(eCaihZMz(* z+gR(u=LUZDD=Zo#J;TMb4vIh|G64@kG(CBV!%@T}A_4-eUw6I1BNZ-e;O`3rgg{@Q zwX?M|&>Ii~0sg+$PQPEo1%Dsz_Te_}^6A6r9sK=so^kHeGj1M#pCk83PVnc^e;&lH z&7GFd7w?=u|KP>*`SbJfaxCJ5sW`9di-9{l4fl5y3n2m@J zfUDPy!!A3HkR7tmwjj<(0ct^_>O3z%xYH%LCCSx8A4j~` zV)R@Tk!Az%XD!999@}Xj!V>H~Fujp(i*@YqDLJNWrJY^L*D7Q;Ic%Im5jW5xuawBW z-vdibdvfGXl;+k!1&XMF--DIvx!M?c+wU-*fe%0Sj3NBop9%z0{?_hr_?awu_{T>w znUUM{=3l9RpzHij@|i5P?dC&{lVzMD0B+Nl(CsCVEP5Sx#`5XZV&XYJ?Og9UuRAC_hx*KWAOQmp^Fv#ge_;tVP=#@ou?fCz8)RD# z<`rjZ8qFijMG&HSeuqEl$6xD`cH>)@xbs1NM_!!H$6A;86B)Ygc09kMU5wum%Tt?a zeoS#W)9t97wX`3G3^J$(G4spAXbd*%Om*6XgQY4?2n1Lx%*L~m;i7tEa*Uuwl{hfP zr{O-Nts4d9$Mi#l^e)00Ugde?hW*f#?O%z3;sE&OMiJ|o?_ z*{OY>8;RRY;%p-<=g)T9#@|o;2<%DQSby{DFlE3YcnQA_0m%qjypBiIDcyqz4neVP zs0aFXMUtd*WGoKDf>qqeohVEE?Ha=QRi8&QXl$@<8uZPfCkKeWNns&X8#6pYORUuW z63uj51v6n{(u zR?q?Nka?ZB9<6M^ePmQHlc4RU+7E$MAc6zJsG?R7KuWIc!;Iq2K-BWfBZxvrq@N_N zZ6}()4n!=UEJTVU;y_V5_>6P@1`5O8@24Zr|M8{jhko_7)?eoH>HysM$$@!v5GP~U z(+!JLnniRS>Jv}UnX6S2x&6aKxUE>cOl(fstmFU@=4_j_AE9_E|) zXbStJq?|)rznI;>t%kVFRYYe%z5i|72&j^r#gGhdNE}O_-~C1dN$WtWQh_u0XLPDm zenzh0O6BjdkK9tOS1R@L+#~qc;W-l7eg4jt9rN?wxNpy~KJ-m?<$0YgYV+UwRnfMY znc`^R#m3~$M|KUG-Z=}|5Q%oo4}W97M~!4UqG_Jn?!s1IQY4c$Z@(kZ6_kR3+iph? znH=a3-hQmcy@{3T+t|P+lF1l1-)<$a-T=Gn+;Xdrd!@iY;Feng-2piez=oY@GHCEe zj+_R!4c28uUC-yba8tdxlCL`9C&I-1CKma-7j#3)sf+SAk;6C*+>; zXl5eRyjsf^vf9P6?c@qge(mrr9=LC9f9_eT0f)8s_2=DmzJK%PBk3im=UJ-fS$gm^ zoSh3lV+1&MPd{pRO5H4afs15d#L%~TV2%N(-cCITvHUnRkQvs zLE`LdN`gdSp|~fE?Hl5uIn+CM_s=&n;42X)(-Dsg)A7(DW`<4t;eTAjIeT-1(VOt) z<~yl^j`-1Yi2RW`1o5LIy5S(Shh^BwdMoj7*o|pFO&lE+q3G;3Ns5BAWyOFS&sImo z6)m0QSX_j#7g9B{rnxm09JqAJanO$BydSHYbs73idTDjB6X$AhN`7{+Fgq!Qodr zVd9Y|AE>#>)t`KEebbYT9Q^glOga!4>$~!n>qm|x$N!{hCtS35_nxWxhTzc;(55n z^AMi(XceyKD0VoFR^KIjy1Dc>SZc~HyR13fe_nCxjxV1f?EHH7`&+@!<)2wGD(bCU z(@%Be9{EJiNBGj#L(7&eb8!Oi5QIjF_0}BHBhB}EXzRs2ujxBF!6te{Sb-Ipb2F_XvScIAQ5x;Q=9&YoH;V+$v#X4Sp zDh;2Af8HpU;6W2x?^b#;Eo`%5zJk?OK7QH3)1FbWZ{$r_>vZIL2eXkS8RoiP7%G{k2|fh!+nbEQi4uo6#>2DxE-ClaV@5W|I@YbFWn2fx)ydf zzZoi2F#Iq#h=qfn&JF7WJ{}8fGwu4)I#y5aHSO9mBu);-I-2_MTVz{``A+|%rd*B9 zDCqDzUAaopox>~bTwH%P)7`zWyE`2&SXRMGcXjb6%9)3M7>MK+S1OBh?h!i$T^;ZE zc6sYcZ|K%`bw?_mn}SMosO8|)Gr+0WuU+gxME*Va{~RB}|1kM7`yu#G)$XCSI+bIe zi&$i>0+pOSRDfL$O4Vh@hJ&4_;4ni305m4740Iy~92A8%Q>Rr9!?Y_PA*vfO>R=^h zk)D9f59pU1XYF{sYP}s|jW=Saq9~?kwCEH2VUCnA$e91q&dwNJ+Fk=Zl6-aJJm2=! zk^iopCEVS4%pZQ5^o-frHE+T6NLOm0r(abQg=OdRufpu$F}h4{l!j}=R>YQC?~?3@ zHk#vTKEmw8|~?^3Y$ms;j#Wqi^2qS1LJ9>7jz-%_z_Znd*k>hNiL4`QX&-d{&C zG56I*_0IJtX-kZZp-Bk8^xMtrj0~pJ2*{N3$^N82Rq8DHXoZlkB-|WE((6T%@|*;} zy0dH3kw5Mo9s$|OeS#|GQk~fTL=fbM6mQt@3vysch+?xOE3z<`TNtryq|$Y-EclJE zPafAe*7b2!^(hI<(rd+%GKHvab*0gn9hI=nuU89z?)imX9*(VUuM`v|^zWvr*(@0`Y(+2z18jIt}*i7EAC z*ARy^X^Xnj5FH7r5Ice4Bh3m0g0LiFh7RlD?3q_gU5)h&_r^G;1_M*w@8UATHABoyY26e@Mv%mmMmu$aOtd^d#xCh(gAQ zKxq^XVfB-#8@k2)rw9GL{@{|hnzIKxr#8KH<5cI6ol_&}z6jPZMENUG6H9Wj(~i~p zgXPBtKiGK0A29t=>oa~2wwqmoR$eYPwUaW*bh(xWZ2r!RsM|yc8^`$|AWGa@_W2{e zK)tkhdP%9ypGCk1LTSHc1-!J}1)H^I`9w14^97R={C-~Qi23b+4-p*!+aK#_y%zJn z*EUSku)iBJyt#sg*lO&|X?j9}5W`RNyY$&*IvirETMt~}A#X>IoeNr4FlYA^{E{I> zf-%*DU9OYma6Z1oh(?Wg#Ei$yC5gOMPI}QA{CkCOSczaT8G2x8U&`Ox>reG9Rij1- zF$s6@P%K2vB3(E1zM_dhUV=MmO(TAKJtgx|#kRj!$NCEaDP{x^(;DAXL&Eq3c z3R&oJLQu(nMZcKSJ5DUuKMC#$qH=@&qBXE$dH}vXu?WjOEsy{%wG$AiK-W=s-$@{b zvtZNNJg^8XMkHDZ{y(6v8X-pR;5k%4=biYH9Jn|5Z?P==!CtY@=Nao8xN2Qx>4lSg z>4nR^$u-4fCnm3=U(Qrve3~x`rnlqx-mrgs&s5s;9c-N~O7iN}h*=OtSYv&GNC(1I z(zgG&S|HaU?B!G9ilrj<=YYag%+1q1T-W3^YuaZI;(hpP1dh@wBoFGrx+Gx2yoK13 z*W+tu)j%xV6%ta3h$;Bg@x_)Wz{4ZMF>kc&eVlK2+@H{u!R&ka?Im3weBl0_lCb>Z z8!lSP{}FFAv`X^i6SaU+$_4{LELk@aNiHoob>AXyCS?W%uOY^>J)7RO&hPbg1Z>f- zu3BANC1bw|A=vzubjBHy#5JEP4R@OXuMndHkeg$J!XAzd79{+e1>|vlilkzZ{7|ui z?m+~yEZa&{%tTdK{-y<=Y>%E_>FDU+Sk6^cm&ZNI(X%sm=Wn&E&e;^z3cSR3g9?4r7|A7OM?tFy*lVcO4Z<=&;j~smH6gQhE zjn>Xb4=+l^yamDjZI6(RP^2mpIT%7|p$POiu^NN{!WMI_X+BLbQ%WA3PL?Ju@1vGi znD$!D>A?{GNk`~a%iCgJ>%jCbuO)O&erodW)(rjo0G{IqycRMoZ}R{-a(YHbdjyoU znt$Y|gY-+9^FJ*96ui9z&nW&U3(pf$w-peVklO1y%Cm%p4u#?a)rTUq9RYw6dBtJ0 zPK-CSoFQl}?M2Pb0))d05nOrZ+VaWjLMncH9W=j+>jMKY#tN~7ts$1r9|>kU(h+C? zs%gd&IU}Ix{^%-hXu2KQc2kdpl^Myd`RRP~$N9|s&a`2Kdv4m+5vzELG0(QCP%IYO zz1um)3$b%(E0A-}p~$DT+dQ#?=M3Slr7N_6$C9DIV>KR@$ihCNV3$hlorGO-WDj)M zv%9hFM_AZ!;C#>Eyjo!h8+md)I8<6NHhBK$)(g47>7H28vn^JLZHX1}j#w;sPOK2$ zf{bnS74VEXef(MR5pfwJILh!MG7D~yAt$083<*o}pr>O?R^TcY@?q%)$H3G4zYFeY zS}F62#}l*b^X#=#_Pn|s^Lmei?s4#aIPmWO!cs^62tOI8{}MiwSsb}A-&a@g~&2v6P^R{30w(Z|SxdC|B#t9mld3~H3; z!Fw^^A~RUg$~(~yP8$EJ!_7n+cY@D2M0H9 z*>(Eyn+J#a(BP)yPHnxmaGlo&QP7sT?EI%WpD|S2vteYF_=&B&21q0# z*Ah)gs8}@uH~|8N0oX+L&?UQQ7vH*pNa6$vqH*yE^hW1Bi!V-3xI-cL8U>j|iCUY_ zhrK5G+)=m#LSC~*dxP4dzCmNv+>ZMxjmddf+AEu$vriUH(C0sky&-qO9lF^^db+-w zS;&Q_r<~@(7L8V++^kUai(;n@ZKE3iN1#$eiYSZFV>2!XCZCcoPOf<5tUDNVpM^~u z`$*L6YF5-&JX=w(NK{$NYgg9dCv3%q)voMznWb9dXtN)gU6EPmTyK|X4Y@?Jk5f29 zYh31vXtcuYs_m;SY{vyZ;j?usYYRctFGI(0J;AR5=bOblWEH=~DYgp8%1n@!XFxHN zsyfJDQ2F5NxS{b*ibb@KPX345kb1*5PU z59k2cR&{4%hgr|6yTTfeRnyz9HET3x?fUhgERE}#6=+K94OXjRJ-@d1YOEgZ>gxjj zV2#UBS78CF39DRGWi%+(d{3}wm2RNyi3{S;s`f|KIEqF4_*j)qX);%JRQ_B8L}_iW z#$+{Vy5)ptzae|{YO&?l04Nr7DCVozu%@oUZl17h%Rs$>B2ZV_i-v4!3>*v%^eJGK zkT4A=(9r6Fh4e1n%2?sF)htHWb<|9si?s`^BPRCNbZE}ibad2&0EUF0aK1XMy+@&w z-uh^yrMX%PhMQW#ce0kXEj!Ukf=*|#A3qCP!;Ue%9{4LCK|Z*}9=QF98H>7vy%jq< zG%1=zc0ePl_!j(4Y)mL?tqIz-sTlG;Cs`i{CU`R>wnyFNfmsP;a0vaIiHNYR&-M&uN8X znbi#umRPm1PQCi7b;@N&S9?20*Hs%klh^?0Hkur!%{n+X^J`Cagxfc+UZ=EKL}hP} z)@0Id5}ih?&Cu8zX>Extm999aHyZU*RmRQ4X*_|hCKTg$g_{CJ!U$Yz3lua#PtA6TZ#l}4Z~2BS22)}#dWOcqQ~M| zhS{qv0ke5o^wUMkp=5F5W~-ll))X^UnM`Nz1h#LtlzQF;Xhqr$8}B|cAER2MF^xx#YKL9iM567Nonqrv+6pg0z+pUyeWYyqvD()Z0yp%HfvJ+Zg(H1LVQ zf(3z3tdy!LID72{fQ~>L;Z6hq3y0_DSKQ9WhtpMCIj^I7COa%aGy6=QpyDCdA;~uq zP2hh;K=tt5zZ1LvY8c?q8_pRMhd*Ym@kuZEYV;pQmx>DC!L{&hm@N~k4X|W3N{<_$ zL#8$K(IfX4Zok%DQQ^L}H6q!Gslncfv`Rigq+vC5eP)yaF0b(9tdBgd6^$6zB;)?G z%J4D7g+|C=ZjaU0l8_6M&yucP8Yi%I_Vhq!?%k3@dJaX zyFS+5zM;KctaeoZZ3D^~!-V8SkfLV*j82~M%EI2NCNW+qd=fYEq5p+!Js1$&|RP-5V!sJbp#AhHL%@$i@APA zM__&(tias%Cy5jPN89XB**+`&P~47rznbU)CDaFCRwHZnicsZu1jGw9UH3eC{p!`% zKl&BPUC-Z=AAilRqL?!&OV{&si>dLoriQiAqLtbXun0JVa}mXrk+( z+JLk@P4_x;llk=d-iCv3D=M?Lm=ILLTqDc2qK=w#6a0NwNC7q+! ztQTsyAJSQL_5;zNEAY*cDGYZ_PE2Lim=A3uF_Xp!=9K1 z>UD5MTwPjbF4y(Yvms;+d!ulL4VBhlAPm=H4GbrrgdnZRBUdCp6W# zRckb@Ffewrv-KyjF<5Q$R8@IwYc;l$^(wdSKS0h0A#D-tE|(o#7pFq^TaD|CR=cTx z^X7ikEp!J^!A}Zbz#eiNPKUaJb1cA>BF+=~0EygY_LB)WU~=7;5DB!kLUIh50Bt}c zM5Hfaggq4$ihD0R`VBZSZd%|f+J#`NY2yeVXS3>ZS}9v}%ZpO)3Sq^n)E%n$WitKaOY3NxG``5D6D z_>4w(tu0_w8*EVhXYVrM(1LQ8x4h;MPR+7IBoL^&Mz0X>wzyr^rY5V)WxX5c2q>=! zS3vy~?_DbeIx-3vxaw6gM+D;FGwRUp_CTFR z=Pzg=CKm+lH^8~>fEp{)XkGP{j^#n0Nv#3aw5W6%Y&w#$A>T`dpJTSbMlnM9Ayq6e z))KI$mAMPZ8)gH}%!C1lyi3ISgT=Qv9LU{HYGNB^5Wc%8ROfV?3}GYA5BZu> z~R9=WO5EPQ0 zTABDNbaXY~7A^t3w!3T$XJOw0-HXzumY7NMUJ|DCnCD5*&+lNXfPQWeK<<~c(uj7$ zaf+pVimaMe4;VEf++@P8eSYW*)d4W;KqvynIiH9Awtam&e!_!=HU1i_zFKLlhIqId zcn#%BQx!Q)%Amn!uZkBwt58gd3ZphFDtidl6Ii$k#f{AVFsT4M3>ki#LcE$@TqPMPxC2G-T~)}VO_tXy%D{O(X`z4l3^dO>L8FFo}h{D72*&QA3$oD+KK zyn0UOf^|86$4xdG6-+pTLl7-_SICtwIoLyUpJZ=Jj;AS-J)#~DF*S7KpdCm0apwcC zzh3$Y$>19^4|JOS`Rm2^#U9W!6*zgK8>@JKSr#XspDuf#?9sBXl)ZpSu-IzYGsz7p z%I$iohnYsE4J;O*nI?zeYt~J(*#`@a#f2z@xgjY9T2bk9oZ%pnuGVbV!k$6SiR^`a z27On4kRwp9Y-tmJenMk3YQ_yV%$Hij{M$IaI)V98`VC#RClCOaqN~d0_1aEA(d-04 zJDuQY-szbj(tG5z8OJF2n9){@c?yr@mT$~BliF4A=3%dcEJ`u^8JyTR^Ie7>JjSz# zK-2$03E7O|?c`%KNXKWgLJk9|&KXXy8|AmtIV4jmsd#(oONjTA*>6dO*>6e5<%sA* zL|cAN@hj*L$T}=#q}NvZFB}n$6mBits`%CW4puIHe|mv9b({1H`ceOrX@Al^AUmgE z(bCDvPtLZsz}yP-NR$RYpx^l%FeR2vO%=+fgm2f+J1~Zh%^MI~I^iPp_ zLTne(qAc}IF3hWEs$x%-b?Sw(5yFVYjv8m0zdY+4+3~5XR;;+{Q;*BHjMj%1wE1*@ zVG_Qq(_O3c+jZA!VZq<@I*vLvza4D$`f9k>{<w0`ZiI=f#xrPE1o*hBUJtb_teYsj&%wtl28hU4k5MxDPy{H=Hdyb+?y!QvJ8 zI>j}tWl46)K!xN%BvLCvCxJ&yB5MdRu{?ptN1Ezbst6@t+@({iakQznZ_n;M$$O#^ zwff-p%k~|3d{H|XODbz5tf{kE`c}Pq{OIVR>vh`3h0h&3oIRX1)dU3No2EMR6wE{^ z{%+wXT8t>DtF83=ZMMJIwPRoMp@j_!abWYty~*A7u+d`6A3Ks999JkhyT5z<=)~k1 zx3j8R`mtH?)tY~AVdfjO9)>vqLYmv`R7oW4ccIKcec>WP@NjTm08rutR01vAuw@jo z%+mm1PR2SmcI+02FCV|ncDduB^H*AUK2vErV8#{0^g}1>6WKnP@3RdQhHPpBmYg*BCp3-iv?w)ze zZm^dUM)HNvnxau3ASGR0b?jR@*z$Tjm|lD_DPl95BF)WqAF@m16g2JmYrry*ZKak# zC;e7CG=ga6(`1dQ=36%X5N1zK9 zw^Yz&z`h)ddy$?dY8o027x>BG#e9QKR6_!5Kfhz+PILj;N6_ZI8!@X9Y5-{v zVY-sfEax^6vBki^Bh)C;J}EMSAPk8?Us>Jmj2 z&%UtJUSl`fM{@f=fAiY4H-G*dZqn7sb7j z*f}!z*r;ZK&KRxLwiKh_wtq+H`R7A-|9E)#$9IDcn6clofj8faToVr>hQ^8#rde}4 zo%TZdrGLQ81A2S3_(Cs0_+gt}|Kt|Ey$v+?hx8HsyQ1=^moPKP4ejsf?CjV-^j66s zw3+|&3NzCyUND>4Mx~Cey|{hB^uWAmJU+F-YK%6;Ul!(YOVC=^rk&~^7RJH3_m7z{{E+QU=(*#}Y+UbcJfA^gK_r57tZki7A= zR{B!JE4{*B@F0Es1?9!pW^j}{4fOu|b7RZdoQ;jDCR%I?^*sd{ZZ&!jEvZ;yx$GF* zTLQRIVse_xRTTFZdh6HL<0qWs_kvU4g5v^2$Q|Mo{N@Gd?Wo~zYA6&nFKBVz#^fSh z^scZO~iq#IA5L#_=*x+N;Xe zLJGZ+MlL*G5-#vfgsF=uN9Ygaql z`JZr(fW)L;(j9xTYDG&$z;DqRDjfSN8yhR7162zfDw7s3K)h>XmgS9CFz~zd(3Uoc z349ioL!>{|i>AO&xJGGjSh8xV8|Szg9N>&JE?nMV4+OQIo%{Rr(!VOe4^s;Z973(I zh~eBihbTG((3Fho?YxX1Xv4T5G_BIyRW*0+!kol){I~(5jBGJ$o;GLRdb-h~yML9= z(g>;2Rl1PwA4J8ui`YS>2Kt*4iKhO6Z#(a6FIfFksCr$&D>n(FSE zaZG<_UJM>}PW~O(8};zH>W|E9JF$H~Fi-taxm|l22ds%o@gbYg%k6)R z{EnC?(mM+AN6N7}GT!y(AJd)}d$fHP6 zxzh>DHF>56djerqe#VPihmc3OWm2u3#F1 z(T$>Fjno$5atIw=ul3oV#r}B+8a@w_0{?@EDBWjvJZtx@nV$X?TMWsgOZwVY!VB8U zp1$$M*PtW^ttFafz^^+0y7)HcMJ;9%r9B4qQKcH+mtN`o4cl_pU2My5I;TF)Hoeot znxyYGy(2wQwzvEr}Qt`spYNqj)uWBiGz0nj_d(x$GCKRf%U-UlA&ec&8BXIHkj?ASFP z2#oLA(bBH8vvbl(v$C;a{f50x=iUwL8yb~n0o;<_^QfU-HZ>^?kMG;lz1XZ!m=|~N z**DJ4H0+b^-M4j9OB+sEG_zgM}a&ttbPA8eh_DwTB=!n?WV7Hx~?3spBYZfm#e^fr@S z8B(cCRdEFl^KmN|Mi=S*XB03fFnE2|n89K+TNKd{Y=N|aZHM|R3`zkQ87~}vW%-fI zJ^rx66tM5Os_&KK8mn1fUZYWJttP$Mpf(6gEPeai-?{B0Z?z@+EGmay3*~mldaKT$ zY^%4powj8S5v!$eRH0BC8*ISZFxx6kdYp);wcERvbT2j-R8|<@p>K29DB#}y7Sxsp zt0Q<~982aYihoOOi^~<^=)zy*iW$OnXoBJU27E?lUy~UJ} z+_^|)2WH>A2E6f_1@#^E3u@xtz`O_40qiO;2!0@(1l<$FPJrg~GB8;} zXm#oZCKf7gXMpHU<`3ixW49T%5|cThoY9u21ayWV4rl9|Y~amSrM}!PHa;)C{EY^M zyIi*`rBOJ`)x&Cq!}DlNGxjn^h@yXVZAdkp0| zgW-njufM@y(3PM1sNQQ)=;^9FbFaaT{rJ5`m)cl<)}YgS3}+2meR=wNoz1JeUd!yH z3Rbkq2E~LjVtmU45%EuCi4U~f{FUW}?Hm>85qIUA>~}Ab0J88DU0?ba;YPWyoIeNp za4D#-8qU34F-$jU=ig=YrZ+6w z$rrrQsCRk_S7FJwI@#in&vqM3F2xAp#zbSp&e##H_DIxQxR&Aw*LkBoJ%#5IJ9!@) z-3jAi+7D5FdvPwDAM*xjg3ZgAveIfN0B*8^wR5_kmYQA>mISgrK}5WFdg@ndzy8c) zy0GRKg%Dn}MIvHv#8)VzKq9Wag*LX^pwM3Zo=LDsy}~vM(uU8e@qOA8PvQI3=vC{W z6`3o$iALDGY$WW}FvfslV;8U;dT2(gP859-l?iwW@L{De#2CCV5PAL4fy7KCk%&zH zbGW4?>{aN1{Hooggy|v-uWrU6t%6=7SQQ#A!%;xx|DD(3R7-gJpXpnoJKRzL;i|7t z>Wvq@u@>@H=?E5YCe)lqytnECKrCiVzF+W2c-m<2TR;}iJp-_;y~uL`dCvvf5ZBBR zdjo;-f@kb`=J9RBKk)o`zrkWLT-ItS+C1ay=)GRIalgHVvkZBu{NO*8)VNnTu71rC! zCZ)gZW#`1QF6n9M=`J=!;r^fFYY`@ojOpUT3{|QFFrkQx1LQ^!41~kT1qUTg2lj_t zi-i5>!Q`IP1owA(Px9dK-pg+z_idN&&FYNWM^!eX>S3Uie&Fq}9P3r17HIqGM^#3f z>g;(f1eS!Saw}vTB>$05ge~Pq&d%I6kylTsEVyALhjqsSY9lH-L4Sb?WABg5X6EI+ zm){<(sfpfx`QDKelVeMkEn6}+$rPD!a*b#5em~BY;;#|1R027YpMpx$rJzhf(F<4h z_p{GPk1;3${u%PDW$id7JI4N$JWEfq(+=qh1;74DnV0@iy28OuOP8|`IixJ|KbHsA z#I-dpH40GU7w7CTAO{0taW1&eT+Y{lT?02pqS45W1G}D|bxMyo9%HK<(o2^bI{ph| z$dM(N;|pvpVAbTj6G0|0PK!mcUd@nUAjvL$Ox#Pem|H9{3+Bb1!ZBRMSL}>`#=UMf z_^gZC9^(}ictSW{2FftPfHwy0N%1=AIvjFy-A346C4S02A&OFR8`~f~c|mvr*=2yJ zoEKh*NJ-dDd}13~c*8urEFf}Tk~;~~Yc8%ZREi)5Em}`qs#$I!LPz)f^E$6x_w}#O zeYjME6qX{a_S`wG-KTx-xjAk=kJ5gqx6DhsA!Q630Rnw3lDeD-=4@?18quEPLJrHx zS6X^kcMtE_)|^N*Z`<*m0XXcosvj4Aw`JuD63wny`C!S>`?FeKpd~S|^Lsl75-sFN z_jGnFd{y|Dx|$WMKD}y1E&g#w4G>3W=Xjb^;Bo0W9-A3VbznGgPBuVAFI96askW=7 z*KSwajjH?MWG(7TRhjf84jp>!b`>+))c4~^ci53op5%TrB}~zJP(we|1Rep1$Z3c?9ju+`A)Lh3=jeUrCr?$waRw%bI3kQx`~S!8?RZud3jAm z{hD|nzNY?h-ite^E3=zoD`NP?H#8}B>`*jqi2oihKgqj6dWXdnDLhV^PGCM?C^^>ImdjIE_~2 zPDI-=WkWD8yRqe*ga0(kV7sIkf&HkjFWytvBlHT%jT%*#vQcXido-(;i<;B{51x-j0^zAyQ+bO53lsgXHpYi{ z@90~xQ3BY0v@IHaRlc!Te6biFb+@yo2ls5aX|$uGwfW|IZfFZx| z%}#KTxhhdSOQ8D)+JZxH^UXQ5XL)@9LJ7w=yTS=St=?0< zjJ29{Hm&JCGO@bPq_ycx_mW|h*r_wRZCz{Hnj4w}b{I+H&?sykw9uz?1p_vx-W76a zoq9F1=#{!IlgeTT9e}~I50j` zTXSmLuFvn>cB-a!Xl(HD`}ZYxt-W^r)(5w)zjp1e1AEzhOEcGJmh#Jjwq0YFx3*qB zwyUl1uF0~Yue-NrG!P61Mtgd@`!-li3k-&~cw%y&ALr`qn@q&p3+lkS|J`n5;K!0MNl&&9ipTEz!{;PHu!#YiiaE?ydOj(xD-q!FhgV{ zi=ZUQj$meB@%QkiaY6%xXNOu6e+~k`=3nCrT|LQ!T`lys;@!SG}I8bastKV-=Y-7VTWs%YcF} zd{wJeMkAM1+ZKeFXjN-9cAT%hKGtAlZ>Zft^t-xPU%=y^`@%Yn&TiJ&ea`5@aI~SvR*lm{ zOy=d49RY8|?)KRXW;=p}`|1~1SG6<+f(sPx#+_U$?{hXu9wzzUp&>yqF*xjtOTTn^CB~8ulwJnJX zvqo)%(xG$VmB!{_myyy|da5g(s+Q_VI4-hK; zzqRM|NB?l8F2^#x$V*CMILR7KuOaJBxhdn}{CyZ|7Z}Jzu z;$K)%vCz+~;NCp*II(c(g42uHLYm&CzsFi~>~fI5>coIitLe}(i{U`hXc4p>YHei< znlfspep44Rt1N2$KPh}+ukfBX9QI0&QCe(k1tnimFaot6U;HV0Co|d&6JYTI(2E_{ zuh!|-=)now+;7k;0s&EP=-;fj78YorWDf&!)@oF1L~YnC{XOx$Ky?E%@jB3_7Stf2 z2mp0j<}u1sAg@O%DnudRGIB})x-F<76;!4%Me);(al{r#IV>*35(aCG=D`ap4XaJAhb=CP0K<68ZB{s7kri!iQR-0$D zJ>2LmyyFG`n{Ae+ln&9gmkEs_!5gaIM^F2qCQ#iJ{#^NzuY)-VWdZ3W`OY5IuNl8) zd<_try&$4A6cDcuDDZeb-5NHZ~8a~Utt0jB}fS8S5u|s-D z<>_^8m);81i;W>>->xd}b#MQ&+8qje*WK$BrAb*aLB77Sd~EUJL(4@qrhlPrps8t~ zO;D ztu*kupYpBsNxQt>(Uyp?I?|fi`zwU~YSFAG_Z6^JaJ%{!z z(FqEw3-*hB-+{fb|FTc}e9}qZI`2N|AEK?TID~qicb&!?_0Ig>Uoz6wIkH5A3{J&b zE^BPOtc5|}lFC?CW-I$&^6nOH$W4lF27M%Z(Jg>i;w!pE_*WI(3b^ZvZYAWZ%|*8g z{yjyv4zi||MYkR)PJ+S#p^NWC%T5;E3}gCi(JcTc-t;x)pH$sOVP0>izAa zTLu3@(XA`n&WuI3zAVZHmuFMSd}=6k;8-X_%I4CU ziBMC+!jjjj)I=&xM!)QJ~+1c1g-y#2o z!OS?sY}v9DjMehE4wZ$V9)AqiblD&_HWOvT{F?v3^Hzi&!Ehc!%e<|c-4DJvbklr0c zI)ez^zzL7SJAVcNRrzh@X!;ut{i7_@VuJ z6SNu7l2(S(sF?#C4i{MQ<;(+JSs(Kg5sL{t#41@8I9c(At#V%*N*&eo+?PL2{k{w`!Y>1`UFdJc`EX@wGLu`zV zvk8`Alk5tXWjU5-huIN!lwHY=vEzWdx{6)Ru3^{W0GsRB33ifQ&u(BhvYXh=>=t$_ zJH>9p*%}{Wr`cb!53@ViM*!h>C%cP%jNQ%dVQ1LA>^^os`#9jA9$*i$PqM#apJJb8 z53$d%huK;7S@sC~9D9^K#{QZ;&YobOXHT*(u)kqXu`jYOu`jc)u&3Eq*)#0fGHotC zp2?=-nI=sxK9m|ua(ZZJ7v$;C6-k>o`BcruUi5zipbNH%kLlDme} zWBF9J34ViPsbn^uG3Davv9ZIsJPn+92C0o_##0k{IC7&IMADUfGpgT*`} z-O>Znn@AnaAwP8Eg}5v=F_fMdL7+9`lbI|&j<+j^C>L;S**cgRO5sz>vgy?DU^17o z=HeSO`SfsFPChd{j9{Bn6NBk7I4;XmJs^|IlG){mX@*yFEVUt(%OyupMr3S#I+s6^ zP92SBknHC4VE!<*0jln@Mw;)(<5qU5;+@8X7fl8pP+o=#mXxulM_R768Pl$ z3^f=+T$ainNe`w_l7Xb03Yu?jD*TI=rSf^C6VDiP@oktJ$A-4126_C=*$i4VrCOh! zK!V0?xm0#0Fp^J>WK(hplG$wLXnZJhbb{JxXh?3aiHX#eD4zUsEH#`*M&yUXlQy)~ zXln4#fy|Y%BQ=D#B`->al7v_4%E8g(#7GKWyieh~JXC53KB;5)J~jJTCYPco^oV30 z-yBY*hU9*W`lceq2h&-^=NTK!W^y^i9#2mk&Y=TP8B4+P*)+a3M*Uvy%=q4LCVMoK z9YV-SbY=2D1Pl)fLrGIrr^k6~!b=`OXq9YgD4i*O7X`_tXldYqbB6~9(f){*O$}#L zxltsYLq9cj$_;o zqhk-H^2zjA&OFx-BU28O9HjA=8RCPh$;iVTIGjsQpd9+*)6hsNujTHM^l;wFU6@S< zu{!c-2JVxdIFdnsl>?4pROq-jWhbZM&dKC4IVirKOAj4WV-`6KZAdvMgBjE!)?0ZX z$^j9B<^~gwz6Ko~Yk2mU{76l8WolvbkX$g{hV-1W@X&ILk;kwcfOmL2CyJ%SKpdhT zAit$2xmD!y73(gOA5CTD5C<~(d}cg{Q7wO<7~()CnU@0;J&@A8BzR-Z^FhG$#Jo7D zak;=4ek0lBF}dpaz>upB{&K}qsf%xE1QxS~NnRcz@+)3cIl-|^lI9utq1g51l;}Y& z$((L0hePM59$l=+^vGylPQ93CbTau_Ziw6J zNOCMWo;i#upEnfG?2sHhJyFby+!0F?fm|v+7K-8c+@74sd*vi}av6-q^!S0p*&N2e zMBc$)<&wjx{IO&%hYpGG@+Y$?%pODXH!$yDVopuWJn>qWi@td@lh2?%CP$CSMW3AU zke|^klk${b9C4Y+eZ0%Whm(UTIj{MWpZslkWtP8&DKYWVQjC}xnHT!TDor6xu%94wBk zp)6K&S^(rM%41u0%hQhh>G8v3`Sj#iYH*YWy4RDotl1Moa<-^a$Bz{U zB6sr|ms6&fa$va+%s%r#PM$6DoIHGBEIl}h;h0OwJ?TPU9zkv_dNm6AN3QbH6AwVN G@P7eOTc>OQ literal 0 HcmV?d00001 diff --git a/packages/mobile-render/src/assets/main.scss b/packages/mobile-render/src/assets/main.scss new file mode 100644 index 00000000000..13dd3a5ff63 --- /dev/null +++ b/packages/mobile-render/src/assets/main.scss @@ -0,0 +1,88 @@ +@font-face { + font-family: 'farrisMobile'; + font-style: normal; + font-weight: normal; + src: url(./fonts/farris-mobile-icon.ttf) format('truetype'); +} + +.fm-tmpl-listview-common { + font-size: 16px; + color: #333; + padding: 12px 16px 12px 0; + margin-left: 16px; + border-bottom: 1px solid #ddd; + position: relative +} + +.fm-tmpl-listview-common .fm-tmpl-row { + display: flex; + justify-content: space-between +} + +.fm-tmpl-listview-common .fm-tmpl-row:not(:last-child) { + padding-bottom: 8px +} + +.fm-tmpl-listview-common .fm-tmpl-col { + display: flex; + align-items: flex-start +} + +.fm-tmpl-listview-common .fm-tmpl-title { + line-height: 22px +} + +.fm-tmpl-listview-common .fm-tmpl-price { + font-size: 18px; + line-height: 22px; + color: #fa6400 +} + +.fm-tmpl-listview-common .fm-tmpl-label { + font-size: 14px; + line-height: 20px; + display: flex; + overflow: hidden +} + +.fm-tmpl-listview-common .fm-tmpl-label .fm-tmpl-label-title { + color: #999; + width: 92px +} + +.fm-tmpl-listview-common .fm-tmpl-label .fm-tmpl-label-text { + flex: 1; + overflow: hidden; + text-overflow: ellipsis +} + +.fm-tmpl-listview-common .fm-tmpl-col-1 { + flex: 1; + white-space: nowrap; + overflow: hidden +} + +.fm-tmpl-listview-common .fm-tmpl-col-1:not(:last-child) { + padding-right: 10px +} + +.fm-tmpl-listview-card { + margin: 10px 12px 0; + padding: 0; + border-radius: 8px; + background: #fff; + overflow: hidden; + box-shadow: 0 2px 8px 0 rgba(81,120,159,.12) +} + +.fm-tmpl-listview-card .fm-tmpl-listview-content { + padding: 16px +} + +.fm-tmpl-listview-card .fm-tmpl-listview-content .fm-tmpl-label { + color: #666 +} + +.fm-tmpl-listview-card .fm-tmpl-listview-content.active { + border: 1px solid #3A90FF; +} \ No newline at end of file diff --git a/packages/mobile-render/src/common/event-emitter.ts b/packages/mobile-render/src/common/event-emitter.ts new file mode 100644 index 00000000000..ebb955d37aa --- /dev/null +++ b/packages/mobile-render/src/common/event-emitter.ts @@ -0,0 +1,39 @@ +import { Reactive, reactive, toRefs } from 'vue'; +import { Callable } from './types'; + +export class EventEmitter { + private events: Reactive>; + + constructor() { + this.events = reactive({}); + } + + on(event: string, callback: Callable) { + if (!this.events[event]) { + this.events[event] = []; + } + this.events[event].push(callback); + } + + off(event: string, callback?: Callable) { + if (!this.events[event]) { + return; + } + const callbacks = this.events[event]; + if (callback) { + const index = callbacks.indexOf(callback); + if (index !== -1) { + callbacks.splice(index, 1); + } + } else { + callbacks.length = 0; + } + } + + emit(event: string, args: any[]) { + if (!this.events[event]) {return;} + this.events[event].forEach((callback) => { + callback(args); + }); + } +} diff --git a/packages/mobile-render/src/common/index.ts b/packages/mobile-render/src/common/index.ts new file mode 100644 index 00000000000..6dce9a10036 --- /dev/null +++ b/packages/mobile-render/src/common/index.ts @@ -0,0 +1,2 @@ +export * from './types'; +export * from './event-emitter'; diff --git a/packages/mobile-render/src/common/providers.ts b/packages/mobile-render/src/common/providers.ts new file mode 100644 index 00000000000..2761df9479c --- /dev/null +++ b/packages/mobile-render/src/common/providers.ts @@ -0,0 +1,6 @@ +import { StaticProvider } from "@farris/devkit-vue"; +import { EventEmitter } from "./event-emitter"; + +export const eventEmitterProviders: StaticProvider[] = [ + { provide: EventEmitter, useClass: EventEmitter, deps: [] } +]; diff --git a/packages/mobile-render/src/common/types.ts b/packages/mobile-render/src/common/types.ts new file mode 100644 index 00000000000..448a521dc41 --- /dev/null +++ b/packages/mobile-render/src/common/types.ts @@ -0,0 +1 @@ +export type Callable = (...args: U) => T; diff --git a/packages/mobile-render/src/main.ts b/packages/mobile-render/src/main.ts new file mode 100644 index 00000000000..660dfba3808 --- /dev/null +++ b/packages/mobile-render/src/main.ts @@ -0,0 +1,46 @@ +import '@components/index.scss'; +import './assets/main.scss'; + +import { createApp } from 'vue'; +import MobileUI from '@farris/mobile-ui-vue'; +import { registerComponents } from '@farris/mobile-ui-vue'; +import { StaticProvider, createDevkit } from '@farris/devkit-vue'; +import { ROUTER_TOKEN } from '@farris/mobile-command-services-vue'; +import { befRootProviders } from '@farris/bef-vue'; +import { renderServiceProviders } from './services/index'; + +import App from './app.vue'; +import router from './router'; +import { checkFormRoute, addFormRoute } from './router/use-form-routes'; + +// devkit +export const devkitProviders: StaticProvider[] = [ + ...befRootProviders, + ...renderServiceProviders, + { provide: ROUTER_TOKEN, useValue: router } +]; +const devkit = createDevkit({ + providers: [...devkitProviders] +}); + +// 创建App +const app = createApp(App); +app.use(router); +app.use(devkit); +app.use(MobileUI); + +// 注册组件 +registerComponents(); + +/** + * 全局前置守卫 + */ +router.beforeEach(async (to: any, from: any, next: any) => { + if (checkFormRoute(to, router)) { + next(); + } + await addFormRoute(to, router, devkit); + next({ ...to, replace: true });; +}); + +app.mount('#app'); diff --git a/packages/mobile-render/src/router.ts b/packages/mobile-render/src/router.ts new file mode 100644 index 00000000000..288f230df01 --- /dev/null +++ b/packages/mobile-render/src/router.ts @@ -0,0 +1,14 @@ +import { createRouter, createWebHashHistory } from 'vue-router'; +import { testRoutes } from './views/test/route'; +const router = createRouter({ + history: createWebHashHistory(), + routes: [ + { + path: '/', + redirect: '/test' + }, + testRoutes + ] +}); + +export default router; diff --git a/packages/mobile-render/src/router/use-form-routes.ts b/packages/mobile-render/src/router/use-form-routes.ts new file mode 100644 index 00000000000..de05d2e324d --- /dev/null +++ b/packages/mobile-render/src/router/use-form-routes.ts @@ -0,0 +1,127 @@ +import { RouteRecordRaw, Router, RouteRecord } from 'vue-router'; +import { Devkit } from '@farris/devkit-vue'; +import { MetadataDataService, MetadataCacheService } from '../services/index'; +import Form from '../views/form/form.vue'; +import Page from '../views/page/page.vue'; + +/** + * 根据ID获取元数据(发布模式) + */ +function loadMetadataById( + metadataId: string, metadataDataService: MetadataDataService, metadataCacheService: MetadataCacheService +): Promise { + const metadatasPromise = metadataDataService.loadMetadataById(metadataId).then((metadatas: any) => { + if (!metadatas || !metadatas.form) { + throw new Error(`Failed to load form metadata(ID=${metadataId})`); + } + const formCode = metadatas.form.content.module.code; + metadataCacheService.setCache(formCode, metadatas); + + return metadatas; + }); + + return metadatasPromise; +} + +/** + * 根据Path获取元数据(开发模式) + */ +function loadMetadataByPath( + metadataPath: string, projectPath: string, metadataDataService: MetadataDataService, metadataCacheService: MetadataCacheService +): Promise { + const metadatasPromise = metadataDataService.loadMetadataByPath(projectPath, metadataPath).then((metadatas: any) => { + if (!metadatas || !metadatas.form) { + throw new Error(`Failed to load form metadata(Path=${metadataPath})`); + } + const formCode = metadatas.form.content.module.code; + metadataCacheService.setCache(formCode, metadatas); + + return metadatas; + }); + + return metadatasPromise; +} + +/** + * 从缓存中获取元数据(开发模式下刷新场景) + */ +function loadMetadataFromCache(formCode: string, metadataCacheService: MetadataCacheService): Promise { + const metadatas = metadataCacheService.getCache(formCode); + return Promise.resolve(metadatas); +} + +/** + * 加载表单元数据 + */ +function loadMetadatas(to: any, devkit: Devkit): Promise { + const injector = devkit.getInjector(); + const metadataDataService = injector.get(MetadataDataService, undefined); + const metadataCacheService = injector.get(MetadataCacheService, undefined); + + const { metadataId, metadataPath, projectPath } = to.query; + if (metadataId) { + return loadMetadataById(metadataId, metadataDataService, metadataCacheService); + } else if (metadataPath) { + return loadMetadataByPath(metadataPath, projectPath, metadataDataService, metadataCacheService); + } else { + const formCode = to.path.split('/')[1]; + return loadMetadataFromCache(formCode, metadataCacheService); + } +} + +/** + * 检查路由规则是否存在 + */ +function checkFormRoute(to: any, router: Router): boolean { + const routes = router.getRoutes(); + const targetRoute = routes.find((route) => { + return route.path === to.path; + }); + + return !!targetRoute; +} + +/** + * 添加表单页面路由 + */ +function createFormRoute(formMetadata: any) { + const formModuleNode = formMetadata.content.module; + const componentNodes = formModuleNode.components as any[]; + + const formCode = formModuleNode.code; + const formRoute: RouteRecordRaw = { + path: `/${formCode}`, + component: Form, + children: [] + }; + + componentNodes.forEach((componentNode) => { + const pageRoute: RouteRecordRaw = { + path: componentNode.route.uri, + component: Page + }; + formRoute.children.push(pageRoute); + }); + + return formRoute; +} + +/** + * 添加表单路由配置 + */ +function addFormRoute(to: any, router: Router, devkit: Devkit) { + return loadMetadatas(to, devkit).then((formMetadatas) => { + const formMetadata = formMetadatas.form; + const formRoute = createFormRoute(formMetadata); + + // 进行二次检查 + if (checkFormRoute(formRoute, router)) { + return; + } + router.addRoute(formRoute); + }); +} + +export { checkFormRoute, addFormRoute }; + + diff --git a/packages/mobile-render/src/services/dynamic-route-service.ts b/packages/mobile-render/src/services/dynamic-route-service.ts new file mode 100644 index 00000000000..22e872c0a09 --- /dev/null +++ b/packages/mobile-render/src/services/dynamic-route-service.ts @@ -0,0 +1,146 @@ +import { RouteRecordRaw, Router } from 'vue-router'; +import { MetadataDataService, MetadataCacheService } from '../services/index'; +import Form from '../views/form/form.vue'; +import Page from '../views/page/page.vue'; + +/** + * 动态路由服务 + */ +class DynamicRouteService { + + /** + * 路由器 + */ + private router: Router; + + /** + * 元数据数据服务 + */ + private metadataDataService: MetadataDataService; + + /** + * 元数据缓存服务 + */ + private metadataCacheService: MetadataCacheService; + + /** + * 构造函数 + */ + constructor(router: Router, metadataDataService: MetadataDataService, metadataCacheService: MetadataCacheService) { + this.router = router; + this.metadataDataService = metadataDataService; + this.metadataCacheService = metadataCacheService; + } + + /** + * 检查路由规则是否存在 + */ + public checkFormRoute(to: any): boolean { + const routes = this.router.getRoutes(); + const targetRoute = routes.find((route) => { + return route.path === to.path; + }); + + return !!targetRoute; + } + /** + * 添加表单路由配置 + */ + public addFormRoute(to: any) { + return this.loadMetadatas(to).then((formMetadatas) => { + const formMetadata = formMetadatas.form; + const formRoute = this.createFormRoute(formMetadata); + + // 进行二次检查 + if (this.checkFormRoute(formRoute)) { + return; + } + this.router.addRoute(formRoute); + }); + } + + /** + * 加载表单元数据 + */ + private loadMetadatas(to: any): Promise { + const { metadataId, metadataPath, projectPath } = to.query; + if (metadataId) { + return this.loadMetadataById(metadataId); + } else if (metadataPath) { + return this.loadMetadataByPath(metadataPath, projectPath); + } else { + const formCode = to.path.split('/')[1]; + return this.loadMetadataFromCache(formCode); + } + } + + /** + * 创建表单的页面路由 + */ + private createFormRoute(formMetadata: any) { + const formModuleNode = formMetadata.content.module; + const componentNodes = formModuleNode.components as any[]; + + const formCode = formModuleNode.code; + const formRoute: RouteRecordRaw = { + path: `/${formCode}`, + component: Form, + children: [] + }; + + componentNodes.forEach((componentNode) => { + const pageRoute: RouteRecordRaw = { + path: componentNode.route.uri, + component: Page + }; + formRoute.children.push(pageRoute); + }); + + return formRoute; + } + + + /** + * 根据ID获取元数据(发布模式) + */ + private loadMetadataById(metadataId: string): Promise { + const metadatasPromise = this.metadataDataService.loadMetadataById(metadataId).then((metadatas: any) => { + if (!metadatas || !metadatas.form) { + throw new Error(`Failed to load form metadata(ID=${metadataId})`); + } + const formCode = metadatas.form.content.module.code; + this.metadataCacheService.setCache(formCode, metadatas); + + return metadatas; + }); + + return metadatasPromise; + } + + /** + * 根据Path获取元数据(开发模式) + */ + private loadMetadataByPath(metadataPath: string, projectPath: string): Promise { + const metadatasPromise = this.metadataDataService.loadMetadataByPath(metadataPath, projectPath).then((metadatas: any) => { + if (!metadatas || !metadatas.form) { + throw new Error(`Failed to load form metadata(Path=${metadataPath})`); + } + const formCode = metadatas.form.content.module.code; + this.metadataCacheService.setCache(formCode, metadatas); + + return metadatas; + }); + + return metadatasPromise; + } + + /** + * 从缓存中获取元数据(开发模式下刷新场景) + */ + private loadMetadataFromCache(formCode: string): Promise { + const metadatas = this.metadataCacheService.getCache(formCode); + return Promise.resolve(metadatas); + } +} + +export { DynamicRouteService }; diff --git a/packages/mobile-render/src/services/index.ts b/packages/mobile-render/src/services/index.ts new file mode 100644 index 00000000000..7a2b9937c7d --- /dev/null +++ b/packages/mobile-render/src/services/index.ts @@ -0,0 +1,6 @@ +export * from './metadata/index'; +export * from './module-config/index'; +export * from './page-config/index'; +export * from './dynamic-route-service'; +export * from './providers'; + diff --git a/packages/mobile-render/src/services/metadata/form/converters/base-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/base-converter.ts new file mode 100644 index 00000000000..c03e131d742 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/base-converter.ts @@ -0,0 +1,27 @@ +import { ConverterContext } from './converter-context'; + +/** + * 转换基类 + */ +abstract class BaseConverter { + + /** + * 转换上下文 + */ + protected context: ConverterContext; + + /** + * 构造函数 + */ + constructor(context: ConverterContext) { + this.context = context; + } + + /** + * 转换方法 + */ + abstract convert(node: any): void; + +} + +export { BaseConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/button-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/button-converter.ts new file mode 100644 index 00000000000..51ddd7a5ecf --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/button-converter.ts @@ -0,0 +1,21 @@ +import { ComponentConverter } from "./component-converter"; + +/** + * 按钮组件转换器 + */ +class ButtonConverter extends ComponentConverter { + + /** + * 执行转换 + */ + public convert(button: any): void { + button.type = 'button'; + + if (button.click) { + button.onClick = button.click; + } + } + +} + +export { ButtonConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/button-group-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/button-group-converter.ts new file mode 100644 index 00000000000..f7986fe3dd2 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/button-group-converter.ts @@ -0,0 +1,23 @@ +import { ComponentConverter } from "./component-converter"; + +/** + * 基础组件转换器 + */ +class ButtonGroupConverter extends ComponentConverter { + + /** + * 执行转换 + */ + public convert(buttonGroup: any) { + buttonGroup.type = 'button-group'; + + if (Array.isArray(buttonGroup.items)) { + buttonGroup.items.forEach((item: any) => { + item.onClick = item.click; + }); + } + } + +} + +export { ButtonGroupConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/component-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/component-converter.ts new file mode 100644 index 00000000000..1afd5e20b81 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/component-converter.ts @@ -0,0 +1,25 @@ +import { StringUtil } from '../../../../../utils/index'; +import { BaseConverter } from "../base-converter"; + + +/** + * 基础组件转换器 + */ +class ComponentConverter extends BaseConverter { + + /** + * 执行转换 + */ + public convert(component: any): void { + this.convertType(component); + } + + /** + * 统一转换控件类型 + */ + private convertType(component: any) { + component.type = StringUtil.convertCamelToKebab(component.type); + } +} + +export { ComponentConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/index.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/index.ts new file mode 100644 index 00000000000..56616ac3116 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/index.ts @@ -0,0 +1,8 @@ +export * from './component-converter'; +export * from './page-content-container-converter'; +export * from './button-converter'; +export * from './button-group-converter'; +export * from './listview-converter'; +export * from './input-converter'; +export * from './textbox-converter'; + diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/input-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/input-converter.ts new file mode 100644 index 00000000000..9f58c57aac8 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/input-converter.ts @@ -0,0 +1,33 @@ +import { JsonUtil } from '../../../../../utils/index'; +import { ComponentConverter } from "./component-converter"; + +/** + * 按钮组件转换器 + */ +class InputConverter extends ComponentConverter { + + /** + * 执行转换 + */ + public convert(input: any): void { + this.convertToFormItem(input); + } + + /** + * 转换成FormItem + */ + protected convertToFormItem(input: any) { + const originInput = JsonUtil.cloneJsonObj(input); + Object.keys(input).forEach((propName) => { + delete input[propName]; + }); + + input.id = originInput.id + '-form-item'; + input.type = 'form-item'; + input.label = originInput.title; + input.binding = originInput.binding; + input.editor = originInput; + } +} + +export { InputConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/listview-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/listview-converter.ts new file mode 100644 index 00000000000..53714265810 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/listview-converter.ts @@ -0,0 +1,67 @@ +import { ComponentConverter } from "./component-converter"; + +/** + * 列表组件转换器 + */ +class ListViewConverter extends ComponentConverter { + + /** + * 执行转换 + */ + public convert(listview: any) { + + listview.type = 'list-view'; + + const wrappedListView = this.context.getWrappedComponentById(listview.id); + if (!wrappedListView) { + throw new Error(`WrappedListView(id=${listview.id}) not found`); + } + + // 补全dataSource + const { bindTo } = wrappedListView.vm; + listview.dataSource = this.getEntityLabelFromBindTo(bindTo); + + + // 将listClick事件转换为onItemClick事件 + if (listview.listClick) { + listview.onItemClick = listview.listClick; + } + + // 转换行模板 + this.convertContentTemplate(listview); + } + + /** + * 转换行模板 + */ + public convertContentTemplate(listview: any) { + let { contentTemplate } = listview; + delete listview.contentTemplate; + + const regex = /props\.item/g; + contentTemplate = contentTemplate.replace(regex, 'item'); + + listview.itemTemplate = contentTemplate; + } + + /** + * 从视图模型的bindTo中提取绑定实体的Label + */ + private getEntityLabelFromBindTo(bindTo: string): string { + let entityLabel = ''; + if (bindTo === '/') { + const schemas = this.context.getOriginSchemas(); + if (Array.isArray(schemas) && schemas[0]) { + const { entities } = schemas[0]; + const parentEntity = entities[0]; + entityLabel = parentEntity.label; + } + } else { + entityLabel = bindTo.split('/').pop() || ''; + } + + return entityLabel; + } +} + +export { ListViewConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/page-content-container-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/page-content-container-converter.ts new file mode 100644 index 00000000000..bd089b693f0 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/page-content-container-converter.ts @@ -0,0 +1,17 @@ +import { ComponentConverter } from "./component-converter"; + +/** + * 按钮组件转换器 + */ +class PageContentContainerConverter extends ComponentConverter { + + /** + * 执行转换 + */ + public convert(pageContentContainer: any): void { + pageContentContainer.type = 'page-body-container'; + } + +} + +export { PageContentContainerConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/textbox-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/textbox-converter.ts new file mode 100644 index 00000000000..8b5df4e3a73 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/textbox-converter.ts @@ -0,0 +1,17 @@ +import { InputConverter } from "./input-converter"; + +/** + * 按钮组件转换器 + */ +class TextBoxConverter extends InputConverter { + + /** + * 执行转换 + */ + public convert(input: any): void { + super.convert(input); + input.editor.type = 'input-group'; + } +} + +export { TextBoxConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/converter-context.ts b/packages/mobile-render/src/services/metadata/form/converters/converter-context.ts new file mode 100644 index 00000000000..33ca9a43abc --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/converter-context.ts @@ -0,0 +1,166 @@ +import { WrappedComponent } from './types'; + +/** + * 表单元数据上下文 + */ +class ConverterContext { + + /** + * 视图模型Map + */ + private vmMap: Map; + + /** + * 视图模型组件Map + */ + private vmComponentMap: Map; + + /** + * 初始化组件Map + */ + private wrappedComponentMap: Map; + + /** + * 表单元数据 + */ + private formMetadata: any; + + /** + * 表单Module + */ + private formModule: any; + + /** + * 原始的表单Module + */ + private originFormModule: any; + + /** + * 构造函数 + */ + constructor(formMetadata: any) { + this.formMetadata = formMetadata; + this.formModule = formMetadata.content.module; + this.originFormModule = Object.assign({}, this.formModule); + + this.initViewModelMap(); + this.initVmComponentMap(); + this.initComponentMap(); + } + + /** + * 获取FormModule + */ + public getFormModule() { + return this.formModule; + } + + /** + * 获取Schema节点集合 + */ + public getSchemas(): any[] { + return this.formModule.schemas; + } + + /** + * 获取ViewModel节点集合 + */ + public getViewModels(): any[] { + return this.formModule.viewmodels; + } + + /** + * 获取根组件集合 + */ + public getVmComponents(): any[] { + return this.formModule.components; + } + + /** + * 获取原始FormModule + */ + public getOriginFormModule() { + return this.originFormModule; + } + + /** + * 获取原始Schema节点集合 + */ + public getOriginSchemas(): any[] { + return this.originFormModule.schemas; + } + + /** + * 获取包装后的组件 + */ + public getWrappedComponentById(id: string): WrappedComponent | undefined { + return this.wrappedComponentMap.get(id); + } + + /** + * 获取VM组件ID数组 + */ + public getVmComponentIds(): string[] { + const ids = Array.from(this.vmComponentMap.keys()); + return ids; + } + + /** + * 初始化视图模型Map + */ + private initViewModelMap() { + this.vmMap = new Map(); + const viewModelNodes = this.originFormModule.viewmodels as any[]; + viewModelNodes.forEach((viewModel) => { + this.vmMap.set(viewModel.id, viewModel); + }); + } + + /** + * 初始化VM组件Map + */ + private initVmComponentMap() { + this.vmComponentMap = new Map(); + + const vmComponents = this.originFormModule.components as any[]; + vmComponents.forEach((viewModelComponent) => { + this.vmComponentMap.set(viewModelComponent.id, viewModelComponent); + }); + } + + /** + * 初始化组件Map + */ + private initComponentMap() { + this.wrappedComponentMap = new Map(); + const vmComponents = this.originFormModule.components as any[]; + vmComponents.forEach((vmComponent: any) => { + const vm = this.vmMap.get(vmComponent.viewModel); + this.collectComponent(vmComponent, null, vmComponent, vm); + }); + } + + /** + * 收集组件 + */ + private collectComponent(component: any, parentComponent: any, vmComponent: any, vm: any) { + const wrappedCompoent: WrappedComponent = { + component: component, + parentComponent: parentComponent, + vmComponent: vmComponent, + vm: vm + }; + this.wrappedComponentMap.set(component.id, wrappedCompoent); + + // 收集子节点 + const childComponents = component.contents; + if (!Array.isArray(childComponents)) { + return; + } + childComponents.forEach((childComponent) => { + this.collectComponent(childComponent, component, vmComponent, vm); + }); + } +} + +export { ConverterContext }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts b/packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts new file mode 100644 index 00000000000..03246b603ea --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts @@ -0,0 +1,74 @@ +import { BaseConverter } from './base-converter'; +import { ConverterContext } from './converter-context'; +import { SchemasConverter } from './schemas-converter'; +import { ViewModelsConverter } from './viewodels-converter'; +import { + ComponentConverter, PageContentContainerConverter, ButtonConverter, ButtonGroupConverter, + ListViewConverter, TextBoxConverter +} from './component-converters'; + +type ComponentConverterConstructor = new (context: ConverterContext) => ComponentConverter; + +/** + * 转换器工程 + */ +class ConverterFactory { + + /** + * 转换器类型 + */ + private cmpConverterCtors: Map; + + /** + * 转换上下文 + */ + protected context: ConverterContext; + + /** + * 构造函数 + */ + constructor(context: ConverterContext) { + this.context = context; + this.initConverterCtors(); + } + + /** + * 创建转换器 + */ + public create(type: string): BaseConverter { + switch (type) { + case 'schemas': + return new SchemasConverter(this.context); + case 'viewmodels': + return new ViewModelsConverter(this.context); + default: + return this.createComponentConverter(type); + } + } + + /** + * 创建组件转换器 + */ + private createComponentConverter(type: string) { + const cmpConverterCtor = this.cmpConverterCtors.get(type); + if (!cmpConverterCtor) { + return new ComponentConverter(this.context); + } + const cmpConverter = new cmpConverterCtor(this.context); + return cmpConverter; + } + + /** + * 初始化组件构造函数Map + */ + private initConverterCtors() { + this.cmpConverterCtors = new Map(); + this.cmpConverterCtors.set('PageContentContainer', PageContentContainerConverter); + this.cmpConverterCtors.set('Button', ButtonConverter); + this.cmpConverterCtors.set('ButtonGroup', ButtonGroupConverter); + this.cmpConverterCtors.set('ListView', ListViewConverter); + this.cmpConverterCtors.set('TextBox', TextBoxConverter); + } +} + +export { ConverterFactory }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/index.ts b/packages/mobile-render/src/services/metadata/form/converters/index.ts new file mode 100644 index 00000000000..b25756eab26 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/index.ts @@ -0,0 +1,3 @@ +export * from './converter-context'; +export * from './converter-factory'; + diff --git a/packages/mobile-render/src/services/metadata/form/converters/schemas-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/schemas-converter.ts new file mode 100644 index 00000000000..f463af16baa --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/schemas-converter.ts @@ -0,0 +1,18 @@ +import { BaseConverter } from './base-converter'; + +/** + * 实体Schema转换器 + */ +class SchemasConverter extends BaseConverter { + + /** + * 执行转换 + */ + public convert(schemas: any) { + const formModule = this.context.getFormModule(); + formModule.entity = schemas; + delete formModule.schemas; + } +} + +export { SchemasConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/types.ts b/packages/mobile-render/src/services/metadata/form/converters/types.ts new file mode 100644 index 00000000000..f41d4b7a76c --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/types.ts @@ -0,0 +1,8 @@ +interface WrappedComponent { + component: any; + parentComponent: any; + vmComponent: any; + vm: any; +} + +export { WrappedComponent }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/viewodels-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/viewodels-converter.ts new file mode 100644 index 00000000000..36e66f2c2cb --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/viewodels-converter.ts @@ -0,0 +1,58 @@ +import { TypeUtil } from '../../../../utils/index'; +import { BaseConverter } from './base-converter'; + +/** + * 实体Schema转换器 + */ +class ViewModelsConverter extends BaseConverter { + + /** + * 构造函数 + */ + public convert(viewModelNodes: any): void { + viewModelNodes.forEach((viewModelNode: any) => { + this.convertViewModel(viewModelNode); + }); + } + + /** + * 转换ViewModel节点 + */ + private convertViewModel(viewModelNode: any): void { + this.convertCommands(viewModelNode.commands); + } + + /** + * 批量转换命令 + */ + private convertCommands(commands: any): void { + commands.forEach((command: any) => { + this.convertCommand(command); + }); + } + + /** + * 转换命令 + */ + private convertCommand(command: any): void { + const params = command.params as any; + const componentIds = this.context.getVmComponentIds(); + const variablePrefixs = new Map(); + componentIds.forEach((componentId) => { + variablePrefixs.set(`{DATA~/${componentId}/`, `{DATA~/`); + variablePrefixs.set(`{UISTATE~/${componentId}/`, `{UISTATE~/#{${componentId}}/`); + variablePrefixs.set(`{STATEMACHINE~/${componentId}/`, `{STATEMACHINE~/#{${componentId}}/`); + }); + + params.forEach((param: any) => { + if (!param.value || !TypeUtil.isString(param.value)) { + return; + } + variablePrefixs.forEach((newVariablePrefix, oldVariablePrefix) => { + param.value = param.value.replace(oldVariablePrefix, newVariablePrefix); + }); + }); + } +} + +export { ViewModelsConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/entity-schema-query.ts b/packages/mobile-render/src/services/metadata/form/entity-schema-query.ts new file mode 100644 index 00000000000..8859760f241 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/entity-schema-query.ts @@ -0,0 +1,153 @@ +/** + * 包装后的实体描述 + */ +interface WrappedEntitySchema { + bindingPath: string; + entitySchema: any; + parentWrappedEntitySchema: WrappedEntitySchema; +} + + +/** + * 包装后的字段描述 + */ +interface WrappedFieldSchema { + bindingPath: string; + fieldSchema: any; +} + +/** + * EntitySchema查询服务 + */ +class EntitySchemaQuery { + + /** + * 表单Schema + */ + private rootEntitySchema: any; + + /** + * 实体标签和实体描述Map + */ + private labelAndEntitySchemaMap: Map; + + /** + * 字段ID和字段描述Map + */ + private idAndFieldSchemaMap: Map; + + /** + * 实体Schema查询服务 + */ + constructor(formModule:any) { + this.rootEntitySchema = formModule.entity[0].entities[0]; + this.labelAndEntitySchemaMap = new Map(); + this.idAndFieldSchemaMap = new Map(); + this.collectEntitySchema(this.rootEntitySchema, null); + } + + /** + * 根据Label获取WrappedEntitySchema + */ + public getWrappedEntitySchemaByLabel(label: string): WrappedEntitySchema { + if (!this.labelAndEntitySchemaMap.has(label)) { + throw new Error(`EntitySchema(label=${label}) not found`); + } + + return this.labelAndEntitySchemaMap.get(label); + } + + /** + * 根据ID获取WrappedFieldSchema + */ + public getWrappedFieldSchemaById(id: string): WrappedFieldSchema { + if (!this.idAndFieldSchemaMap.has(id)) { + throw new Error(`FieldSchema(id=${id}) not found`); + } + + return this.idAndFieldSchemaMap.get(id); + } + + /** + * 搜集所有实体信息 + */ + private collectEntitySchema(entitySchema: any, wrappedParentEntitySchema: any) { + const bindingPath = this.getEntityBindingPath(wrappedParentEntitySchema, entitySchema); + const wrappedEntitySchema = { + entitySchema, + bindingPath, + wrappedParentEntitySchema, + }; + + this.labelAndEntitySchemaMap.set(entitySchema.label, wrappedEntitySchema); + this.collectFieldSchemas(entitySchema.type.fields, wrappedEntitySchema); + + const childEntitySchemas = entitySchema.type.entities as any[]; + if (Array.isArray(childEntitySchemas)) { + childEntitySchemas.forEach((childEntitySchema: any) => { + this.collectEntitySchema(childEntitySchema, wrappedEntitySchema); + }); + } + } + + /** + * 搜集所有字段信息 + */ + private collectFieldSchemas(fieldSchemas: any[], wrappedEntitySchema: any) { + fieldSchemas.forEach((fieldSchema: any) => { + this.collectFieldSchema(fieldSchema, wrappedEntitySchema); + }); + } + + /** + * 搜集字段信息 + */ + private collectFieldSchema(fieldSchema: any, wrappedEntitySchema: any) { + const bindingPath = this.getFieldBindingPath(wrappedEntitySchema, fieldSchema); + const wrappedFieldSchema = { bindingPath, fieldSchema }; + this.idAndFieldSchemaMap.set(fieldSchema.id, wrappedFieldSchema); + + if (fieldSchema.$type === 'ComplexField') { + + // 关联字段 + if (fieldSchema.type.$type === 'EntityType') { + const assoFieldSchemas = fieldSchema.type.fields; + this.collectFieldSchemas(assoFieldSchemas, wrappedEntitySchema); + } + + // 业务字段 + if (fieldSchema.type.$type === 'ObjectType') { + const udtFieldSchemas = fieldSchema.type.fields; + this.collectFieldSchemas(udtFieldSchemas, wrappedEntitySchema); + } + } + } + + /** + * 获取实体绑定路径 + */ + private getEntityBindingPath(wrappedParentEntitySchema: any, entitySchema: any) { + if (!wrappedParentEntitySchema) { + return `/`; + } + + const parentBindingPath = wrappedParentEntitySchema.bindingPath; + return `${parentBindingPath}/${entitySchema.label}`; + } + + /** + * 获取字段绑定路径 + */ + private getFieldBindingPath(wrappedEntitySchema: any, fieldSchema: any): string { + const entityBindingPaht = wrappedEntitySchema.bindingPath; + const shortBindingPath = fieldSchema.bindingPath.split('.').join('/'); + + if (entityBindingPaht === '/') { + return `/${shortBindingPath}`; + } else { + return `${entityBindingPaht}/${shortBindingPath}`; + } + } +} + +export { WrappedEntitySchema, WrappedFieldSchema, EntitySchemaQuery }; \ No newline at end of file diff --git a/packages/mobile-render/src/services/metadata/form/form-metadata-converter.ts b/packages/mobile-render/src/services/metadata/form/form-metadata-converter.ts new file mode 100644 index 00000000000..031732a573d --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/form-metadata-converter.ts @@ -0,0 +1,94 @@ +import { ConverterContext, ConverterFactory } from './converters'; + +/** + * 表单元数据转换器 + * @summary + * 1、识别新老表单元数据差异; + * 2、对老表单元数据进行转换,以便动态解析老表单; + */ +class FormMetadataConverter { + + /** + * 转换器上下文 + */ + private context: ConverterContext; + + /** + * 转换器工厂 + */ + private converterFactory: ConverterFactory; + + /** + * 构造函数 + */ + public constructor(formMetadata: any) { + this.context = new ConverterContext(formMetadata); + this.converterFactory = new ConverterFactory(this.context); + } + + /** + * 执行转换 + */ + public convert() { + if (!this.isOldForm()) { + return; + } + + this.convertSchemas(); + this.convertViewModels(); + this.convertComponents(); + } + + /** + * 检查是否是老表单元数据 + */ + private isOldForm(): boolean { + const formModule = this.context.getFormModule(); + return !!formModule.schemas; + } + + /** + * 转换Schema结构 + */ + private convertSchemas() { + const schemasConverter = this.converterFactory.create('schemas'); + const schemas = this.context.getSchemas(); + schemasConverter.convert(schemas); + } + + /** + * 转换视图模型 + */ + private convertViewModels() { + const viewModelsConverter = this.converterFactory.create('viewmodels'); + const viewModelNodes = this.context.getViewModels(); + viewModelsConverter.convert(viewModelNodes); + } + + /** + * 转换组件结构 + */ + private convertComponents() { + const vmComponents = this.context.getVmComponents(); + vmComponents.forEach((vmComponent) => { + this.convertComponent(vmComponent); + }); + } + + /** + * 转换组件结构 + */ + private convertComponent(component: any) { + const componentConverter = this.converterFactory.create(component.type); + componentConverter.convert(component); + + // 递归转换子组件 + if (Array.isArray(component.contents)) { + component.contents.forEach((childComponent: any) => { + this.convertComponent(childComponent); + }); + } + } +} + +export { FormMetadataConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/form-metadata-data-service.ts b/packages/mobile-render/src/services/metadata/form/form-metadata-data-service.ts new file mode 100644 index 00000000000..4961f267cc6 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/form-metadata-data-service.ts @@ -0,0 +1,55 @@ + +import { Metadata } from '../types'; +import { MetadataRepository } from '../metadata-repository'; +import { FormMetadataConverter } from './form-metadata-converter'; +import { FormMetadataNormalizer } from './form-metadata-normalizer'; + +/** + * 表单元数据数据服务 + */ +export class FormMetadataDataService { + + /** + * 元数据仓库 + */ + constructor(private repository: MetadataRepository) { } + + /** + * 根据Path加载元数据 + */ + public loadByFullPath(metadataFullPath: string): Promise { + return this.repository.load(metadataFullPath).then((response: any) => { + return this.createMetadata(response); + }); + } + + /** + * 根据ID加载元数据 + */ + public loadById(metadataId: string) { + return this.repository.retrieve(metadataId).then((response: any) => { + return this.createMetadata(response); + }); + } + + /** + * 创建元数据对象 + */ + private createMetadata(response: any) { + const { Contents: content } = JSON.parse(response.content); + const refs = JSON.parse(response.refs); + const metadata = { id: response.id, content, refs }; + + const metadataConverter = new FormMetadataConverter(metadata); + metadataConverter.convert(); + console.log('----------after convert: FormMetadata----------'); + console.log(metadata.content.module); + + const metadataNormalizer = new FormMetadataNormalizer(metadata); + metadataNormalizer.normalize(); + console.log('----------after normalize: FormMetadata----------'); + console.log(metadata.content.module); + + return metadata; + } +} diff --git a/packages/mobile-render/src/services/metadata/form/form-metadata-normalizer.ts b/packages/mobile-render/src/services/metadata/form/form-metadata-normalizer.ts new file mode 100644 index 00000000000..4210262201f --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/form-metadata-normalizer.ts @@ -0,0 +1,58 @@ +import { FormMetadataQuery } from './form-metadata-query'; +import { ComponentNormalizerFactory } from './normalizers/index'; + +/** + * 表单元数据标准化器 + * @summary + * 1、对现有表单元数据中表达不充分的属性值进行标准化,增强表达能力; + * 2、标准化后的结果,需要进一步评审、沉淀; + */ +class FormMetadataNormalizer { + + /** + * 表单元数据查询服务 + */ + private formMetadataQuery: FormMetadataQuery; + + /** + * 组件标准化器工厂 + */ + private componentNormalizerFactory: ComponentNormalizerFactory; + + /** + * 构造函数 + */ + constructor(formMetadata: any) { + this.formMetadataQuery = new FormMetadataQuery(formMetadata); + this.componentNormalizerFactory = new ComponentNormalizerFactory(this.formMetadataQuery); + } + + /** + * 标准化表单元数据 + */ + public normalize() { + this.normalizeSchema(); + this.normalizeComponents(); + } + + /** + * 对Schema进行标准化 + */ + private normalizeSchema() { + return; + } + + /** + * 对组件进行标准化 + */ + private normalizeComponents() { + const wrappedComponents = this.formMetadataQuery.getWrappedComponents(); + wrappedComponents.forEach((wrappedComponent) => { + const { component, componentSchema, viewModelComponent } = wrappedComponent; + const componentNormalizer = this.componentNormalizerFactory.create(component.type); + componentNormalizer.normalize(component, componentSchema, viewModelComponent.id); + }); + } +} + +export { FormMetadataNormalizer }; diff --git a/packages/mobile-render/src/services/metadata/form/form-metadata-query.ts b/packages/mobile-render/src/services/metadata/form/form-metadata-query.ts new file mode 100644 index 00000000000..554a801ca35 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/form-metadata-query.ts @@ -0,0 +1,132 @@ +import { schemaMap } from '@farris/mobile-ui-vue'; +import { WrappedComponent } from './types'; +import { WrappedEntitySchema, WrappedFieldSchema, EntitySchemaQuery } from './entity-schema-query'; + +/** + * 表单元数据查询 + */ +class FormMetadataQuery { + + /** + * 表单元数据 + */ + private formMetadata: any; + + /** + * 表单模块 + */ + private formModule: any; + + /** + * 视图模型Map + */ + private viewModelMap!: Map; + + /** + * 包装后的组件Map + */ + private wrappedComponentMap!: Map; + + /** + * EntitySchema查询 + */ + private entitySchemaQuery: EntitySchemaQuery; + + /** + * 构造函数 + */ + constructor(formMetadata: any) { + this.formMetadata = formMetadata; + this.formModule = formMetadata.content.module; + this.entitySchemaQuery = new EntitySchemaQuery(this.formModule); + this.initViewModelMap(); + this.initWrappedComponentMap(); + } + + /** + * 根据label获取EntitySchema + */ + public getWrappedEntitySchemaByLabel(label: string): WrappedEntitySchema { + return this.entitySchemaQuery.getWrappedEntitySchemaByLabel(label); + } + + /** + * 根据ID获取FieldSchema + */ + public getWrappedFieldSchemaById(id: string) { + return this.entitySchemaQuery.getWrappedFieldSchemaById(id); + } + + /** + * 根据ID获取包装组件 + */ + public getWrappedComponentById(id: string): WrappedComponent | undefined { + const wrappedComponent = this.wrappedComponentMap.get(id); + return wrappedComponent; + } + + /** + * 获取全部包装组件 + */ + public getWrappedComponents(): WrappedComponent[] { + const wrappedComponents = Array.from(this.wrappedComponentMap.values()); + return wrappedComponents; + } + + /** + * 构造视图模型Map + */ + private initViewModelMap() { + this.viewModelMap = new Map(); + const viewModels = this.formMetadata.content.module.viewmodels as any[]; + viewModels.forEach((viewModel) => { + this.viewModelMap.set(viewModel.id, viewModel); + }); + } + + /** + * 根据ID获取ViewModel + */ + private getViewModelById(id: string): any { + const targetViewModel = this.viewModelMap.get(id); + return targetViewModel; + } + + /** + * 初始化包装组件Map + */ + private initWrappedComponentMap() { + this.wrappedComponentMap = new Map(); + const viewModelComponents = this.formMetadata.content.module.components as any[]; + viewModelComponents.forEach((viewModelComponent) => { + const currentViewModel = this.getViewModelById(viewModelComponent.viewModel); + this.appendWrappedComponentToMap(viewModelComponent, currentViewModel, viewModelComponent); + }); + } + + /** + * 追加组件到组件Map + */ + private appendWrappedComponentToMap(component: any, currentViewModel: any, currentViewModelComponent: any) { + const componentSchema = schemaMap[component.type]; + const wrappedComponent = { + component: component, + componentSchema: componentSchema, + viewModel: currentViewModel, + viewModelComponent: currentViewModelComponent + }; + this.wrappedComponentMap.set(component.id, wrappedComponent); + + if (component.editor) { + this.appendWrappedComponentToMap(component.editor, currentViewModel, currentViewModelComponent); + } + + if (Array.isArray(component.contents)) { + component.contents.forEach((childComponent: any) => { + this.appendWrappedComponentToMap(childComponent, currentViewModel, currentViewModelComponent); + }); + } + } +} + +export { FormMetadataQuery }; diff --git a/packages/mobile-render/src/services/metadata/form/index.ts b/packages/mobile-render/src/services/metadata/form/index.ts new file mode 100644 index 00000000000..d089bdae664 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/index.ts @@ -0,0 +1,4 @@ +export * from './form-metadata-query'; +export * from './form-metadata-converter'; +export * from './form-metadata-normalizer'; +export * from './form-metadata-data-service'; diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/button-group-normalizer.ts b/packages/mobile-render/src/services/metadata/form/normalizers/button-group-normalizer.ts new file mode 100644 index 00000000000..28922cb8494 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/normalizers/button-group-normalizer.ts @@ -0,0 +1,30 @@ +import { ComponentNormalizer } from './component-normalizer'; + +/** + * Button标准化器 + */ +class ButtonGroupNormalizer extends ComponentNormalizer { + + /** + * 标准化组件 + */ + public normalize(component: any, componentSchema: any, viewModelId: string) { + super.normalize(component, componentSchema, viewModelId); + + if (Array.isArray(component.items)) { + const itemSchema = componentSchema.properties.items.items; + this.normalizeItems(component.items, itemSchema, viewModelId); + } + } + + /** + * 规范化Items + */ + public normalizeItems(items: any[], itemSchema: any, viewModelId: string) { + items.forEach((item: any) => { + super.normalize(item, itemSchema, viewModelId); + }); + } +} + +export { ButtonGroupNormalizer }; diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer-factory.ts b/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer-factory.ts new file mode 100644 index 00000000000..412077695a9 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer-factory.ts @@ -0,0 +1,55 @@ +import { FormMetadataQuery } from '../form-metadata-query'; +import { ComponentNormalizer } from './component-normalizer'; +import { ListviewNormalizer } from './listview-normalizer'; +import { FormItemNormalizer } from './form-item-normalizer'; +import { ButtonGroupNormalizer } from './button-group-normalizer'; + + +/** + * 组件标准化器工厂 + */ +class ComponentNormalizerFactory { + + /** + * 组件标准化器缓存 + */ + private normalizerMap: Map; + + /** + * 表单元数据查询服务 + */ + protected formMetadataQuery: FormMetadataQuery; + + /** + * 构造函数 + */ + constructor(formMetadataQueryService: FormMetadataQuery) { + this.normalizerMap = new Map(); + this.formMetadataQuery = formMetadataQueryService; + } + + /** + * 创建标准化器 + */ + public create(componentType: string): ComponentNormalizer { + if (this.normalizerMap.has(componentType)) { + return this.normalizerMap.get(componentType) as ComponentNormalizer; + } + + let componentNormalizer; + if (componentType === 'list-view') { + componentNormalizer = new ListviewNormalizer(this.formMetadataQuery); + } else if (componentType === 'form-item') { + componentNormalizer = new FormItemNormalizer(this.formMetadataQuery); + } else if (componentType === 'button-group') { + componentNormalizer = new ButtonGroupNormalizer(this.formMetadataQuery); + } else { + componentNormalizer = new ComponentNormalizer(this.formMetadataQuery); + } + this.normalizerMap.set(componentType, componentNormalizer); + + return componentNormalizer; + } +} + +export { ComponentNormalizerFactory }; diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts b/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts new file mode 100644 index 00000000000..a7ca25fe972 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts @@ -0,0 +1,215 @@ +import { FormMetadataQuery } from '../form-metadata-query'; +import { isObject, isString } from '../../../../utils/index'; + +/** + * 通用组件标准化器 + * /** + * 属性配置构造器 + * @summary + * -------------------------------------------------------------------------------- + * 问题 + * 1、老表单的组件DOM结构不合理的地方需要转换; + * 2、新表单的组件DOM结构部分内容表达不充分,先进行临时性转换,后续再沉淀; + * + * 目标: + * 1、将老表单中不规范的组件DOM结构进行标准化; + * 2、标准化后组件DOM结构,根据实际情况沉淀成标准,或根据标准调整转换逻辑; + * + * 对于普通的属性值 + * 1、常量: + * 2、字段:{"type": "Form", "field": "guid", "path": "StrField", "bindingPath": "strField" } + * 3、变量:{"path": "strVar", "field": "guid", "fullPath": "strVar", "type": "Variable"} + * 4、状态机:stateMachine['canEdit'] + * 5、表达式:{"type": "Expression", "expressionId": "guid_visible"}, + * 6、界面规则: {"type": "FormRule", "ruleId": "guid", "ruleName": "规则1", "expressionId": "guid_visible"} + * 7、自定义:currentEntityData.xxx/bindingData.xxx/uiState.xxx/stateMachine.xxx以及他们的混合 + * + * 对于需要双向绑定的输入控件 + * 1、字段:{"type": "Form", "path": "code", "field": "guid", "fullPath": "Code"} + * 2、组件变量:{"type": "Variable", "path": "strVar", "field": "guid", "fullPath": "strVar"}, + * 3、表单变量;{"type": "Variable", "path": "root-component.textVoVar", "field": "guid", "fullPath": "textVoVar"} + * + * 对于绑定集合数据的控件 + * 1、ListView:未有明确的配置,生成器根据ViewModle的直接绑定了entityListData直接取的ViewModel的bindingPath + * 2、LightAttachment:同Listview + * + * 对于事件属性 + * 1、当前ViewModle的命令:命令编号,比如LoadAndAddForCard + * 2、移动端暂无跨ViewModel绑定的情况 + * + * 其他情况 + * 1、在Html模板中直接使:currentEntityData、entityListData、uiState、stateMachine等; + * 2、附件的parentDirName使用了:bindingData.id + * + * -------------------------------------------------------------------------------- + * 处理策略 + * 1、针对存在type和field的属性,转换成 { bindingType: 'Entity', bindingPath: 'xxx' } 、{ bindingType: 'Variable', bindingPath: 'xxx' } + * 2、针对stateMachine开头的,转换成 { bindingType: 'StateMachine', bindingPath: 'xxx' } + * 3、识别其他情况:自定义的暂时不支持,统一按静态值处理,设计时控制住不允许配置; + * + * 4、针对ListView和LightAttachment,补上binding属性,结构同情况1; + * + * 5、针对事件属性,提前补全viewModelId + * -------------------------------------------------------------------------------- + */ +class ComponentNormalizer { + + /** + * 表单元数据查询服务 + */ + protected formMetadataQuery: FormMetadataQuery; + + /** + * 构造函数 + */ + constructor(formMetadataQuery: FormMetadataQuery) { + this.formMetadataQuery = formMetadataQuery; + } + + /** + * 标准化组件属性 + * @todo 需要支持递归处理属性 + */ + public normalize(component: any, componentSchema: any, viewModelId: string) { + if (!componentSchema) { + throw new Error(`Can't not find schema for the component(type=${component.type})`); + } + const eventPropNames = componentSchema.events || []; + + Object.keys(component).forEach((propName: string) => { + if (eventPropNames.includes(propName)) { + this.normalizeEventPropValue(propName, component, viewModelId); + } else { + this.normalizeCommonPropValue(propName, component, viewModelId); + } + }); + } + + /** + * 标准化事件属性 + * @summary + * 转换后形如{ type: 'Command', name: 'LoadAndAddForCard', viewModelId: 'card-page-component'} + */ + protected normalizeEventPropValue(propName: string, component: any, viewModelId: string): void { + const commandName = component[propName]; + if (!commandName) { + component[propName] = null; + } else { + const normalizedPropValue = { + type: 'Command', + name: component[propName], + viewModelId: viewModelId + }; + component[propName] = normalizedPropValue; + } + } + + /** + * 标准化普通属性 + */ + protected normalizeCommonPropValue(propName: string, component: any, viewModelId: string): void { + const propValue = component[propName]; + let normalizedPropValue = propValue; + if (isObject(propValue) && propValue.type && propValue.field) { + normalizedPropValue = this.getNormalizeObjectPropValue(propValue, viewModelId); + } else if (isString(propValue)) { + normalizedPropValue = this.getNormalizeStringPropValue(propValue, viewModelId); + } else { + normalizedPropValue = propValue; + } + + component[propName] = normalizedPropValue; + } + + /** + * 规范化对象类型的属性值 + * @summary + * 暂时仅支持Form和Variable + * 字段:{ bindingType: 'EntityField', bindingPath: '/deptInfo/name', isTwoWay: false} + * 变量:{ bindingType: 'Variable', bindingPath: '/filter/name', isTwoWay: false, viewModelId: 'cad-page-component'} + */ + private getNormalizeObjectPropValue(propValue: any, currentViewModelId: string): any { + const { type } = propValue; + + let normalizePropValue; + if (type === 'Form') { + normalizePropValue = this.getEntityFieldBinding(propValue, currentViewModelId); + } else if (type === 'Variable') { + normalizePropValue = this.getVariableBinding(propValue, currentViewModelId); + } else { + normalizePropValue = null; + } + + return normalizePropValue; + } + + /** + * 标准化字符串类型的属性值 + * @summary + * 暂时仅支持StateMachine + * 转换后形如:{ bindingType: 'StateMachine', bindingPath: '/canInput', isTwoWay: false, viewModelId: 'cad-page-component'} + */ + private getNormalizeStringPropValue(propValue: string, currentViewModelId: string): any { + if (!propValue.startsWith('stateMachine')) { + return propValue; + } + const normalizedPropValue = this.getStateMachineBinding(propValue, currentViewModelId); + return normalizedPropValue; + } + + /** + * 获取字段绑定 + */ + private getEntityFieldBinding(originBinding: any, currentViewModelId: string) { + + const { field } = originBinding; + const wrappedFieldSchema = this.formMetadataQuery.getWrappedFieldSchemaById(field); + const path = wrappedFieldSchema.bindingPath; + + const binding = { + type: 'EntityField', + path: path, + direction: 'OneWay', + viewModelId: currentViewModelId + }; + + return binding; + } + + /** + * 获取变量绑定 + */ + private getVariableBinding(propValue: any, currentViewModelId: string) { + const { path } = propValue; + const binding = { + type: 'Variable', + path: `/${path}`, + direction: 'OneWay', + viewModelId: currentViewModelId + }; + + return binding; + } + + /** + * 获取状态机绑定 + */ + private getStateMachineBinding(propValue: any, currentViewModelId: string) { + const matchArray = propValue.match(/stateMachine\['(.*?)'\]/); + if (!matchArray) { + return propValue; + } + + const renderState = matchArray[1]; + const binding = { + type: 'StateMachine', + path: `/${renderState}`, + direction: 'OneWay', + viewModelId: currentViewModelId + }; + + return binding; + } +} + +export { ComponentNormalizer }; diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/form-item-normalizer.ts b/packages/mobile-render/src/services/metadata/form/normalizers/form-item-normalizer.ts new file mode 100644 index 00000000000..4993dbaf295 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/normalizers/form-item-normalizer.ts @@ -0,0 +1,29 @@ +import { schemaMap } from '@farris/mobile-ui-vue'; +import { ComponentNormalizer } from './component-normalizer'; + +/** + * FormItem标准化器 + */ +class FormItemNormalizer extends ComponentNormalizer { + + /** + * 标准化组件 + */ + public normalize(component: any, componentSchema: any, viewModelId: string) { + super.normalize(component, componentSchema, viewModelId); + this.normalizeEditor(component.editor, viewModelId); + } + + /** + * 标准化编辑器配置 + */ + public normalizeEditor(editor: any, viewModelId: string) { + const editorSchema = schemaMap[editor.type]; + super.normalize(editor, editorSchema, viewModelId); + + // 标记binding为双向绑定 + editor.binding.direction = 'TwoWay'; + } +} + +export { FormItemNormalizer }; diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/index.ts b/packages/mobile-render/src/services/metadata/form/normalizers/index.ts new file mode 100644 index 00000000000..e7eb5186602 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/normalizers/index.ts @@ -0,0 +1,4 @@ +export * from './component-normalizer'; +export * from './listview-normalizer'; +export * from './form-item-normalizer'; +export * from './component-normalizer-factory'; diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/listview-normalizer.ts b/packages/mobile-render/src/services/metadata/form/normalizers/listview-normalizer.ts new file mode 100644 index 00000000000..9e1b4cccf6d --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/normalizers/listview-normalizer.ts @@ -0,0 +1,38 @@ +import { ComponentNormalizer } from './component-normalizer'; + +/** + * ListView标准化器 + */ +class ListviewNormalizer extends ComponentNormalizer { + + /** + * 事件属性 + */ + protected eventPropNames: string[] = []; + + /** + * 标准化组件 + */ + public normalize(component: any, componentSchema: any, viewModelId: string) { + super.normalize(component, componentSchema, viewModelId); + this.normalizeDatasource(component, viewModelId); + } + + /** + * 标准化数据绑定 + */ + public normalizeDatasource(component: any, viewModelId: string) { + const wrappeEntitySchema = this.formMetadataQuery.getWrappedEntitySchemaByLabel(component.dataSource); + const path = wrappeEntitySchema.bindingPath; + + const dataSource = { + type: 'EntityList', + path: path, + direction: 'OneWay', + viewModelId: viewModelId + }; + component.dataSource = dataSource; + } +} + +export { ListviewNormalizer }; diff --git a/packages/mobile-render/src/services/metadata/form/types.ts b/packages/mobile-render/src/services/metadata/form/types.ts new file mode 100644 index 00000000000..daa0044ece1 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/types.ts @@ -0,0 +1,36 @@ +/** + * 表单模块 +*/ +export interface FormModule { + entity: any; + viewmodels: any[]; + components: any[]; + webCmds: any[]; +} + +/** + * 表单元数据内容 + */ +export interface FormMetadataContent { + module: any; + options: any; +} + +/** + * 表单元数据 + */ +export interface FormMetadata { + id: string; + code: string; + content: FormMetadataContent; +} + +/** + * 包装后的组件 + */ +export interface WrappedComponent { + component: any, + componentSchema: any, + viewModel: any, + viewModelComponent: any +} diff --git a/packages/mobile-render/src/services/metadata/index.ts b/packages/mobile-render/src/services/metadata/index.ts new file mode 100644 index 00000000000..691ad235c75 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/index.ts @@ -0,0 +1,8 @@ +export * from './types'; +export * from './metadata-repository'; +export * from './form/index'; +export * from './statemachine/index'; +export * from './webcmp/index'; +export * from './webcmd/index'; +export * from './metadata-data-service'; +export * from './metadata-cahce-service'; diff --git a/packages/mobile-render/src/services/metadata/metadata-cahce-service.ts b/packages/mobile-render/src/services/metadata/metadata-cahce-service.ts new file mode 100644 index 00000000000..66ec93d5fcd --- /dev/null +++ b/packages/mobile-render/src/services/metadata/metadata-cahce-service.ts @@ -0,0 +1,45 @@ + +/** + * 元数据缓存服务 + * @summary + * 1、为了方便调试,开发模式下将元数据缓存到SessionStorage中; + * 2、只有URL中指定了表单ID或表单路径时再更新SessionStorage; + */ +class MetadataCacheService { + + /** + * 源数据缓存 + */ + private metadatasCache: Map; + + /** + * 构造函数 + */ + constructor() { + this.metadatasCache = new Map(); + } + + /** + * 设置缓存 + */ + public setCache(formCode: string, metadatas: any) { + // this.metadatasCache.set(formCode, metadatas); + const metadataString = JSON.stringify(metadatas); + window.sessionStorage.setItem(formCode, metadataString); + } + + /** + * 获取缓存 + */ + public getCache(formCode: string) { + // const metadatas = this.metadatasCache.get(formCode); + const metadatasString = window.sessionStorage.getItem(formCode); + if (!metadatasString) { + throw new Error(`Metadatas(code=${formCode}) don't exist`); + } + + return JSON.parse(metadatasString); + } +} + +export { MetadataCacheService }; diff --git a/packages/mobile-render/src/services/metadata/metadata-data-service.ts b/packages/mobile-render/src/services/metadata/metadata-data-service.ts new file mode 100644 index 00000000000..e4a4610d764 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/metadata-data-service.ts @@ -0,0 +1,100 @@ +import { Metadata, FormMetadata, StateMachineRefMetadata, WebCommandRefMetadata } from './types'; +import { CustomWebComponentMetadataDataService } from './webcmp/index'; +import { CommonWebCommandMetadataDataService, CustomWebCommandMetadataDataService } from './webcmd/index'; +import { StateMachineMetadataDataService } from './statemachine/index'; +import { FormMetadataDataService } from './form/index'; + +/** + * 元数据数据服务 + */ +export class MetadataDataService { + constructor( + private formMetadataDataService: FormMetadataDataService, + private stateMachineMetadataDataService: StateMachineMetadataDataService, + private webCommandMetadataDataService: CommonWebCommandMetadataDataService, + private customWebComponentMetadataDataService: CustomWebComponentMetadataDataService, + private customWebCommandMetadataDataService: CustomWebCommandMetadataDataService + ) { } + + /** + * 根据Path加载元数据 + */ + public loadMetadataByPath(projectPath: string, metadataPath: string) { + return this.formMetadataDataService.loadByFullPath(metadataPath).then((formMetadata: Metadata) => { + const schema = formMetadata.content as FormMetadata; + const { stateMachines = [] } = schema.module; + // const stateMachineRefSchema = stateMachines; + const stateMachineMetadataPromise = stateMachines && stateMachines.length > 0 ? stateMachines.map((stateMachine: StateMachineRefMetadata) => { + return this.stateMachineMetadataDataService.loadByProjectPath(projectPath, stateMachine.uri); + }) : [Promise.resolve(null)]; + // const stateMachineMetadataPromise = stateMachines ? this.stateMachineMetadataDataService.loadByProjectPath(projectPath, stateMachineRefSchema.uri) : Promise.resolve(null); + const commandsMetadataPromise = schema.module.webcmds.map((webCommand: WebCommandRefMetadata) => { + const { id } = webCommand; + return this.webCommandMetadataDataService.loadByProjectPath(projectPath, id); + }); + const customWebComponentMetadataPromise = this.customWebComponentMetadataDataService.loadByType(projectPath); + const promises = [Promise.all(stateMachineMetadataPromise), Promise.all(commandsMetadataPromise), customWebComponentMetadataPromise]; + return Promise.all(promises).then(([stateMachineSchema, commandSchemas, customWebComponents]) => { + return { + form: formMetadata, + stateMachines: stateMachineSchema as Metadata[], + commands: commandSchemas as Metadata[], + webComponents: customWebComponents as Metadata[] + }; + }); + }); + } + + /** + * 根据ID加载元数据 + */ + public loadMetadataById(metadataId: string) { + return this.formMetadataDataService.loadById(metadataId).then((formMetadata: Metadata) => { + const schema = formMetadata.content as FormMetadata; + const { stateMachines } = schema.module; + // const stateMachineRefSchema = stateMachines[0]; + const stateMachineMetadataPromise = stateMachines && stateMachines.length > 0 ? stateMachines.map((stateMachine: StateMachineRefMetadata) => { + return this.stateMachineMetadataDataService.loadById(stateMachine.uri); + }) : [Promise.resolve(null)]; + // const stateMachineMetadataPromise = stateMachines ? this.stateMachineMetadataDataService.loadById(stateMachineRefSchema.uri) : Promise.resolve(null); + + const commandsMetadataPromise = schema.module.webcmds.map((webCommand: WebCommandRefMetadata) => { + const { id } = webCommand; + return this.webCommandMetadataDataService.loadById(id); + }); + const promises = [Promise.all(stateMachineMetadataPromise), Promise.all(commandsMetadataPromise)]; + return Promise.all(promises).then(([stateMachineSchema, commandSchemas]) => { + const customWebComponents: string[] = []; + if (commandSchemas && commandSchemas.length > 0) { + commandSchemas.forEach((commandSchema: Metadata | null) => { + if (commandSchema && commandSchema.content && commandSchema.content.Extends && commandSchema.content.Extends.IsCommon === false) { + const commands = commandSchema.content.Commands as any[]; + commands.forEach((command: any) => { + const items = command.Items as any[]; + items.forEach((item: any) => { + if (!item.ComponentPath.startsWith('Gsp/')) { + const componentId = item.ComponentId; + if (!customWebComponents.includes(componentId)) { + customWebComponents.push(componentId); + } + } + }); + }); + } + }); + } + const customWebComponentMetadataPromise = customWebComponents.length > 0 ? Promise.all(customWebComponents.map((id: string) => { + return this.customWebComponentMetadataDataService.loadById(id); + })) : Promise.resolve(null); + return customWebComponentMetadataPromise.then((customWebComponents: Metadata[] | null) => { + return { + form: formMetadata, + stateMachines: stateMachineSchema as Metadata[], + commands: commandSchemas as Metadata[], + webComponents: customWebComponents as Metadata[] + }; + }); + }); + }); + } +} diff --git a/packages/mobile-render/src/services/metadata/metadata-repository.ts b/packages/mobile-render/src/services/metadata/metadata-repository.ts new file mode 100644 index 00000000000..a99f2425a04 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/metadata-repository.ts @@ -0,0 +1,59 @@ + +import { HttpClient, HttpParams, HttpRequestConfig } from "@farris/devkit-vue"; + +export class MetadataRepository { + constructor(private httpClient: HttpClient) { + } + + /** + * 加载设计时元数据 + * @param metadataPath 元数据工程路径 + * @returns Promise + */ + public load(metadataPath: string): Promise { + const httpParams: HttpParams = { + metadataFullPath: metadataPath + }; + return this.httpClient.get(`/api/dev/main/v1.0/metadatas/load`, { params: httpParams }); + } + + /** + * 根据元数据类型获取表单定义的其他元数据 + * @param metadataPath 元数据工程路径 + * @param metadataType 元数据类型 + * @returns Promise + */ + public loadMetadatasByType(metadataPath: string, metadataType: string): Promise { + const params: HttpParams = { + path: metadataPath, + metadataTypeList: metadataType + }; + const requestConfig: HttpRequestConfig = { params, headers: { accept: 'application/json' } }; + return this.httpClient.get('/api/dev/main/v1.0/mdservice', requestConfig); + } + + /** + * 获取表单依赖的元数据 + * @param metadataId 元数据id + * @param metadataPath 元数据工程路径 + * @returns Promise + */ + public relied(metadataId: string, metadataPath: string): Promise { + const params: HttpParams = { + metadataPath, + metadataID: metadataId + }; + const requestConfig: HttpRequestConfig = { params }; + return this.httpClient.get('/api/dev/main/v1.0/metadatas/relied', requestConfig); + } + + /** + * 检索元数据 + * @param metadataId 元数据id + * @returns + * @description 用于获取运行时元数据 + */ + public retrieve(metadataId: string): Promise { + return this.httpClient.get(`/api/runtime/lcm/v1.0/rt-metadatas/${metadataId}`, {}); + } +} diff --git a/packages/mobile-render/src/services/metadata/statemachine/index.ts b/packages/mobile-render/src/services/metadata/statemachine/index.ts new file mode 100644 index 00000000000..587c0d51168 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/statemachine/index.ts @@ -0,0 +1 @@ +export * from './state-machine-metadata-data-service'; diff --git a/packages/mobile-render/src/services/metadata/statemachine/state-machine-metadata-data-service.ts b/packages/mobile-render/src/services/metadata/statemachine/state-machine-metadata-data-service.ts new file mode 100644 index 00000000000..e8ab05de200 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/statemachine/state-machine-metadata-data-service.ts @@ -0,0 +1,35 @@ +import { MetadataRepository } from '../metadata-repository'; + +/** + * 状态机元数据数据服务 + */ +export class StateMachineMetadataDataService { + constructor(private metadataRepository: MetadataRepository) { } + + public loadByFullPath(metadataFullPath: string): Promise { + return this.metadataRepository.load(metadataFullPath).then((response: any) => { + return this.createMetadata(response); + }); + } + + public loadByProjectPath(projectPath: string, metadataId: string) { + return this.metadataRepository.relied(metadataId, projectPath).then((response: any) => { + return this.createMetadata(response); + }); + } + + public loadById(metadataId: string) { + return this.metadataRepository.retrieve(metadataId).then((response: any) => { + return this.createMetadata(response); + }); + } + + private createMetadata(response: any) { + const metadata = { + content: JSON.parse(response.content), + refs: JSON.parse(response.refs), + id: response.id + }; + return metadata; + } +} diff --git a/packages/mobile-render/src/services/metadata/types.ts b/packages/mobile-render/src/services/metadata/types.ts new file mode 100644 index 00000000000..3dfaccb8d8a --- /dev/null +++ b/packages/mobile-render/src/services/metadata/types.ts @@ -0,0 +1,233 @@ +/* eslint-disable no-use-before-define */ + +// #region form schema +export interface EntityFieldMetadata { + id: string; + required: any; + multiLanguage: boolean; + defaultValue: any; + readonly: any; + bindingPath: string; + label: string; + type: Record; + name: string; +} +export interface EntityTypeMetadata { + entities: EntityMetadata[]; + primary: string; + displayName: string; + fields: EntityFieldMetadata[]; + name: string; +} +export interface EntityMetadata { + id: string; + label: string; + code: string; + type: EntityTypeMetadata; + name: string; +} +export interface ViewModelFieldMetadata { + id: string; + type: string; + fieldName: string; + groupId: string; + groupName: string; +} +export interface CommandParamMetadata { + name: string; + shownName: string; + value: string; +} +export interface CommandRefMetadata { + id: string; + code: string; + name: string; + params?: CommandParamMetadata[]; + handlerName: string; + cmpId: string; + isInvalid: boolean; +} +export interface StateMetadata { + id: string; + code: string; + name: string; + type: string; + category: string; +} +export interface PaginationMetadata { + enable: boolean; + pageSize: number; + pageList: string; +} +export interface ViewModelMetadata { + id: string; + code: string; + name: string; + fields?: ViewModelFieldMetadata[]; + commands?: CommandRefMetadata[]; + states?: StateMetadata[]; + bindTo?: string; + parent?: string; + enableUnifiedSession?: boolean; + enableValidation?: boolean; + pagination?: PaginationMetadata; + serviceRefs?: any[]; +} +export interface StateMachineRefMetadata { + id: string; + name: string; + uri: string; + code: string; + nameSpace: string; +} +export interface RefedHandlerMetadata { + host: string; + handler: string; +} +export interface WebCommandRefMetadata { + id: string; + path: string; + name: string; + refedHandlers: RefedHandlerMetadata[]; + code: string; + nameSpace: string; +} +export interface ComponentAppearanceMetadata { + class: string; + style?: string; +} +export interface ComponentMetadata { + id: string; + type: string; + appearance?: ComponentAppearanceMetadata | null; + componentType: string; + viewModel: string; + onInit: string; + afterViewInit: string; + contents: ComponentMetadata[]; + items?: any[]; + visible: string | boolean; + component?: ComponentMetadata; + [prop: string]: any; +} +export interface VariableMetadata { + id: string; + name: string; + path: string; + defaultValue: any; + readonly: boolean; + bindingField: string; + bindingPath: string; + code: string; + label: string; + type: any; +} +export interface EntityModelMetadata { + id: string; + code: string; + name: string; + extendProperties: any; + entities: EntityMetadata[]; + sourceUri: string; + sourceType: string; + voPath: string; + eapiNameSpace: string; + eapiName: string; + eapiCode: string; + eapiId: string; + variables: VariableMetadata[]; +} +export interface ModuleMetadata { + id: string; + code: string; + name: string; + bootstrap: string; + entity: EntityModelMetadata[]; + stateMachines: StateMachineRefMetadata[]; + viewmodels: ViewModelMetadata[]; + components: ComponentMetadata[]; + webcmds: WebCommandRefMetadata[]; + expressions: any[]; + actions: any[]; + [prop: string]: any; +} +export interface OptionsMetadata { + renderMode: string; + formRulePushMode: string; +} +export interface FormMetadata { + module: ModuleMetadata; + options: OptionsMetadata; +} +// #endregion + +// #region stateMachine schema +export interface StateMachineStateMetadata { + name: string; + state: string; + description: string; +} +export interface StateMachineActionMetadata { + [actionName: string]: { + name: string; + transitTo: string; + description: string; + }; +} +export interface StateMachineRenderStateMetadata { + [render: string]: { + name: string; + description: string; + condition: any[]; + }; +} +export interface StateMachineMetadata { + action: StateMachineActionMetadata; + initialState: string; + renderState: StateMachineRenderStateMetadata; + state: StateMachineStateMetadata[]; +} + +// #endregion + +// #region resource schema +export interface StringResourceMetadata { + id: string; + resourceType: string; + value: string; +} +export interface ResourceMetadata { + originalLanguage: string; + stringResources: StringResourceMetadata[]; + resourceType: string; +} +// #endregion + +export interface ResolvedEntity { + bindingPaths: string[]; + primaryKey: string; +} + +export interface ResolvedEntityField { + id: string; + bindingPath: string; + required: any; + readonly: any; + multiLanguage: boolean; + label: string; + dataSource: string; +} + + +export interface Metadata { + id: string; + content: any; + refs: any[]; +} + +export interface ViewEvent { + token: string; + eventName: string; + type: string; + payloads: any[]; +} diff --git a/packages/mobile-render/src/services/metadata/webcmd/common-web-command-metadata-data-service.ts b/packages/mobile-render/src/services/metadata/webcmd/common-web-command-metadata-data-service.ts new file mode 100644 index 00000000000..a46d587324f --- /dev/null +++ b/packages/mobile-render/src/services/metadata/webcmd/common-web-command-metadata-data-service.ts @@ -0,0 +1,50 @@ + +import { MetadataRepository } from '../metadata-repository'; +import { Metadata } from '../types'; + +/** + * 内置命令构件元数据数据服务 + */ +export class CommonWebCommandMetadataDataService { + + /** + * 构造函数 + */ + constructor(private metadataRepository: MetadataRepository) { } + + /** + * 根据metadataPath加载元数据 + */ + public loadByFullPath(metadataPath: string, metadataId: string): Promise { + return this.metadataRepository.relied(metadataId, metadataPath).then((response: any) => { + return this.createMetadata(response); + }); + } + + /** + * 根据projectPath和metadataId加载元数据 + */ + public loadByProjectPath(projectPath: string, metadataId: string) { + return this.metadataRepository.relied(metadataId, projectPath).then((response: any) => { + return this.createMetadata(response); + }); + } + + /** + * 根据metadataId加载元数据 + */ + public loadById(metadataId: string) { + return this.metadataRepository.retrieve(metadataId).then((response: any) => { + return this.createMetadata(response); + }); + } + + private createMetadata(response: any) { + const metadata = { + id: response.id, + content: JSON.parse(response.content), + refs: JSON.parse(response.refs) + }; + return metadata; + } +} diff --git a/packages/mobile-render/src/services/metadata/webcmd/custom-web-command-metadata-data-service.ts b/packages/mobile-render/src/services/metadata/webcmd/custom-web-command-metadata-data-service.ts new file mode 100644 index 00000000000..2b2d639732b --- /dev/null +++ b/packages/mobile-render/src/services/metadata/webcmd/custom-web-command-metadata-data-service.ts @@ -0,0 +1,39 @@ +import { MetadataRepository } from '../metadata-repository'; +import { Metadata } from '../types'; + +/** + * 自定义命令构件元数据数据服务 + */ +export class CustomWebCommandMetadataDataService { + constructor(private metadataRepository: MetadataRepository) { } + + public loadByType(metadataPath: string) { + return this.metadataRepository.loadMetadatasByType(metadataPath, ".webcmd"); + } + public loadByFullPath(metadataPath: string, metadataId: string): Promise { + return this.metadataRepository.relied(metadataId, metadataPath).then((response: any) => { + return this.createMetadata(response); + }); + } + + public loadByProjectPath(projectPath: string, metadataId: string) { + return this.metadataRepository.relied(metadataId, projectPath).then((response: any) => { + return this.createMetadata(response); + }); + } + + public loadById(metadataId: string) { + return this.metadataRepository.retrieve(metadataId).then((response: any) => { + return this.createMetadata(response); + }); + } + + private createMetadata(response: any) { + const metadata = { + id: response.id, + content: JSON.parse(response.content), + refs: JSON.parse(response.refs) + }; + return metadata; + } +} diff --git a/packages/mobile-render/src/services/metadata/webcmd/index.ts b/packages/mobile-render/src/services/metadata/webcmd/index.ts new file mode 100644 index 00000000000..354742a9bd6 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/webcmd/index.ts @@ -0,0 +1,2 @@ +export * from './common-web-command-metadata-data-service'; +export * from './custom-web-command-metadata-data-service'; diff --git a/packages/mobile-render/src/services/metadata/webcmp/custom-web-component-metadata-data-service.ts b/packages/mobile-render/src/services/metadata/webcmp/custom-web-component-metadata-data-service.ts new file mode 100644 index 00000000000..1cc500147fe --- /dev/null +++ b/packages/mobile-render/src/services/metadata/webcmp/custom-web-component-metadata-data-service.ts @@ -0,0 +1,46 @@ +import { MetadataRepository } from '../metadata-repository'; +import { Metadata } from '../types'; + +/** + * 自定义服务构件元数据数据服务 + */ +export class CustomWebComponentMetadataDataService { + constructor(private metadataRepository: MetadataRepository) { } + + public loadByType(metadataPath: string) { + return this.metadataRepository.loadMetadatasByType(metadataPath, ".webcmp").then((metadatas: any[]) => { + if (metadatas && metadatas.length > 0) { + return Promise.all(metadatas.map((metadata: any) => { + return this.loadByFullPath(metadataPath, metadata.id); + })); + } + }); + } + public loadByFullPath(metadataPath: string, metadataId: string): Promise { + return this.metadataRepository.relied(metadataId, metadataPath).then((response: any) => { + return this.createMetadata(response); + }); + } + + public loadByProjectPath(projectPath: string, metadataId: string) { + return this.metadataRepository.relied(metadataId, projectPath).then((response: any) => { + return this.createMetadata(response); + }); + } + + public loadById(metadataId: string) { + return this.metadataRepository.retrieve(metadataId).then((response: any) => { + return this.createMetadata(response); + }); + } + + private createMetadata(response: any) { + const metadata = { + id: response.id, + content: JSON.parse(response.content), + refs: JSON.parse(response.refs) + }; + return metadata; + } + +} diff --git a/packages/mobile-render/src/services/metadata/webcmp/index.ts b/packages/mobile-render/src/services/metadata/webcmp/index.ts new file mode 100644 index 00000000000..ba192bde17f --- /dev/null +++ b/packages/mobile-render/src/services/metadata/webcmp/index.ts @@ -0,0 +1 @@ +export * from './custom-web-component-metadata-data-service'; diff --git a/packages/mobile-render/src/services/module-config/command-handler-builder.ts b/packages/mobile-render/src/services/module-config/command-handler-builder.ts new file mode 100644 index 00000000000..f7d43a97df6 --- /dev/null +++ b/packages/mobile-render/src/services/module-config/command-handler-builder.ts @@ -0,0 +1,285 @@ +import { CommandTaskConfig, CommandTaskParamConfig, CommandHandlerConfig, ViewModel } from '@farris/devkit-vue'; + +/** + * 命令编排配置构造器 + */ +class CommandHandlerConfigBuilder { + + /** + * 表单元数据 + */ + private formMeta: any; + + /** + * 表单元数据 + */ + private webCmdMetas: any[]; + + private webComponentMetadatas: any[]; + + /** + * 构造函数 + */ + constructor(formMeta: any, webCmdMetas: any[], webComponentMetadatas: any[]) { + this.formMeta = formMeta; + this.webCmdMetas = webCmdMetas; + this.webComponentMetadatas = webComponentMetadatas; + } + + /** + * 构造命令处理方法 + */ + public build(commandNode: any): CommandHandlerConfig { + const commandHandlerNode = this.getCommandHandlerNode(commandNode.cmpId, commandNode.id); + const itemNodes = commandHandlerNode.Items; + this.formatItemNodes(null, itemNodes); + + const taskConfigs: CommandTaskConfig[] = []; + this.buildTaskConfigs(itemNodes, taskConfigs); + + const commandHandlerConfig: CommandHandlerConfig = { + commandName: commandNode.code, + tasks: taskConfigs + }; + + return commandHandlerConfig; + } + + /** + * 创建任务配置 + */ + private buildTaskConfigs(itemNodes: any[], taskConfigs: CommandTaskConfig[]) { + itemNodes.forEach((itemNode: any, commandItemIndex: number) => { + + // 1=分支 2=分支集合 + if (itemNode.Type === 1 || itemNode.Type === 2) { + return; + } + + // 普通节点 + const paramConfigs = this.buildTaskParamConfigs(itemNode.ParamConfigs); + + // 临时兼容 + if (itemNode.ComponentCode === 'AddDataService') { + itemNode.ComponentCode = 'CreateDataService'; + } + const taskConfig: CommandTaskConfig = { + name: itemNode.itemCode, + service: itemNode.ComponentCode, + method: itemNode.MethodCode, + params: paramConfigs, + links: [] + }; + + // 自定义服务需要特殊处理 + const isCustomService = this.isCustomService(itemNode.ComponentId); + if (isCustomService === true) { + const serviceName = this.getCustomServiceName(itemNode.ComponentId); + if (!serviceName) { + throw new Error(`CustomService(ComponentId=${itemNode.ComponentId}) does not exist`); + } + taskConfig.service = serviceName; + taskConfig.serviceUrl = this.getCustomServiceUrl(itemNode.ComponentPath, itemNode.ComponentCode, itemNode.ComponentId); + taskConfig.serviceDeps = this.getCustomServiceDeps(); + } + + taskConfigs.push(taskConfig); + const nextItemNode = itemNodes[commandItemIndex + 1] || null; + this.buildTaskLinkConfigs(itemNode, nextItemNode, taskConfig, taskConfigs); + }); + + return taskConfigs; + } + + /** + * 是否是自定义服务 + */ + public isCustomService(componentId: string): boolean { + const webcomponent = this.getWebComponentMetadata(componentId); + return !!webcomponent; + } + + /** + * 构造自定义服务名 + */ + private getCustomServiceName(componentId: string): string | null { + const webcomponent = this.getWebComponentMetadata(componentId); + if (!webcomponent) { + return null; + } + const className = webcomponent.ClassName; + return className; + } + + private getWebComponentMetadata(componentId: string): any { + if (!this.webComponentMetadatas || !Array.isArray(this.webComponentMetadatas)) { + return null; + } + const webcomponent = this.webComponentMetadatas.find((webComponentMetadata) => { + return webComponentMetadata.id === componentId; + }); + return webcomponent?.content; + } + + /** + * 构造自定义服务地址 + */ + private getCustomServiceUrl(componentPath: string, componentCode: string, componentId: string): string { + const pathSegs = componentPath.split('/'); + const app = pathSegs[0]; + const su = pathSegs[1]; + const bo = pathSegs[2]; + const proj = pathSegs[3]; + + const webcomponent = this.getWebComponentMetadata(componentId); + if (!webcomponent) { + throw new Error(`WebComponentMetadata(Id=${componentId}) does not exist`); + } + const fullFileName = webcomponent.Source; + if (!fullFileName) { + throw new Error(`WebComponentMetadata(Id=${componentId}) does not exist`); + } + const fileName = fullFileName.split('/').pop().split('.')[0].toLowerCase(); + const serviceUrl = `/apps/${app}/${su}/web/${proj}/${fileName}.js`.toLowerCase(); + return serviceUrl; + } + + /** + * 获取自定义服务的依赖 + */ + private getCustomServiceDeps(): any[] { + const serviceDeps = [ViewModel]; + return serviceDeps; + } + + /** + * 创建任务参数配置 + */ + public buildTaskParamConfigs(paramNodes: any[]): CommandTaskParamConfig[] { + const paramConfigs: CommandTaskParamConfig[] = []; + paramNodes.forEach((paramNode: any) => { + const paramConfig: CommandTaskParamConfig = { + name: paramNode.ParamCode, + value: paramNode.ParamExpress + }; + paramConfigs.push(paramConfig); + }); + + return paramConfigs; + } + + /** + * 构造任务连接配置 + */ + private buildTaskLinkConfigs(currentItemNode: any, nextItemNode: any, currentTaskConfig: any, taskConfigs: CommandTaskConfig[]) { + if (!nextItemNode) { + nextItemNode = this.getNextItemNodeFromParent(currentItemNode); + if (!nextItemNode) { + return []; + } + } + + // 任务节点 + if (nextItemNode.Type === 0) { + currentTaskConfig.links.push({ + nextTaskName: nextItemNode.itemCode, + conditions: true + }); + return; + } + + // 分支节点 + if (nextItemNode.Type === 2) { + const caseItemNodes = nextItemNode.Items as any[]; + caseItemNodes.forEach((caseItemNode) => { + if (!caseItemNode || !caseItemNode.Items || !caseItemNode.Items[0]) { + return; + } + currentTaskConfig.links.push({ + nextTaskName: caseItemNode.Items[0].itemCode, + conditions: caseItemNode.Express + }); + + // 递归处理分支下的任务节点 + this.buildTaskConfigs(caseItemNode.Items, taskConfigs); + }); + } + } + + /** + * 从父层级中获取下一节点 + */ + private getNextItemNodeFromParent(itemNode: any) { + let nextItemNode = null; + let parentItemNode = itemNode.__parent__; + while (!nextItemNode && parentItemNode) { + if (parentItemNode.__nextSlibing__ && parentItemNode.__nextSlibing__.Type === 0) { + nextItemNode = parentItemNode.__nextSlibing__; + } + parentItemNode = parentItemNode.__parent__; + } + + return nextItemNode; + } + + /** + * 从命令构件元数据中获取命令编排信息 + */ + private getCommandHandlerNode(webCmdId: string, commandId: string) { + const commandHandlerName = this.getCommandHandlerName(webCmdId, commandId); + const targetWebCmdMeta = this.webCmdMetas.find((webCmdMeta) => { + return webCmdMeta.id === webCmdId; + }); + + if (!targetWebCmdMeta) { + throw new Error(`WebCmdMeta(Id=${webCmdId}) does not exist`); + } + + const targetCommandHandler = targetWebCmdMeta.content.Commands.find((commandHandler: any) => { + return commandHandler.Code === commandHandlerName; + }); + if (!targetCommandHandler) { + throw new Error(`Command(Code=${commandHandlerName}) does not exist in WebCmdMeta(Id=${webCmdId})`); + } + + return targetCommandHandler; + } + + /** + * 获取命令处理器名称 + */ + private getCommandHandlerName(webCmdId: string, commandName: string) { + const webCmds = this.formMeta.module.webcmds as any[]; + const targetWebCmd = webCmds.find((webCmd) => { + return webCmd.id === webCmdId; + }); + + const refedHandlers = targetWebCmd.refedHandlers as any[]; + const targetRefHandler = refedHandlers.find((refedHandler: any) => { + return refedHandler.host === commandName; + }); + + return targetRefHandler.handler; + } + + /** + * 加工节点,建立父子关系 + */ + private formatItemNodes(parentItemNode: any, itemNodes: any[]) { + if (!Array.isArray(itemNodes)) { + return []; + } + + itemNodes.forEach((itemNode, itemIndex) => { + itemNode.__parent__ = parentItemNode; + itemNode.__preSlibing__ = itemNodes[itemIndex - 1] || null; + itemNode.__nextSlibing__ = itemNodes[itemIndex + 1] || null; + if (Array.isArray(itemNode.Items)) { + this.formatItemNodes(itemNode, itemNode.Items); + } + }); + } + +} + +export { CommandHandlerConfigBuilder }; diff --git a/packages/mobile-render/src/services/module-config/entity-store-config-builder.ts b/packages/mobile-render/src/services/module-config/entity-store-config-builder.ts new file mode 100644 index 00000000000..c1e7bd8b5b5 --- /dev/null +++ b/packages/mobile-render/src/services/module-config/entity-store-config-builder.ts @@ -0,0 +1,135 @@ +import { + FieldConfig, PrimitiveFieldConfig, EntityFieldConfig, EntityListFieldConfig, EntityConfig, + EntityStateConfig, EntityStoreConfig +} from '@farris/devkit-vue'; + +/** + * 实体仓库配置构造器 + */ +class EntityStoreConfigBuilder { + + /** + * 表单元数据 + */ + private formMeta: any; + + /** + * 构造函数 + */ + constructor(formMeta: any) { + this.formMeta = formMeta; + } + + /** + * 构造实体仓库配置 + */ + build(schemaNode: any) { + const id = this.formMeta.module.code + '-entitystore'; + const parentEntitySchema = schemaNode.entities[0]; + const entityStateConfig = this.buildEntityStateConfig(parentEntitySchema); + const entityStoreConfig: EntityStoreConfig = { + id, + state: entityStateConfig + }; + + return entityStoreConfig; + } + + /** + * 创建实体状态配置 + */ + private buildEntityStateConfig(entitySchemaNode: any): EntityStateConfig { + const entityConfig = this.buildEntityConfig(entitySchemaNode); + const entityStateConfig = { + entity: entityConfig + }; + + return entityStateConfig; + } + + /** + * 构造实体配置 + */ + private buildEntityConfig(entitySchemaNode: any): EntityConfig { + const idKey = entitySchemaNode.type.primary; + const { fields, entities } = entitySchemaNode.type; + const fieldConfigs = this.buildEntityFieldConfigs(fields, entities); + const entityConfig = { + idKey, + fields: fieldConfigs + }; + return entityConfig; + } + + /** + * 构造实体字段配置集合 + */ + private buildEntityFieldConfigs(fieldSchemaNodes: any[], childEntitySchemaNodes: any[]): FieldConfig[] { + const fieldConfigs: FieldConfig[] = []; + + // 简单字段和关联字段 + fieldSchemaNodes = fieldSchemaNodes || []; + fieldSchemaNodes.forEach((fieldSchemaNode: any) => { + let fieldConfig: FieldConfig; + if (fieldSchemaNode.$type === 'SimpleField') { + fieldConfig = this.buildPrimitiveFieldConfig(fieldSchemaNode); + } else { + fieldConfig = this.buildEntityFieldConfig(fieldSchemaNode); + } + fieldConfigs.push(fieldConfig); + }); + + // 子实体字段 + childEntitySchemaNodes = childEntitySchemaNodes || []; + childEntitySchemaNodes.forEach((childEntitySchemaNode: any) => { + const fieldConfig = this.buildEntityListFieldConfig(childEntitySchemaNode); + fieldConfigs.push(fieldConfig); + }); + + return fieldConfigs; + } + + /** + * 构造简单字段配置 + */ + private buildPrimitiveFieldConfig(fieldSchemaNode: any): PrimitiveFieldConfig { + const fieldConfig: PrimitiveFieldConfig = { + type: 'Primitive', + name: fieldSchemaNode.label + }; + + return fieldConfig; + } + + /** + * 构造实体字段配置 + */ + private buildEntityFieldConfig(fieldSchemaNode: any): EntityFieldConfig { + const name = fieldSchemaNode.label; + + const entityConfig = this.buildEntityConfig(fieldSchemaNode); + const fieldConfig: EntityFieldConfig = { + type: 'Entity', + name, + entityConfig + }; + + return fieldConfig; + } + + /** + * 构造实体列表字段配置 + */ + private buildEntityListFieldConfig(childEntitySchemaNode: any): EntityListFieldConfig { + const type = 'EntityList'; + const name = childEntitySchemaNode.label; + const childEntityConfig = this.buildEntityConfig(childEntitySchemaNode); + const fieldSchema: EntityListFieldConfig = { + type, name, childEntityConfig + }; + + return fieldSchema; + } +} + +export { EntityStoreConfigBuilder }; diff --git a/packages/mobile-render/src/services/module-config/index.ts b/packages/mobile-render/src/services/module-config/index.ts new file mode 100644 index 00000000000..0a75b9c57ab --- /dev/null +++ b/packages/mobile-render/src/services/module-config/index.ts @@ -0,0 +1,5 @@ +export * from './entity-store-config-builder'; +export * from './ui-store-config-builder'; +export * from './repository-config-builder'; +export * from './module-config-builder'; +export * from './viewmodel-config-builder'; diff --git a/packages/mobile-render/src/services/module-config/module-config-builder.ts b/packages/mobile-render/src/services/module-config/module-config-builder.ts new file mode 100644 index 00000000000..9751e5286e8 --- /dev/null +++ b/packages/mobile-render/src/services/module-config/module-config-builder.ts @@ -0,0 +1,142 @@ +import { + StaticProvider, + EntityStoreConfig, UIStateConfig, StateMachineConfig, RepositoryConfig, + ViewModelConfig, ModuleConfig, + UIStoreConfig, +} from '@farris/devkit-vue'; +import { EntityStoreConfigBuilder } from './entity-store-config-builder'; +import { RepositoryConfigBuilder } from './repository-config-builder'; +import { UIStoreConfigBuilder } from './ui-store-config-builder'; +import { StateMachineConfigBuilder } from './state-machine-config-builder'; +import { ViewModelConfigBuilder } from './viewmodel-config-builder'; + +/** + * 模块配置构造器 + */ +class ModuleConfigBuilder { + + /** + * 上下文 + */ + private context: any; + + /** + * 构造函数 + */ + constructor(context: any) { + this.context = context; + } + + /** + * 构造模块配置 + */ + public build() { + const formMeta = this.context.form; + const webCmdMetas = this.context.webcmds; + const smMetas = this.context.stateMachines; + const webComponentMetadatas = this.context.webComponents; + + const id = formMeta.module.code; + const providers: StaticProvider[] = this.context.moduleProviders; + const entityStoreConfigs = this.buildEntityStoreConfigs(formMeta); + const uiStoreConfigs = this.buildUIStoreConfigs(formMeta); + const stateMachineConfigs = this.buildStateMachineConfigs(formMeta, smMetas); + const repositoryConfigs = this.buildRepositoryConfigs(formMeta); + const viewModelConfigs = this.buildViewModelConfigs(formMeta, webCmdMetas,webComponentMetadatas, this.context.viewModelProviders); + + const moduleConfig: ModuleConfig = { + id, + providers, + entityStores: entityStoreConfigs, + uiStores: uiStoreConfigs, + stateMachines: stateMachineConfigs, + repositories: repositoryConfigs, + viewModels: viewModelConfigs + }; + + return moduleConfig; + } + + /** + * 构造实体仓库配置 + */ + private buildEntityStoreConfigs(formMeta: any): EntityStoreConfig[] { + const builder = new EntityStoreConfigBuilder(formMeta); + const configs: EntityStoreConfig[] = []; + + const schemaNodes = formMeta.module.entity; + schemaNodes.forEach((schema: any) => { + const config = builder.build(schema); + configs.push(config); + }); + + return configs; + } + + /** + * 构造远程实体仓库配置 + */ + private buildRepositoryConfigs(formMeta: any): RepositoryConfig[] { + const builder = new RepositoryConfigBuilder(formMeta); + const configs: RepositoryConfig[] = []; + const schemaNodes = formMeta.module.entity as any[]; + schemaNodes.forEach((schemaNode: any) => { + const config = builder.build(schemaNode); + configs.push(config); + }); + + return configs; + } + + /** + * 构造UI仓库配置 + */ + private buildUIStoreConfigs(formMeta: any): UIStoreConfig[] { + const builder = new UIStoreConfigBuilder(formMeta); + const configs: UIStoreConfig[] = []; + const viewModelNodes = formMeta.module.viewmodels as any[]; + viewModelNodes.forEach((viewModelNode) => { + const config = builder.build(viewModelNode); + configs.push(config); + }); + + return configs; + } + + /** + * 构造状态机配置 + */ + private buildStateMachineConfigs(formMeta: any, smMetas: any): StateMachineConfig[] { + const builder = new StateMachineConfigBuilder(formMeta); + const configs: StateMachineConfig[] = []; + smMetas.forEach((smMeta: any) => { + const config = builder.build(smMeta); + if (!config) { + return; + } + configs.push(config); + }); + + return configs; + } + + /** + * 构造视图模型配置 + */ + public buildViewModelConfigs(formMeta: any, webCmdMetas: any[],webComponentMetadatas: any[], viewModelProviders: any[]): ViewModelConfig[] { + const builder = new ViewModelConfigBuilder(formMeta, webCmdMetas,webComponentMetadatas, viewModelProviders); + const configs: ViewModelConfig[] = []; + const viewModelNodes = formMeta.module.viewmodels as any[]; + viewModelNodes.forEach((viewModelNode) => { + const config = builder.build(viewModelNode); + if (!config) { + return; + } + configs.push(config); + }); + + return configs; + } +} + +export { ModuleConfigBuilder }; diff --git a/packages/mobile-render/src/services/module-config/repository-config-builder.ts b/packages/mobile-render/src/services/module-config/repository-config-builder.ts new file mode 100644 index 00000000000..6ea679932d9 --- /dev/null +++ b/packages/mobile-render/src/services/module-config/repository-config-builder.ts @@ -0,0 +1,38 @@ +import { Module, RepositoryConfig } from '@farris/devkit-vue'; +import { BefRepository } from '@farris/bef-vue'; + +/** + * 远程实体仓库配置构造器 + */ +class RepositoryConfigBuilder { + + /** + * 表单元数据 + */ + private formMeta: any; + + /** + * 构造函数 + */ + constructor(formMeta: any) { + this.formMeta = formMeta; + } + + /** + * 构造配置 + */ + public build(schema: any): RepositoryConfig { + const config = { + id: this.formMeta.module.code + '-repository', + type: BefRepository, + deps: [ Module ], + isDynamic: true, + entityStore: this.formMeta.module.code + '-entitystore', + baseUrl: '/' + schema.sourceUri.toLowerCase() + }; + + return config; + } +} + +export { RepositoryConfigBuilder }; diff --git a/packages/mobile-render/src/services/module-config/state-machine-config-builder.ts b/packages/mobile-render/src/services/module-config/state-machine-config-builder.ts new file mode 100644 index 00000000000..afedc8f890e --- /dev/null +++ b/packages/mobile-render/src/services/module-config/state-machine-config-builder.ts @@ -0,0 +1,210 @@ +import { PageStateConfig, TransitionActionConfig, ConditionConfig, RenderStateConfig, StateMachineConfig } from '@farris/devkit-vue'; + +/** + * 状态机配置 + */ +class StateMachineConfigBuilder { + + /** + * 表单元数据 + */ + private formMeta: any; + + /** + * 构造函数 + */ + constructor(formMeta: any) { + this.formMeta = formMeta; + } + + /** + * 构造配置 + */ + public build(smMeta: any): StateMachineConfig | undefined { + if(!smMeta){ + return; + } + // 未被引用的不处理 + const viewModelNode = this.getViewModelNode(smMeta); + const componentNode = this.getComponentNode(viewModelNode); + if (!componentNode) { + return; + } + + const smMetaContent = smMeta.content; + + const statesNodes = smMetaContent.state; + const pageStateConfigs = this.buildPageStateConfigs(statesNodes); + + const actionsObjNode = smMetaContent.action; + const actionConfigs = this.buildActionConfigs(actionsObjNode); + + const renderStatesObjNode = smMetaContent.renderState; + const renderStateConfigs = this.buildRenderStateConfigs(renderStatesObjNode, componentNode); + + const smConfig: StateMachineConfig = { + id: viewModelNode.stateMachine, + initPageState: smMetaContent.initialState, + pageStates: pageStateConfigs, + transitionActions: actionConfigs, + state: { + renderStates: renderStateConfigs + } + }; + + return smConfig; + } + + /** + * 页面状态配置 + */ + private buildPageStateConfigs(stateNodes: any[]): PageStateConfig[] { + if (!Array.isArray(stateNodes)) { + return []; + } + + const pageStateConfigs: PageStateConfig[] = stateNodes.map((stateNode) => { + const pageStateconfig: PageStateConfig = { + name: stateNode.state + }; + return pageStateconfig; + }); + + return pageStateConfigs; + } + + /** + * 构造迁移动作 + */ + private buildActionConfigs(actionsObjNode: any): TransitionActionConfig[] { + if (!actionsObjNode) { + return []; + } + + const actionConfigs = Object.keys(actionsObjNode).map((actionName: string) => { + const actionNode = actionsObjNode[actionName]; + const actionConfig: TransitionActionConfig = { + name: actionName, + transitionTo: actionNode.transitTo + }; + + return actionConfig; + }); + + return actionConfigs; + } + + /** + * 构造可视化状态配置 + */ + private buildRenderStateConfigs(renderStatesObjNode: any, componentNode: any) { + if (!renderStatesObjNode) { + return []; + } + + const renderStateConfigs = Object.keys(renderStatesObjNode).map((stateName: string) => { + const renderStateNode = renderStatesObjNode[stateName]; + const conditions = this.buildRenderConditionConfigs(renderStateNode.condition, componentNode); + const renderStateConfig: RenderStateConfig = { + name: stateName, + conditions + }; + + return renderStateConfig; + }); + + return renderStateConfigs; + } + + /** + * 构造渲染条件配置 + */ + private buildRenderConditionConfigs(conditionNodes: any[], componentNode: any): ConditionConfig[] { + if (!Array.isArray(conditionNodes)) { + return []; + } + + const conditionConfigs: ConditionConfig[] = conditionNodes.map((conditionNode) => { + const conditionConfig: ConditionConfig = { ...conditionNode }; + conditionConfig.source = this.getSource(conditionNode.source, componentNode); + conditionConfig.target = this.getTarget(conditionNode.target); + + return conditionConfig; + }); + + return conditionConfigs; + } + + /** + * 获取源值 + */ + private getSource(source: string, componentNode: any): string { + const sourceLen = source.length; + if (source.startsWith('getData') === true) { + const startIndex = 9; + const endIndex = sourceLen - 2; + return source.slice(startIndex, endIndex); + } + + if (source.startsWith('getUIState') === true) { + const startIndex = 12; + const endIndex = sourceLen - 2; + return source.slice(startIndex, endIndex); + } + + if (source.startsWith('state') === true) { + return `{STATEMACHINE~/#{${componentNode.id}}/currentPageState}`; + } + + return source; + } + + /** + * 获取目标值 + */ + private getTarget(target: any) { + if (target.startsWith("'") || target.startsWith('"')) { + const startIndex = 1; + const endIndex = target.length -1; + return target.slice(startIndex, endIndex); + } + return JSON.parse(target); + } + + /** + * 获取状态机对应的视图模型节点 + */ + private getViewModelNode(smMeta: any): any | undefined { + const smNodes = this.formMeta.module.stateMachines; + const viewModelNodes = this.formMeta.module.viewmodels; + + const smMetaId = smMeta.id; + const targetSmNode = smNodes.find((smNode: any) => { + return smNode.uri === smMetaId; + }); + + if (!targetSmNode) { + return; + } + + const targetViewModelNode = viewModelNodes.find((viewModelNode: any) => { + return viewModelNode.stateMachine === targetSmNode.id; + }); + + return targetViewModelNode; + } + + /** + * 获取状态机对应组件节点 + */ + private getComponentNode(viewModelNode: any): any | undefined { + const componentNodes = this.formMeta.module.components; + const targetComponentNode = componentNodes.find((componentNode: any) => { + return componentNode.viewModel === viewModelNode.id; + }); + + return targetComponentNode; + } +} + +export { StateMachineConfigBuilder }; diff --git a/packages/mobile-render/src/services/module-config/ui-store-config-builder.ts b/packages/mobile-render/src/services/module-config/ui-store-config-builder.ts new file mode 100644 index 00000000000..9ad39b83bf1 --- /dev/null +++ b/packages/mobile-render/src/services/module-config/ui-store-config-builder.ts @@ -0,0 +1,61 @@ +import { UIStatePropConfig, UIStateConfig, UIStoreConfig, UIState } from '@farris/devkit-vue'; + +/** + * UI状态仓库配置构造器 + */ +class UIStoreConfigBuilder { + + /** + * 表单元数据 + */ + private formMeta: any; + + /** + * 构造函数 + */ + constructor(formMeta: any) { + this.formMeta = formMeta; + } + + /** + * 构造配置 + */ + public build(viewModelNode: any): UIStoreConfig { + const stateConfig = this.getUIStateConfig(viewModelNode.states); + const storeConfig: UIStoreConfig = { + id: viewModelNode.code + '-uistore', + state: stateConfig + }; + + return storeConfig; + } + + /** + * 获取状态配置 + */ + private getUIStateConfig(stateNodes: any[]): UIStateConfig { + const propConfigs = this.getUIStatePropConfigs(stateNodes); + const stateConfig: UIStateConfig = { + props: propConfigs + }; + + return stateConfig; + } + + /** + * 获取属性设置 + */ + private getUIStatePropConfigs(stateNodes: any[]): UIStatePropConfig[] { + const propConfigs: UIStatePropConfig[] = []; + stateNodes.forEach((stateNode) => { + const propConfig: UIStatePropConfig = { + name: stateNode.code + }; + propConfigs.push(propConfig); + }); + + return propConfigs; + } +} + +export { UIStoreConfigBuilder }; diff --git a/packages/mobile-render/src/services/module-config/viewmodel-config-builder.ts b/packages/mobile-render/src/services/module-config/viewmodel-config-builder.ts new file mode 100644 index 00000000000..8fc0509c5d4 --- /dev/null +++ b/packages/mobile-render/src/services/module-config/viewmodel-config-builder.ts @@ -0,0 +1,142 @@ +import { CommandParamConfig, CommandConfig, ViewModelConfig, CommandHandlerConfig } from '@farris/devkit-vue'; +import { CommandHandlerConfigBuilder } from './command-handler-builder'; + +/** + * 视图模型配置构造器 + */ +class ViewModelConfigBuilder { + + /** + * 表单元数据 + */ + private formMeta: any; + + /** + * 表单元数据 + */ + private webCmdMetas: any[]; + + private webComponentMetadatas: any[]; + + /** + * 视图模型注入配置 + */ + private viewModelProviders: any[]; + + /** + * 构造函数 + */ + constructor(formMeta: any, webCmdMetas: any[], webComponentMetadatas: any[],viewModelProviders: any[]) { + this.formMeta = formMeta; + this.webCmdMetas = webCmdMetas; + this.webComponentMetadatas = webComponentMetadatas; + this.viewModelProviders = viewModelProviders; + } + + /** + * 构造配置 + */ + public build(viewModelNode: any) { + const componentNode = this.getComponentNode(viewModelNode.id); + if (!componentNode) { + return; + } + + const moduleId = this.formMeta.module.code; + const commandConfigs = this.buildCommandConfigs(viewModelNode.commands); + const commandHandlerConfigs = this.buildCommandHandlerConfigs(viewModelNode.commands); + + const parentViewModelId = viewModelNode.parent; + let parentComponent = null; + if (parentViewModelId) { + parentComponent = this.getComponentNode(parentViewModelId); + } + this.getComponentNode(parentViewModelId); + + const viewModelConfig: ViewModelConfig = { + id: componentNode.id, + entityStore: moduleId + '-entitystore', + uiStore: viewModelNode.code + '-uistore', + stateMachine: viewModelNode.stateMachine, + repository: moduleId + '-repository', + providers: this.viewModelProviders, + commands: commandConfigs, + commandHandlers: commandHandlerConfigs, + bindingPath: viewModelNode.bindTo, + parentId: parentComponent ? parentComponent.id : null + }; + + return viewModelConfig; + } + + /** + * 构造命令配置 + */ + private buildCommandConfigs(commandNodes: any[]): CommandConfig[] { + const commandConfigs: CommandConfig[] = []; + commandNodes.forEach((commandNode) => { + const paramConfigs = this.buildCommandParamConfigs(commandNode.params); + const commandConfig: CommandConfig = { + name: commandNode.code, + params: paramConfigs + }; + commandConfigs.push(commandConfig); + }); + + return commandConfigs; + } + + /** + * 构造命令参数配置 + */ + private buildCommandParamConfigs(paramNodes: any[]): CommandParamConfig[] { + const paramsConfigs: CommandParamConfig[] = []; + paramNodes.forEach((paramNode) => { + const paramConfig: CommandParamConfig = { + name: paramNode.name, + value: paramNode.value + }; + paramsConfigs.push(paramConfig); + }); + + return paramsConfigs; + } + + /** + * 构造命令处理器配置 + */ + private buildCommandHandlerConfigs(commandNodes: any[]): CommandHandlerConfig[] { + const commandHandlerConfigBuilder = new CommandHandlerConfigBuilder(this.formMeta, this.webCmdMetas, this.webComponentMetadatas); + const commandHandlerConfigs: CommandHandlerConfig[] = []; + commandNodes.forEach((commandNode) => { + // const webCmdId = commandNode.cmpId; + // const commandName = commandNode.code; + // const commandHandlerNode = this.getCommandHandlerNode(webCmdId, commandNode.handlerName); + + // const taskConfigs = this.buildTaskConfigs(commandHandlerNode.Items); + // const commandHandlerConfig: CommandHandlerConfig = { + // commandName, + // tasks: taskConfigs + // }; + // commandHandlerConfigs.push(commandHandlerConfig); + const commandHandlerConfig = commandHandlerConfigBuilder.build(commandNode); + commandHandlerConfigs.push(commandHandlerConfig); + }); + + return commandHandlerConfigs; + } + /** + * 获取视图模型对应组件 + */ + private getComponentNode(viewModelId: string): any | undefined { + const componentNodes = this.formMeta.module.components; + const targetComponentNode = componentNodes.find((componentNode: any) => { + return componentNode.viewModel === viewModelId; + }); + + return targetComponentNode; + } + +} + +export { ViewModelConfigBuilder }; diff --git a/packages/mobile-render/src/services/page-config/bindings/binding-context.ts b/packages/mobile-render/src/services/page-config/bindings/binding-context.ts new file mode 100644 index 00000000000..91df5d2ef0a --- /dev/null +++ b/packages/mobile-render/src/services/page-config/bindings/binding-context.ts @@ -0,0 +1,43 @@ +import { Module, ViewModelState, ViewModel, Store } from '@farris/devkit-vue'; +import { Binding } from './binding'; +import { BindingWatcher } from './binding-watcher'; + +/** + * 绑定上下文 + */ +class BindingContext { + + /** + * 模块 + */ + private module: Module; + + /** + * 监听器 + */ + private watcher: BindingWatcher; + + /** + * 构造函数 + */ + constructor(module: Module) { + this.module = module; + this.watcher = new BindingWatcher(this); + } + + /** + * 获取视图模 + */ + public getViewModel(id: string): ViewModel | null { + return this.module.getViewModel(id); + } + + /** + * 注册状态变更依赖 + */ + public registerDep(store: Store, binding: Binding, bindingConfig: any, target: any, propName: string): void { + this.watcher.registerDep(store, binding, bindingConfig, target, propName); + } +} + +export { BindingContext }; diff --git a/packages/mobile-render/src/services/page-config/bindings/binding-factory.ts b/packages/mobile-render/src/services/page-config/bindings/binding-factory.ts new file mode 100644 index 00000000000..a0a0bf99cd2 --- /dev/null +++ b/packages/mobile-render/src/services/page-config/bindings/binding-factory.ts @@ -0,0 +1,49 @@ +import { Binding } from './binding'; +import { EntityFieldBinding } from './entity-field-binding'; +import { EntityListBinding } from './entity-list-binding'; +import { CommandBinding } from './command-binding'; + +/** + * 绑定工厂 + */ +class BindingFactory { + + /** + * 绑定实例集合 + */ + private bindings: Map; + + /** + * 构造函数 + */ + public constructor() { + this.initBindings(); + } + + /** + * 创建绑定 + */ + public create(name: string): Binding { + const binding = this.bindings.get(name); + if (!binding) { + throw new Error(`Binding(type=${name}) not found`); + } + + return binding; + } + + /** + * 初始化绑定集合 + */ + private initBindings() { + const bindingCtors = [EntityFieldBinding, EntityListBinding, CommandBinding]; + + this.bindings = new Map(); + bindingCtors.forEach((bindingCtor) => { + const binding = new bindingCtor(); + this.bindings.set(binding.name, binding); + }); + } +} + +export { BindingFactory }; diff --git a/packages/mobile-render/src/services/page-config/bindings/binding-util.ts b/packages/mobile-render/src/services/page-config/bindings/binding-util.ts new file mode 100644 index 00000000000..a85c20c3d09 --- /dev/null +++ b/packages/mobile-render/src/services/page-config/bindings/binding-util.ts @@ -0,0 +1,36 @@ +import { TypeUtil } from '../../../utils/index'; + +/** + * 绑定工具类 + */ +class BindingUtil { + + /** + * 全部绑定类型 + */ + public static supportedBindingTypes = [ + 'EntityField', 'Entity', 'EntityList', + 'Variable', 'StatMachine', 'Command' + ]; + + /** + * 判断是否是绑定 + */ + public static isBinding(bindingConfig: any): boolean { + if (!bindingConfig) { + return false; + } + + if (!TypeUtil.isObject(bindingConfig)) { + return false; + } + + if (!this.supportedBindingTypes.includes(bindingConfig.type)) { + return false; + } + + return true; + } +} + +export { BindingUtil }; diff --git a/packages/mobile-render/src/services/page-config/bindings/binding-watcher.ts b/packages/mobile-render/src/services/page-config/bindings/binding-watcher.ts new file mode 100644 index 00000000000..02d7d87c468 --- /dev/null +++ b/packages/mobile-render/src/services/page-config/bindings/binding-watcher.ts @@ -0,0 +1,110 @@ +import { Store, StateChange } from '@farris/devkit-vue'; +import { Binding } from './binding'; +import { BindingContext } from './binding-context'; + +/** + * 属性依赖的绑定信息 + */ +interface PropDep { + binding: Binding, + bindingConfig: any; + target: any; + propName: string; +} + +type UnWatchFunction = () => void; + +/** + * 绑定监听器 + */ +class BindingWatcher { + + /** + * 绑定上下文 + */ + private bindingContext: BindingContext; + + /** + * 仓库监听监听器 + */ + private storeWatchers: Map; + + /** + * 状态仓库依赖 + */ + private storesDeps: Map>>; + + /** + * 构造函数 + */ + constructor(bindingContext: BindingContext) { + this.bindingContext = bindingContext; + this.storesDeps = new Map>>(); + this.storeWatchers = new Map(); + } + + /** + * 注册状态变更依赖 + */ + public registerDep(store: Store, binding: Binding, bindingConfig: any, target: any, propName: string): void { + + // 注册监听 + this.addStoreWatcher(store); + + // 获取仓库所有依赖 + const storeId = store.getId(); + let storeDeps = this.storesDeps.get(storeId); + if (!storeDeps) { + storeDeps = new Map>(); + this.storesDeps.set(storeId, storeDeps); + } + + // 获取属性所有依赖 + const propPath = bindingConfig.bindingPath; + let propDeps = storeDeps.get(propPath); + if (!propDeps) { + propDeps = new Set(); + storeDeps.set(propPath, propDeps); + } + + // 注册依赖 + const propDep = { binding, bindingConfig, target, propName }; + propDeps.add(propDep); + } + + /** + * 添加仓库监听 + */ + private addStoreWatcher(store: Store) { + const storeId = store.getId(); + if (this.storeWatchers.has(storeId)) { + return; + } + + const unWatch = store.watchChange((change) => { + this.updateBindings(storeId, change); + }) as any; + + this.storeWatchers.set(storeId, unWatch); + } + + /** + * 更新绑定 + */ + private updateBindings(storeId: string, change: StateChange) { + const storeDeps = this.storesDeps.get(storeId); + if (!storeDeps) { + return; + } + + // 更新全部绑定 + storeDeps.forEach((propDeps, propPath) => { + propDeps.forEach((propDep) => { + const { binding, bindingConfig, target, propName } = propDep; + binding.update(bindingConfig, target, propName, this.bindingContext); + }); + }); + } +} + +export { BindingWatcher }; diff --git a/packages/mobile-render/src/services/page-config/bindings/binding.ts b/packages/mobile-render/src/services/page-config/bindings/binding.ts new file mode 100644 index 00000000000..c125b171315 --- /dev/null +++ b/packages/mobile-render/src/services/page-config/bindings/binding.ts @@ -0,0 +1,12 @@ +import { BindingContext } from './binding-context'; + +/** + * 属性绑定基类 + */ +abstract class Binding { + abstract name: string; + abstract init(bindingConfig: any, target: any, propName: string, bindingContext: BindingContext): void; + abstract update(bindingConfig: any, target: any, propName: string, bindingContext: BindingContext): void; +} + +export { Binding }; diff --git a/packages/mobile-render/src/services/page-config/bindings/command-binding.ts b/packages/mobile-render/src/services/page-config/bindings/command-binding.ts new file mode 100644 index 00000000000..f98208926c4 --- /dev/null +++ b/packages/mobile-render/src/services/page-config/bindings/command-binding.ts @@ -0,0 +1,36 @@ +import { Binding } from './binding'; +import { BindingContext } from './binding-context'; + +/** + * 命令绑定 + */ +class CommandBinding extends Binding { + + /** + * 绑定名称 + */ + public name = 'Command'; + + /** + * 初始化绑定 + */ + public init(bindingConfig: any, target: any, propName: string, bindingContext: BindingContext): void { + this.update(bindingConfig, target, propName, bindingContext); + } + + /** + * 值更绑定 + */ + public update(bindingConfig: any, target: any, propName: string, bindingContext: BindingContext) { + const { name: commandName, viewModelId, } = bindingConfig; + const viewModel= bindingContext.getViewModel(viewModelId) as any; + if (!viewModel) { + throw new Error(`ViewModel(id=${viewModelId}) not found`); + } + + const commandHandlerFunc = viewModel[commandName]; + target[propName] = commandHandlerFunc.bind(viewModel); + } +} + +export { CommandBinding }; diff --git a/packages/mobile-render/src/services/page-config/bindings/entity-field-binding.ts b/packages/mobile-render/src/services/page-config/bindings/entity-field-binding.ts new file mode 100644 index 00000000000..8e595c99f96 --- /dev/null +++ b/packages/mobile-render/src/services/page-config/bindings/entity-field-binding.ts @@ -0,0 +1,73 @@ +import { Binding } from './binding'; +import { BindingContext } from './binding-context'; + +/** + * 实体字段绑定 + */ +class EntityFieldBinding extends Binding { + + /** + * 绑定名称 + */ + public name = 'EntityField'; + + /** + * 初始化 + */ + public init(bindingConfig: any, target: any, propName: string, bindingContext: BindingContext): void { + const { direction, viewModelId } = bindingConfig; + const entityStore = this.getEntityStore(viewModelId, bindingContext); + + if (direction === 'TwoWay') { + target['onUpdate:modelValue'] = (newValue: any) => { + this.setValue(newValue, bindingConfig, bindingContext); + }; + } + + bindingContext.registerDep(entityStore, this, bindingConfig, target, propName); + this.update(bindingConfig, target, propName, bindingContext); + } + + /** + * 值更新 + */ + public update(bindingConfig: any, target: any, propName: string, bindingContext: BindingContext) { + const value = this.getValue(bindingConfig, bindingContext); + target[propName] = value; + } + + /** + * 获取实体仓库 + */ + private getEntityStore(viewModelId: string, bindingContext: BindingContext): any { + const viewModel = bindingContext.getViewModel(viewModelId); + if (!viewModel) { + return; + } + const { entityStore } = viewModel; + + return entityStore; + } + + /** + * 获取属性值 + */ + private getValue(bindingConfig: any, bindingContext: any): void { + const { path, viewModelId } = bindingConfig; + const entityStore = this.getEntityStore(viewModelId, bindingContext); + const value = entityStore.getValueByPath(path); + + return value; + } + + /** + * 设置属性值 + */ + private setValue(value: any, bindingConfig: any, bindingContext: any): void { + const { path, viewModelId } = bindingConfig; + const entityStore = this.getEntityStore(viewModelId, bindingContext); + entityStore.setValueByPath(path, value); + } +} + +export { EntityFieldBinding }; diff --git a/packages/mobile-render/src/services/page-config/bindings/entity-list-binding.ts b/packages/mobile-render/src/services/page-config/bindings/entity-list-binding.ts new file mode 100644 index 00000000000..9442ebf8d25 --- /dev/null +++ b/packages/mobile-render/src/services/page-config/bindings/entity-list-binding.ts @@ -0,0 +1,58 @@ +import { Binding } from './binding'; +import { BindingContext } from './binding-context'; + +/** + * 实体列表绑定 + */ +class EntityListBinding extends Binding { + + /** + * 绑定名称 + */ + public name = 'EntityList'; + + /** + * 初始化 + */ + public init(bindingConfig: any, target: any, propName: string, bindingContext: BindingContext): void { + const { viewModelId } = bindingConfig; + const entityStore = this.getEntityStore(viewModelId, bindingContext); + + bindingContext.registerDep(entityStore, this, bindingConfig, target, propName); + this.update(bindingConfig, target, propName, bindingContext); + } + + /** + * 值更新 + */ + public update(bindingConfig: any, target: any, propName: string, bindingContext: BindingContext) { + const value = this.getValue(bindingConfig, bindingContext); + target[propName] = value; + } + + /** + * 获取实体仓库 + */ + private getEntityStore(viewModelId: string, bindingContext: BindingContext): any { + const viewModel = bindingContext.getViewModel(viewModelId); + if (!viewModel) { + return; + } + const { entityStore } = viewModel; + + return entityStore; + } + + /** + * 获取属性值 + */ + private getValue(bindingConfig: any, bindingContext: BindingContext): void { + const { path, viewModelId } = bindingConfig; + const entityStore = this.getEntityStore(viewModelId, bindingContext); + const value = entityStore.getEntitiesByPath(path); + + return value; + } +} + +export { EntityListBinding }; diff --git a/packages/mobile-render/src/services/page-config/bindings/index.ts b/packages/mobile-render/src/services/page-config/bindings/index.ts new file mode 100644 index 00000000000..511efd5ab82 --- /dev/null +++ b/packages/mobile-render/src/services/page-config/bindings/index.ts @@ -0,0 +1,8 @@ +export * from './binding'; +export * from './entity-field-binding'; +export * from './entity-list-binding'; +export * from './command-binding'; + +export * from './binding-util'; +export * from './binding-context'; +export * from './binding-factory'; diff --git a/packages/mobile-render/src/services/page-config/index.ts b/packages/mobile-render/src/services/page-config/index.ts new file mode 100644 index 00000000000..b5832ff5179 --- /dev/null +++ b/packages/mobile-render/src/services/page-config/index.ts @@ -0,0 +1,2 @@ +export * from './page-config-builder'; +export * from './page-config-binder'; diff --git a/packages/mobile-render/src/services/page-config/page-config-binder.ts b/packages/mobile-render/src/services/page-config/page-config-binder.ts new file mode 100644 index 00000000000..75ef9256ca3 --- /dev/null +++ b/packages/mobile-render/src/services/page-config/page-config-binder.ts @@ -0,0 +1,150 @@ +import { reactive, Reactive } from 'vue'; +import { Module } from '@farris/devkit-vue'; +import { schemaMap } from '@farris/mobile-ui-vue'; +import { JsonUtil } from '../../utils/index'; +import { BindingUtil, BindingContext, BindingFactory } from './bindings/index'; + +/** + * 页面配置绑定器 + */ +class PageConfigBinder { + + /** + * 模块 + */ + private module: Module; + + /** + * 原始的页面配置 + */ + private originPageConfig: any; + + /** + * 绑定后的页面配置 + */ + private pageConfig: Reactive; + + /** + * 绑定上下文 + */ + private bindingContext: BindingContext; + + /** + * 绑定工厂 + */ + private bindingFactory: BindingFactory; + + /** + * 构造函数 + */ + constructor(module: Module, pageConfig: any) { + this.module = module; + this.bindingContext = new BindingContext(module); + this.bindingFactory = new BindingFactory(); + + this.originPageConfig = pageConfig; + } + + /** + * 获取页面配置 + */ + public getPageConfig(): Reactive { + return this.pageConfig; + } + + /** + * 为页面绑定配置 + */ + public bind(): Reactive { + const pageConfig = reactive(JsonUtil.cloneJsonObj(this.originPageConfig)); + this.bindComponentConfig(pageConfig); + this.pageConfig = pageConfig; + + return this.pageConfig; + } + + /** + * 为组件绑定属性值 + */ + private bindComponentConfig(componentConfig: any, componentSchema?: any) { + const componentType = componentConfig.type; + componentSchema = componentSchema || this.getComponentSchema(componentType); + const specialProps = ['contents', 'editor', 'items']; + + Object.keys(componentConfig).forEach((propName) => { + if (specialProps.includes(propName)) { + this.bindSpecialProp(propName, componentConfig, componentSchema); + return; + } + + const bindingConfig = componentConfig[propName]; + const isBinding = BindingUtil.isBinding(bindingConfig); + if (!isBinding) { + return; + } + + const binding = this.bindingFactory.create(bindingConfig.type); + binding.init(bindingConfig, componentConfig, propName, this.bindingContext); + }); + } + + /** + * 绑定特殊属性 + */ + private bindSpecialProp(propName: string, componentConfig: any, componentSchema: any) { + // 特殊属性:contents + if (propName === 'contents') { + this.bindChildComponentsChonfigs(componentConfig.contents); + } + + // 特殊属性:Editor组件 + if (propName === 'editor') { + this.bindEditorConfig(componentConfig.editor); + } + + // 特殊属性:items + if (propName === 'items') { + this.bindItemConfigs(componentConfig.items, componentSchema); + } + } + + /** + * 绑定子组件配置 + */ + private bindChildComponentsChonfigs(childComponentConfigs: any[]): void { + childComponentConfigs.forEach((childComponentConfig) => { + this.bindComponentConfig(childComponentConfig); + }); + } + + /** + * 绑定编辑器配置 + */ + private bindEditorConfig(editorConfig: any): void { + this.bindComponentConfig(editorConfig); + } + + /** + * 绑定Items属性 + */ + private bindItemConfigs(itemConfigs: any[], parentComponentSchema: any) { + itemConfigs.forEach((itemConfig) => { + const itemsPropSchema = parentComponentSchema.properties.items; + this.bindComponentConfig(itemConfig, itemsPropSchema.items); + }); + } + + /** + * 获取组件描述 + */ + private getComponentSchema(componentType: string): any { + const componentSchema = schemaMap[componentType]; + if (!componentSchema) { + throw new Error(`ComponentScham(type=${componentType}) does not exist`); + } + + return componentSchema; + } +} + +export { PageConfigBinder }; diff --git a/packages/mobile-render/src/services/page-config/page-config-builder.ts b/packages/mobile-render/src/services/page-config/page-config-builder.ts new file mode 100644 index 00000000000..31a1072a847 --- /dev/null +++ b/packages/mobile-render/src/services/page-config/page-config-builder.ts @@ -0,0 +1,98 @@ +/** + * 页面配置 + * @summary + * 1、深拷贝视图模型组件生成PageConfig; + * 2、遍历PageConfig将下级的ComponentRef替换为真实的ComponentConfig + */ +class PageConfigBuilder { + + /** + * 视图模型组件集合 + */ + private viewModelComponentNodes: any[]; + + /** + * 页面组件 + */ + private pageViewModelComponentNode: any; + + /** + * 页面配置 + */ + private pageConfig: any; + + /** + * 构造函数 + */ + constructor(formMetadata: any, pageId: string) { + this.viewModelComponentNodes = formMetadata.content.module.components; + this.pageViewModelComponentNode = this.getViewModelComponentNodeById(pageId); + if (!this.pageViewModelComponentNode) { + throw new Error(`Page(id=${pageId}) does not exist`); + } + } + + /** + * 构造页面配置 + */ + public build() { + this.pageConfig = this.cloneJsonObj(this.pageViewModelComponentNode); + this.replaceComponentRef(this.pageConfig); + + return this.pageConfig; + } + + /** + * 替换ComponentRef + */ + private replaceComponentRef(componentConfig: any) { + if (componentConfig.contents) { + componentConfig.contents.forEach((childComponentConfig: any) => { + this.replaceComponentRef(childComponentConfig); + }); + + return; + } + + if (componentConfig.type !== 'ComponentRef') { + return; + } + + // 替换ComponentRef + const childViewModelComponentId = componentConfig.component; + const childViewModelComponentNode = this.getViewModelComponentNodeById(childViewModelComponentId); + if (!childViewModelComponentNode) { + throw new Error(`ViewModelComponent(id=${childViewModelComponentId}) does not exist`); + } + + const childViewModelComponentConfig = this.cloneJsonObj(childViewModelComponentNode); + Object.keys(childViewModelComponentConfig).forEach((propName: string) => { + componentConfig[propName] = childViewModelComponentConfig[propName]; + }); + + this.replaceComponentRef(childViewModelComponentConfig); + } + + /** + * 根据ID获取视图模型组件 + */ + private getViewModelComponentNodeById(pageId: string) { + const targetViewModelComponentNode = this.viewModelComponentNodes.find((viewModelComponent: any) => { + return viewModelComponent.id === pageId; + }); + + return targetViewModelComponentNode; + } + + /** + * 克隆JSON对象 + */ + private cloneJsonObj(jsonObj: any) { + const jsonString = JSON.stringify(jsonObj); + const newJsonObj = JSON.parse(jsonString); + + return newJsonObj; + } +} + +export { PageConfigBuilder }; diff --git a/packages/mobile-render/src/services/providers.ts b/packages/mobile-render/src/services/providers.ts new file mode 100644 index 00000000000..8285a3d2990 --- /dev/null +++ b/packages/mobile-render/src/services/providers.ts @@ -0,0 +1,26 @@ + +import { StaticProvider, HttpClient } from '@farris/devkit-vue'; +import { + MetadataRepository, FormMetadataDataService, StateMachineMetadataDataService, CommonWebCommandMetadataDataService, + CustomWebComponentMetadataDataService, CustomWebCommandMetadataDataService, MetadataDataService, MetadataCacheService +} from './metadata/index'; + +/** + * 渲染器相关服务 + */ +export const renderServiceProviders: StaticProvider[] = [ + { provide: MetadataRepository, useClass: MetadataRepository, deps: [HttpClient] }, + { provide: FormMetadataDataService, useClass: FormMetadataDataService, deps: [MetadataRepository] }, + { provide: StateMachineMetadataDataService, useClass: StateMachineMetadataDataService, deps: [MetadataRepository] }, + { provide: CommonWebCommandMetadataDataService, useClass: CommonWebCommandMetadataDataService, deps: [MetadataRepository] }, + { provide: CustomWebComponentMetadataDataService, useClass: CustomWebComponentMetadataDataService, deps: [MetadataRepository] }, + { provide: CustomWebCommandMetadataDataService, useClass: CustomWebCommandMetadataDataService, deps: [MetadataRepository] }, + { + provide: MetadataDataService, useClass: MetadataDataService, + deps: [ + FormMetadataDataService, StateMachineMetadataDataService, CommonWebCommandMetadataDataService, + CustomWebComponentMetadataDataService, CustomWebCommandMetadataDataService + ] + }, + { provide: MetadataCacheService, useClass: MetadataCacheService, deps: [] } +]; diff --git a/packages/mobile-render/src/types.ts b/packages/mobile-render/src/types.ts new file mode 100644 index 00000000000..816bd2caea9 --- /dev/null +++ b/packages/mobile-render/src/types.ts @@ -0,0 +1,294 @@ +import { EventEmitter } from "./common"; + +/* eslint-disable no-use-before-define */ +// #region form schema +export interface EntityFieldMetadata { + id: string; + required: any; + multiLanguage: boolean; + defaultValue: any; + readonly: any; + bindingPath: string; + label: string; + type: Record; + name: string; +} +export interface EntityTypeMetadata { + entities: EntityMetadata[]; + primary: string; + displayName: string; + fields: EntityFieldMetadata[]; + name: string; +} +export interface EntityMetadata { + id: string; + label: string; + code: string; + type: EntityTypeMetadata; + name: string; +} +export interface ViewModelFieldMetadata { + id: string; + type: string; + fieldName: string; + groupId: string; + groupName: string; +} +export interface CommandParamMetadata { + name: string; + shownName: string; + value: string; +} +export interface CommandRefMetadata { + id: string; + code: string; + name: string; + params?: CommandParamMetadata[]; + handlerName: string; + cmpId: string; + isInvalid: boolean; +} +export interface StateMetadata { + id: string; + code: string; + name: string; + type: string; + category: string; +} +export interface PaginationMetadata { + enable: boolean; + pageSize: number; + pageList: string; +} +export interface ViewModelMetadata { + id: string; + code: string; + name: string; + fields?: ViewModelFieldMetadata[]; + commands?: CommandRefMetadata[]; + states?: StateMetadata[]; + bindTo?: string; + parent?: string; + enableUnifiedSession?: boolean; + enableValidation?: boolean; + pagination?: PaginationMetadata; + serviceRefs?: any[]; +} +export interface StateMachineRefMetadata { + /** + * 状态机标识,非元数据id + */ + id: string; + name: string; + /** + * 状态机元数据id + */ + uri: string; + code: string; + nameSpace: string; +} +export interface RefedHandlerMetadata { + host: string; + handler: string; +} +export interface WebCommandRefMetadata { + id: string; + path: string; + name: string; + refedHandlers: RefedHandlerMetadata[]; + code: string; + nameSpace: string; +} +export interface ComponentAppearanceMetadata { + class: string; + style?: string; +} +export interface ComponentMetadata { + id: string; + type: string; + appearance?: ComponentAppearanceMetadata | null; + componentType: string; + viewModel: string; + onInit: string; + afterViewInit: string; + contents: ComponentMetadata[]; + items?: any[]; + visible: string | boolean; + component?: ComponentMetadata; + [prop: string]: any; +} +export interface VariableMetadata { + id: string; + name: string; + path: string; + defaultValue: any; + readonly: boolean; + bindingField: string; + bindingPath: string; + code: string; + label: string; + type: any; +} +export interface EntityModelMetadata { + id: string; + code: string; + name: string; + extendProperties: any; + entities: EntityMetadata[]; + sourceUri: string; + sourceType: string; + voPath: string; + eapiNameSpace: string; + eapiName: string; + eapiCode: string; + eapiId: string; + variables: VariableMetadata[]; +} +export interface ModuleMetadata { + id: string; + code: string; + name: string; + bootstrap: string; + entity: EntityModelMetadata[]; + stateMachines: StateMachineRefMetadata[]; + viewmodels: ViewModelMetadata[]; + components: ComponentMetadata[]; + webcmds: WebCommandRefMetadata[]; + expressions: any[]; + actions: any[]; + [prop: string]: any; +} +export interface OptionsMetadata { + renderMode: string; + formRulePushMode: string; +} +export interface FormMetadata { + module: ModuleMetadata; + options: OptionsMetadata; +} +// #endregion + +// #region stateMachine schema +export interface StateMachineStateMetadata { + name: string; + state: string; + description: string; +} +export interface StateMachineActionMetadata { + [actionName: string]: { + name: string; + transitTo: string; + description: string; + }; +} +export interface StateMachineRenderStateMetadata { + [render: string]: { + name: string; + description: string; + condition: any[]; + }; +} +export interface StateMachineMetadata { + action: StateMachineActionMetadata; + initialState: string; + renderState: StateMachineRenderStateMetadata; + state: StateMachineStateMetadata[]; +} + +// #endregion + +// #region resource schema +export interface StringResourceMetadata { + id: string; + resourceType: string; + value: string; +} +export interface ResourceMetadata { + originalLanguage: string; + stringResources: StringResourceMetadata[]; + resourceType: string; +} +// #endregion + +export interface ResolvedEntity { + bindingPaths: string[]; + primaryKey: string; +} + +export interface ResolvedEntityField { + id: string; + bindingPath: string; + required: any; + readonly: any; + multiLanguage: boolean; + label: string; + dataSource: string; +} + +export interface UseEntityResolver { + resolve(dataSource: string): ResolvedEntity | null; +} + +export interface UseFieldResolver { + resolve(fieldId: string): ResolvedEntityField | null; +} + +export interface UseParamPersistence { + persist(): Promise; +} +export interface UseEventEmitter { + emitter: EventEmitter; +} + +export interface UseEventHandler { + bind(): void; + destroy(): void; +} +export interface Metadata { + id: string; + content: any; + refs: any[]; +} +export interface UseMetadata { + setup(): void; + getViewModels(): ViewModelMetadata[]; + getFrameComponent(): ComponentMetadata | null; + getEntity(): EntityMetadata; + getMetadataById(id: string): any; + getComponents(): any[]; + getRelatedComponent(metadataId: string): Record; + getViewModelById(id: string): ViewModelMetadata | null; + getModuleId(): string; +} + +export interface UseSession { + sessionId: string; + metadataId: string; + version: string; + mode: string; +} + +export interface UseCache { + get(key: string): any; + set(key: string, value: any): void; + remove(key: string): boolean; +} + +export interface UseSchemas { + form: Metadata; + stateMachine: Metadata; + webcmd: Metadata[]; + resource: Metadata[]; +} +export enum MetadataType { + Component = 'component', + DataGrid = 'data-grid', + TreeGrid = 'tree-grid' +} + +export interface ViewEvent { + token: string; + eventName: string; + type: string; + payloads: any[]; +} diff --git a/packages/mobile-render/src/utils/index.ts b/packages/mobile-render/src/utils/index.ts new file mode 100644 index 00000000000..ffd6e57c4b8 --- /dev/null +++ b/packages/mobile-render/src/utils/index.ts @@ -0,0 +1,4 @@ +export * from './type-util'; +export * from './json-util'; +export * from './string-util'; + diff --git a/packages/mobile-render/src/utils/json-util.ts b/packages/mobile-render/src/utils/json-util.ts new file mode 100644 index 00000000000..de9c25c1f14 --- /dev/null +++ b/packages/mobile-render/src/utils/json-util.ts @@ -0,0 +1,17 @@ +/** + * Json工具类 + */ +class JsonUtil { + + /** + * 深拷贝JSON对象 + */ + public static cloneJsonObj(jsonObj: any) { + const jsonString = JSON.stringify(jsonObj); + const newJsonObj = JSON.parse(jsonString); + + return newJsonObj; + } +} + +export { JsonUtil }; diff --git a/packages/mobile-render/src/utils/string-util.ts b/packages/mobile-render/src/utils/string-util.ts new file mode 100644 index 00000000000..414a40a0327 --- /dev/null +++ b/packages/mobile-render/src/utils/string-util.ts @@ -0,0 +1,14 @@ +/** + * 字符串工具类 + */ +class StringUtil { + + /** + * 将Camel格式转换成Kebab格式 + */ + public static convertCamelToKebab(camelStr: any) { + return camelStr.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); + } +} + +export { StringUtil }; diff --git a/packages/mobile-render/src/utils/type-util.ts b/packages/mobile-render/src/utils/type-util.ts new file mode 100644 index 00000000000..3ad67ca041c --- /dev/null +++ b/packages/mobile-render/src/utils/type-util.ts @@ -0,0 +1,124 @@ + +export function isDef(val: T): val is NonNullable { + return val !== undefined && val !== null; +} + +export function isNull(val: unknown): val is null { + return val === null; +} + +export function isUndefined(val: unknown): val is undefined { + return val === undefined; +} + +export function isString(val: unknown): val is string { + return typeof val === 'string'; +} + +export function isNumber(val: unknown): val is number { + return typeof val === 'number'; +} + +export function isBoolean(val: unknown): val is null { + return typeof val === 'boolean'; +} + +export const { isArray } = Array; + +export function isSymbol(val: unknown): val is symbol { + return typeof val === 'symbol'; +} + +export function isFunction(val: unknown): val is FunctionConstructor { + return typeof val === 'function'; +} + +export function isObject(val: unknown): val is Record { + return val !== null && typeof val === 'object'; +} + +export function isPromise(val: unknown): val is Promise { + return isObject(val) && isFunction(val.then) && isFunction(val.catch); +} + +export function isNumeric(val: string) { + return /^-?\d+(\.\d+)?$/.test(val); +} + +export function isDate(val: unknown): val is Date { + return typeof val === 'object' && val instanceof Date; +} + +export function getType(val: unknown) { + let type: string; + switch (val) { + case isString(val): { + type = 'string'; + break; + } + case isNumber(val): { + type = 'number'; + break; + } + case isDate(val): { + type = 'date'; + break; + } + case isNull(val): { + type = 'null'; + break; + } + case isUndefined(val): { + type = 'undefined'; + break; + } + case isArray(val): { + type = 'array'; + break; + } + case isSymbol(val): { + type = 'symbol'; + break; + } + case isFunction(val): { + type = 'function'; + break; + } + case isPromise(val): { + type = 'promise'; + break; + } + case isObject(val): { + type = 'object'; + break; + } + default: + type = typeof val; + break; + } + return type; +} + + +/** + * 类型工具类 + */ +class TypeUtil { + + /** + * 是否为对象 + */ + public static isObject(value: any) { + return value !== null && typeof value === 'object'; + } + + /** + * 是否为字符串 + */ + public static isString(value: any) { + return typeof value === 'string'; + } +} + +export { TypeUtil }; + diff --git a/packages/mobile-render/src/views/form/form-runner.ts b/packages/mobile-render/src/views/form/form-runner.ts new file mode 100644 index 00000000000..31f70ea9e89 --- /dev/null +++ b/packages/mobile-render/src/views/form/form-runner.ts @@ -0,0 +1,113 @@ +import { provide } from 'vue'; +import { Router } from 'vue-router'; +import { Devkit, Module, createDynamicModule, MODULE_INJECTION_TOKEN } from '@farris/devkit-vue'; +import { befProviders } from '@farris/bef-vue'; +import { commandServiceModuleProviders, commandServiceViewModelProviders, ROUTER_TOKEN } from '@farris/mobile-command-services-vue'; +import { ModuleConfigBuilder } from '../../services/index'; +import { MetadataCacheService } from '../../services/index'; + +/** + * 运行表单 + */ +class FormRunner { + + /** + * 路由实例 + */ + private router: Router; + + /** + * 开发框架 + */ + private devkit!: Devkit; + + /** + * 模块 + */ + private module!: Module; + + /** + * 元数据缓存服务 + */ + private metadataCacheService: MetadataCacheService; + + /** + * 构造函数 + */ + constructor(devkit: Devkit, router: Router) { + this.devkit = devkit; + this.router = router; + const devkitInjector = devkit.getInjector(); + this.metadataCacheService = devkitInjector.get(MetadataCacheService); + } + + /** + * 运行表单 + */ + public runForm() { + this.initModule(); + } + + /** + * 初始化模块 + */ + private initModule() { + const formCode = this.getFormCode(); + let module = this.devkit.getModule(formCode); + if (!module) { + const metadatas = this.metadataCacheService.getCache(formCode); + module = this.createModule(metadatas); + } + + this.module = module; + provide(MODULE_INJECTION_TOKEN, module); + } + + /** + * 创建模块 + */ + private createModule(metadatas: any): Module { + const moduleConfig = this.buildModuleConfig(metadatas); + const module = createDynamicModule(moduleConfig); + + return module; + } + + /** + * 构造表单配置 + */ + private buildModuleConfig(metadatas: any) { + const moduleConfigBuildContext: any = { + form: metadatas.form.content, + webcmds: metadatas.commands, + webComponents: metadatas.webComponents, + stateMachines: metadatas.stateMachines, + moduleProviders: [ + ...commandServiceModuleProviders, + ...befProviders, + { provide: ROUTER_TOKEN, useValue: this.router } + ], + viewModelProviders: [ + ...commandServiceViewModelProviders + ], + }; + const moduleConfigBuilder = new ModuleConfigBuilder(moduleConfigBuildContext); + const moduleConfig = moduleConfigBuilder.build(); + + return moduleConfig; + } + + /** + * 获取表单编号 + */ + private getFormCode() { + const route = this.router.currentRoute.value; + const { fullPath } = route; + const pathSegs = fullPath.split('/'); + const formCode = pathSegs[1]; + + return formCode; + } +} + +export { FormRunner }; diff --git a/packages/mobile-render/src/views/form/form.vue b/packages/mobile-render/src/views/form/form.vue new file mode 100644 index 00000000000..23e50dd2256 --- /dev/null +++ b/packages/mobile-render/src/views/form/form.vue @@ -0,0 +1,18 @@ + + + + + diff --git a/packages/mobile-render/src/views/page/dynamic-view-context.ts b/packages/mobile-render/src/views/page/dynamic-view-context.ts new file mode 100644 index 00000000000..314c1124a16 --- /dev/null +++ b/packages/mobile-render/src/views/page/dynamic-view-context.ts @@ -0,0 +1,33 @@ +import { ViewModel, ViewModelState } from '@farris/devkit-vue'; +import { DefaultDynamicViewContext } from '@farris/mobile-ui-vue'; + +export class DynamicViewContextWithViewModel extends DefaultDynamicViewContext { + + /** + * 视图模型 + */ + private viewModel: ViewModel; + + /** + * 构造函数 + */ + constructor(viewModel: ViewModel) { + super(); + this.viewModel = viewModel; + } + + /** + * 创建模板VNode + */ + public createVNodeByTemplate(template: string, templateContext: any) { + const { entityState, uiState, stateMachine } = this.viewModel.state; + + const extendTemplateContext = Object.assign({ + viewModel: this.viewModel, + entityState, uiState, stateMachine + + }, templateContext); + + return super.createVNodeByTemplate(template, extendTemplateContext); + } +} diff --git a/packages/mobile-render/src/views/page/page-runner.ts b/packages/mobile-render/src/views/page/page-runner.ts new file mode 100644 index 00000000000..63feee192c6 --- /dev/null +++ b/packages/mobile-render/src/views/page/page-runner.ts @@ -0,0 +1,157 @@ +import { provide, Reactive } from 'vue'; +import { Router } from 'vue-router'; +import { Devkit, Module, ViewModel, ViewModelState, createViewModel, VIEWMODEL_INJECTION_TOKEN, Injector } from '@farris/devkit-vue'; +import { MetadataCacheService, PageConfigBuilder, PageConfigBinder } from '../../services/index'; + +/** + * 运行页面 + */ +class PageRunner { + + /** + * 路由实例 + */ + private router: Router; + + /** + * 开发框架 + */ + private devkit: Devkit; + + /** + * 开发框架 + */ + private module!: Module; + + /** + * 视图模型 + */ + private viewModel!: ViewModel; + + /** + * 页面配置响应式对象 + */ + private pageConfig: Reactive; + + /** + * 构造函数 + */ + constructor(devkit: Devkit, router: Router) { + this.devkit = devkit; + this.router = router; + } + + /** + * 加载页面 + */ + public runPage() { + this.initModule(); + this.initViewModel(); + this.initUIState(); + this.initPageConfig(); + } + + /** + * 获取当前页面的视图模型 + */ + public getViewModel() { + return this.viewModel; + } + + /** + * 获取页面配置 + */ + public getPageConfig(): Reactive { + return this.pageConfig; + } + + /** + * 初始化模块 + */ + private initModule() { + const { moduleId: moduleId } = this.getModuleIdAndPageId(); + const module = this.devkit.getModule(moduleId); + if (!module) { + throw new Error(`Module(id=${moduleId}) does not exist`); + } + this.module = module; + } + + /** + * 初始化视图模型 + */ + private initViewModel() { + const { pageId: viewModelId } = this.getModuleIdAndPageId(); + let viewModel = this.module.getViewModel(viewModelId); + if (!viewModel) { + viewModel = createViewModel(this.module, viewModelId); + } + + this.viewModel = viewModel; + provide(VIEWMODEL_INJECTION_TOKEN, viewModel); + } + + /** + * 初始化查询参数 + */ + private initUIState() { + const routerState = { + params: this.router.currentRoute.value.params, + queryParams: this.router.currentRoute.value.query + }; + if (this.viewModel.uiStore) { + this.viewModel.uiStore.setValue('routerState', routerState); + } + } + + /** + * 初始化页面 + */ + private initPageConfig() { + const formMetadata = this.getFormMetadata(); + const { pageId } = this.getModuleIdAndPageId(); + + // 构造页面配置 + const pageConfigBuilder = new PageConfigBuilder(formMetadata, pageId); + const pageConfig = pageConfigBuilder.build(); + + console.log('----------pageConfig----------'); + console.log(pageConfig); + + // 绑定页面配置 + const pageConfigBinder = new PageConfigBinder(this.module, pageConfig); + this.pageConfig = pageConfigBinder.bind(); + + console.log('----------binded pageConfig----------'); + console.log(this.pageConfig); + } + + /** + * 获取页面配置 + */ + private getFormMetadata() { + const devkitInjector = this.devkit.getInjector(); + const metadataCacheService = devkitInjector.get(MetadataCacheService); + const { moduleId, pageId } = this.getModuleIdAndPageId(); + + const metadatas = metadataCacheService.getCache(moduleId); + const formMetadata = metadatas.form; + + return formMetadata; + } + + /** + * 获取模块ID和页面ID + */ + private getModuleIdAndPageId() { + const route = this.router.currentRoute.value; + const { path } = route; + const pathSegs = path.split('/'); + const moduleId = pathSegs[1]; + const pageId = pathSegs[2]; + + return { moduleId: moduleId, pageId: pageId }; + } +} + +export { PageRunner }; diff --git a/packages/mobile-render/src/views/page/page.vue b/packages/mobile-render/src/views/page/page.vue new file mode 100644 index 00000000000..0e714182e3e --- /dev/null +++ b/packages/mobile-render/src/views/page/page.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/packages/mobile-render/src/views/test/route.ts b/packages/mobile-render/src/views/test/route.ts new file mode 100644 index 00000000000..fbe0bf8bd3e --- /dev/null +++ b/packages/mobile-render/src/views/test/route.ts @@ -0,0 +1,8 @@ +import Test from './test.vue'; + +const testRoutes = { + path: '/test', + component: Test +}; + +export { testRoutes }; diff --git a/packages/mobile-render/src/views/test/test.vue b/packages/mobile-render/src/views/test/test.vue new file mode 100644 index 00000000000..90118d16d7a --- /dev/null +++ b/packages/mobile-render/src/views/test/test.vue @@ -0,0 +1,51 @@ + + + + + diff --git a/packages/mobile-render/tsconfig.json b/packages/mobile-render/tsconfig.json new file mode 100644 index 00000000000..d6ee5227787 --- /dev/null +++ b/packages/mobile-render/tsconfig.json @@ -0,0 +1,45 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "jsx": "preserve", + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": false, + "esModuleInterop": true, + "lib": [ + "ESNext", + "DOM", + "dom.iterable", + "scripthost" + ], + "skipLibCheck": true, + "importHelpers": true, + "experimentalDecorators": true, + "strictPropertyInitialization": false, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "types": [ + "vitest/globals", + "@farris/bef-vue", + "@farris/devkit-vue", + "@farris/mobile-ui-vue", + "@farris/mobile-command-services-vue" + ] + }, + "include": [ + "src/**/*.ts", + "src/**/*.d.ts", + "src/**/*.tsx", + "src/**/*.vue", + "test/**/*.ts" + ], + "references": [ + { + "path": "./tsconfig.node.json" + } + ] +} diff --git a/packages/mobile-render/tsconfig.node.json b/packages/mobile-render/tsconfig.node.json new file mode 100644 index 00000000000..d8915f131ad --- /dev/null +++ b/packages/mobile-render/tsconfig.node.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "strict": false, + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "verbatimModuleSyntax": false, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true + }, + "include": [ + "vite.config.ts" + ] +} \ No newline at end of file diff --git a/packages/mobile-render/vite.config.ts b/packages/mobile-render/vite.config.ts new file mode 100644 index 00000000000..94675916c38 --- /dev/null +++ b/packages/mobile-render/vite.config.ts @@ -0,0 +1,52 @@ +// / +import path from 'path'; +import { defineConfig } from 'vite'; +import type { InlineConfig } from 'vitest'; +import type { UserConfig } from 'vite'; +import vue from '@vitejs/plugin-vue'; +import vueJsx from '@vitejs/plugin-vue-jsx'; + +interface VitestConfigExport extends UserConfig { + test: InlineConfig; +} + +// https://vitejs.dev/config/ +export default defineConfig({ + base: process.env.NODE_ENV === 'production' ? '/platform/common/web/mobile-renderer/' : '/', + build: { + minify: false + }, + plugins: [vue(), vueJsx()], + test: { + globals: true, + environment: 'happy-dom', + include: ['**/*.test.tsx'] + }, + server: { + proxy: { + "/api": { + target: "http://127.0.0.1:5200", + changeOrigin: true, + secure: false + }, + "/apps": { + target: "http://127.0.0.1:5200", + changeOrigin: true, + secure: false + } + } + }, + resolve: { + alias: { + 'vue': 'vue/dist/vue.esm-bundler.js', + "@farris/devkit-vue": path.resolve(__dirname, "../devkit/lib/index"), + "@farris/bef-vue": path.resolve(__dirname, "../bef/lib/index"), + "@farris/mobile-ui-vue": path.resolve(__dirname, "../mobile-ui-vue/components/index"), + "@farris/mobile-command-services-vue": path.resolve(__dirname, "../mobile-command-services/lib/index"), + "@components": path.resolve(__dirname, "../mobile-ui-vue/components"), + "@/components": path.resolve(__dirname, "../mobile-ui-vue/components"), + + } + }, + logLevel: 'error' +} as VitestConfigExport); diff --git a/packages/mobile-ui-vue/components/dynamic-view/index.ts b/packages/mobile-ui-vue/components/dynamic-view/index.ts index 76d301e4aa9..37063e6d02b 100644 --- a/packages/mobile-ui-vue/components/dynamic-view/index.ts +++ b/packages/mobile-ui-vue/components/dynamic-view/index.ts @@ -1,6 +1,7 @@ import type { App } from 'vue'; import FDynamicView from './src/dynamic-view.component'; +export { type DynamicViewContext, DYNAMIC_VIEW_CONTEXT, DefaultDynamicViewContext } from './src/composition/use-context'; export * from './src/dynamic-view.props'; export { FDynamicView }; diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/index.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/index.ts new file mode 100644 index 00000000000..e7bbb6ad073 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-view/src/composition/index.ts @@ -0,0 +1,2 @@ +export * from './use-context'; +export * from './use-render-component'; diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-context.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-context.ts new file mode 100644 index 00000000000..5e37885a76d --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-context.ts @@ -0,0 +1,54 @@ +import { inject, VNodeTypes, VNodeProps, VNode, createVNode, compile } from 'vue'; + +/** + * 上下文接口 + */ +export interface DynamicViewContext { + createVNode(componentType: VNodeTypes, props: VNodeProps, children?: any): VNode; + createVNodeByTemplate(template: string, context: any): VNode; +} + +/** + * 上下文注入Token + */ +export const DYNAMIC_VIEW_CONTEXT = Symbol('DYNAMIC_VIEW_CONTEXT'); + +/** + * 默认上下文 + */ +export class DefaultDynamicViewContext implements DynamicViewContext { + + /** + * 创建组件VNode + */ + public createVNode(component: VNodeTypes, props: VNodeProps, children?: any) { + return createVNode(component, props, children); + } + + /** + * 创建模板VNode + */ + public createVNodeByTemplate(template: string, templateContext: any) { + const templateRenderFn = compile(template); + const templateProps = Array.from(Object.keys(templateContext)); + const templateComponent = { + render: templateRenderFn, + props: templateProps + }; + + const templateVNode = this.createVNode(templateComponent, templateContext); + return templateVNode; + } +} + +/** + * 使用上下文 + */ +export function useContext(): DynamicViewContext { + let dynamicViewContext = inject(DYNAMIC_VIEW_CONTEXT) as DynamicViewContext; + if (!dynamicViewContext) { + dynamicViewContext = new DefaultDynamicViewContext(); + } + + return dynamicViewContext; +} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-render-component.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-render-component.ts new file mode 100644 index 00000000000..33c2d46af0a --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-render-component.ts @@ -0,0 +1,101 @@ +/* eslint-disable no-use-before-define */ +import { createVNode, VNode } from 'vue'; +import { registerComponents } from '@components/register'; +import { componentMap, propsConverterMap } from '@components/register'; +import { schemaMap } from '@components/dynamic-resolver'; +import { DynamicViewContext } from './use-context'; + +export function useRenderComponent(context: DynamicViewContext) { + + registerComponents(); + + /** + * 处理属性 + */ + function resolveProps(componentConfig: any): any { + const componentType = componentConfig.type; + const componentPropsConverter = propsConverterMap[componentType]; + const resolovedComponentConfig = componentPropsConverter ? componentPropsConverter(componentConfig) : {}; + + return resolovedComponentConfig; + } + + /** + * 处理插槽 + */ + function resolveSlots(componentConfig: any): any { + const componentType = componentConfig.type; + const componentSchema = schemaMap[componentType]; + if (!componentSchema) { + return; + } + if (!Array.isArray(componentSchema.slots)) { + return; + } + + const slotPropNames = componentSchema.slots; + const slots = {}; + slotPropNames.map((slotPropName: string) => { + const slotTemplateInfo = componentConfig[slotPropName]; + if (!slotTemplateInfo || !slotTemplateInfo.content) { + return null; + } + const {name: slotName, content: slotTemplate } = slotTemplateInfo; + slots[slotName] = (slotProps: any) => { + return context.createVNodeByTemplate(slotTemplate, slotProps); + }; + }); + + return slots; + } + + /** + * 处理子组件 + */ + function resolveChildren(componentConfig: any): any { + return () => { + const { editor, contents } = componentConfig; + let childComponentConfigs: any[]; + + if (editor) { + childComponentConfigs = [editor]; + } else if (Array.isArray(contents)) { + childComponentConfigs = componentConfig.contents; + } else { + childComponentConfigs = []; + } + + return childComponentConfigs.map((childComponentConfig: any) => { + return renderComponent(childComponentConfig); + }); + }; + } + + /** + * 渲染组件 + */ + function renderComponent(componentConfig: any): VNode { + const componentType = componentConfig.type; + const Component = componentMap[componentType]; + if (!Component) { + throw new Error(`Component(type=${componentType}) not found`); + } + + const resolvedComponentConfig = resolveProps(componentConfig); + const slots = resolveSlots(resolvedComponentConfig) || {}; + + const children = { + default: resolveChildren(resolvedComponentConfig), + ...slots + }; + + return createVNode( + Component, + resolvedComponentConfig, + children + ); + } + + return renderComponent; +} + diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx b/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx index 4f1569d3c01..592eaeebd00 100644 --- a/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx +++ b/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx @@ -1,57 +1,23 @@ - -import { SetupContext, defineComponent, ref, watch, createVNode } from 'vue'; -import { componentMap, registerComponents, propsConverterMap } from '@components/register'; +import { SetupContext, defineComponent, ref, watch } from 'vue'; +import { useContext, useRenderComponent } from './composition/index'; import { DYNAMIC_VIEW_NAME, dynamicViewProps, DynamicViewProps } from './dynamic-view.props'; -registerComponents(); - +/** + * 动态组件 + */ const FDynamicView = defineComponent({ name: DYNAMIC_VIEW_NAME, props: dynamicViewProps, emits: [], setup(props: DynamicViewProps, setupContext: SetupContext) { - const viewConfig = ref(props.config); - - function renderComponent(componentConfig: any) { - const componentType = componentConfig.type; - const Component = componentMap[componentType]; - if (!Component) { - return null; - } - - const componentPropsConverter = propsConverterMap[componentType]; - const componentProps = componentPropsConverter ? componentPropsConverter(componentConfig) : {}; - - const renderChildComponents = () => { - const { editor, contents } = componentConfig; - let childComponentConfigs: any[]; - - if (editor) { - childComponentConfigs = [editor]; - } else if (Array.isArray(contents)) { - childComponentConfigs = componentConfig.contents; - } else { - childComponentConfigs = []; - } - - return childComponentConfigs.map((childComponentConfig: any) => { - return renderComponent(childComponentConfig); - }); - }; - - return createVNode( - Component, - { ...componentProps }, - { - default: renderChildComponents - } - ); - } + const config = ref(props.config); + const context = useContext(); + const renderComponent = useRenderComponent(context); watch( [() => props.config], - ([newViewConfig]) => { - viewConfig.value = newViewConfig; + ([newConfig]) => { + config.value = newConfig; } ); @@ -59,7 +25,7 @@ const FDynamicView = defineComponent({ return () => (
- {renderComponent(viewConfig.value)} + {renderComponent(config.value)}
); } diff --git a/packages/mobile-ui-vue/components/index.ts b/packages/mobile-ui-vue/components/index.ts index b1536a66140..55c3b962122 100644 --- a/packages/mobile-ui-vue/components/index.ts +++ b/packages/mobile-ui-vue/components/index.ts @@ -71,6 +71,7 @@ import FDesignerCanvas from './designer-canvas'; export * from './register'; export * from './designer'; export { schemaMap } from './dynamic-resolver'; +export { type DynamicViewContext, DYNAMIC_VIEW_CONTEXT, DefaultDynamicViewContext } from './dynamic-view'; const components = [ Button, diff --git a/packages/mobile-ui-vue/components/list-view/src/schema/list-view.schema.json b/packages/mobile-ui-vue/components/list-view/src/schema/list-view.schema.json index 3ae41f52561..0816ea49c4d 100644 --- a/packages/mobile-ui-vue/components/list-view/src/schema/list-view.schema.json +++ b/packages/mobile-ui-vue/components/list-view/src/schema/list-view.schema.json @@ -46,11 +46,20 @@ "description": "行点击事件", "type": "string", "default": "" + }, + + "itemTemplate": { + "description": "列表行模板", + "type": "string", + "default": "" } }, "events": [ "onItemClick" ], + "slots": [ + "itemTemplate" + ], "required": [ "id", "type", diff --git a/packages/mobile-ui-vue/components/list-view/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/list-view/src/schema/schema-mapper.ts index ac06d37022a..37dd6b3f6c4 100644 --- a/packages/mobile-ui-vue/components/list-view/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/list-view/src/schema/schema-mapper.ts @@ -1,7 +1,19 @@ import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; +function createTemplatePropResolver(name: string): MapperFunction { + return (key: string, content: string) => { + if (!content) { + return {}; + } + const itemTemplate = { name, content }; + + return { itemTemplate }; + }; +} + export const schemaMapper = new Map([ ['appearance', resolveAppearance], ['dataSource', 'data'], - ['onItemClick', 'onClickItem'] + ['onItemClick', 'onClickItem'], + ['itemTemplate', createTemplatePropResolver('item')] ]); diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 05d09d3eb0b..91b6d3f51e2 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,13 +4,14 @@ packages: - 'packages/designer' - 'packages/devkit' - 'packages/bef' - - 'packages/mobile-command-services' - 'packages/eslint-config' - 'packages/farris-theme' - - 'packages/mobile-ui-vue' - 'packages/renderer' - 'packages/ui-vue' - 'packages/command-services' - 'packages/ui-binding' - 'packages/farris-admin' - 'packages/code-editor' + - 'packages/mobile-ui-vue' + - 'packages/mobile-command-services' + - 'packages/mobile-render' \ No newline at end of file -- Gitee From ca4aa5307a28eb786220926db5433d1eb67bda49 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Fri, 14 Mar 2025 09:40:54 +0800 Subject: [PATCH 041/153] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E4=BE=9D=E8=B5=96=E8=A7=A3=E6=9E=90=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E4=B8=BA=E8=A1=A8=E8=BE=BE=E5=BC=8F=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...y-resolve-service.ts => expression-dependency-resolver.ts} | 2 +- packages/devkit/lib/expression-dependency-resolver/index.ts | 2 +- .../devkit/lib/expression-dependency-resolver/providers.ts | 4 ++-- packages/devkit/lib/expression/expression-engine-proxy.ts | 4 ++-- packages/devkit/lib/expression/providers.ts | 4 ++-- packages/devkit/lib/viewmodel/viewmodel-creator.ts | 4 +++- 6 files changed, 11 insertions(+), 9 deletions(-) rename packages/devkit/lib/expression-dependency-resolver/{expression-dependency-resolve-service.ts => expression-dependency-resolver.ts} (97%) diff --git a/packages/devkit/lib/expression-dependency-resolver/expression-dependency-resolve-service.ts b/packages/devkit/lib/expression-dependency-resolver/expression-dependency-resolver.ts similarity index 97% rename from packages/devkit/lib/expression-dependency-resolver/expression-dependency-resolve-service.ts rename to packages/devkit/lib/expression-dependency-resolver/expression-dependency-resolver.ts index 86b2f4f8667..4d23cf910c5 100644 --- a/packages/devkit/lib/expression-dependency-resolver/expression-dependency-resolve-service.ts +++ b/packages/devkit/lib/expression-dependency-resolver/expression-dependency-resolver.ts @@ -2,7 +2,7 @@ import { CommentExpressionDependencyResolver } from "./comment-expression-depend import { ExpressionDependencyResolverRegistry } from "./expression-dependency-resolver-registry"; import { Resolver } from "./types"; -export class ExpressionDependencyResolveService { +export class ExpressionDependencyResolver { constructor(private expressionDependencyResolverRegistry: ExpressionDependencyResolverRegistry) { } public resolve(expression: string) { diff --git a/packages/devkit/lib/expression-dependency-resolver/index.ts b/packages/devkit/lib/expression-dependency-resolver/index.ts index 15fd0a65405..2d5735345c4 100644 --- a/packages/devkit/lib/expression-dependency-resolver/index.ts +++ b/packages/devkit/lib/expression-dependency-resolver/index.ts @@ -3,5 +3,5 @@ export * from './comment-expression-dependency-resolver'; export * from './entity-expression-dependency-resolver'; export * from './ui-state-expression-dependency-resolver'; export * from './expression-dependency-resolver-registry'; -export * from './expression-dependency-resolve-service'; +export * from './expression-dependency-resolver'; export * from './providers'; diff --git a/packages/devkit/lib/expression-dependency-resolver/providers.ts b/packages/devkit/lib/expression-dependency-resolver/providers.ts index 667afaf794a..53800150789 100644 --- a/packages/devkit/lib/expression-dependency-resolver/providers.ts +++ b/packages/devkit/lib/expression-dependency-resolver/providers.ts @@ -4,7 +4,7 @@ import { EntityExpressionDependencyResolver } from "./entity-expression-dependen import { CommentExpressionDependencyResolver } from "./comment-expression-dependency-resolver"; import { ExpressionDependencyResolverRegistry } from "./expression-dependency-resolver-registry"; import { RESOLVER_TOKEN } from "./types"; -import { ExpressionDependencyResolveService } from "./expression-dependency-resolve-service"; +import { ExpressionDependencyResolver } from "./expression-dependency-resolver"; import { ViewModel } from "../viewmodel"; export const expressionDependencyResolverProviders: StaticProvider[] = [ @@ -12,5 +12,5 @@ export const expressionDependencyResolverProviders: StaticProvider[] = [ { provide: RESOLVER_TOKEN, useClass: EntityExpressionDependencyResolver, deps: [ViewModel], multi: true }, { provide: RESOLVER_TOKEN, useClass: CommentExpressionDependencyResolver, deps: [], multi: true }, { provide: ExpressionDependencyResolverRegistry, useClass: ExpressionDependencyResolverRegistry, deps: [Injector] }, - { provide: ExpressionDependencyResolveService, useClass: ExpressionDependencyResolveService, deps: [ExpressionDependencyResolverRegistry] } + { provide: ExpressionDependencyResolver, useClass: ExpressionDependencyResolver, deps: [ExpressionDependencyResolverRegistry] } ]; diff --git a/packages/devkit/lib/expression/expression-engine-proxy.ts b/packages/devkit/lib/expression/expression-engine-proxy.ts index 1445b8f24e1..7222ada9365 100644 --- a/packages/devkit/lib/expression/expression-engine-proxy.ts +++ b/packages/devkit/lib/expression/expression-engine-proxy.ts @@ -3,7 +3,7 @@ import { Change } from "../change-observer"; import { ExpressionEventEmitter } from "./expression-event-emitter"; import { ExpressionExecutor } from "./expression-executor"; import { ExpressionRegistry } from "./expression-registry"; -import { ExpressionDependencyResolverRegistry, ExpressionDependencyResolveService } from "../expression-dependency-resolver"; +import { ExpressionDependencyResolverRegistry, ExpressionDependencyResolver } from "../expression-dependency-resolver"; import { ExpressionObject } from "./types"; import { CHANGE_HANDLERS_TOKEN, ChangeHandler } from "../change-handler"; @@ -14,7 +14,7 @@ export class ExpressionEngineProxy { private expressionExecutor: ExpressionExecutor, private expressionRegistry: ExpressionRegistry, private expressionDependencyResolverRegistry: ExpressionDependencyResolverRegistry, - private expressionDependencyResolveService: ExpressionDependencyResolveService, + private expressionDependencyResolveService: ExpressionDependencyResolver, ) { const { expressions } = this.expressionRegistry; this.resolveDependency(expressions); diff --git a/packages/devkit/lib/expression/providers.ts b/packages/devkit/lib/expression/providers.ts index d8a5a1bcf0a..078434f7faf 100644 --- a/packages/devkit/lib/expression/providers.ts +++ b/packages/devkit/lib/expression/providers.ts @@ -5,12 +5,12 @@ import { ExpressionExecutor } from './expression-executor'; import { ExpressionRegistry } from './expression-registry'; import { FormMetadataService } from '../service'; import { DataSourceResolver, FieldResolver } from '../resolvers'; -import { ExpressionDependencyResolverRegistry, ExpressionDependencyResolveService } from '../expression-dependency-resolver'; +import { ExpressionDependencyResolverRegistry, ExpressionDependencyResolver } from '../expression-dependency-resolver'; import { ExpressionResult } from './expression-result'; export const expressionProviders: StaticProvider[] = [ { provide: ExpressionEventEmitter, useClass: ExpressionEventEmitter, deps: [Injector] }, - { provide: ExpressionEngineProxy, useClass: ExpressionEngineProxy, deps: [Injector, ExpressionEventEmitter, ExpressionExecutor, ExpressionRegistry, ExpressionDependencyResolverRegistry, ExpressionDependencyResolveService] }, + { provide: ExpressionEngineProxy, useClass: ExpressionEngineProxy, deps: [Injector, ExpressionEventEmitter, ExpressionExecutor, ExpressionRegistry, ExpressionDependencyResolverRegistry, ExpressionDependencyResolver] }, { provide: ExpressionExecutor, useClass: ExpressionExecutor, deps: [] }, { provide: ExpressionRegistry, useClass: ExpressionRegistry, deps: [FormMetadataService, FieldResolver, DataSourceResolver] }, { provide: ExpressionResult, useClass: ExpressionResult, deps: [] } diff --git a/packages/devkit/lib/viewmodel/viewmodel-creator.ts b/packages/devkit/lib/viewmodel/viewmodel-creator.ts index 794b14081ad..0aacbae9c99 100644 --- a/packages/devkit/lib/viewmodel/viewmodel-creator.ts +++ b/packages/devkit/lib/viewmodel/viewmodel-creator.ts @@ -5,6 +5,7 @@ import { CommandHandlerConfig, COMMAND_HANDLERS_TOKEN, DynamicCommandHandler, co import { ViewModelNode } from './viewmodel-node'; import { VIEWMODEL_INJECTION_TOKEN, ViewModelState, ViewModel, } from './viewmodel'; import { ViewModelConfig } from './configs'; +import { expressionDependencyResolverProviders } from '../expression-dependency-resolver'; /** * 获取命令处理器的Providers @@ -51,7 +52,8 @@ function getViewModelProviders(viewModelConfig: ViewModelConfig): StaticProvider const providers = [ ...configProviders, ...commandHandlerProviders, - ...commandBusProviders + ...commandBusProviders, + ...expressionDependencyResolverProviders ]; if (viewModelConfig.type) { -- Gitee From 1c1ae92d3c5103624fcb500ee7d81b18c5796f43 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Fri, 14 Mar 2025 14:21:35 +0800 Subject: [PATCH 042/153] =?UTF-8?q?chore:=20=E8=B0=83=E6=95=B4=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E6=B3=A8=E5=85=A5=E5=B1=82=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/expression/expression-engine-proxy.ts | 1 - .../lib/expression/expression-registry.ts | 42 +++++++++---------- packages/devkit/lib/expression/index.ts | 1 + packages/devkit/lib/expression/providers.ts | 4 +- packages/devkit/lib/expression/tokens.ts | 4 ++ packages/devkit/lib/expression/types.ts | 27 ++++++------ .../lib/module/configs/module-config.ts | 3 ++ packages/devkit/lib/module/module-creator.ts | 14 ++++++- .../config-builders/module-config-builder.ts | 3 +- 9 files changed, 58 insertions(+), 41 deletions(-) create mode 100644 packages/devkit/lib/expression/tokens.ts diff --git a/packages/devkit/lib/expression/expression-engine-proxy.ts b/packages/devkit/lib/expression/expression-engine-proxy.ts index 7222ada9365..2e88281767c 100644 --- a/packages/devkit/lib/expression/expression-engine-proxy.ts +++ b/packages/devkit/lib/expression/expression-engine-proxy.ts @@ -18,7 +18,6 @@ export class ExpressionEngineProxy { ) { const { expressions } = this.expressionRegistry; this.resolveDependency(expressions); - console.log(expressions); this.attachEvent(expressions); } private attachEvent(expressions: ExpressionObject[]) { diff --git a/packages/devkit/lib/expression/expression-registry.ts b/packages/devkit/lib/expression/expression-registry.ts index d91f8760ed7..7c03d30c50b 100644 --- a/packages/devkit/lib/expression/expression-registry.ts +++ b/packages/devkit/lib/expression/expression-registry.ts @@ -1,22 +1,22 @@ import { DataSourceResolver, FieldResolver } from "../resolvers"; -import { FormMetadataService } from "../service"; -import { DEFAULT_EXPRESSION_VALIDATE_MESSAGE, ElementExpressionMetadata, ExpressionMetadata, ExpressionObject, ExpressionType } from "./types"; +import { ViewModel, ViewModelState } from "../viewmodel"; +import { DEFAULT_EXPRESSION_VALIDATE_MESSAGE, ExpressionConfig, ExpressionObject, ExpressionRule, ExpressionType } from "./types"; export class ExpressionRegistry { - constructor(private formMetadataService: FormMetadataService, private fieldResolver: FieldResolver, private dataSourceResolver: DataSourceResolver) { + constructor(private expressionConfigs: ExpressionConfig[], private viewModel:ViewModel, private fieldResolver: FieldResolver, private dataSourceResolver: DataSourceResolver) { } public get expressions(): ExpressionObject[] { - const expressions: ElementExpressionMetadata[] = this.formMetadataService.getExpressions(); + const expressions: ExpressionConfig[] = this.expressionConfigs; const expressionObjects: ExpressionObject[] = []; - expressions.forEach((elementExpression: ElementExpressionMetadata) => { - const { expression: elementExpressions, elementId, elementType } = elementExpression; - if (!elementId || !elementType || !elementExpressions || elementExpressions.length < 1) { + expressions.forEach((elementExpression: ExpressionConfig) => { + const { rules, target, targetType } = elementExpression; + if (!target || !targetType || !rules || rules.length < 1) { return; } - elementExpressions.forEach((expression: ExpressionMetadata) => { - let path = expression.id; - if (elementExpression.elementType === 'Field') { - const resolvedField = this.fieldResolver.resolve(elementExpression.elementId); + rules.forEach((rule: ExpressionRule) => { + let path = rule.id; + if (elementExpression.targetType === 'Field') { + const resolvedField = this.fieldResolver.resolve(elementExpression.target); if (!resolvedField) { return; } @@ -29,21 +29,21 @@ export class ExpressionRegistry { const fullPaths = bindingPaths.concat(bindingPath.split('.')); path = fullPaths.join('/'); } - const expressionValue = this.cleanSpecialCharacters(expression.value); + const expressionValue = this.cleanSpecialCharacters(rule.expression); const expressionObject: ExpressionObject = { - id: expression.id, + id: rule.id, ns: '', path: path, - bindingType: elementExpression.elementType, - type: expression.type, + bindingType: elementExpression.targetType, + type: rule.type, expression: expressionValue, - message: expression.message, + message: rule.message, deps: [] }; // 构造表达式提示信息 - if ((expression.type === ExpressionType.Required || expression.type === ExpressionType.Validate || expression.type === ExpressionType.DataPicking)) { - if (!expression.message) { - expressionObject.message = this.getExpressionMessage(expression.type); + if ((rule.type === ExpressionType.Required || rule.type === ExpressionType.Validate || rule.type === ExpressionType.DataPicking)) { + if (!rule.message) { + expressionObject.message = this.getExpressionMessage(rule.type); } } expressionObjects.push(expressionObject); @@ -58,8 +58,8 @@ export class ExpressionRegistry { return DEFAULT_EXPRESSION_VALIDATE_MESSAGE['zh-CHS'][expressionType]; } private cleanSpecialCharacters(expression: string) { - const mainEntity = this.formMetadataService.getEntity(); - const regex = new RegExp(`[\\'\\"]?\\s*(${mainEntity.code}|${mainEntity.label})[\\.\\[\\]a-zA-Z0-9_]+\\s*[\\'\\"]?`, 'g'); + const entityCode = this.viewModel.entityStore.getEntitySchema().getCode(); + const regex = new RegExp(`[\\'\\"]?\\s*(${entityCode})[\\.\\[\\]a-zA-Z0-9_]+\\s*[\\'\\"]?`, 'g'); const entityPropertyExpressions: RegExpMatchArray | null = expression.match(regex); if (Array.isArray(entityPropertyExpressions) && entityPropertyExpressions.length > 0) { // 解析出所有实体相关的字符串,以主实体名字开头,包含主实体属性或子表 diff --git a/packages/devkit/lib/expression/index.ts b/packages/devkit/lib/expression/index.ts index 23aae3d671a..e15f8ba591d 100644 --- a/packages/devkit/lib/expression/index.ts +++ b/packages/devkit/lib/expression/index.ts @@ -1,4 +1,5 @@ export * from './types'; +export * from './tokens'; export * from './expression-engine-proxy'; export * from './expression-event-emitter'; export * from './expression-executor'; diff --git a/packages/devkit/lib/expression/providers.ts b/packages/devkit/lib/expression/providers.ts index 078434f7faf..307a2c17458 100644 --- a/packages/devkit/lib/expression/providers.ts +++ b/packages/devkit/lib/expression/providers.ts @@ -3,15 +3,15 @@ import { ExpressionEventEmitter } from './expression-event-emitter'; import { ExpressionEngineProxy } from './expression-engine-proxy'; import { ExpressionExecutor } from './expression-executor'; import { ExpressionRegistry } from './expression-registry'; -import { FormMetadataService } from '../service'; import { DataSourceResolver, FieldResolver } from '../resolvers'; import { ExpressionDependencyResolverRegistry, ExpressionDependencyResolver } from '../expression-dependency-resolver'; import { ExpressionResult } from './expression-result'; +import { EXPRESSIONS_TOKEN } from './tokens'; export const expressionProviders: StaticProvider[] = [ { provide: ExpressionEventEmitter, useClass: ExpressionEventEmitter, deps: [Injector] }, { provide: ExpressionEngineProxy, useClass: ExpressionEngineProxy, deps: [Injector, ExpressionEventEmitter, ExpressionExecutor, ExpressionRegistry, ExpressionDependencyResolverRegistry, ExpressionDependencyResolver] }, { provide: ExpressionExecutor, useClass: ExpressionExecutor, deps: [] }, - { provide: ExpressionRegistry, useClass: ExpressionRegistry, deps: [FormMetadataService, FieldResolver, DataSourceResolver] }, + { provide: ExpressionRegistry, useClass: ExpressionRegistry, deps: [EXPRESSIONS_TOKEN, FieldResolver, DataSourceResolver] }, { provide: ExpressionResult, useClass: ExpressionResult, deps: [] } ]; diff --git a/packages/devkit/lib/expression/tokens.ts b/packages/devkit/lib/expression/tokens.ts new file mode 100644 index 00000000000..35f261f9c6f --- /dev/null +++ b/packages/devkit/lib/expression/tokens.ts @@ -0,0 +1,4 @@ +import { InjectionToken } from "../common"; +import { ExpressionConfig } from './types'; + +export const EXPRESSIONS_TOKEN = new InjectionToken('@farris/expressions_token'); \ No newline at end of file diff --git a/packages/devkit/lib/expression/types.ts b/packages/devkit/lib/expression/types.ts index 98f8e11b5b9..a76fc8cf7b4 100644 --- a/packages/devkit/lib/expression/types.ts +++ b/packages/devkit/lib/expression/types.ts @@ -54,6 +54,17 @@ export enum ExpressionMessageType { info = 'info', warning = 'warning' } +export interface ExpressionRule { + id: string; + type: ExpressionType; + expression: string; + message?: string; +} +export interface ExpressionConfig { + target: string; + targetType: ExpressionBindingType; + rules: ExpressionRule[]; +} /** * 表达式对象 */ @@ -114,18 +125,6 @@ export interface ExpressionObject { export interface Executor { compile(expressionObject: ExpressionObject, context?: { [prop: string]: any; }): any; } - -export interface ExpressionMetadata { - id: string; - type: ExpressionType; - value: string; - message?: string | null | undefined; -} -export interface ElementExpressionMetadata { - elementId: string; - elementType: ExpressionBindingType; - expression: ExpressionMetadata[]; -} export const DEFAULT_EXPRESSION_VALIDATE_MESSAGE = { 'zh-CHS': { require: `请输入'$property'`, @@ -145,5 +144,5 @@ export const DEFAULT_EXPRESSION_VALIDATE_MESSAGE = { }; export interface ExpressionResultChange { id: string; - result: any - } + result: any; +} diff --git a/packages/devkit/lib/module/configs/module-config.ts b/packages/devkit/lib/module/configs/module-config.ts index 1f4cb56f949..5f940b75fe6 100644 --- a/packages/devkit/lib/module/configs/module-config.ts +++ b/packages/devkit/lib/module/configs/module-config.ts @@ -4,6 +4,7 @@ import { RepositoryConfig } from '../../repository'; import { EntityStoreConfig, StateMachineConfig, UIStoreConfig, FormStoreConfig, FormArrayStoreConfig } from '../../store/index'; import { ViewModelConfig } from '../../viewmodel/index'; import { Module } from '../module'; +import { ExpressionConfig } from '../../expression'; /** * Module配置 @@ -22,6 +23,8 @@ interface ModuleConfig { formArrayStores: FormArrayStoreConfig[]; viewModels: ViewModelConfig[]; + expressions: ExpressionConfig[]; + schema: Record; } export { ModuleConfig }; \ No newline at end of file diff --git a/packages/devkit/lib/module/module-creator.ts b/packages/devkit/lib/module/module-creator.ts index 1b337e26e02..4570c09597c 100644 --- a/packages/devkit/lib/module/module-creator.ts +++ b/packages/devkit/lib/module/module-creator.ts @@ -4,6 +4,7 @@ import { DEVKIT_INJECTION_TOKEN, Devkit } from '../devkit'; import { RepositoryConfig, getDynamicRepositoryToken } from '../repository/index'; import { MODULE_INJECTION_TOKEN, Module } from './module'; import { ModuleConfig, ModuleConfigBuilder } from './configs/index'; +import { ExpressionConfig, EXPRESSIONS_TOKEN } from '../expression'; /** * 创建远程实体仓库注入 @@ -42,16 +43,25 @@ function createRepositoryProviders(repositoryConfigs: RepositoryConfig[]) { return providers; } - +function createExpressionsProviders(expressions: ExpressionConfig[]) { + if (!expressions || !Array.isArray(expressions)) { + return []; + } + const providers: StaticProvider[] = []; + providers.push({ provide: EXPRESSIONS_TOKEN, useValue: expressions }); + return providers; +} /** * 创建模块Providers */ function createModuleProviders(moduleConfig: ModuleConfig) { const extendProviders: StaticProvider[] = moduleConfig.providers || []; const repositoryProviders = createRepositoryProviders(moduleConfig.repositories); + const expressionsProviders = createExpressionsProviders(moduleConfig.expressions); const providers = [ ...extendProviders, - ...repositoryProviders + ...repositoryProviders, + ...expressionsProviders ]; if (moduleConfig.type) { diff --git a/packages/renderer/src/config-builders/module-config-builder.ts b/packages/renderer/src/config-builders/module-config-builder.ts index 9751e5286e8..539989003ed 100644 --- a/packages/renderer/src/config-builders/module-config-builder.ts +++ b/packages/renderer/src/config-builders/module-config-builder.ts @@ -51,7 +51,8 @@ class ModuleConfigBuilder { uiStores: uiStoreConfigs, stateMachines: stateMachineConfigs, repositories: repositoryConfigs, - viewModels: viewModelConfigs + viewModels: viewModelConfigs, + expressions: formMeta.module.expressions, }; return moduleConfig; -- Gitee From 54aae46d2882c1738000e429b9c99dfe9911c64e Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Fri, 14 Mar 2025 21:10:12 +0800 Subject: [PATCH 043/153] =?UTF-8?q?chore:=20=E5=89=A5=E7=A6=BB=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8Fid=E8=BD=ACpath=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/expression/expression-registry.ts | 24 +++++-------------- packages/devkit/lib/expression/providers.ts | 4 ++-- .../lib/module/configs/module-config.ts | 1 - 3 files changed, 8 insertions(+), 21 deletions(-) diff --git a/packages/devkit/lib/expression/expression-registry.ts b/packages/devkit/lib/expression/expression-registry.ts index 7c03d30c50b..89ebd2b2469 100644 --- a/packages/devkit/lib/expression/expression-registry.ts +++ b/packages/devkit/lib/expression/expression-registry.ts @@ -1,40 +1,28 @@ -import { DataSourceResolver, FieldResolver } from "../resolvers"; import { ViewModel, ViewModelState } from "../viewmodel"; import { DEFAULT_EXPRESSION_VALIDATE_MESSAGE, ExpressionConfig, ExpressionObject, ExpressionRule, ExpressionType } from "./types"; export class ExpressionRegistry { - constructor(private expressionConfigs: ExpressionConfig[], private viewModel:ViewModel, private fieldResolver: FieldResolver, private dataSourceResolver: DataSourceResolver) { + constructor(private expressionConfigs: ExpressionConfig[], private viewModel: ViewModel) { } public get expressions(): ExpressionObject[] { const expressions: ExpressionConfig[] = this.expressionConfigs; const expressionObjects: ExpressionObject[] = []; - expressions.forEach((elementExpression: ExpressionConfig) => { - const { rules, target, targetType } = elementExpression; + expressions.forEach((expressionConfig: ExpressionConfig) => { + const { rules, target, targetType } = expressionConfig; if (!target || !targetType || !rules || rules.length < 1) { return; } rules.forEach((rule: ExpressionRule) => { let path = rule.id; - if (elementExpression.targetType === 'Field') { - const resolvedField = this.fieldResolver.resolve(elementExpression.target); - if (!resolvedField) { - return; - } - const { dataSource, bindingPath } = resolvedField; - const resolvedDataSource = this.dataSourceResolver.resolve(dataSource); - if (!resolvedDataSource) { - return; - } - const { bindingPaths } = resolvedDataSource; - const fullPaths = bindingPaths.concat(bindingPath.split('.')); - path = fullPaths.join('/'); + if (expressionConfig.targetType === 'Field') { + path = expressionConfig.target; } const expressionValue = this.cleanSpecialCharacters(rule.expression); const expressionObject: ExpressionObject = { id: rule.id, ns: '', path: path, - bindingType: elementExpression.targetType, + bindingType: expressionConfig.targetType, type: rule.type, expression: expressionValue, message: rule.message, diff --git a/packages/devkit/lib/expression/providers.ts b/packages/devkit/lib/expression/providers.ts index 307a2c17458..51b1801a346 100644 --- a/packages/devkit/lib/expression/providers.ts +++ b/packages/devkit/lib/expression/providers.ts @@ -3,15 +3,15 @@ import { ExpressionEventEmitter } from './expression-event-emitter'; import { ExpressionEngineProxy } from './expression-engine-proxy'; import { ExpressionExecutor } from './expression-executor'; import { ExpressionRegistry } from './expression-registry'; -import { DataSourceResolver, FieldResolver } from '../resolvers'; import { ExpressionDependencyResolverRegistry, ExpressionDependencyResolver } from '../expression-dependency-resolver'; import { ExpressionResult } from './expression-result'; import { EXPRESSIONS_TOKEN } from './tokens'; +import { ViewModel } from '../viewmodel'; export const expressionProviders: StaticProvider[] = [ { provide: ExpressionEventEmitter, useClass: ExpressionEventEmitter, deps: [Injector] }, { provide: ExpressionEngineProxy, useClass: ExpressionEngineProxy, deps: [Injector, ExpressionEventEmitter, ExpressionExecutor, ExpressionRegistry, ExpressionDependencyResolverRegistry, ExpressionDependencyResolver] }, { provide: ExpressionExecutor, useClass: ExpressionExecutor, deps: [] }, - { provide: ExpressionRegistry, useClass: ExpressionRegistry, deps: [EXPRESSIONS_TOKEN, FieldResolver, DataSourceResolver] }, + { provide: ExpressionRegistry, useClass: ExpressionRegistry, deps: [EXPRESSIONS_TOKEN, ViewModel] }, { provide: ExpressionResult, useClass: ExpressionResult, deps: [] } ]; diff --git a/packages/devkit/lib/module/configs/module-config.ts b/packages/devkit/lib/module/configs/module-config.ts index 5f940b75fe6..273505573e3 100644 --- a/packages/devkit/lib/module/configs/module-config.ts +++ b/packages/devkit/lib/module/configs/module-config.ts @@ -24,7 +24,6 @@ interface ModuleConfig { viewModels: ViewModelConfig[]; expressions: ExpressionConfig[]; - schema: Record; } export { ModuleConfig }; \ No newline at end of file -- Gitee From d50c2a434facd5d9afa9e354b1f3f5eb7c99d4e8 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Sat, 15 Mar 2025 09:23:33 +0800 Subject: [PATCH 044/153] =?UTF-8?q?chore:=20=E8=A7=86=E5=9B=BE=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E6=94=AF=E6=8C=81=E6=A0=B9=E6=B3=A8=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/devkit/lib/index.ts | 2 ++ .../lib/viewmodel/configs/viewmodel-config.ts | 1 + .../devkit/lib/viewmodel/viewmodel-creator.ts | 28 +++++++++++++------ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/devkit/lib/index.ts b/packages/devkit/lib/index.ts index cc320743e76..60d16c496e9 100644 --- a/packages/devkit/lib/index.ts +++ b/packages/devkit/lib/index.ts @@ -14,3 +14,5 @@ export * from './context/index'; export * from './change-observer'; export * from './expression-dependency-resolver'; +export * from './effector'; +export * from './expression'; diff --git a/packages/devkit/lib/viewmodel/configs/viewmodel-config.ts b/packages/devkit/lib/viewmodel/configs/viewmodel-config.ts index 904ebfbfb5a..b9308004bf4 100644 --- a/packages/devkit/lib/viewmodel/configs/viewmodel-config.ts +++ b/packages/devkit/lib/viewmodel/configs/viewmodel-config.ts @@ -45,6 +45,7 @@ interface ViewModelConfig { type?: Type>; deps?: any[]; providers?: StaticProvider[], + rootProviders?: StaticProvider[], entityStore?: string; uiStore?: string; diff --git a/packages/devkit/lib/viewmodel/viewmodel-creator.ts b/packages/devkit/lib/viewmodel/viewmodel-creator.ts index 0aacbae9c99..02b3769d17f 100644 --- a/packages/devkit/lib/viewmodel/viewmodel-creator.ts +++ b/packages/devkit/lib/viewmodel/viewmodel-creator.ts @@ -6,7 +6,7 @@ import { ViewModelNode } from './viewmodel-node'; import { VIEWMODEL_INJECTION_TOKEN, ViewModelState, ViewModel, } from './viewmodel'; import { ViewModelConfig } from './configs'; import { expressionDependencyResolverProviders } from '../expression-dependency-resolver'; - +import { expressionProviders } from '../expression'; /** * 获取命令处理器的Providers */ @@ -42,31 +42,43 @@ function getCommandHandlerProviders(commandHandlerConfigs: CommandHandlerConfig[ return providers; } - +/** + * 获取根视图模型的Providers + * @param viewModelConfig 视图模型配置 + * @returns + */ +function getRootViewModelProviders(viewModelConfig: ViewModelConfig): StaticProvider[] { + const rootProviders = viewModelConfig.rootProviders || []; + return [ + ...rootProviders, + ...expressionDependencyResolverProviders, + ...expressionProviders + ]; +} /** * 获取ViewModel的Providers */ function getViewModelProviders(viewModelConfig: ViewModelConfig): StaticProvider[] { const configProviders = viewModelConfig.providers || []; - const commandHandlerProviders = getCommandHandlerProviders(viewModelConfig.commandHandlers) + const commandHandlerProviders = getCommandHandlerProviders(viewModelConfig.commandHandlers); const providers = [ ...configProviders, ...commandHandlerProviders, - ...commandBusProviders, - ...expressionDependencyResolverProviders + ...commandBusProviders ]; if (viewModelConfig.type) { const deps = viewModelConfig.deps || []; providers.push({ provide: ViewModel, useClass: viewModelConfig.type, deps: deps }); } else { - providers.push({ provide: ViewModel, useClass: ViewModel, deps: [Injector] }) + providers.push({ provide: ViewModel, useClass: ViewModel, deps: [Injector] }); } providers.push({ provide: ViewModelNode, useExisting: ViewModel }); - + if (!viewModelConfig.parentId) { + providers.push(...getRootViewModelProviders(viewModelConfig)); + } return providers; } - /** * 创建ViewModel */ -- Gitee From 13b75d7196b116b5c0ad784b0155ee78142ac201 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Sat, 15 Mar 2025 09:47:01 +0800 Subject: [PATCH 045/153] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9observer?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E4=B8=BAviewModel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity-state-change-observer.ts | 11 ++---- .../devkit/lib/change-observer/providers.ts | 8 ++-- .../change-observer/state-machine-observer.ts | 7 ++-- .../ui-state-change-observer.ts | 38 +++++++++---------- 4 files changed, 29 insertions(+), 35 deletions(-) diff --git a/packages/devkit/lib/change-observer/entity-state-change-observer.ts b/packages/devkit/lib/change-observer/entity-state-change-observer.ts index 9842cd4c421..08352a9db93 100644 --- a/packages/devkit/lib/change-observer/entity-state-change-observer.ts +++ b/packages/devkit/lib/change-observer/entity-state-change-observer.ts @@ -1,21 +1,18 @@ -import { Injector } from "../common"; -import { Module } from '../module'; import { Entity, EntityChange, EntityState, StateChange } from '../store'; import { Callable } from "../common"; import { ChangeObserver } from "./change-observer"; import { Change, ChangeSource } from "./types"; -import { ENTITY_STORE_SUFFIX, MODULE_CONFIG_ID_TOKEN } from "../common"; +import { ViewModel, ViewModelState } from "../viewmodel"; export class EntityStateChangeObserver extends ChangeObserver { - constructor(private module: Module, private injector: Injector) { + constructor(private viewModel: ViewModel) { super(); } public observe(callback: Callable): void { - if (!this.module) { + if (!this.viewModel) { return; } - const moduleConfigId = this.injector.get(MODULE_CONFIG_ID_TOKEN); - const entityStore = this.module.getEntityStore(`${moduleConfigId}${ENTITY_STORE_SUFFIX}`); + const entityStore = this.viewModel.entityStore; if (!entityStore) { return; } diff --git a/packages/devkit/lib/change-observer/providers.ts b/packages/devkit/lib/change-observer/providers.ts index 904e9503e39..2cb5e41bcff 100644 --- a/packages/devkit/lib/change-observer/providers.ts +++ b/packages/devkit/lib/change-observer/providers.ts @@ -1,14 +1,14 @@ import { Injector, StaticProvider } from "../common"; -import { Module } from "../module"; import { StateMachineObserver } from "./state-machine-observer"; import { CHANGE_OBSERVER_TOKEN } from "./tokens"; import { ChangeObserverRegistry } from "./change-observer-registry"; import { EntityStateChangeObserver } from "./entity-state-change-observer"; import { UIStateChangeObserver } from "./ui-state-change-observer"; +import { ViewModel } from "../viewmodel"; export const changeObserverProviders: StaticProvider[] = [ - { provide: CHANGE_OBSERVER_TOKEN, useClass: StateMachineObserver, deps: [Module], multi: true }, - { provide: CHANGE_OBSERVER_TOKEN, useClass: EntityStateChangeObserver, deps: [Module, Injector], multi: true }, - { provide: CHANGE_OBSERVER_TOKEN, useClass: UIStateChangeObserver, deps: [Module], multi: true }, + { provide: CHANGE_OBSERVER_TOKEN, useClass: StateMachineObserver, deps: [ViewModel], multi: true }, + { provide: CHANGE_OBSERVER_TOKEN, useClass: EntityStateChangeObserver, deps: [ViewModel], multi: true }, + { provide: CHANGE_OBSERVER_TOKEN, useClass: UIStateChangeObserver, deps: [ViewModel], multi: true }, { provide: ChangeObserverRegistry, useClass: ChangeObserverRegistry, deps: [Injector] } ]; diff --git a/packages/devkit/lib/change-observer/state-machine-observer.ts b/packages/devkit/lib/change-observer/state-machine-observer.ts index 831b834b1d6..7d35889f5e1 100644 --- a/packages/devkit/lib/change-observer/state-machine-observer.ts +++ b/packages/devkit/lib/change-observer/state-machine-observer.ts @@ -3,18 +3,19 @@ import { Module } from '../module'; import { ChangeObserver } from "./change-observer"; import { Change, ChangeSource, StateMachineChangeType } from "./types"; import { Callable } from "../common"; +import { ViewModel, ViewModelState } from "../viewmodel"; export class StateMachineObserver extends ChangeObserver { - constructor(private module: Module) { + constructor(private viewModel: ViewModel) { super(); } public observe(callback: Callable) { - if (!this.module) { + if (!this.viewModel) { return; } - const stateMachine = this.module.getStateMachines()[0]; + const stateMachine = this.viewModel.stateMachine; if (!stateMachine) { return; } diff --git a/packages/devkit/lib/change-observer/ui-state-change-observer.ts b/packages/devkit/lib/change-observer/ui-state-change-observer.ts index 697fc03632a..7b6977817c6 100644 --- a/packages/devkit/lib/change-observer/ui-state-change-observer.ts +++ b/packages/devkit/lib/change-observer/ui-state-change-observer.ts @@ -1,4 +1,3 @@ -import { Module } from '../module'; import { ViewModel, ViewModelState } from "../viewmodel"; import { StateChange, UIState, UIStateChange } from '../store'; import { Callable } from "../common"; @@ -7,32 +6,29 @@ import { Change, ChangeSource } from "./types"; export class UIStateChangeObserver extends ChangeObserver { - constructor(private module: Module) { + constructor(private viewModel: ViewModel) { super(); } public observe(callback: Callable): void { - if (!this.module) { + if (!this.viewModel) { return; } - const viewModels = this.module.getViewModels(); - viewModels.forEach((viewModel: ViewModel) => { - const { uiStore } = viewModel; - if (!uiStore) { - return; - } - uiStore.watchChange((change: StateChange) => { - const stateChange = change as UIStateChange; - const uiStateChange: Change> = { - // TODO: namespace应与组合表单ns一致 - ns: '', - source: ChangeSource.UIState, - detail: change, - viewModelId: viewModel.id, - type: stateChange.type - }; - callback(uiStateChange); - }); + const { uiStore } = this.viewModel; + if (!uiStore) { + return; + } + uiStore.watchChange((change: StateChange) => { + const stateChange = change as UIStateChange; + const uiStateChange: Change> = { + // TODO: namespace应与组合表单ns一致 + ns: '', + source: ChangeSource.UIState, + detail: change, + viewModelId: this.viewModel.id, + type: stateChange.type + }; + callback(uiStateChange); }); } } -- Gitee From e7c9c87be567128cf2afe2459dcb75aa72339935 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Sat, 15 Mar 2025 09:53:30 +0800 Subject: [PATCH 046/153] =?UTF-8?q?chore:=20=E6=A0=B9=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E5=A2=9E=E5=8A=A0=E5=8F=98=E6=9B=B4=E8=A7=82?= =?UTF-8?q?=E5=AF=9F=E6=B3=A8=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/devkit/lib/expression/expression-engine-proxy.ts | 5 ++--- packages/devkit/lib/expression/providers.ts | 2 +- packages/devkit/lib/viewmodel/viewmodel-creator.ts | 2 ++ 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/devkit/lib/expression/expression-engine-proxy.ts b/packages/devkit/lib/expression/expression-engine-proxy.ts index 2e88281767c..3bc73c3a4d6 100644 --- a/packages/devkit/lib/expression/expression-engine-proxy.ts +++ b/packages/devkit/lib/expression/expression-engine-proxy.ts @@ -11,10 +11,9 @@ export class ExpressionEngineProxy { constructor( private injector: Injector, private expressionEventEmitter: ExpressionEventEmitter, - private expressionExecutor: ExpressionExecutor, private expressionRegistry: ExpressionRegistry, private expressionDependencyResolverRegistry: ExpressionDependencyResolverRegistry, - private expressionDependencyResolveService: ExpressionDependencyResolver, + private expressionDependencyResolver: ExpressionDependencyResolver, ) { const { expressions } = this.expressionRegistry; this.resolveDependency(expressions); @@ -36,7 +35,7 @@ export class ExpressionEngineProxy { } expressionObjects.forEach((expressionObject: ExpressionObject) => { const { expression } = expressionObject; - const dependencies = this.expressionDependencyResolveService.resolve(expression); + const dependencies = this.expressionDependencyResolver.resolve(expression); expressionObject.deps = dependencies; }); } diff --git a/packages/devkit/lib/expression/providers.ts b/packages/devkit/lib/expression/providers.ts index 51b1801a346..f05d9965ab5 100644 --- a/packages/devkit/lib/expression/providers.ts +++ b/packages/devkit/lib/expression/providers.ts @@ -10,7 +10,7 @@ import { ViewModel } from '../viewmodel'; export const expressionProviders: StaticProvider[] = [ { provide: ExpressionEventEmitter, useClass: ExpressionEventEmitter, deps: [Injector] }, - { provide: ExpressionEngineProxy, useClass: ExpressionEngineProxy, deps: [Injector, ExpressionEventEmitter, ExpressionExecutor, ExpressionRegistry, ExpressionDependencyResolverRegistry, ExpressionDependencyResolver] }, + { provide: ExpressionEngineProxy, useClass: ExpressionEngineProxy, deps: [Injector, ExpressionEventEmitter, ExpressionRegistry, ExpressionDependencyResolverRegistry, ExpressionDependencyResolver] }, { provide: ExpressionExecutor, useClass: ExpressionExecutor, deps: [] }, { provide: ExpressionRegistry, useClass: ExpressionRegistry, deps: [EXPRESSIONS_TOKEN, ViewModel] }, { provide: ExpressionResult, useClass: ExpressionResult, deps: [] } diff --git a/packages/devkit/lib/viewmodel/viewmodel-creator.ts b/packages/devkit/lib/viewmodel/viewmodel-creator.ts index 02b3769d17f..0f4e332dfde 100644 --- a/packages/devkit/lib/viewmodel/viewmodel-creator.ts +++ b/packages/devkit/lib/viewmodel/viewmodel-creator.ts @@ -7,6 +7,7 @@ import { VIEWMODEL_INJECTION_TOKEN, ViewModelState, ViewModel, } from './viewmod import { ViewModelConfig } from './configs'; import { expressionDependencyResolverProviders } from '../expression-dependency-resolver'; import { expressionProviders } from '../expression'; +import { changeObserverProviders } from '../change-observer'; /** * 获取命令处理器的Providers */ @@ -51,6 +52,7 @@ function getRootViewModelProviders(viewModelConfig: ViewModelConfig): StaticProv const rootProviders = viewModelConfig.rootProviders || []; return [ ...rootProviders, + ...changeObserverProviders, ...expressionDependencyResolverProviders, ...expressionProviders ]; -- Gitee From 3e650d9e1620d22fce025bc718a803f722c7af11 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Sat, 15 Mar 2025 11:01:09 +0800 Subject: [PATCH 047/153] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E4=B8=8A=E4=B8=8B=E6=96=87=E6=9E=84=E9=80=A0?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../expression-context-builder.ts | 136 +++++++----------- 1 file changed, 54 insertions(+), 82 deletions(-) diff --git a/packages/devkit/lib/change-handler/expression-context-builder.ts b/packages/devkit/lib/change-handler/expression-context-builder.ts index 36bdbe1e262..160eed6c32a 100644 --- a/packages/devkit/lib/change-handler/expression-context-builder.ts +++ b/packages/devkit/lib/change-handler/expression-context-builder.ts @@ -1,58 +1,61 @@ -import { Entity, EntityState, EntityStore} from "../store"; +import { Entity, EntityListFieldSchema, EntitySchema, EntityState, EntityStore, FieldSchema, FieldType } from "../store"; import BigNumber from "bignumber.js"; -import { EntityResolver } from "../resolvers"; -import { ResolvedEntity } from "../types"; import { Module } from "../module"; import { ViewModel, ViewModelState } from "../viewmodel"; export class ExpressionContextBuilder { constructor() { } - public buildContext(entityResolver: EntityResolver, entityStore: EntityStore> | null, module: Module, currentRows?: { bindingPath: string, primaryValue: string; }[]) { - const context = []; - const entityContext = this.buildEntityContext(entityResolver, entityStore, currentRows); - context.push(entityContext); - const stateContext = this.buildStateContext(module); - const entityCode = entityResolver.getEntityCode(); - let entity = null; - if (context.length === 1) { - entity = context.pop(); - } else { - entity = context[0]; - if (!entity['__type__']) { - entity['__type__'] = 'Entity'; - } - entity['__items__'] = context; - } - // const runtimeFrameworkContext = ExpressionUtil.buildRuntimeFrameworkContext(this.frameContext.appContext); + public buildContext(viewModel: ViewModel, currentRows?: { bindingPath: string, primaryValue: string; }[]) { + const entitySchema = viewModel.entityStore.getEntitySchema(); + const entityContext = this.buildEntityContext(entitySchema, viewModel.entityStore, currentRows); + const stateContext = this.buildStateContext(viewModel); + const entityCode = viewModel.entityStore.getEntitySchema().getCode(); return { // ...runtimeFrameworkContext, - [entityCode]: entity, + [entityCode]: entityContext, ...stateContext, BigNumber, CurrentLanguage: 'zh-CHS' }; } - private buildStateContext(module: Module) { - const viewModels = module.getViewModels(); - const rootViewModel = viewModels.find((viewModel: ViewModel) => !viewModel.getParent()); + private buildStateContext(viewModel: ViewModel) { const result: Record = {}; - if (rootViewModel) { - const uiState = rootViewModel.uiStore?.getState(); - if (uiState) { - const propertyNames = Object.getOwnPropertyNames(uiState) || []; - propertyNames.forEach((prop: string) => { - if (prop.match(/^[a-zA-Z0-9_$]+$/g) !== null) { - result[prop] = uiState[prop]; - } - }); - } + const uiState = viewModel.uiStore?.getState(); + if (uiState) { + const propertyNames = Object.getOwnPropertyNames(uiState) || []; + propertyNames.forEach((prop: string) => { + if (prop.match(/^[a-zA-Z0-9_$]+$/g) !== null) { + result[prop] = uiState[prop]; + } + }); } return result; } - private buildEntityContext(entityResolver: EntityResolver, entityStore: EntityStore> | null, currentRows?: { bindingPath: string, primaryValue: string; }[]) { - const resolvedEntitys = entityResolver.resolve(); - const childrenEntityPaths = resolvedEntitys.map((resolvedEntity: ResolvedEntity) => resolvedEntity.bindingPaths).filter((paths: string[]) => paths.length > 0); - // 获取当前行 + private buildEntityContext(entitySchema: EntitySchema, entityStore: EntityStore> | null, currentRows?: { bindingPath: string, primaryValue: string; }[]) { + function traverse(currentContext: any, schema: EntityListFieldSchema, paths: string[] = []) { + const fullPath = paths.concat(schema.name).join('/'); + const bindingList = entityStore?.getEntityListByPath('/' + fullPath); + if (!bindingList || bindingList.getEntities().length < 1) { + currentContext[schema.name] = this.createIteratorableNode(); + return; + } + const currentId = bindingList?.getCurrentEntity().idValue; + const targetId = currentRows && currentRows.find((row) => row.bindingPath === fullPath)?.primaryValue || currentId; + const targetEntity = bindingList.getEntityById(targetId); + const node = this.createIteratorableNode(); + currentContext[schema.name] = node; + if (!targetEntity) { + return; + } + node.__items__ = Array.from(bindingList.toJSON()); + Object.assign(node, targetEntity.toJSON()); + const entityListSchema = schema.entitySchema.getFieldSchemasByType(FieldType.EntityList); + if (entityListSchema && entityListSchema.length > 0) { + entityListSchema.forEach((subSchema: EntityListFieldSchema) => { + traverse(node, subSchema, paths.concat(schema.name)); + }); + } + } const row = currentRows && currentRows.find((row) => row.bindingPath === '' || row.bindingPath === '/') || null; const primaryValue = row && row.primaryValue || entityStore?.getCurrentEntity().idValue; const entity = entityStore?.getEntityById(primaryValue); @@ -61,54 +64,23 @@ export class ExpressionContextBuilder { } const entityContext = entity.toJSON(); entityContext['__type__'] = 'Entity'; - // 至少包含一个主表的实体 - if (!childrenEntityPaths || childrenEntityPaths.length < 1) { + const entityListSchema = entitySchema.getFieldSchemasByType(FieldType.EntityList); + // 当前实体无子表 + if (!entityListSchema || entityListSchema.length < 1) { return entityContext; } - childrenEntityPaths.sort((v1, v2) => v1.length - v2.length); - // 找到所有子表 - childrenEntityPaths.forEach((paths: string[]) => { - const bindingList = entityStore?.getEntityListByPath('/'+paths.join('/')); - let currentRowId = bindingList?.getCurrentEntity().idValue; - const propertyName = paths[paths.length - 1]; - // parent 为entity或entitylist或null - const parentNode = paths.slice(0, paths.length - 1).reduce((object: any, path: string) => { - return object && object[path] || null; - }, entityContext); - if (!parentNode) { - return; - } - let node: any = null; - if (!currentRowId) { - // 当前表没有数据 - node = { __items__: [], __type__: 'List' }; - node.length = () => node.__items__.length; - } else { - // 纠正当前行 - if (currentRows && currentRows.length > 0) { - // 是否指定了当前行 - const userAssignCurrentRow = currentRows.find((row) => { - const bindingPaths = row.bindingPath.split('/').filter((p) => p); - return bindingPaths.join('/') === paths.join('/'); - }); - if (userAssignCurrentRow) { - currentRowId = userAssignCurrentRow.primaryValue; - } - } - // 子表当前行 - const row = bindingList?.getEntityById(currentRowId); - // 找到子表当前行的上级 - const list = parentNode[propertyName]; - node = { __items__: [], ...row && row.toJSON() || {}, __type__: 'List' }; - node.length = () => node.__items__.length; - if (list && Array.isArray(list)) { - node.__items__ = Array.from(list); - } - } - parentNode[propertyName] = node; + entityListSchema.forEach((fieldSchema: EntityListFieldSchema) => { + traverse(entityContext, fieldSchema); }); return entityContext; } - + private createIteratorableNode() { + const node = { + __items__: [], + __type__: 'List', + length: () => node.__items__.length + }; + return node; + } } -- Gitee From 10f6e21817c7b4cfd9b40fe5aa162966e4e22c50 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Sat, 15 Mar 2025 11:19:57 +0800 Subject: [PATCH 048/153] =?UTF-8?q?chore:=20=E9=87=8D=E6=9E=84=E5=8F=98?= =?UTF-8?q?=E6=9B=B4=E5=A4=84=E7=90=86=E5=99=A8=EF=BC=8C=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E4=BE=9D=E8=B5=96module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../change-handler/abstract-change-handler.ts | 6 +++- ...tity-store-append-entity-change-handler.ts | 29 +++++++++---------- .../entity-store-current-change-handler.ts | 22 ++++++-------- ...entity-store-load-entity-change-handler.ts | 24 +++++++-------- ...tity-store-remove-entity-change-handler.ts | 22 ++++++-------- .../entity-store-update-change-handler.ts | 20 +++++-------- .../entity-store-value-change-handler.ts | 26 +++++++---------- .../expression-context-builder.ts | 3 +- .../devkit/lib/change-handler/providers.ts | 18 ++++++------ .../state-store-value-change-handler.ts | 24 ++++++--------- packages/devkit/lib/index.ts | 1 + 11 files changed, 84 insertions(+), 111 deletions(-) diff --git a/packages/devkit/lib/change-handler/abstract-change-handler.ts b/packages/devkit/lib/change-handler/abstract-change-handler.ts index 261bfa9d214..09b47a79e6c 100644 --- a/packages/devkit/lib/change-handler/abstract-change-handler.ts +++ b/packages/devkit/lib/change-handler/abstract-change-handler.ts @@ -2,9 +2,10 @@ import { Change } from "../change-observer"; import { ExpressionBindingType, ExpressionExecutor, ExpressionObject, ExpressionType } from "../expression"; import { ChangeHandler } from "./types"; import { EffectorFactory } from "../effector"; +import { ViewModel, ViewModelState } from "../viewmodel"; export abstract class AbstractChangeHandler implements ChangeHandler { - constructor(public expressionExecutor: ExpressionExecutor, protected effectorFactory: EffectorFactory) { } + constructor(protected viewModel:ViewModel ,protected expressionExecutor: ExpressionExecutor, protected effectorFactory: EffectorFactory) { } abstract handle(change: Change, expressionObjects: ExpressionObject[]): void; protected getEffector(expressionObject: ExpressionObject) { return this.effectorFactory.getEffector(expressionObject); @@ -38,6 +39,9 @@ export abstract class AbstractChangeHandler implements ChangeHandler { return this.isReadonlyExpression(expressionObject) || this.isVisibleExpression(expressionObject) || this.isValidateExpression(expressionObject) || this.isRequiredExpression(expressionObject) || this.isDependencyExpression(expressionObject) || this.isButtonDisabledExpression(expressionObject) || this.isButtonVisibleExpression(expressionObject) || this.isContainerVisibleExpression(expressionObject); } + protected resolvePath(path: string | string[]) { + return this.viewModel.entityStore.getEntitySchema().resolvePath(path); + } private isReadonlyExpression(expressionObject: ExpressionObject): boolean { return expressionObject && expressionObject.type === ExpressionType.Readonly || false; } diff --git a/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts index f53e54861b4..ad223c1b931 100644 --- a/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts @@ -1,23 +1,20 @@ import { AppendEntityChange, EntityChangeType } from "../store"; -import { Module } from '../module'; import { Change, ChangeSource } from "../change-observer"; import { ExpressionBindingType, ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE, STATE_TEMPLATE } from "../expression-dependency-resolver"; import { AbstractChangeHandler } from "./abstract-change-handler"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; import { ExpressionContextBuilder } from "./expression-context-builder"; import { EffectOption, EffectorFactory } from "../effector"; +import { ViewModel, ViewModelState } from "../viewmodel"; export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler { constructor( - public expressionExecutor: ExpressionExecutor, - private entityPathResolver: EntityPathResolver, + protected viewModel: ViewModel, + protected expressionExecutor: ExpressionExecutor, private expressionResult: ExpressionResult, - private entityResolver: EntityResolver, - private module: Module, protected effectorFactory: EffectorFactory ) { - super(expressionExecutor, effectorFactory); + super(viewModel, expressionExecutor, effectorFactory); } handle(change: Change, expressionObjects: ExpressionObject[]): void { // 仅处理来自实体的新增变更 @@ -30,8 +27,7 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler } matches.forEach((expressionObject: ExpressionObject) => { const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module); + const expressionContext = expressionContextBuilder.buildContext(this.viewModel); const result = this.expressionExecutor.compile(expressionObject, expressionContext); if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { return; @@ -67,7 +63,7 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler } private buildEffectPaths(change: Change, expressionObject: ExpressionObject): string | null { const { entityPaths: changePaths } = this.resolveChangePath(change); - const { entityPaths: expressionPaths } = this.entityPathResolver.resolve(expressionObject.path); + const { entityPaths: expressionPaths } = this.viewModel.entityStore.getEntitySchema().resolvePath(expressionObject.path); // 对表达式进行校验,只应出现上级聚合下级的情况 if (changePaths.length !== expressionPaths.length + 1) { console.warn(`表达式${expressionObject.id}聚合了自身或下级数据,不支持此类表达式`); @@ -111,7 +107,7 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler const index = entityDependencies.findIndex((dependency: string) => { // 去掉ENTITY~前缀 const dependencyPath = dependency.split(DEPENDENCY_SPLITER).slice(1).join(DEPENDENCY_SPLITER); - const { entityPaths: dependencyPaths } = this.entityPathResolver.resolve(dependencyPath); + const { entityPaths: dependencyPaths } = this.resolvePath(dependencyPath); // 获取依赖字段所在的表路径 return dependencyPaths.join(DEPENDENCY_SPLITER) === changePaths.join(DEPENDENCY_SPLITER); }); @@ -123,7 +119,7 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler } const { entityPaths: changePaths } = this.resolveChangePath(change); const expressionPath = expressionObject.path; - const { entityPaths: expressionPaths } = this.entityPathResolver.resolve(expressionPath); + const { entityPaths: expressionPaths } = this.resolvePath(expressionPath); // 主表新增 if (changePaths.length === 0 && expressionObject.bindingType === ExpressionBindingType.Field) { // 认为主表新增时不需要处理聚合函数 @@ -146,7 +142,7 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler return false; } const deps = dependency.split(DEPENDENCY_SPLITER).filter((p) => p).slice(1); - const { entityPaths: resolvedDependencyPath } = this.entityPathResolver.resolve(deps); + const { entityPaths: resolvedDependencyPath } = this.resolvePath(deps); if (resolvedDependencyPath && resolvedDependencyPath.join(DEPENDENCY_SPLITER) === changePaths.join(DEPENDENCY_SPLITER)) { return true; } @@ -164,7 +160,7 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler if (onlyDependOnState) { return true; } - const { entityPaths: expressionPaths } = this.entityPathResolver.resolve(expressionObject.path); + const { entityPaths: expressionPaths } = this.resolvePath(expressionObject.path); const { entityPaths: changePaths } = this.resolveChangePath(change); // 过滤掉非当前表的表达式 if (expressionPaths.join(DEPENDENCY_SPLITER) !== changePaths.join(DEPENDENCY_SPLITER)) { @@ -190,7 +186,7 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler // 去掉ENTITY~前缀 const dependencyPath = dependency.split('/').slice(1).join('/'); // 获取路径中的实体信息 - const { entityPaths: resolvedDependencyPath } = this.entityPathResolver.resolve(dependencyPath); + const { entityPaths: resolvedDependencyPath } = this.resolvePath(dependencyPath); const { entityPaths: changePaths } = this.resolveChangePath(change); return changePaths.join('/') === resolvedDependencyPath.join('/'); }); @@ -199,6 +195,7 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler private resolveChangePath(change: Change) { const appendEntityChange = change.detail as AppendEntityChange; const changePath = appendEntityChange.path.toShortPath(); - return this.entityPathResolver.resolve(changePath); + return this.viewModel.entityStore.getEntitySchema().resolvePath(changePath); } + } diff --git a/packages/devkit/lib/change-handler/entity-store-current-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-current-change-handler.ts index 56990788f9a..4f9ad45e80d 100644 --- a/packages/devkit/lib/change-handler/entity-store-current-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-current-change-handler.ts @@ -1,24 +1,21 @@ import { ChangeCurrentEntityChange, EntityChangeType } from "../store"; -import { Module } from '../module'; import { isEqual } from 'lodash-es'; import { Change, ChangeSource } from "../change-observer"; -import { ExpressionBindingType, ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; +import { ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; import { AbstractChangeHandler } from "./abstract-change-handler"; -import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE } from "../expression-dependency-resolver"; +import { ENTITY_TEMPLATE } from "../expression-dependency-resolver"; import { ExpressionContextBuilder } from "./expression-context-builder"; import { EffectorFactory } from "../effector"; +import { ViewModel, ViewModelState } from "../viewmodel"; export class EntityStoreCurrentChangeHandler extends AbstractChangeHandler { constructor( - public expressionExecutor: ExpressionExecutor, - private entityPathResolver: EntityPathResolver, + protected viewModel: ViewModel, + protected expressionExecutor: ExpressionExecutor, private expressionResult: ExpressionResult, - private entityResolver: EntityResolver, - private module: Module, protected effectorFactory: EffectorFactory ) { - super(expressionExecutor, effectorFactory); + super(viewModel, expressionExecutor, effectorFactory); } handle(change: Change, expressionObjects: ExpressionObject[]): void { // 仅处理来自实体的当前行变更 @@ -32,8 +29,7 @@ export class EntityStoreCurrentChangeHandler extends AbstractChangeHandler { matches.forEach((expressionObject: ExpressionObject) => { const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module); + const expressionContext = expressionContextBuilder.buildContext(this.viewModel); const result = this.expressionExecutor.compile(expressionObject, expressionContext); if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { return; @@ -79,7 +75,7 @@ export class EntityStoreCurrentChangeHandler extends AbstractChangeHandler { return false; } const { entityPaths: changePaths } = this.resolveChangePath(change); - const { entityPaths: expressionPaths } = this.entityPathResolver.resolve(expressionObject.path); + const { entityPaths: expressionPaths } = this.resolvePath(expressionObject.path); // 只关注从表行切换 if (changePaths.length !== 1) { return false; @@ -108,6 +104,6 @@ export class EntityStoreCurrentChangeHandler extends AbstractChangeHandler { private resolveChangePath(change: Change) { const appendEntityChange = change.detail as ChangeCurrentEntityChange; const changePath = appendEntityChange.path.toShortPath(); - return this.entityPathResolver.resolve(changePath); + return this.resolvePath(changePath); } } diff --git a/packages/devkit/lib/change-handler/entity-store-load-entity-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-load-entity-change-handler.ts index b776a23de37..ee88666f9f5 100644 --- a/packages/devkit/lib/change-handler/entity-store-load-entity-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-load-entity-change-handler.ts @@ -1,24 +1,21 @@ import { EntityChangeType, LoadEntityChange } from "../store"; -import { Module } from '../module'; import { isEqual } from 'lodash-es'; import { Change, ChangeSource } from "../change-observer"; -import { ExpressionBindingType, ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; +import { ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; import { AbstractChangeHandler } from "./abstract-change-handler"; import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE } from "../expression-dependency-resolver"; import { ExpressionContextBuilder } from "./expression-context-builder"; import { EffectorFactory } from "../effector"; +import { ViewModel, ViewModelState } from "../viewmodel"; export class EntityStoreLoadEntityChangeHandler extends AbstractChangeHandler { constructor( - public expressionExecutor: ExpressionExecutor, - private entityPathResolver: EntityPathResolver, + protected viewModel: ViewModel, + protected expressionExecutor: ExpressionExecutor, private expressionResult: ExpressionResult, - private entityResolver: EntityResolver, - private module: Module, protected effectorFactory: EffectorFactory ) { - super(expressionExecutor, effectorFactory); + super(viewModel, expressionExecutor, effectorFactory); } handle(change: Change, expressionObjects: ExpressionObject[]): void { if (!(change.source === ChangeSource.EntityState && change.type === EntityChangeType.Load)) { @@ -30,8 +27,7 @@ export class EntityStoreLoadEntityChangeHandler extends AbstractChangeHandler { } matches.forEach((expressionObject: ExpressionObject) => { const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module); + const expressionContext = expressionContextBuilder.buildContext(this.viewModel); const result = this.expressionExecutor.compile(expressionObject, expressionContext); if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { return; @@ -64,7 +60,7 @@ export class EntityStoreLoadEntityChangeHandler extends AbstractChangeHandler { // 是否是匹配变更的元素表达式 return this.filterElementExpression(change, expressionObject); } - const { entityPaths: expressionPaths } = this.entityPathResolver.resolve(expressionObject.path); + const { entityPaths: expressionPaths } = this.resolvePath(expressionObject.path); // 影响一个表达式是否要计算的因子有两个:表达式作用的字段、表达式的依赖 // 以下判断的前提时数据加载场景!! // 1、表达式作用的字段 @@ -92,7 +88,7 @@ export class EntityStoreLoadEntityChangeHandler extends AbstractChangeHandler { // 去掉ENTITY~前缀 const dependencyPath = dep.split('/').slice(1); // 获取依赖字段所在的表路径 - const { entityPaths: dependencyPaths } = this.entityPathResolver.resolve(dependencyPath); + const { entityPaths: dependencyPaths } = this.resolvePath(dependencyPath); return isEqual(dependencyPaths, changePaths); }); return index !== -1; @@ -111,7 +107,7 @@ export class EntityStoreLoadEntityChangeHandler extends AbstractChangeHandler { // 去掉ENTITY~前缀 const depPath = dep.split('/').slice(1).join('/'); // 获取依赖字段所在的表路径 - const { entityPaths: dependencyPaths } = this.entityPathResolver.resolve(depPath); + const { entityPaths: dependencyPaths } = this.resolvePath(depPath); return dependencyPaths.join(DEPENDENCY_SPLITER) === changePath; }); return index !== -1; @@ -119,6 +115,6 @@ export class EntityStoreLoadEntityChangeHandler extends AbstractChangeHandler { private resolveChangePath(change: Change) { const appendEntityChange = change.detail as LoadEntityChange; const changePath = appendEntityChange.path.toShortPath(); - return this.entityPathResolver.resolve(changePath); + return this.resolvePath(changePath); } } diff --git a/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts index 223ec15beed..5be64c081e6 100644 --- a/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts @@ -1,24 +1,21 @@ import { EntityChangeType, RemoveEntityChange } from "../store"; -import { Module } from '../module'; import { Change, ChangeSource } from "../change-observer"; -import { ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; -import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE, STATE_TEMPLATE } from "../expression-dependency-resolver"; +import { ExpressionExecutor, ExpressionObject, ExpressionResult } from "../expression"; +import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE } from "../expression-dependency-resolver"; import { AbstractChangeHandler } from "./abstract-change-handler"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; import { ExpressionContextBuilder } from "./expression-context-builder"; import { isEqual } from "lodash-es"; import { EffectOption, EffectorFactory } from "../effector"; +import { ViewModel, ViewModelState } from "../viewmodel"; export class EntityStoreRemoveEntityChangeHandler extends AbstractChangeHandler { constructor( - public expressionExecutor: ExpressionExecutor, - private entityPathResolver: EntityPathResolver, + protected viewModel: ViewModel, + protected expressionExecutor: ExpressionExecutor, private expressionResult: ExpressionResult, - private entityResolver: EntityResolver, - private module: Module, protected effectorFactory: EffectorFactory ) { - super(expressionExecutor, effectorFactory); + super(viewModel, expressionExecutor, effectorFactory); } handle(change: Change, expressionObjects: ExpressionObject[]): void { if (!(change.source === ChangeSource.EntityState && change.type === EntityChangeType.Remove)) { @@ -33,8 +30,7 @@ export class EntityStoreRemoveEntityChangeHandler extends AbstractChangeHandler } matches.forEach((expressionObject: ExpressionObject) => { const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module); + const expressionContext = expressionContextBuilder.buildContext(this.viewModel); const result = this.expressionExecutor.compile(expressionObject, expressionContext); if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { return; @@ -76,7 +72,7 @@ export class EntityStoreRemoveEntityChangeHandler extends AbstractChangeHandler if (this.isElementExpression(expressionObject)) { return this.filterElementExpression(change, expressionObject); } - const { entityPaths: expressionPaths } = this.entityPathResolver.resolve(expressionObject.path); + const { entityPaths: expressionPaths } = this.resolvePath(expressionObject.path); // 仅处理上级表达式 if (changePaths.length - 1 !== expressionPaths.length) { return false; @@ -114,6 +110,6 @@ export class EntityStoreRemoveEntityChangeHandler extends AbstractChangeHandler private resolveChangePath(change: Change) { const appendEntityChange = change.detail as RemoveEntityChange; const changePath = appendEntityChange.path.toShortPath(); - return this.entityPathResolver.resolve(changePath); + return this.resolvePath(changePath); } } diff --git a/packages/devkit/lib/change-handler/entity-store-update-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-update-change-handler.ts index b7132dcbf6c..e3ea012fd0e 100644 --- a/packages/devkit/lib/change-handler/entity-store-update-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-update-change-handler.ts @@ -1,23 +1,20 @@ import { EntityChangeType } from "../store"; -import { Module } from '../module'; import { Change, ChangeSource } from "../change-observer"; import { ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE } from "../expression-dependency-resolver"; import { AbstractChangeHandler } from "./abstract-change-handler"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; import { ExpressionContextBuilder } from "./expression-context-builder"; import { EffectOption, EffectorFactory } from "../effector"; +import { ViewModel, ViewModelState } from "../viewmodel"; export class EntityStoreUpdateChangeHandler extends AbstractChangeHandler { constructor( - public expressionExecutor: ExpressionExecutor, - private entityPathResolver: EntityPathResolver, + protected viewModel: ViewModel, + protected expressionExecutor: ExpressionExecutor, private expressionResult: ExpressionResult, - private entityResolver: EntityResolver, - private module: Module, protected effectorFactory: EffectorFactory ) { - super(expressionExecutor, effectorFactory); + super(viewModel, expressionExecutor, effectorFactory); } handle(change: Change, expressionObjects: ExpressionObject[]): void { @@ -33,8 +30,7 @@ export class EntityStoreUpdateChangeHandler extends AbstractChangeHandler { } matches.forEach((expressionObject: ExpressionObject) => { const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module); + const expressionContext = expressionContextBuilder.buildContext(this.viewModel); const result = this.expressionExecutor.compile(expressionObject, expressionContext); if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { return; @@ -49,7 +45,7 @@ export class EntityStoreUpdateChangeHandler extends AbstractChangeHandler { this.effect(change, expressionObject, result); }); } - private effect(change: Change, expressionObject: ExpressionObject, result: any) { + private effect(change: Change, expressionObject: ExpressionObject, result: any) { const effector = this.getEffector(expressionObject); if (!effector) { return; @@ -64,7 +60,7 @@ export class EntityStoreUpdateChangeHandler extends AbstractChangeHandler { return false; } if (this.isFieldExpression(expressionObject)) { - const { entityPaths: expressionPaths } = this.entityPathResolver.resolve(expressionObject.path); + const { entityPaths: expressionPaths } = this.resolvePath(expressionObject.path); // 必须是主表表达式 if (expressionPaths.length !== 0) { return false; @@ -75,7 +71,7 @@ export class EntityStoreUpdateChangeHandler extends AbstractChangeHandler { return false; } const dependencyPath = dependency.split(DEPENDENCY_SPLITER).filter((p) => p).slice(1).join(DEPENDENCY_SPLITER); - const { entityPaths: dependencyPaths } = this.entityPathResolver.resolve(dependencyPath); + const { entityPaths: dependencyPaths } = this.resolvePath(dependencyPath); return dependencyPaths.length === 0; }); return index === -1 ? false : true; diff --git a/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts index 2c6d4143e94..21a062435cf 100644 --- a/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts @@ -1,24 +1,21 @@ -import { ChangeValueChange, EntityChangeType, EntityPathNode, EntityPathNodeType,RemoveEntityChange } from "../store"; -import { Module } from '../module'; +import { ChangeValueChange, EntityChangeType, EntityPathNode, EntityPathNodeType, RemoveEntityChange } from "../store"; import { Change, ChangeSource } from "../change-observer"; import { ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE } from "../expression-dependency-resolver"; import { AbstractChangeHandler } from "./abstract-change-handler"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; import { ExpressionContextBuilder } from "./expression-context-builder"; import { EffectOption, EffectorFactory } from "../effector"; import { isEqual } from "lodash-es"; +import { ViewModel, ViewModelState } from "../viewmodel"; export class EntityStoreValueChangeHandler extends AbstractChangeHandler { constructor( - public expressionExecutor: ExpressionExecutor, - private entityPathResolver: EntityPathResolver, + protected viewModel: ViewModel, + protected expressionExecutor: ExpressionExecutor, private expressionResult: ExpressionResult, - private entityResolver: EntityResolver, - private module: Module, protected effectorFactory: EffectorFactory ) { - super(expressionExecutor, effectorFactory); + super(viewModel, expressionExecutor, effectorFactory); } handle(change: Change, expressionObjects: ExpressionObject[]): void { if (!(change.source === ChangeSource.EntityState && change.type === EntityChangeType.ValueChange)) { @@ -34,8 +31,7 @@ export class EntityStoreValueChangeHandler extends AbstractChangeHandler { matches.forEach((expressionObject: ExpressionObject) => { if (this.isElementExpression(expressionObject)) { const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module); + const expressionContext = expressionContextBuilder.buildContext(this.viewModel); const result = this.expressionExecutor.compile(expressionObject, expressionContext); expressionObject.result = this.convertBooleanTypeExpressionResult(expressionObject, result); if (expressionObject.id) { @@ -53,7 +49,7 @@ export class EntityStoreValueChangeHandler extends AbstractChangeHandler { } const option: EffectOption = { message: expressionObject.message, messageType: expressionObject.messageType }; const { entityPaths: changePaths } = this.resolveChangePath(change); - const { entityPaths: expressionPaths, propertyPaths: expressionPropertyPaths } = this.entityPathResolver.resolve(expressionObject.path); + const { entityPaths: expressionPaths, propertyPaths: expressionPropertyPaths } = this.resolvePath(expressionObject.path); const valueChange = change.detail as ChangeValueChange; // 根据表达式绑定的字段、变更的路径进行处理 if (isEqual(changePaths, expressionPaths) || changePaths.length === expressionPaths.length + 1) { @@ -96,8 +92,7 @@ export class EntityStoreValueChangeHandler extends AbstractChangeHandler { } return paths; }, []); - const entityStores = this.module.getEntityStores(); - const entityStore = entityStores.at(0); + const entityStore = this.viewModel.entityStore; const expressionEntityPath = expressionPaths[changePaths.length]; basePaths.push(expressionEntityPath); const childrenEntities = entityStore?.getEntityListByPath(`/${basePaths.join('/')}`); @@ -131,8 +126,7 @@ export class EntityStoreValueChangeHandler extends AbstractChangeHandler { } private executeExpression(expressionObject: ExpressionObject, currentRows?: { bindingPath: string, primaryValue: string; }[]) { const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module, currentRows); + const expressionContext = expressionContextBuilder.buildContext(this.viewModel, currentRows); return this.expressionExecutor.compile(expressionObject, expressionContext); } private filter(change: Change, expressionObjects: ExpressionObject[]) { @@ -152,6 +146,6 @@ export class EntityStoreValueChangeHandler extends AbstractChangeHandler { private resolveChangePath(change: Change) { const appendEntityChange = change.detail as RemoveEntityChange; const changePath = appendEntityChange.path.toShortPath(); - return this.entityPathResolver.resolve(changePath); + return this.resolvePath(changePath); } } diff --git a/packages/devkit/lib/change-handler/expression-context-builder.ts b/packages/devkit/lib/change-handler/expression-context-builder.ts index 160eed6c32a..d5352005839 100644 --- a/packages/devkit/lib/change-handler/expression-context-builder.ts +++ b/packages/devkit/lib/change-handler/expression-context-builder.ts @@ -1,6 +1,5 @@ -import { Entity, EntityListFieldSchema, EntitySchema, EntityState, EntityStore, FieldSchema, FieldType } from "../store"; +import { Entity, EntityListFieldSchema, EntitySchema, EntityState, EntityStore, FieldType } from "../store"; import BigNumber from "bignumber.js"; -import { Module } from "../module"; import { ViewModel, ViewModelState } from "../viewmodel"; export class ExpressionContextBuilder { diff --git a/packages/devkit/lib/change-handler/providers.ts b/packages/devkit/lib/change-handler/providers.ts index 587a781dd52..8dc07eb7afb 100644 --- a/packages/devkit/lib/change-handler/providers.ts +++ b/packages/devkit/lib/change-handler/providers.ts @@ -1,22 +1,22 @@ import { StaticProvider } from "../common"; -import { Module } from '../module'; import { EntityStoreAppendEntityChangeHandler } from "./entity-store-append-entity-change-handler"; import { CHANGE_HANDLERS_TOKEN } from "./tokens"; import { ExpressionExecutor, ExpressionResult } from "../expression"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; import { EntityStoreLoadEntityChangeHandler } from "./entity-store-load-entity-change-handler"; import { EntityStoreRemoveEntityChangeHandler } from './entity-store-remove-entity-change-handler'; import { EntityStoreCurrentChangeHandler } from "./entity-store-current-change-handler"; import { EntityStoreValueChangeHandler } from "./entity-store-value-change-handler"; import { EntityStoreUpdateChangeHandler } from "./entity-store-update-change-handler"; import { StateStoreValueChangeHandler } from "./state-store-value-change-handler"; +import { ViewModel } from "../viewmodel"; +import { EffectorFactory } from "../effector"; export const changeHandlerProviders: StaticProvider[] = [ - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreAppendEntityChangeHandler, deps: [ExpressionExecutor, EntityPathResolver, ExpressionResult, EntityResolver, Module], multi: true }, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreLoadEntityChangeHandler, deps: [ExpressionExecutor, EntityPathResolver, ExpressionResult, EntityResolver, Module], multi: true }, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreRemoveEntityChangeHandler, deps: [ExpressionExecutor, EntityPathResolver, ExpressionResult, EntityResolver, Module], multi: true }, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreCurrentChangeHandler, deps: [ExpressionExecutor, EntityPathResolver, ExpressionResult, EntityResolver, Module], multi: true }, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreValueChangeHandler, deps: [ExpressionExecutor, EntityPathResolver, ExpressionResult, EntityResolver, Module], multi: true}, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreUpdateChangeHandler, deps: [ExpressionExecutor, EntityPathResolver, ExpressionResult, EntityResolver, Module], multi: true}, - { provide: CHANGE_HANDLERS_TOKEN, useClass: StateStoreValueChangeHandler, deps: [ExpressionExecutor, EntityPathResolver, ExpressionResult, EntityResolver, Module], multi: true} + { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreAppendEntityChangeHandler, deps: [ViewModel, ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, + { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreLoadEntityChangeHandler, deps: [ViewModel, ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, + { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreRemoveEntityChangeHandler, deps: [ViewModel, ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, + { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreCurrentChangeHandler, deps: [ViewModel, ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, + { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreValueChangeHandler, deps: [ViewModel, ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, + { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreUpdateChangeHandler, deps: [ViewModel, ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, + { provide: CHANGE_HANDLERS_TOKEN, useClass: StateStoreValueChangeHandler, deps: [ViewModel, ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true } ]; diff --git a/packages/devkit/lib/change-handler/state-store-value-change-handler.ts b/packages/devkit/lib/change-handler/state-store-value-change-handler.ts index 773b12df38d..8d0f9e3448e 100644 --- a/packages/devkit/lib/change-handler/state-store-value-change-handler.ts +++ b/packages/devkit/lib/change-handler/state-store-value-change-handler.ts @@ -1,23 +1,20 @@ -import { Entity, EntityList, EntityState, EntityStore, UIStateChangeType, UIStateValueChange } from "../store"; -import { Module } from '../module'; +import { Entity, EntityState, EntityStore, UIStateChangeType, UIStateValueChange } from "../store"; import { Change, ChangeSource } from "../change-observer"; import { ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; import { DEPENDENCY_SPLITER, STATE_TEMPLATE } from "../expression-dependency-resolver"; import { AbstractChangeHandler } from "./abstract-change-handler"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; import { ExpressionContextBuilder } from "./expression-context-builder"; import { EffectOption, EffectorFactory } from "../effector"; +import { ViewModel, ViewModelState } from "../viewmodel"; export class StateStoreValueChangeHandler extends AbstractChangeHandler { constructor( - public expressionExecutor: ExpressionExecutor, - private entityPathResolver: EntityPathResolver, + protected viewModel: ViewModel, + protected expressionExecutor: ExpressionExecutor, private expressionResult: ExpressionResult, - private entityResolver: EntityResolver, - private module: Module, protected effectorFactory: EffectorFactory ) { - super(expressionExecutor, effectorFactory); + super(viewModel, expressionExecutor, effectorFactory); } handle(change: Change, expressionObjects: ExpressionObject[]): void { if (!(change.source === ChangeSource.UIState && change.type === UIStateChangeType.ValueChange)) { @@ -29,8 +26,7 @@ export class StateStoreValueChangeHandler extends AbstractChangeHandler { } matches.forEach((expressionObject: ExpressionObject) => { const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module); + const expressionContext = expressionContextBuilder.buildContext(this.viewModel); const result = this.expressionExecutor.compile(expressionObject, expressionContext); if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { return; @@ -59,11 +55,9 @@ export class StateStoreValueChangeHandler extends AbstractChangeHandler { return; } // 目前仅支持实体表达式,没有变量表达式 - const { entityPaths: expressionPaths, propertyPaths: expressionPropertyPaths } = this.entityPathResolver.resolve(expressionObject.path); - const entityStores = this.module.getEntityStores(); - const entityStore = entityStores[0]; - const entities = entityStore.getEntities(); - const paths = this.buildPaths(entityStore, entities); + const { entityPaths: expressionPaths, propertyPaths: expressionPropertyPaths } = this.resolvePath(expressionObject.path); + const entities = this.viewModel.entityStore.getEntities(); + const paths = this.buildPaths(this.viewModel.entityStore, entities); // 仅处理计算、校验表达式 paths.forEach((path: string) => { const fullPath = path + '/' + expressionPropertyPaths.join(DEPENDENCY_SPLITER); diff --git a/packages/devkit/lib/index.ts b/packages/devkit/lib/index.ts index 60d16c496e9..d21f7ddc2b9 100644 --- a/packages/devkit/lib/index.ts +++ b/packages/devkit/lib/index.ts @@ -15,4 +15,5 @@ export * from './context/index'; export * from './change-observer'; export * from './expression-dependency-resolver'; export * from './effector'; +export * from './change-handler'; export * from './expression'; -- Gitee From d9c0891bc8b0c5cf89818862689447f8af5d3599 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Sat, 15 Mar 2025 11:43:49 +0800 Subject: [PATCH 049/153] =?UTF-8?q?chore:=20=E4=BF=AE=E5=A4=8D=E6=89=93?= =?UTF-8?q?=E5=8C=85=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/devkit/lib/module/configs/module-config.ts | 2 +- .../store/entity-store/configs/entity-store-config-builder.ts | 3 ++- packages/devkit/tsconfig.json | 1 + .../lib/expression-engine/expression_engine.ts | 2 -- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/devkit/lib/module/configs/module-config.ts b/packages/devkit/lib/module/configs/module-config.ts index 273505573e3..fcf942ee29b 100644 --- a/packages/devkit/lib/module/configs/module-config.ts +++ b/packages/devkit/lib/module/configs/module-config.ts @@ -23,7 +23,7 @@ interface ModuleConfig { formArrayStores: FormArrayStoreConfig[]; viewModels: ViewModelConfig[]; - expressions: ExpressionConfig[]; + expressions?: ExpressionConfig[]; } export { ModuleConfig }; \ No newline at end of file diff --git a/packages/devkit/lib/store/entity-store/configs/entity-store-config-builder.ts b/packages/devkit/lib/store/entity-store/configs/entity-store-config-builder.ts index d145a8beb2b..910ad853ab7 100644 --- a/packages/devkit/lib/store/entity-store/configs/entity-store-config-builder.ts +++ b/packages/devkit/lib/store/entity-store/configs/entity-store-config-builder.ts @@ -40,7 +40,8 @@ class EntityStoreConfigBuilder { private buildEntityConfig(entityType: Type): EntityConfig { const entityConfig: EntityConfig = { idKey: '', - fields: [] + fields: [], + code: '' // TODO: 支持生成型 }; this.appendPrimitiveFieldConfigs(entityConfig, entityType); diff --git a/packages/devkit/tsconfig.json b/packages/devkit/tsconfig.json index 9217ec5f4b5..c1de19f6e42 100644 --- a/packages/devkit/tsconfig.json +++ b/packages/devkit/tsconfig.json @@ -7,6 +7,7 @@ "strict": false, "jsx": "preserve", "sourceMap": true, + "downlevelIteration": true, "resolveJsonModule": true, "isolatedModules": false, "esModuleInterop": true, diff --git a/packages/expression-engine/lib/expression-engine/expression_engine.ts b/packages/expression-engine/lib/expression-engine/expression_engine.ts index 9a5d9e42e1c..408ef167e72 100644 --- a/packages/expression-engine/lib/expression-engine/expression_engine.ts +++ b/packages/expression-engine/lib/expression-engine/expression_engine.ts @@ -4,8 +4,6 @@ import { Expression } from "../expression/index"; import { AbstractExpressionEngine } from "./abstract_expression_engine"; export class ExpressionEngine extends AbstractExpressionEngine { - protected context: IExpressionContext | undefined; - constructor(context?: IExpressionContext) { super(context); } -- Gitee From 9ac3d0153c454ae31e0dcfa0cd072548acfd8fc7 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Sat, 15 Mar 2025 14:20:11 +0800 Subject: [PATCH 050/153] =?UTF-8?q?chore:=20=E6=9B=BF=E6=8D=A2lodash?= =?UTF-8?q?=E4=B8=BAlodash-es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/command-services/lib/navigation.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/command-services/lib/navigation.service.ts b/packages/command-services/lib/navigation.service.ts index 2782c59558e..a2a2e317bc4 100644 --- a/packages/command-services/lib/navigation.service.ts +++ b/packages/command-services/lib/navigation.service.ts @@ -2,7 +2,7 @@ import { RuntimeFrameworkService } from './rtf.service'; import { QuerystringService } from './querystring.service'; import { ViewModel, Injector, ViewModelState, CommandContext, Command } from '@farris/devkit-vue'; import { AppType } from './types'; -import lodash from 'lodash'; +import { merge } from 'lodash-es'; import { NavigationEventService } from './navigation-event.service'; import { NavigationHistoryService } from './navigation-history.service'; /** @@ -281,7 +281,7 @@ export class NavigationService { if (typeof params !== 'object') { params = JSON.parse(params); } - params = lodash.merge(params, options); + params = merge(params, options); } if (typeof params === 'object') { params = JSON.stringify(params); @@ -301,7 +301,7 @@ export class NavigationService { if (typeof params !== 'object') { params = JSON.parse(params); } - params = lodash.merge(params, options); + params = merge(params, options); } if (typeof params !== 'object') { params = JSON.parse(params); -- Gitee From cf2d3f93eb437030be936a8800a4399586e1b42d Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Sat, 15 Mar 2025 14:38:58 +0800 Subject: [PATCH 051/153] =?UTF-8?q?chore:=20=E5=AE=8C=E6=88=90=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/devkit/lib/expression/expression-engine-proxy.ts | 1 - packages/devkit/lib/viewmodel/viewmodel-creator.ts | 2 ++ packages/devkit/lib/viewmodel/viewmodel-initializer.ts | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/devkit/lib/expression/expression-engine-proxy.ts b/packages/devkit/lib/expression/expression-engine-proxy.ts index 3bc73c3a4d6..8877d04e4fd 100644 --- a/packages/devkit/lib/expression/expression-engine-proxy.ts +++ b/packages/devkit/lib/expression/expression-engine-proxy.ts @@ -1,7 +1,6 @@ import { Injector } from "../common"; import { Change } from "../change-observer"; import { ExpressionEventEmitter } from "./expression-event-emitter"; -import { ExpressionExecutor } from "./expression-executor"; import { ExpressionRegistry } from "./expression-registry"; import { ExpressionDependencyResolverRegistry, ExpressionDependencyResolver } from "../expression-dependency-resolver"; import { ExpressionObject } from "./types"; diff --git a/packages/devkit/lib/viewmodel/viewmodel-creator.ts b/packages/devkit/lib/viewmodel/viewmodel-creator.ts index 0f4e332dfde..62a87cae3f6 100644 --- a/packages/devkit/lib/viewmodel/viewmodel-creator.ts +++ b/packages/devkit/lib/viewmodel/viewmodel-creator.ts @@ -8,6 +8,7 @@ import { ViewModelConfig } from './configs'; import { expressionDependencyResolverProviders } from '../expression-dependency-resolver'; import { expressionProviders } from '../expression'; import { changeObserverProviders } from '../change-observer'; +import { changeHandlerProviders } from '../change-handler'; /** * 获取命令处理器的Providers */ @@ -54,6 +55,7 @@ function getRootViewModelProviders(viewModelConfig: ViewModelConfig): StaticProv ...rootProviders, ...changeObserverProviders, ...expressionDependencyResolverProviders, + ...changeHandlerProviders, ...expressionProviders ]; } diff --git a/packages/devkit/lib/viewmodel/viewmodel-initializer.ts b/packages/devkit/lib/viewmodel/viewmodel-initializer.ts index 5ddf389d467..70bdbe42ded 100644 --- a/packages/devkit/lib/viewmodel/viewmodel-initializer.ts +++ b/packages/devkit/lib/viewmodel/viewmodel-initializer.ts @@ -4,6 +4,7 @@ import { Module } from '../module/index'; import { CommandBus } from '../command/index'; import { ViewModelConfig } from './configs/index'; import { ViewModelState, ViewModel } from './viewmodel'; +import { ExpressionEngineProxy } from '../expression'; /** * 视图模型初始化器 @@ -53,6 +54,7 @@ class ViewModelInitializer { this.initRepository(); this.initCommandBus(); this.initCommandAction(); + this.initExpression(); } /** @@ -207,6 +209,12 @@ class ViewModelInitializer { }); }); } + private initExpression(): void { + const parentViewModel = this.viewModel.getParent(); + if (!parentViewModel) { + this.injector.get(ExpressionEngineProxy, null); + } + } } export { ViewModelInitializer }; -- Gitee From 940fa5dd68ba54277a9856ab7d0abbd79546e244 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Mon, 17 Mar 2025 11:04:38 +0800 Subject: [PATCH 052/153] =?UTF-8?q?chore:=20=E8=B0=83=E6=95=B4=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E6=B3=A8=E5=85=A5=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devkit/lib/change-observer/change-observer-registry.ts | 7 +------ packages/devkit/lib/change-observer/providers.ts | 4 ++-- packages/devkit/lib/expression/expression-engine-proxy.ts | 7 +++---- packages/devkit/lib/expression/expression-event-emitter.ts | 6 ++---- packages/devkit/lib/expression/providers.ts | 6 ++++-- packages/devkit/lib/viewmodel/viewmodel-creator.ts | 7 +++---- 6 files changed, 15 insertions(+), 22 deletions(-) diff --git a/packages/devkit/lib/change-observer/change-observer-registry.ts b/packages/devkit/lib/change-observer/change-observer-registry.ts index e61f418c484..5eef62636d0 100644 --- a/packages/devkit/lib/change-observer/change-observer-registry.ts +++ b/packages/devkit/lib/change-observer/change-observer-registry.ts @@ -1,11 +1,6 @@ -import { Injector } from "../common"; import { ChangeObserver } from "./change-observer"; -import { CHANGE_OBSERVER_TOKEN } from "./tokens"; export class ChangeObserverRegistry { - public observers: ChangeObserver[]; - - constructor(private injector: Injector) { - this.observers = this.injector.get(CHANGE_OBSERVER_TOKEN); + constructor(public observers: ChangeObserver[]) { } } diff --git a/packages/devkit/lib/change-observer/providers.ts b/packages/devkit/lib/change-observer/providers.ts index 2cb5e41bcff..ab7d32e8ada 100644 --- a/packages/devkit/lib/change-observer/providers.ts +++ b/packages/devkit/lib/change-observer/providers.ts @@ -1,4 +1,4 @@ -import { Injector, StaticProvider } from "../common"; +import { StaticProvider } from "../common"; import { StateMachineObserver } from "./state-machine-observer"; import { CHANGE_OBSERVER_TOKEN } from "./tokens"; import { ChangeObserverRegistry } from "./change-observer-registry"; @@ -10,5 +10,5 @@ export const changeObserverProviders: StaticProvider[] = [ { provide: CHANGE_OBSERVER_TOKEN, useClass: StateMachineObserver, deps: [ViewModel], multi: true }, { provide: CHANGE_OBSERVER_TOKEN, useClass: EntityStateChangeObserver, deps: [ViewModel], multi: true }, { provide: CHANGE_OBSERVER_TOKEN, useClass: UIStateChangeObserver, deps: [ViewModel], multi: true }, - { provide: ChangeObserverRegistry, useClass: ChangeObserverRegistry, deps: [Injector] } + { provide: ChangeObserverRegistry, useClass: ChangeObserverRegistry, deps: [CHANGE_OBSERVER_TOKEN] } ]; diff --git a/packages/devkit/lib/expression/expression-engine-proxy.ts b/packages/devkit/lib/expression/expression-engine-proxy.ts index 8877d04e4fd..bd210b5528c 100644 --- a/packages/devkit/lib/expression/expression-engine-proxy.ts +++ b/packages/devkit/lib/expression/expression-engine-proxy.ts @@ -4,11 +4,11 @@ import { ExpressionEventEmitter } from "./expression-event-emitter"; import { ExpressionRegistry } from "./expression-registry"; import { ExpressionDependencyResolverRegistry, ExpressionDependencyResolver } from "../expression-dependency-resolver"; import { ExpressionObject } from "./types"; -import { CHANGE_HANDLERS_TOKEN, ChangeHandler } from "../change-handler"; +import { ChangeHandler } from "../change-handler"; export class ExpressionEngineProxy { constructor( - private injector: Injector, + private changeHandlers: ChangeHandler[], private expressionEventEmitter: ExpressionEventEmitter, private expressionRegistry: ExpressionRegistry, private expressionDependencyResolverRegistry: ExpressionDependencyResolverRegistry, @@ -21,8 +21,7 @@ export class ExpressionEngineProxy { private attachEvent(expressions: ExpressionObject[]) { this.expressionEventEmitter.attach().subscribe((changes: Change[]) => { changes.forEach((change: Change) => { - const changeHandlers = this.injector.get(CHANGE_HANDLERS_TOKEN); - changeHandlers.forEach((handler: ChangeHandler) => { + this.changeHandlers.forEach((handler: ChangeHandler) => { handler.handle(change, expressions); }); }); diff --git a/packages/devkit/lib/expression/expression-event-emitter.ts b/packages/devkit/lib/expression/expression-event-emitter.ts index a30cdf741a8..c987a5800e2 100644 --- a/packages/devkit/lib/expression/expression-event-emitter.ts +++ b/packages/devkit/lib/expression/expression-event-emitter.ts @@ -1,4 +1,3 @@ -import { Injector } from "../common"; import { BehaviorSubject, Observable } from 'rxjs'; import { Change, ChangeObserver, ChangeObserverRegistry } from "../change-observer"; @@ -8,10 +7,9 @@ import { Change, ChangeObserver, ChangeObserverRegistry } from "../change-observ export class ExpressionEventEmitter { private onEvent: BehaviorSubject>> | undefined; private events: Array>; - constructor(private injector: Injector) { - const changeObserverRegistry = this.injector.get(ChangeObserverRegistry); + constructor(private changeObserverRegistry: ChangeObserverRegistry) { this.events = new Array>(); - changeObserverRegistry.observers.forEach((observer: ChangeObserver) => { + this.changeObserverRegistry.observers.forEach((observer: ChangeObserver) => { observer.observe((change: Change) => { if (this.onEvent && this.onEvent.observers.length > 0) { let events: any[] = []; diff --git a/packages/devkit/lib/expression/providers.ts b/packages/devkit/lib/expression/providers.ts index f05d9965ab5..5ebb36bab28 100644 --- a/packages/devkit/lib/expression/providers.ts +++ b/packages/devkit/lib/expression/providers.ts @@ -7,10 +7,12 @@ import { ExpressionDependencyResolverRegistry, ExpressionDependencyResolver } fr import { ExpressionResult } from './expression-result'; import { EXPRESSIONS_TOKEN } from './tokens'; import { ViewModel } from '../viewmodel'; +import { ChangeObserverRegistry } from '../change-observer'; +import { CHANGE_HANDLERS_TOKEN } from '../change-handler'; export const expressionProviders: StaticProvider[] = [ - { provide: ExpressionEventEmitter, useClass: ExpressionEventEmitter, deps: [Injector] }, - { provide: ExpressionEngineProxy, useClass: ExpressionEngineProxy, deps: [Injector, ExpressionEventEmitter, ExpressionRegistry, ExpressionDependencyResolverRegistry, ExpressionDependencyResolver] }, + { provide: ExpressionEventEmitter, useClass: ExpressionEventEmitter, deps: [ChangeObserverRegistry] }, + { provide: ExpressionEngineProxy, useClass: ExpressionEngineProxy, deps: [CHANGE_HANDLERS_TOKEN, ExpressionEventEmitter, ExpressionRegistry, ExpressionDependencyResolverRegistry, ExpressionDependencyResolver] }, { provide: ExpressionExecutor, useClass: ExpressionExecutor, deps: [] }, { provide: ExpressionRegistry, useClass: ExpressionRegistry, deps: [EXPRESSIONS_TOKEN, ViewModel] }, { provide: ExpressionResult, useClass: ExpressionResult, deps: [] } diff --git a/packages/devkit/lib/viewmodel/viewmodel-creator.ts b/packages/devkit/lib/viewmodel/viewmodel-creator.ts index 62a87cae3f6..14443965cec 100644 --- a/packages/devkit/lib/viewmodel/viewmodel-creator.ts +++ b/packages/devkit/lib/viewmodel/viewmodel-creator.ts @@ -78,9 +78,6 @@ function getViewModelProviders(viewModelConfig: ViewModelConfig): StaticProvider providers.push({ provide: ViewModel, useClass: ViewModel, deps: [Injector] }); } providers.push({ provide: ViewModelNode, useExisting: ViewModel }); - if (!viewModelConfig.parentId) { - providers.push(...getRootViewModelProviders(viewModelConfig)); - } return providers; } /** @@ -112,7 +109,9 @@ function createViewModel>(module: Module, v const viewModel = viewModelInjector.get(ViewModel); module.registerViewModel(viewModelConfig.id, viewModel); provide(VIEWMODEL_INJECTION_TOKEN, viewModel); - + if (!viewModelConfig.parentId) { + providers.push(...getRootViewModelProviders(viewModelConfig)); + } viewModel.init(viewModelConfig); return viewModel as VM; -- Gitee From 35e4a14e92914fb2ad8fef76064690932c0a214f Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Mon, 17 Mar 2025 15:27:06 +0800 Subject: [PATCH 053/153] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E6=B3=A8=E5=85=A5=E6=96=B9=E5=BC=8F=EF=BC=8C=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E5=AF=BC=E5=87=BA=E9=A1=BA=E5=BA=8F=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E6=9C=AA=E5=88=9D=E5=A7=8B=E5=8C=96=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devkit/lib/change-handler/providers.ts | 20 +++++++++---------- .../devkit/lib/change-observer/providers.ts | 10 +++++----- packages/devkit/lib/common/di/index.ts | 3 ++- .../lib/effector/entity-store-effector.ts | 7 ++++--- packages/devkit/lib/effector/providers.ts | 8 ++++---- .../devkit/lib/effector/validate-effector.ts | 7 ++++--- .../providers.ts | 6 +++--- .../lib/expression/expression-engine-proxy.ts | 5 ++++- .../lib/expression/expression-registry.ts | 2 +- packages/devkit/lib/expression/providers.ts | 6 +++--- packages/devkit/lib/index.ts | 16 +++++++-------- .../devkit/lib/viewmodel/viewmodel-creator.ts | 18 ++++++++++++----- .../lib/viewmodel/viewmodel-initializer.ts | 3 ++- packages/devkit/rollup.config.js | 2 +- 14 files changed, 63 insertions(+), 50 deletions(-) diff --git a/packages/devkit/lib/change-handler/providers.ts b/packages/devkit/lib/change-handler/providers.ts index 8dc07eb7afb..0374c666e69 100644 --- a/packages/devkit/lib/change-handler/providers.ts +++ b/packages/devkit/lib/change-handler/providers.ts @@ -1,4 +1,4 @@ -import { StaticProvider } from "../common"; +import { forwardRef, StaticProvider } from "../common"; import { EntityStoreAppendEntityChangeHandler } from "./entity-store-append-entity-change-handler"; import { CHANGE_HANDLERS_TOKEN } from "./tokens"; import { ExpressionExecutor, ExpressionResult } from "../expression"; @@ -8,15 +8,15 @@ import { EntityStoreCurrentChangeHandler } from "./entity-store-current-change-h import { EntityStoreValueChangeHandler } from "./entity-store-value-change-handler"; import { EntityStoreUpdateChangeHandler } from "./entity-store-update-change-handler"; import { StateStoreValueChangeHandler } from "./state-store-value-change-handler"; -import { ViewModel } from "../viewmodel"; -import { EffectorFactory } from "../effector"; +import { ViewModel } from "../viewmodel/index"; +import { EffectorFactory } from "../effector/index"; export const changeHandlerProviders: StaticProvider[] = [ - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreAppendEntityChangeHandler, deps: [ViewModel, ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreLoadEntityChangeHandler, deps: [ViewModel, ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreRemoveEntityChangeHandler, deps: [ViewModel, ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreCurrentChangeHandler, deps: [ViewModel, ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreValueChangeHandler, deps: [ViewModel, ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreUpdateChangeHandler, deps: [ViewModel, ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, - { provide: CHANGE_HANDLERS_TOKEN, useClass: StateStoreValueChangeHandler, deps: [ViewModel, ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true } + { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreAppendEntityChangeHandler, deps: [forwardRef(() => ViewModel), ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, + { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreLoadEntityChangeHandler, deps: [forwardRef(() => ViewModel), ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, + { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreRemoveEntityChangeHandler, deps: [forwardRef(() => ViewModel), ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, + { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreCurrentChangeHandler, deps: [forwardRef(() => ViewModel), ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, + { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreValueChangeHandler, deps: [forwardRef(() => ViewModel), ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, + { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreUpdateChangeHandler, deps: [forwardRef(() => ViewModel), ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true }, + { provide: CHANGE_HANDLERS_TOKEN, useClass: StateStoreValueChangeHandler, deps: [forwardRef(() => ViewModel), ExpressionExecutor, ExpressionResult, EffectorFactory], multi: true } ]; diff --git a/packages/devkit/lib/change-observer/providers.ts b/packages/devkit/lib/change-observer/providers.ts index ab7d32e8ada..791639c4022 100644 --- a/packages/devkit/lib/change-observer/providers.ts +++ b/packages/devkit/lib/change-observer/providers.ts @@ -1,14 +1,14 @@ -import { StaticProvider } from "../common"; +import { forwardRef, StaticProvider } from "../common"; import { StateMachineObserver } from "./state-machine-observer"; import { CHANGE_OBSERVER_TOKEN } from "./tokens"; import { ChangeObserverRegistry } from "./change-observer-registry"; import { EntityStateChangeObserver } from "./entity-state-change-observer"; import { UIStateChangeObserver } from "./ui-state-change-observer"; -import { ViewModel } from "../viewmodel"; +import { ViewModel } from "../viewmodel/index"; export const changeObserverProviders: StaticProvider[] = [ - { provide: CHANGE_OBSERVER_TOKEN, useClass: StateMachineObserver, deps: [ViewModel], multi: true }, - { provide: CHANGE_OBSERVER_TOKEN, useClass: EntityStateChangeObserver, deps: [ViewModel], multi: true }, - { provide: CHANGE_OBSERVER_TOKEN, useClass: UIStateChangeObserver, deps: [ViewModel], multi: true }, + { provide: CHANGE_OBSERVER_TOKEN, useClass: StateMachineObserver, deps: [forwardRef(() => ViewModel)], multi: true }, + { provide: CHANGE_OBSERVER_TOKEN, useClass: EntityStateChangeObserver, deps: [forwardRef(() => ViewModel)], multi: true }, + { provide: CHANGE_OBSERVER_TOKEN, useClass: UIStateChangeObserver, deps: [forwardRef(() => ViewModel)], multi: true }, { provide: ChangeObserverRegistry, useClass: ChangeObserverRegistry, deps: [CHANGE_OBSERVER_TOKEN] } ]; diff --git a/packages/devkit/lib/common/di/index.ts b/packages/devkit/lib/common/di/index.ts index 7d5d2bb95cb..c61e4c6fa41 100644 --- a/packages/devkit/lib/common/di/index.ts +++ b/packages/devkit/lib/common/di/index.ts @@ -4,4 +4,5 @@ export * from './providers'; export * from './injector'; export * from './static-injector'; export * from './injector'; -export * from './injector-creator'; \ No newline at end of file +export * from './injector-creator'; +export * from './forward-ref'; \ No newline at end of file diff --git a/packages/devkit/lib/effector/entity-store-effector.ts b/packages/devkit/lib/effector/entity-store-effector.ts index ca0348f1756..84f77dfebc1 100644 --- a/packages/devkit/lib/effector/entity-store-effector.ts +++ b/packages/devkit/lib/effector/entity-store-effector.ts @@ -1,10 +1,11 @@ -import { ViewModel, ViewModelState } from "../viewmodel"; +import { ViewModel, ViewModelState } from "../viewmodel/index"; import { ExpressionBindingType, ExpressionObject, ExpressionType } from "../expression"; import { EffectOption, Effector } from "./types"; export class EntityStoreEffector implements Effector { - constructor(public namespace: string, private viewModel: ViewModel) { - this.namespace = namespace; + public namespace: string; + constructor(/*public namespace: string, */private viewModel: ViewModel) { + this.namespace = ''; } public effect(expressionObject: ExpressionObject, value: any, option?: EffectOption) { const { path } = option || {}; diff --git a/packages/devkit/lib/effector/providers.ts b/packages/devkit/lib/effector/providers.ts index ecfa67fc50f..ed4be7187f5 100644 --- a/packages/devkit/lib/effector/providers.ts +++ b/packages/devkit/lib/effector/providers.ts @@ -1,14 +1,14 @@ -import { NAMESPACE_TOKEN, StaticProvider } from "../common"; +import { forwardRef, NAMESPACE_TOKEN, StaticProvider } from "../common"; import { EFFECTORS_TOKEN } from "./tokens"; import { EntityStoreEffector } from "./entity-store-effector"; import { ValidateEffector } from "./validate-effector"; import { EffectorRegistry } from "./effector-registry"; import { EffectorFactory } from "./effector-factory"; -import { ViewModel } from "../viewmodel"; +import { ViewModel } from "../viewmodel/index"; export const effectorProviders: StaticProvider[] = [ - { provide: EFFECTORS_TOKEN, useClass: EntityStoreEffector, deps: [NAMESPACE_TOKEN, ViewModel] }, - { provide: EFFECTORS_TOKEN, useClass: ValidateEffector, deps: [NAMESPACE_TOKEN, ViewModel] }, + { provide: EFFECTORS_TOKEN, useClass: EntityStoreEffector, deps: [/*NAMESPACE_TOKEN,*/ forwardRef(() => ViewModel)] }, + { provide: EFFECTORS_TOKEN, useClass: ValidateEffector, deps: [/*NAMESPACE_TOKEN,*/ forwardRef(() => ViewModel)] }, { provide: EffectorRegistry, useClass: EffectorRegistry, deps: [EFFECTORS_TOKEN] }, { provide: EffectorFactory, useClass: EffectorFactory, deps: [EffectorRegistry] }, ]; diff --git a/packages/devkit/lib/effector/validate-effector.ts b/packages/devkit/lib/effector/validate-effector.ts index c1f7db22388..6b0211d03be 100644 --- a/packages/devkit/lib/effector/validate-effector.ts +++ b/packages/devkit/lib/effector/validate-effector.ts @@ -1,10 +1,11 @@ -import { ViewModel, ViewModelState } from "../viewmodel"; +import { ViewModel, ViewModelState } from "../viewmodel/index"; import { ExpressionBindingType, ExpressionObject, ExpressionType } from "../expression"; import { EffectOption, Effector } from "./types"; export class ValidateEffector implements Effector { - constructor(public namespace: string, private viewModel: ViewModel) { - this.namespace = namespace; + public namespace: string; + constructor(/*public namespace: string,*/ private viewModel: ViewModel) { + this.namespace = ''; } public effect(expressionObject: ExpressionObject, value: boolean, option?: EffectOption) { if (this.namespace !== expressionObject.ns) { diff --git a/packages/devkit/lib/expression-dependency-resolver/providers.ts b/packages/devkit/lib/expression-dependency-resolver/providers.ts index 53800150789..7e21de820d1 100644 --- a/packages/devkit/lib/expression-dependency-resolver/providers.ts +++ b/packages/devkit/lib/expression-dependency-resolver/providers.ts @@ -1,15 +1,15 @@ -import { Injector, StaticProvider } from "../common"; +import { forwardRef, Injector, StaticProvider } from "../common"; import { UIStateExpressionDependencyResolver } from "./ui-state-expression-dependency-resolver"; import { EntityExpressionDependencyResolver } from "./entity-expression-dependency-resolver"; import { CommentExpressionDependencyResolver } from "./comment-expression-dependency-resolver"; import { ExpressionDependencyResolverRegistry } from "./expression-dependency-resolver-registry"; import { RESOLVER_TOKEN } from "./types"; import { ExpressionDependencyResolver } from "./expression-dependency-resolver"; -import { ViewModel } from "../viewmodel"; +import { ViewModel } from "../viewmodel/index"; export const expressionDependencyResolverProviders: StaticProvider[] = [ { provide: RESOLVER_TOKEN, useClass: UIStateExpressionDependencyResolver, deps: [], multi: true }, - { provide: RESOLVER_TOKEN, useClass: EntityExpressionDependencyResolver, deps: [ViewModel], multi: true }, + { provide: RESOLVER_TOKEN, useClass: EntityExpressionDependencyResolver, deps: [forwardRef(() => ViewModel)], multi: true }, { provide: RESOLVER_TOKEN, useClass: CommentExpressionDependencyResolver, deps: [], multi: true }, { provide: ExpressionDependencyResolverRegistry, useClass: ExpressionDependencyResolverRegistry, deps: [Injector] }, { provide: ExpressionDependencyResolver, useClass: ExpressionDependencyResolver, deps: [ExpressionDependencyResolverRegistry] } diff --git a/packages/devkit/lib/expression/expression-engine-proxy.ts b/packages/devkit/lib/expression/expression-engine-proxy.ts index bd210b5528c..de2fd1c17b2 100644 --- a/packages/devkit/lib/expression/expression-engine-proxy.ts +++ b/packages/devkit/lib/expression/expression-engine-proxy.ts @@ -1,4 +1,3 @@ -import { Injector } from "../common"; import { Change } from "../change-observer"; import { ExpressionEventEmitter } from "./expression-event-emitter"; import { ExpressionRegistry } from "./expression-registry"; @@ -20,6 +19,10 @@ export class ExpressionEngineProxy { } private attachEvent(expressions: ExpressionObject[]) { this.expressionEventEmitter.attach().subscribe((changes: Change[]) => { + if (!changes || changes.length < 1) { + return; + } + console.log(changes); changes.forEach((change: Change) => { this.changeHandlers.forEach((handler: ChangeHandler) => { handler.handle(change, expressions); diff --git a/packages/devkit/lib/expression/expression-registry.ts b/packages/devkit/lib/expression/expression-registry.ts index 89ebd2b2469..f9e43a00c2d 100644 --- a/packages/devkit/lib/expression/expression-registry.ts +++ b/packages/devkit/lib/expression/expression-registry.ts @@ -1,4 +1,4 @@ -import { ViewModel, ViewModelState } from "../viewmodel"; +import { ViewModel, ViewModelState } from "../viewmodel/index"; import { DEFAULT_EXPRESSION_VALIDATE_MESSAGE, ExpressionConfig, ExpressionObject, ExpressionRule, ExpressionType } from "./types"; export class ExpressionRegistry { diff --git a/packages/devkit/lib/expression/providers.ts b/packages/devkit/lib/expression/providers.ts index 5ebb36bab28..69da493cfb4 100644 --- a/packages/devkit/lib/expression/providers.ts +++ b/packages/devkit/lib/expression/providers.ts @@ -1,4 +1,4 @@ -import { Injector, StaticProvider } from '../common'; +import { forwardRef, Injector, StaticProvider } from '../common'; import { ExpressionEventEmitter } from './expression-event-emitter'; import { ExpressionEngineProxy } from './expression-engine-proxy'; import { ExpressionExecutor } from './expression-executor'; @@ -11,9 +11,9 @@ import { ChangeObserverRegistry } from '../change-observer'; import { CHANGE_HANDLERS_TOKEN } from '../change-handler'; export const expressionProviders: StaticProvider[] = [ + { provide: ExpressionResult, useClass: ExpressionResult, deps: [] }, { provide: ExpressionEventEmitter, useClass: ExpressionEventEmitter, deps: [ChangeObserverRegistry] }, { provide: ExpressionEngineProxy, useClass: ExpressionEngineProxy, deps: [CHANGE_HANDLERS_TOKEN, ExpressionEventEmitter, ExpressionRegistry, ExpressionDependencyResolverRegistry, ExpressionDependencyResolver] }, { provide: ExpressionExecutor, useClass: ExpressionExecutor, deps: [] }, - { provide: ExpressionRegistry, useClass: ExpressionRegistry, deps: [EXPRESSIONS_TOKEN, ViewModel] }, - { provide: ExpressionResult, useClass: ExpressionResult, deps: [] } + { provide: ExpressionRegistry, useClass: ExpressionRegistry, deps: [EXPRESSIONS_TOKEN, forwardRef(() => ViewModel)] } ]; diff --git a/packages/devkit/lib/index.ts b/packages/devkit/lib/index.ts index d21f7ddc2b9..c738791be0b 100644 --- a/packages/devkit/lib/index.ts +++ b/packages/devkit/lib/index.ts @@ -1,19 +1,17 @@ export * from './common/index'; export * from './condition/index'; export * from './http/index'; - export * from './store/index'; export * from './command/index'; export * from './repository/index'; export * from './variable/index'; +export * from './context/index'; export * from './viewmodel/index'; +export * from './change-observer/index'; +export * from './expression-dependency-resolver/index'; +export * from './effector/index'; +export * from './change-handler/index'; +export * from './expression/index'; export * from './module/index'; -export * from './devkit'; -export * from './context/index'; - -export * from './change-observer'; -export * from './expression-dependency-resolver'; -export * from './effector'; -export * from './change-handler'; -export * from './expression'; +export * from './devkit'; \ No newline at end of file diff --git a/packages/devkit/lib/viewmodel/viewmodel-creator.ts b/packages/devkit/lib/viewmodel/viewmodel-creator.ts index 14443965cec..a7a89480b41 100644 --- a/packages/devkit/lib/viewmodel/viewmodel-creator.ts +++ b/packages/devkit/lib/viewmodel/viewmodel-creator.ts @@ -1,4 +1,4 @@ -import { provide } from 'vue'; +import { effectScope, provide } from 'vue'; import { StaticProvider, Injector, createInjector } from '../common/index'; import { Module } from '../module/index'; import { CommandHandlerConfig, COMMAND_HANDLERS_TOKEN, DynamicCommandHandler, commandBusProviders } from '../command/index'; @@ -6,9 +6,10 @@ import { ViewModelNode } from './viewmodel-node'; import { VIEWMODEL_INJECTION_TOKEN, ViewModelState, ViewModel, } from './viewmodel'; import { ViewModelConfig } from './configs'; import { expressionDependencyResolverProviders } from '../expression-dependency-resolver'; -import { expressionProviders } from '../expression'; +import { ExpressionEngineProxy, expressionProviders } from '../expression'; import { changeObserverProviders } from '../change-observer'; import { changeHandlerProviders } from '../change-handler'; +import { effectorProviders } from '../effector'; /** * 获取命令处理器的Providers */ @@ -56,6 +57,7 @@ function getRootViewModelProviders(viewModelConfig: ViewModelConfig): StaticProv ...changeObserverProviders, ...expressionDependencyResolverProviders, ...changeHandlerProviders, + ...effectorProviders, ...expressionProviders ]; } @@ -78,6 +80,9 @@ function getViewModelProviders(viewModelConfig: ViewModelConfig): StaticProvider providers.push({ provide: ViewModel, useClass: ViewModel, deps: [Injector] }); } providers.push({ provide: ViewModelNode, useExisting: ViewModel }); + if (!viewModelConfig.parentId) { + providers.push(...getRootViewModelProviders(viewModelConfig)); + } return providers; } /** @@ -104,14 +109,17 @@ function createViewModel>(module: Module, v const parentInjector = parentViewModel ? parentViewModel.getInjector() : module.getInjector(); const providers = getViewModelProviders(viewModelConfig); + const viewModelInjector = createInjector(providers, parentInjector); const viewModel = viewModelInjector.get(ViewModel); + // const rootViewModelProviders = getRootViewModelProviders(viewModelConfig); + // const rootViewModelInjector = createInjector(rootViewModelProviders, viewModelInjector); + // const expressionEngineProxy = rootViewModelInjector.get(ExpressionEngineProxy); + // console.log(expressionEngineProxy); module.registerViewModel(viewModelConfig.id, viewModel); provide(VIEWMODEL_INJECTION_TOKEN, viewModel); - if (!viewModelConfig.parentId) { - providers.push(...getRootViewModelProviders(viewModelConfig)); - } + viewModel.init(viewModelConfig); return viewModel as VM; diff --git a/packages/devkit/lib/viewmodel/viewmodel-initializer.ts b/packages/devkit/lib/viewmodel/viewmodel-initializer.ts index 70bdbe42ded..440df05e659 100644 --- a/packages/devkit/lib/viewmodel/viewmodel-initializer.ts +++ b/packages/devkit/lib/viewmodel/viewmodel-initializer.ts @@ -212,7 +212,8 @@ class ViewModelInitializer { private initExpression(): void { const parentViewModel = this.viewModel.getParent(); if (!parentViewModel) { - this.injector.get(ExpressionEngineProxy, null); + const expressionEngineProxy = this.injector.get(ExpressionEngineProxy, null); + console.log(expressionEngineProxy); } } } diff --git a/packages/devkit/rollup.config.js b/packages/devkit/rollup.config.js index f4f5e80a88f..498fe32f67a 100644 --- a/packages/devkit/rollup.config.js +++ b/packages/devkit/rollup.config.js @@ -17,7 +17,7 @@ const packageName = name.split('/')[1]; export default { input: 'lib/index.ts', - external: ["lodash", "vue", "tslib", "vue-router", "axios"], + external: ["lodash", "vue", "tslib", "vue-router", "axios", "lodash-es", "bignumber.js", "rxjs", "@farris/expression-engine-vue", "date-fns"], output: [{ file: `dist-rollup/@farris/devkit-vue.js`, format: 'system', -- Gitee From afabc84a668902610f16ba933c3ba710fc8e78bd Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Mon, 17 Mar 2025 16:25:04 +0800 Subject: [PATCH 054/153] =?UTF-8?q?chore:=20=E5=88=A0=E9=99=A4=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/devkit/lib/viewmodel/viewmodel-creator.ts | 8 +------- packages/devkit/lib/viewmodel/viewmodel-initializer.ts | 3 +-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/devkit/lib/viewmodel/viewmodel-creator.ts b/packages/devkit/lib/viewmodel/viewmodel-creator.ts index a7a89480b41..b576310f797 100644 --- a/packages/devkit/lib/viewmodel/viewmodel-creator.ts +++ b/packages/devkit/lib/viewmodel/viewmodel-creator.ts @@ -6,7 +6,7 @@ import { ViewModelNode } from './viewmodel-node'; import { VIEWMODEL_INJECTION_TOKEN, ViewModelState, ViewModel, } from './viewmodel'; import { ViewModelConfig } from './configs'; import { expressionDependencyResolverProviders } from '../expression-dependency-resolver'; -import { ExpressionEngineProxy, expressionProviders } from '../expression'; +import { expressionProviders } from '../expression'; import { changeObserverProviders } from '../change-observer'; import { changeHandlerProviders } from '../change-handler'; import { effectorProviders } from '../effector'; @@ -109,14 +109,8 @@ function createViewModel>(module: Module, v const parentInjector = parentViewModel ? parentViewModel.getInjector() : module.getInjector(); const providers = getViewModelProviders(viewModelConfig); - const viewModelInjector = createInjector(providers, parentInjector); - const viewModel = viewModelInjector.get(ViewModel); - // const rootViewModelProviders = getRootViewModelProviders(viewModelConfig); - // const rootViewModelInjector = createInjector(rootViewModelProviders, viewModelInjector); - // const expressionEngineProxy = rootViewModelInjector.get(ExpressionEngineProxy); - // console.log(expressionEngineProxy); module.registerViewModel(viewModelConfig.id, viewModel); provide(VIEWMODEL_INJECTION_TOKEN, viewModel); diff --git a/packages/devkit/lib/viewmodel/viewmodel-initializer.ts b/packages/devkit/lib/viewmodel/viewmodel-initializer.ts index 440df05e659..8f6684f9648 100644 --- a/packages/devkit/lib/viewmodel/viewmodel-initializer.ts +++ b/packages/devkit/lib/viewmodel/viewmodel-initializer.ts @@ -212,8 +212,7 @@ class ViewModelInitializer { private initExpression(): void { const parentViewModel = this.viewModel.getParent(); if (!parentViewModel) { - const expressionEngineProxy = this.injector.get(ExpressionEngineProxy, null); - console.log(expressionEngineProxy); + this.injector.get(ExpressionEngineProxy); } } } -- Gitee From 58b8205a59ed4f9d53430db5c8e3cce312ead397 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Mon, 17 Mar 2025 19:40:23 +0800 Subject: [PATCH 055/153] =?UTF-8?q?chore:=20module=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=A0=B9=E8=A7=86=E5=9B=BE=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/devkit/lib/module/module.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/devkit/lib/module/module.ts b/packages/devkit/lib/module/module.ts index 9d7a1f07633..1c9b1018062 100644 --- a/packages/devkit/lib/module/module.ts +++ b/packages/devkit/lib/module/module.ts @@ -133,7 +133,13 @@ class Module { public getViewModels(): ViewModel[] { return Array.from(this.viewModels.values()); } - + /** + * 获取当前module的根视图模型 + * @returns + */ + public getRootViewModel() { + return Array.from(this.viewModels.values()).find((viewModel) => !(viewModel.getParent())); + } /** * 获取实体仓库 */ -- Gitee From 2f3390eba670a0d7a98eaac6842791eb226ce81d Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Mon, 17 Mar 2025 19:41:32 +0800 Subject: [PATCH 056/153] =?UTF-8?q?chore:=20=E7=A7=BB=E5=8A=A8=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E7=9B=B8=E5=85=B3=E7=B1=BB=E5=88=B0=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=99=A8=EF=BC=8C=E7=A7=BB=E9=99=A4=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E5=AF=B9=E5=BA=94=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../change-handler/abstract-change-handler.ts | 66 ------ ...tity-store-append-entity-change-handler.ts | 203 ------------------ .../entity-store-current-change-handler.ts | 112 ---------- ...entity-store-load-entity-change-handler.ts | 123 ----------- ...tity-store-remove-entity-change-handler.ts | 118 ---------- .../entity-store-update-change-handler.ts | 83 ------- .../entity-store-value-change-handler.ts | 156 -------------- .../expression-context-builder.ts | 112 ---------- packages/renderer/src/change-handler/index.ts | 11 - .../renderer/src/change-handler/providers.ts | 21 -- .../state-store-value-change-handler.ts | 117 ---------- .../renderer/src/change-handler/tokens.ts | 4 - packages/renderer/src/change-handler/types.ts | 6 - .../change-observer-registry.ts | 11 - .../src/change-observer/change-observer.ts | 5 - .../entity-state-change-observer.ts | 33 --- .../renderer/src/change-observer/index.ts | 7 - .../renderer/src/change-observer/providers.ts | 13 -- .../change-observer/state-machine-observer.ts | 31 --- .../renderer/src/change-observer/types.ts | 28 --- .../ui-state-change-observer.ts | 36 ---- .../change-resolver/change-resolve-service.ts | 2 +- .../entity-store-change-resolver.ts | 2 +- .../state-machine-change-resolver.ts | 2 +- .../ui-state-change-resolver.ts | 2 +- packages/renderer/src/composition/index.ts | 1 - .../src/composition/use-expression.ts | 6 - .../src/composition/use-form-injector.ts | 44 +--- .../src/composition/use-module-config.ts | 30 ++- packages/renderer/src/debug.vue | 2 +- .../renderer/src/effector/effector-factory.ts | 29 --- .../src/effector/effector-registry.ts | 6 - .../src/effector/entity-store-effector.ts | 26 --- packages/renderer/src/effector/index.ts | 7 - packages/renderer/src/effector/providers.ts | 13 -- packages/renderer/src/effector/tokens.ts | 4 - packages/renderer/src/effector/types.ts | 32 --- .../src/effector/validate-effector.ts | 24 --- .../comment-expression-dependency-resolver.ts | 24 --- .../entity-expression-dependency-resolver.ts | 142 ------------ .../expression-dependency-resolve-service.ts | 38 ---- ...expression-dependency-resolver-registry.ts | 10 - .../expression-dependency-resolver/index.ts | 7 - .../providers.ts | 17 -- .../expression-dependency-resolver/types.ts | 10 - ...ui-state-expression-dependency-resolver.ts | 23 -- .../src/expression/expression-engine-proxy.ts | 44 ---- .../expression/expression-event-emitter.ts | 38 ---- .../src/expression/expression-executor.ts | 51 ----- .../src/expression/expression-registry.ts | 87 -------- .../src/expression/expression-result.ts | 21 -- packages/renderer/src/expression/index.ts | 6 - packages/renderer/src/expression/providers.ts | 17 -- packages/renderer/src/expression/types.ts | 149 ------------- .../renderer/src/form-engine/form-engine.ts | 2 +- .../renderer/src/form-engine/providers.ts | 5 +- packages/renderer/src/preview.vue | 5 +- packages/renderer/src/providers.ts | 5 +- packages/renderer/src/renderer.vue | 2 +- packages/renderer/src/tokens.ts | 2 +- 60 files changed, 44 insertions(+), 2189 deletions(-) delete mode 100644 packages/renderer/src/change-handler/abstract-change-handler.ts delete mode 100644 packages/renderer/src/change-handler/entity-store-append-entity-change-handler.ts delete mode 100644 packages/renderer/src/change-handler/entity-store-current-change-handler.ts delete mode 100644 packages/renderer/src/change-handler/entity-store-load-entity-change-handler.ts delete mode 100644 packages/renderer/src/change-handler/entity-store-remove-entity-change-handler.ts delete mode 100644 packages/renderer/src/change-handler/entity-store-update-change-handler.ts delete mode 100644 packages/renderer/src/change-handler/entity-store-value-change-handler.ts delete mode 100644 packages/renderer/src/change-handler/expression-context-builder.ts delete mode 100644 packages/renderer/src/change-handler/index.ts delete mode 100644 packages/renderer/src/change-handler/providers.ts delete mode 100644 packages/renderer/src/change-handler/state-store-value-change-handler.ts delete mode 100644 packages/renderer/src/change-handler/tokens.ts delete mode 100644 packages/renderer/src/change-handler/types.ts delete mode 100644 packages/renderer/src/change-observer/change-observer-registry.ts delete mode 100644 packages/renderer/src/change-observer/change-observer.ts delete mode 100644 packages/renderer/src/change-observer/entity-state-change-observer.ts delete mode 100644 packages/renderer/src/change-observer/index.ts delete mode 100644 packages/renderer/src/change-observer/providers.ts delete mode 100644 packages/renderer/src/change-observer/state-machine-observer.ts delete mode 100644 packages/renderer/src/change-observer/types.ts delete mode 100644 packages/renderer/src/change-observer/ui-state-change-observer.ts delete mode 100644 packages/renderer/src/composition/use-expression.ts delete mode 100644 packages/renderer/src/effector/effector-factory.ts delete mode 100644 packages/renderer/src/effector/effector-registry.ts delete mode 100644 packages/renderer/src/effector/entity-store-effector.ts delete mode 100644 packages/renderer/src/effector/index.ts delete mode 100644 packages/renderer/src/effector/providers.ts delete mode 100644 packages/renderer/src/effector/tokens.ts delete mode 100644 packages/renderer/src/effector/types.ts delete mode 100644 packages/renderer/src/effector/validate-effector.ts delete mode 100644 packages/renderer/src/expression-dependency-resolver/comment-expression-dependency-resolver.ts delete mode 100644 packages/renderer/src/expression-dependency-resolver/entity-expression-dependency-resolver.ts delete mode 100644 packages/renderer/src/expression-dependency-resolver/expression-dependency-resolve-service.ts delete mode 100644 packages/renderer/src/expression-dependency-resolver/expression-dependency-resolver-registry.ts delete mode 100644 packages/renderer/src/expression-dependency-resolver/index.ts delete mode 100644 packages/renderer/src/expression-dependency-resolver/providers.ts delete mode 100644 packages/renderer/src/expression-dependency-resolver/types.ts delete mode 100644 packages/renderer/src/expression-dependency-resolver/ui-state-expression-dependency-resolver.ts delete mode 100644 packages/renderer/src/expression/expression-engine-proxy.ts delete mode 100644 packages/renderer/src/expression/expression-event-emitter.ts delete mode 100644 packages/renderer/src/expression/expression-executor.ts delete mode 100644 packages/renderer/src/expression/expression-registry.ts delete mode 100644 packages/renderer/src/expression/expression-result.ts delete mode 100644 packages/renderer/src/expression/index.ts delete mode 100644 packages/renderer/src/expression/providers.ts delete mode 100644 packages/renderer/src/expression/types.ts diff --git a/packages/renderer/src/change-handler/abstract-change-handler.ts b/packages/renderer/src/change-handler/abstract-change-handler.ts deleted file mode 100644 index f981e6afbce..00000000000 --- a/packages/renderer/src/change-handler/abstract-change-handler.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { EntityPath } from "@farris/devkit-vue"; -import { Change } from "../change-observer"; -import { ExpressionBindingType, ExpressionExecutor, ExpressionObject, ExpressionType } from "../expression"; -import { ChangeHandler } from "./types"; -import { EffectorFactory } from "../effector"; - -export abstract class AbstractChangeHandler implements ChangeHandler { - constructor(public expressionExecutor: ExpressionExecutor, protected effectorFactory: EffectorFactory) { } - abstract handle(change: Change, expressionObjects: ExpressionObject[]): void; - protected getEffector(expressionObject: ExpressionObject) { - return this.effectorFactory.getEffector(expressionObject); - } - /** - * 是否为字段表达式 - * @param expressionObject - * @returns - */ - public isFieldExpression(expressionObject: ExpressionObject) { - return expressionObject.bindingType === ExpressionBindingType.Field; - } - public isElementExpression(expressionObject: ExpressionObject) { - return expressionObject.bindingType === ExpressionBindingType.Button || expressionObject.bindingType === ExpressionBindingType.Container; - } - - public isStateExpression(expressionObject: ExpressionObject) { - return expressionObject.bindingType === ExpressionBindingType.State; - } - protected isValidateOrRequiredExpression(expressionObject: ExpressionObject) { - return expressionObject && (expressionObject.type === ExpressionType.Validate || expressionObject.type === ExpressionType.Required); - } - protected convertBooleanTypeExpressionResult(expressionObject: ExpressionObject, result: any) { - if (this.isBooleanTypeExpression(expressionObject)) { - return result === true ? true : false; - } else { - return result; - } - } - protected isBooleanTypeExpression(expressionObject: ExpressionObject): boolean { - return this.isReadonlyExpression(expressionObject) || this.isVisibleExpression(expressionObject) || this.isValidateExpression(expressionObject) || this.isRequiredExpression(expressionObject) || - this.isDependencyExpression(expressionObject) || this.isButtonDisabledExpression(expressionObject) || this.isButtonVisibleExpression(expressionObject) || this.isContainerVisibleExpression(expressionObject); - } - private isReadonlyExpression(expressionObject: ExpressionObject): boolean { - return expressionObject && expressionObject.type === ExpressionType.Readonly || false; - } - private isVisibleExpression(expressionObject: ExpressionObject): boolean { - return expressionObject && expressionObject.type === ExpressionType.Visible; - } - private isValidateExpression(expressionObject: ExpressionObject): boolean { - return expressionObject && expressionObject.type === ExpressionType.Validate; - } - private isRequiredExpression(expressionObject: ExpressionObject): boolean { - return expressionObject && expressionObject.type === ExpressionType.Required; - } - private isDependencyExpression(expressionObject: ExpressionObject): boolean { - return expressionObject && expressionObject.type === ExpressionType.Dependency; - } - private isButtonVisibleExpression(expressionObject: ExpressionObject): boolean { - return expressionObject && expressionObject.type === ExpressionType.Visible && expressionObject.bindingType === ExpressionBindingType.Button; - } - private isButtonDisabledExpression(expressionObject: ExpressionObject): boolean { - return expressionObject && expressionObject.type === ExpressionType.Disable && expressionObject.bindingType === ExpressionBindingType.Button; - } - private isContainerVisibleExpression(expressionObject: ExpressionObject): boolean { - return expressionObject && expressionObject.type === ExpressionType.Visible && expressionObject.bindingType === ExpressionBindingType.Container; - } -} diff --git a/packages/renderer/src/change-handler/entity-store-append-entity-change-handler.ts b/packages/renderer/src/change-handler/entity-store-append-entity-change-handler.ts deleted file mode 100644 index b5f3fdf7ed2..00000000000 --- a/packages/renderer/src/change-handler/entity-store-append-entity-change-handler.ts +++ /dev/null @@ -1,203 +0,0 @@ -import { AppendEntityChange, EntityChangeType, Module, ViewModel, ViewModelState } from "@farris/devkit-vue"; -import { Change, ChangeSource } from "../change-observer"; -import { ExpressionBindingType, ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; -import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE, STATE_TEMPLATE } from "../expression-dependency-resolver"; -import { AbstractChangeHandler } from "./abstract-change-handler"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; -import { ExpressionContextBuilder } from "./expression-context-builder"; -import { EffectOption, EffectorFactory } from "../effector"; - -export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler { - constructor( - public expressionExecutor: ExpressionExecutor, - private entityPathResolver: EntityPathResolver, - private expressionResult: ExpressionResult, - private entityResolver: EntityResolver, - private module: Module, - protected effectorFactory: EffectorFactory - ) { - super(expressionExecutor, effectorFactory); - } - handle(change: Change, expressionObjects: ExpressionObject[]): void { - // 仅处理来自实体的新增变更 - if (!(change.source === ChangeSource.EntityState && change.type === EntityChangeType.Append)) { - return; - } - const matches = this.filter(change, expressionObjects); - if (!matches || matches.length < 1) { - return; - } - matches.forEach((expressionObject: ExpressionObject) => { - const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module); - const result = this.expressionExecutor.compile(expressionObject, expressionContext); - if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { - return; - } - expressionObject.result = this.convertBooleanTypeExpressionResult(expressionObject, result); - if (expressionObject.id) { - this.expressionResult.set(expressionObject.id, expressionObject.result); - } - // 界面元素表达式不需要副作用器,变量表达式不支持 - if (this.isElementExpression(expressionObject) || this.isStateExpression(expressionObject)) { - return; - } - // 如果是可见、必填、只读表达式,则路径中不需要拼接数据id,这些表达式只与界面相关。或者说这些表达式只需要依赖表达式结果,不需要副作用器 - if (expressionObject.type === ExpressionType.Visible || expressionObject.type === ExpressionType.Required || expressionObject.type === ExpressionType.Readonly) { - return; - } - this.effect(change, expressionObject, result); - }); - } - private effect(change: Change, expressionObject: ExpressionObject, result: any) { - const effector = this.getEffector(expressionObject); - if (!effector) { - return; - } - // 需要处理校验、聚合类计算表达式 - if (expressionObject.type === ExpressionType.Validate) { - // 校验场景仅处理当前行场景,多条数据场景不处理,再保存时触发校验 - return null; - } - const paths = this.buildEffectPaths(change, expressionObject); - const option: EffectOption = { path: paths, message: expressionObject.message, messageType: expressionObject.messageType }; - effector.effect(expressionObject, result, option); - } - private buildEffectPaths(change: Change, expressionObject: ExpressionObject): string | null { - const { entityPaths: changePaths } = this.resolveChangePath(change); - const { entityPaths: expressionPaths } = this.entityPathResolver.resolve(expressionObject.path); - // 对表达式进行校验,只应出现上级聚合下级的情况 - if (changePaths.length !== expressionPaths.length + 1) { - console.warn(`表达式${expressionObject.id}聚合了自身或下级数据,不支持此类表达式`); - return null; - } - return null; - } - private filter(change: Change, expressionObjects: ExpressionObject[]) { - if (expressionObjects && expressionObjects.length > 0) { - // 找到聚合相关表达式(依赖新增表的表达式),聚合的前提是表达式path位于事件路径的上方 - // 给实体属性或vo变量设置了聚合相关的表达式,此时表达式依赖中路径到子表属性 - // 事件表中表达式(事件表本身的表达式) - return expressionObjects.filter((expressionObject: ExpressionObject) => { - // expressionObject.bindingType !== ExpressionBindingType.Field 暂不支持State表达式 - if (expressionObject.ns !== change.ns) { - return false; - } - if (this.isElementExpression(expressionObject)) { - return this.filterElementExpressions(change, expressionObject); - } - return this.filterGroupExpressions(change, expressionObject) - || this.filterChangeSourceExpressions(change, expressionObject) - || this.filterRelateExpressions(change, expressionObject); - - }); - } - return null; - } - private filterRelateExpressions(change: Change, expressionObject: ExpressionObject) { - if (expressionObject.ns !== change.ns || !expressionObject.deps || expressionObject.deps.length < 1 || (expressionObject.type !== ExpressionType.Visible && expressionObject.type !== ExpressionType.Readonly && expressionObject.type !== ExpressionType.Required && expressionObject.type !== ExpressionType.Validate)) { - return false; - } - // 过滤出所有实体依赖 - const entityDependencies = expressionObject.deps.filter((dep: string) => dep.startsWith(ENTITY_TEMPLATE)); - if (!entityDependencies || entityDependencies.length < 1) { - return false; - } - const { entityPaths: changePaths } = this.resolveChangePath(change); - // 表达式依赖了字段,需要确认依赖的字段所在的表是否是事件表 - // 2、获取依赖字段的表路径 - const index = entityDependencies.findIndex((dependency: string) => { - // 去掉ENTITY~前缀 - const dependencyPath = dependency.split(DEPENDENCY_SPLITER).slice(1).join(DEPENDENCY_SPLITER); - const { entityPaths: dependencyPaths } = this.entityPathResolver.resolve(dependencyPath); - // 获取依赖字段所在的表路径 - return dependencyPaths.join(DEPENDENCY_SPLITER) === changePaths.join(DEPENDENCY_SPLITER); - }); - return index !== -1; - } - private filterGroupExpressions(change: Change, expressionObject: ExpressionObject) { - if (!expressionObject.deps || expressionObject.deps.length < 1) { - return false; - } - const { entityPaths: changePaths } = this.resolveChangePath(change); - const expressionPath = expressionObject.path; - const { entityPaths: expressionPaths } = this.entityPathResolver.resolve(expressionPath); - // 主表新增 - if (changePaths.length === 0 && expressionObject.bindingType === ExpressionBindingType.Field) { - // 认为主表新增时不需要处理聚合函数 - return false; - } - // 仅处理上级表达式 - if (changePaths.length - 1 !== expressionPaths.length) { - return false; - } - // 不支持跨表 - if (!changePaths.join(DEPENDENCY_SPLITER).startsWith(expressionPaths.join(DEPENDENCY_SPLITER))) { - return false; - } - - const index = expressionObject.deps.findIndex((dependency: string) => { - // 依赖 - const fullChangePaths = Array.from(changePaths); - fullChangePaths.splice(0, 0, ENTITY_TEMPLATE); - if (!dependency.startsWith(fullChangePaths.join(DEPENDENCY_SPLITER))) { - return false; - } - const deps = dependency.split(DEPENDENCY_SPLITER).filter((p) => p).slice(1); - const { entityPaths: resolvedDependencyPath } = this.entityPathResolver.resolve(deps); - if (resolvedDependencyPath && resolvedDependencyPath.join(DEPENDENCY_SPLITER) === changePaths.join(DEPENDENCY_SPLITER)) { - return true; - } - return false; - }); - return index === -1 ? false : true; - } - private filterChangeSourceExpressions(change: Change, expressionObject: ExpressionObject) { - // 没有依赖的表达式 - if (!expressionObject.deps || expressionObject.deps.length < 1) { - return true; - } - // 仅依赖State - const onlyDependOnState = expressionObject.deps.every((dependency: string) => dependency.startsWith(STATE_TEMPLATE)); - if (onlyDependOnState) { - return true; - } - const { entityPaths: expressionPaths } = this.entityPathResolver.resolve(expressionObject.path); - const { entityPaths: changePaths } = this.resolveChangePath(change); - // 过滤掉非当前表的表达式 - if (expressionPaths.join(DEPENDENCY_SPLITER) !== changePaths.join(DEPENDENCY_SPLITER)) { - return false; - } - // TODO: 需支持树分层加载场景 - // 表达式是计算或依赖表达式不计算,仅当依赖变化时计算 - if (expressionObject.type === ExpressionType.Compute || expressionObject.type === ExpressionType.Dependency) { - return false; - } - return true; - } - private filterElementExpressions(change: Change, expressionObject: ExpressionObject) { - if (!this.isElementExpression(expressionObject)) { - return false; - } - // 确认表达式是否依赖了实体 - const dependencies = expressionObject.deps?.filter((dep: string) => dep.startsWith(ENTITY_TEMPLATE)); - if (!dependencies || dependencies.length < 1) { - return false; - } - const index = dependencies.findIndex((dependency: string) => { - // 去掉ENTITY~前缀 - const dependencyPath = dependency.split('/').slice(1).join('/'); - // 获取路径中的实体信息 - const { entityPaths: resolvedDependencyPath } = this.entityPathResolver.resolve(dependencyPath); - const { entityPaths: changePaths } = this.resolveChangePath(change); - return changePaths.join('/') === resolvedDependencyPath.join('/'); - }); - return index !== -1; - } - private resolveChangePath(change: Change) { - const appendEntityChange = change.detail as AppendEntityChange; - const changePath = appendEntityChange.path.toShortPath(); - return this.entityPathResolver.resolve(changePath); - } -} diff --git a/packages/renderer/src/change-handler/entity-store-current-change-handler.ts b/packages/renderer/src/change-handler/entity-store-current-change-handler.ts deleted file mode 100644 index a7ed549bed9..00000000000 --- a/packages/renderer/src/change-handler/entity-store-current-change-handler.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { ChangeCurrentEntityChange, EntityChangeType, LoadEntityChange, Module } from "@farris/devkit-vue"; -import { isEqual } from 'lodash-es'; -import { Change, ChangeSource } from "../change-observer"; -import { ExpressionBindingType, ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; -import { AbstractChangeHandler } from "./abstract-change-handler"; -import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE } from "../expression-dependency-resolver"; -import { ExpressionContextBuilder } from "./expression-context-builder"; -import { EffectorFactory } from "../effector"; - -export class EntityStoreCurrentChangeHandler extends AbstractChangeHandler { - constructor( - public expressionExecutor: ExpressionExecutor, - private entityPathResolver: EntityPathResolver, - private expressionResult: ExpressionResult, - private entityResolver: EntityResolver, - private module: Module, - protected effectorFactory: EffectorFactory - ) { - super(expressionExecutor, effectorFactory); - } - handle(change: Change, expressionObjects: ExpressionObject[]): void { - // 仅处理来自实体的当前行变更 - if (!(change.source === ChangeSource.EntityState && change.type === EntityChangeType.CurrentChange)) { - return; - } - const matches = this.filter(change, expressionObjects); - if (!matches || matches.length < 1) { - return; - } - - matches.forEach((expressionObject: ExpressionObject) => { - const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module); - const result = this.expressionExecutor.compile(expressionObject, expressionContext); - if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { - return; - } - expressionObject.result = this.convertBooleanTypeExpressionResult(expressionObject, result); - if (expressionObject.id) { - this.expressionResult.set(expressionObject.id, expressionObject.result); - } - if (this.isElementExpression(expressionObject)) { - return; - } - }); - } - /** - * 根据变更过滤表达式 - * @param change 变更 - * @param expressionObjects 表达式集合 - * @returns 过滤后的表达式 - * @description - * 过滤出以下表达式: - * 1、依赖实体的从从表表达式 - * 2、依赖实体的元素表达式 - */ - private filter(change: Change, expressionObjects: ExpressionObject[]) { - return expressionObjects.filter((expressionObject: ExpressionObject) => { - if (expressionObject.ns !== change.ns) { - return false; - } - // 没有依赖的表达式不需要关注 - if (!expressionObject.deps || expressionObject.deps.length < 1) { - return false; - } - // 不依赖实体的表达式不需要关注 - let index = expressionObject.deps.findIndex((dependency) => dependency.startsWith(ENTITY_TEMPLATE)); - if (index === -1) { - return false; - } - if (this.isElementExpression(expressionObject)) { - return this.filterElementExpressions(change, expressionObject); - } - // 行切换时不处理计算、依赖、校验类实体表达式 - if (this.isFieldExpression(expressionObject) && (expressionObject.type === ExpressionType.Compute || expressionObject.type === ExpressionType.Dependency || expressionObject.type === ExpressionType.Validate)) { - return false; - } - const { entityPaths: changePaths } = this.resolveChangePath(change); - const { entityPaths: expressionPaths } = this.entityPathResolver.resolve(expressionObject.path); - // 只关注从表行切换 - if (changePaths.length !== 1) { - return false; - } - // 只关注从从表表达式 - if (expressionPaths.length !== 2) { - return false; - } - // 只关注事件直接下级的表达式,跨表的不需要关注 - if (!expressionPaths.join('/').startsWith(changePaths.join('/'))) { - return false; - } - // 从从表表达式需要依赖上级表 - index = expressionObject.deps.findIndex((dependency) => dependency.startsWith(`${ENTITY_TEMPLATE}/${changePaths[0]}`)); - return index === -1 ? false : true; - }); - } - private filterElementExpressions(change: Change, expressionObject: ExpressionObject) { - const { entityPaths: changePaths } = this.resolveChangePath(change); - const index = expressionObject.deps?.findIndex((dependency: string) => { - const dependencyPaths = dependency.split('/').slice(1); - return isEqual(dependencyPaths, changePaths); - }); - return index !== -1; - } - private resolveChangePath(change: Change) { - const appendEntityChange = change.detail as ChangeCurrentEntityChange; - const changePath = appendEntityChange.path.toShortPath(); - return this.entityPathResolver.resolve(changePath); - } -} diff --git a/packages/renderer/src/change-handler/entity-store-load-entity-change-handler.ts b/packages/renderer/src/change-handler/entity-store-load-entity-change-handler.ts deleted file mode 100644 index cd1b55c3938..00000000000 --- a/packages/renderer/src/change-handler/entity-store-load-entity-change-handler.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { EntityChangeType, LoadEntityChange, Module } from "@farris/devkit-vue"; -import { isEqual } from 'lodash-es'; -import { Change, ChangeSource } from "../change-observer"; -import { ExpressionBindingType, ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; -import { AbstractChangeHandler } from "./abstract-change-handler"; -import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE } from "../expression-dependency-resolver"; -import { ExpressionContextBuilder } from "./expression-context-builder"; -import { EffectorFactory } from "../effector"; - -export class EntityStoreLoadEntityChangeHandler extends AbstractChangeHandler { - constructor( - public expressionExecutor: ExpressionExecutor, - private entityPathResolver: EntityPathResolver, - private expressionResult: ExpressionResult, - private entityResolver: EntityResolver, - private module: Module, - protected effectorFactory: EffectorFactory - ) { - super(expressionExecutor, effectorFactory); - } - handle(change: Change, expressionObjects: ExpressionObject[]): void { - if (!(change.source === ChangeSource.EntityState && change.type === EntityChangeType.Load)) { - return; - } - const matches = this.filter(change, expressionObjects); - if (!matches || matches.length < 1) { - return; - } - matches.forEach((expressionObject: ExpressionObject) => { - const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module); - const result = this.expressionExecutor.compile(expressionObject, expressionContext); - if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { - return; - } - expressionObject.result = this.convertBooleanTypeExpressionResult(expressionObject, result); - if (expressionObject.id) { - this.expressionResult.set(expressionObject.id, expressionObject.result); - } - // 界面元素表达式不需要使用副作用器 - if (this.isElementExpression(expressionObject)) { - return; - } - // 不需要副作用器参与 - }); - } - private filter(change: Change, expressionObjects: ExpressionObject[]) { - // 数据加载完成后需要计算当前绑定路径下的只读、显隐、必填、校验表达式 - if (!expressionObjects || expressionObjects.length < 1) { - return null; - } - return expressionObjects.filter((expressionObject: ExpressionObject) => { - // 重新加载实体时不计算计算、校验表达式,只处理只读、必填、可见表达式 - if (expressionObject.ns !== change.ns || (expressionObject.type !== ExpressionType.Readonly && expressionObject.type !== ExpressionType.Visible && expressionObject.type !== ExpressionType.Required)) { - return false; - } - // 计算事件表路径 - const { entityPaths: changePaths } = this.resolveChangePath(change); - // const changePath = changePaths.join(DEPENDENCY_SPLITER); - if (this.isElementExpression(expressionObject)) { - // 是否是匹配变更的元素表达式 - return this.filterElementExpression(change, expressionObject); - } - const { entityPaths: expressionPaths } = this.entityPathResolver.resolve(expressionObject.path); - // 影响一个表达式是否要计算的因子有两个:表达式作用的字段、表达式的依赖 - // 以下判断的前提时数据加载场景!! - // 1、表达式作用的字段 - // 如果加载的数据对应的表就是表达式字段所在的表,应该计算 - // 2、表达式依赖 - // 如果表达式依赖的字段加载了,应该计算 - // 如果表达式没有任何依赖,应该计算 - if (isEqual(expressionPaths, changePaths)) { - return true; - } - // 如果没有依赖则应该计算,保证只读、必填、显隐、校验表达式结果正确 - if (!expressionObject.deps || expressionObject.deps.length === 0) { - return true; - } - - // 过滤出所有实体依赖 - const deps = expressionObject.deps.filter((dep: string) => dep.startsWith(ENTITY_TEMPLATE)); - // 未依赖实体,只依赖了uistate,那么绑定数据加载时不需要计算 - if (!deps || deps.length < 1) { - return false; - } - // 表达式依赖了字段,需要确认依赖的字段所在的表是否是事件表 - // 获取依赖字段的表路径 - const index = deps.findIndex((dep: string) => { - // 去掉ENTITY~前缀 - const dependencyPath = dep.split('/').slice(1); - // 获取依赖字段所在的表路径 - const { entityPaths: dependencyPaths } = this.entityPathResolver.resolve(dependencyPath); - return isEqual(dependencyPaths, changePaths); - }); - return index !== -1; - }); - } - private filterElementExpression(change: Change, expressionObject: ExpressionObject) { - const { entityPaths: changePaths } = this.resolveChangePath(change); - const changePath = changePaths.join(DEPENDENCY_SPLITER); - // 过滤出所有实体依赖 - const deps = expressionObject.deps?.filter((dep: string) => dep.startsWith(ENTITY_TEMPLATE)); - // 未依赖实体,只依赖了uistate,那么绑定数据加载时不需要计算 - if (!deps || deps.length < 1) { - return false; - } - const index = deps.findIndex((dep: string) => { - // 去掉ENTITY~前缀 - const depPath = dep.split('/').slice(1).join('/'); - // 获取依赖字段所在的表路径 - const { entityPaths: dependencyPaths } = this.entityPathResolver.resolve(depPath); - return dependencyPaths.join(DEPENDENCY_SPLITER) === changePath; - }); - return index !== -1; - } - private resolveChangePath(change: Change) { - const appendEntityChange = change.detail as LoadEntityChange; - const changePath = appendEntityChange.path.toShortPath(); - return this.entityPathResolver.resolve(changePath); - } -} diff --git a/packages/renderer/src/change-handler/entity-store-remove-entity-change-handler.ts b/packages/renderer/src/change-handler/entity-store-remove-entity-change-handler.ts deleted file mode 100644 index a029d057d19..00000000000 --- a/packages/renderer/src/change-handler/entity-store-remove-entity-change-handler.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { AppendEntityChange, EntityChangeType, Module, RemoveEntityChange, ViewModel, ViewModelState } from "@farris/devkit-vue"; -import { Change, ChangeSource } from "../change-observer"; -import { ExpressionBindingType, ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; -import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE, STATE_TEMPLATE } from "../expression-dependency-resolver"; -import { AbstractChangeHandler } from "./abstract-change-handler"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; -import { ExpressionContextBuilder } from "./expression-context-builder"; -import { isEqual } from "lodash-es"; -import { EffectOption, EffectorFactory } from "../effector"; - -export class EntityStoreRemoveEntityChangeHandler extends AbstractChangeHandler { - constructor( - public expressionExecutor: ExpressionExecutor, - private entityPathResolver: EntityPathResolver, - private expressionResult: ExpressionResult, - private entityResolver: EntityResolver, - private module: Module, - protected effectorFactory: EffectorFactory - ) { - super(expressionExecutor, effectorFactory); - } - handle(change: Change, expressionObjects: ExpressionObject[]): void { - if (!(change.source === ChangeSource.EntityState && change.type === EntityChangeType.Remove)) { - return; - } - if (!expressionObjects || expressionObjects.length < 1) { - return; - } - const matches = this.filter(change, expressionObjects); - if (!matches || matches.length < 1) { - return; - } - matches.forEach((expressionObject: ExpressionObject) => { - const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module); - const result = this.expressionExecutor.compile(expressionObject, expressionContext); - if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { - return; - } - expressionObject.result = this.convertBooleanTypeExpressionResult(expressionObject, result); - if (expressionObject.id) { - this.expressionResult.set(expressionObject.id, expressionObject.result); - } - if (this.isElementExpression(expressionObject)) { - return; - } - this.effect(change, expressionObject, result); - }); - } - private effect(change: Change, expressionObject: ExpressionObject, result: any) { - const effector = this.getEffector(expressionObject); - if (!effector) { - return; - } - const option: EffectOption = { message: expressionObject.message, messageType: expressionObject.messageType }; - effector.effect(expressionObject, result, option); - } - private filter(change: Change, expressionObjects: ExpressionObject[]) { - if (!expressionObjects || expressionObjects.length < 1) { - return null; - } - // 找到聚合相关表达式 - return expressionObjects.filter((expressionObject: ExpressionObject) => { - if (expressionObject.ns !== change.ns || !expressionObject.deps || expressionObject.deps.length < 1) { - return false; - } - // event.path like [id:xxxx] or [id:xxxx,子表s] - const { entityPaths: changePaths } = this.resolveChangePath(change); - // 主表删除 - if (changePaths.length === 0 && (this.isFieldExpression(expressionObject) || this.isElementExpression(expressionObject))) { - return false; - } - // 从表或从从表删除 - if (this.isElementExpression(expressionObject)) { - return this.filterElementExpression(change, expressionObject); - } - const { entityPaths: expressionPaths } = this.entityPathResolver.resolve(expressionObject.path); - // 仅处理上级表达式 - if (changePaths.length - 1 !== expressionPaths.length) { - return false; - } - // 不支持跨表 - if (!changePaths.join(DEPENDENCY_SPLITER).startsWith(expressionPaths.join(DEPENDENCY_SPLITER))) { - return false; - } - const index = expressionObject.deps.findIndex((dependency: string) => { - const fullChangePaths = Array.from(changePaths); - fullChangePaths.splice(0, 0, ENTITY_TEMPLATE); - if (!dependency.startsWith(fullChangePaths.join(DEPENDENCY_SPLITER))) { - return false; - } - const dependencyPaths = dependency.split(DEPENDENCY_SPLITER).filter((p) => p).slice(1); - return isEqual(dependencyPaths, changePaths); - }); - return index === -1 ? false : true; - }); - } - private filterElementExpression(change: Change, expressionObject: ExpressionObject) { - const { entityPaths: changePaths } = this.resolveChangePath(change); - const index = expressionObject.deps?.findIndex((dependency: string) => { - // 依赖 TODO:依赖不可能以实体路径开始,必须是ENTITY~或STATE~ - const fullChangePaths = Array.from(changePaths); - fullChangePaths.splice(0, 0, ENTITY_TEMPLATE); - if (!dependency.startsWith(fullChangePaths.join(DEPENDENCY_SPLITER))) { - return false; - } - const dependencyPaths = dependency.split(DEPENDENCY_SPLITER).filter((p) => p).slice(1); - return isEqual(dependencyPaths, changePaths); - }); - return index === -1 ? false : true; - } - private resolveChangePath(change: Change) { - const appendEntityChange = change.detail as RemoveEntityChange; - const changePath = appendEntityChange.path.toShortPath(); - return this.entityPathResolver.resolve(changePath); - } -} diff --git a/packages/renderer/src/change-handler/entity-store-update-change-handler.ts b/packages/renderer/src/change-handler/entity-store-update-change-handler.ts deleted file mode 100644 index 86621585e11..00000000000 --- a/packages/renderer/src/change-handler/entity-store-update-change-handler.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { EntityChangeType, Module } from "@farris/devkit-vue"; -import { Change, ChangeSource } from "../change-observer"; -import { ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; -import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE } from "../expression-dependency-resolver"; -import { AbstractChangeHandler } from "./abstract-change-handler"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; -import { ExpressionContextBuilder } from "./expression-context-builder"; -import { EffectOption, EffectorFactory } from "../effector"; - -export class EntityStoreUpdateChangeHandler extends AbstractChangeHandler { - constructor( - public expressionExecutor: ExpressionExecutor, - private entityPathResolver: EntityPathResolver, - private expressionResult: ExpressionResult, - private entityResolver: EntityResolver, - private module: Module, - protected effectorFactory: EffectorFactory - ) { - super(expressionExecutor, effectorFactory); - } - - handle(change: Change, expressionObjects: ExpressionObject[]): void { - if (!(change.source === ChangeSource.EntityState && change.type === EntityChangeType.Update)) { - return; - } - if (!expressionObjects || expressionObjects.length < 1) { - return; - } - const matches = this.filter(change, expressionObjects); - if (!matches || matches.length < 1) { - return; - } - matches.forEach((expressionObject: ExpressionObject) => { - const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module); - const result = this.expressionExecutor.compile(expressionObject, expressionContext); - if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { - return; - } - expressionObject.result = this.convertBooleanTypeExpressionResult(expressionObject, result); - if (expressionObject.id) { - this.expressionResult.set(expressionObject.id, expressionObject.result); - } - if (this.isElementExpression(expressionObject)) { - return; - } - this.effect(change, expressionObject, result); - }); - } - private effect(change: Change, expressionObject: ExpressionObject, result: any) { - const effector = this.getEffector(expressionObject); - if (!effector) { - return; - } - const option: EffectOption = { message: expressionObject.message, messageType: expressionObject.messageType }; - effector.effect(expressionObject, result, option); - } - private filter(change: Change, expressionObjects: ExpressionObject[]) { - return expressionObjects.filter((expressionObject: ExpressionObject) => { - // 重新加载实体时不计算计算表达式,只处理只读、必填等 - if (expressionObject.ns !== change.ns || !expressionObject.deps || expressionObject.deps.length === 0 || expressionObject.type === ExpressionType.Compute || expressionObject.type === ExpressionType.Dependency || expressionObject.type === ExpressionType.DataPicking) { - return false; - } - if (this.isFieldExpression(expressionObject)) { - const { entityPaths: expressionPaths } = this.entityPathResolver.resolve(expressionObject.path); - // 必须是主表表达式 - if (expressionPaths.length !== 0) { - return false; - } - } - const index = expressionObject.deps.findIndex((dependency: string) => { - if (!dependency.startsWith(ENTITY_TEMPLATE)) { - return false; - } - const dependencyPath = dependency.split(DEPENDENCY_SPLITER).filter((p) => p).slice(1).join(DEPENDENCY_SPLITER); - const { entityPaths: dependencyPaths } = this.entityPathResolver.resolve(dependencyPath); - return dependencyPaths.length === 0; - }); - return index === -1 ? false : true; - }); - } -} diff --git a/packages/renderer/src/change-handler/entity-store-value-change-handler.ts b/packages/renderer/src/change-handler/entity-store-value-change-handler.ts deleted file mode 100644 index eb55b171350..00000000000 --- a/packages/renderer/src/change-handler/entity-store-value-change-handler.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { ChangeValueChange, EntityChangeType, EntityPathNode, EntityPathNodeType, Module, RemoveEntityChange } from "@farris/devkit-vue"; -import { Change, ChangeSource } from "../change-observer"; -import { ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; -import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE } from "../expression-dependency-resolver"; -import { AbstractChangeHandler } from "./abstract-change-handler"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; -import { ExpressionContextBuilder } from "./expression-context-builder"; -import { EffectOption, EffectorFactory } from "../effector"; -import { isEqual } from "lodash-es"; - -export class EntityStoreValueChangeHandler extends AbstractChangeHandler { - constructor( - public expressionExecutor: ExpressionExecutor, - private entityPathResolver: EntityPathResolver, - private expressionResult: ExpressionResult, - private entityResolver: EntityResolver, - private module: Module, - protected effectorFactory: EffectorFactory - ) { - super(expressionExecutor, effectorFactory); - } - handle(change: Change, expressionObjects: ExpressionObject[]): void { - if (!(change.source === ChangeSource.EntityState && change.type === EntityChangeType.ValueChange)) { - return; - } - if (!expressionObjects || expressionObjects.length < 1) { - return; - } - const matches = this.filter(change, expressionObjects); - if (!matches || matches.length < 1) { - return; - } - matches.forEach((expressionObject: ExpressionObject) => { - if (this.isElementExpression(expressionObject)) { - const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module); - const result = this.expressionExecutor.compile(expressionObject, expressionContext); - expressionObject.result = this.convertBooleanTypeExpressionResult(expressionObject, result); - if (expressionObject.id) { - this.expressionResult.set(expressionObject.id, expressionObject.result); - } - return; - } - this.effect(change, expressionObject); - }); - } - private effect(change: Change, expressionObject: ExpressionObject) { - const effector = this.getEffector(expressionObject); - if (!effector) { - return; - } - const option: EffectOption = { message: expressionObject.message, messageType: expressionObject.messageType }; - const { entityPaths: changePaths } = this.resolveChangePath(change); - const { entityPaths: expressionPaths, propertyPaths: expressionPropertyPaths } = this.entityPathResolver.resolve(expressionObject.path); - const valueChange = change.detail as ChangeValueChange; - // 根据表达式绑定的字段、变更的路径进行处理 - if (isEqual(changePaths, expressionPaths) || changePaths.length === expressionPaths.length + 1) { - // 1、表达式和变更路径相同,即一个实体的字段值变了,同实体的其他字段的表达式需要重新计算 - // 2、表达式和变更路径不同,表达式绑定的字段在变更路径的上级,即一个实体的字段值变了,上级实体的字段的表达式需要重新计算 - const sliceLength = expressionPaths.length === 0 ? 1 : expressionPaths.length * 2; - const entityPaths = valueChange.path.getNodes().slice(0, sliceLength); - const currentRows: { bindingPath: string, primaryValue: string; }[] = []; - const fullPaths = entityPaths.reduce((paths: string[], node: EntityPathNode) => { - const nodeValue = node.getNodeValue(); - if (node.getNodeType() === EntityPathNodeType.IdValue) { - paths.push(`[${nodeValue}]`); - currentRows.push({ bindingPath: paths.join('/'), primaryValue: nodeValue }); - } else { - paths.push(nodeValue); - } - return paths; - }, []); - fullPaths.push(...expressionPropertyPaths); - const result = this.executeExpression(expressionObject, currentRows); - expressionObject.result = this.convertBooleanTypeExpressionResult(expressionObject, result); - if (expressionObject.id) { - this.expressionResult.set(expressionObject.id, expressionObject.result); - } - option.path = `/${fullPaths.join('/')}`; - effector.effect(expressionObject, expressionObject.result, option); - } else if (changePaths.length === expressionPaths.length - 1) { - // 3、表达式和变更路径不同,表达式绑定的字段在变更路径的下级,即一个实体的字段值变了,下级实体的字段的表达式需要重新计算(下级依赖了上级,如果是计算表达式则需要批量处理) - // [id]/prop or [id]/entitys/[id]/prop or [id]/entitys/[id]/entitys/[id]/prop - const sliceLength = changePaths.length === 0 ? 1 : 2 * changePaths.length + 1; - const entityPaths = valueChange.path.getNodes().slice(0, sliceLength); - const currentRows: { bindingPath: string, primaryValue: string; }[] = []; - const basePaths = entityPaths.reduce((paths: string[], node: EntityPathNode) => { - const nodeValue = node.getNodeValue(); - if (node.getNodeType() === EntityPathNodeType.IdValue) { - paths.push(`[${nodeValue}]`); - currentRows.push({ bindingPath: paths.join('/'), primaryValue: nodeValue }); - } else { - paths.push(nodeValue); - } - return paths; - }, []); - const entityStores = this.module.getEntityStores(); - const entityStore = entityStores.at(0); - const expressionEntityPath = expressionPaths[changePaths.length]; - basePaths.push(expressionEntityPath); - const childrenEntities = entityStore?.getEntityListByPath(`/${basePaths.join('/')}`); - - // 如果下级表没有数据,同时又是计算表达式、依赖表达式,则不需要处理 - if ((!childrenEntities || childrenEntities.getEntities().length < 1) && (expressionObject.type === ExpressionType.Compute || expressionObject.type === ExpressionType.Dependency)) { - return; - } - if (expressionObject.type === ExpressionType.Readonly || expressionObject.type === ExpressionType.Visible || expressionObject.type === ExpressionType.Required) { - // 只读、显隐、必填表达式不需要逐行处理 - const result = this.executeExpression(expressionObject, currentRows); - const convertedResult = this.convertBooleanTypeExpressionResult(expressionObject, result); - expressionObject.result = convertedResult; - if (expressionObject.id) { - this.expressionResult.set(expressionObject.id, expressionObject.result); - } - return; - } - childrenEntities?.getEntities().forEach((entity) => { - const childrenCurrentRows = currentRows.concat({ bindingPath: `/${changePaths.concat(expressionEntityPath).join('/')}`, primaryValue: entity.idValue }); - const result = this.executeExpression(expressionObject, childrenCurrentRows); - const convertedResult = this.convertBooleanTypeExpressionResult(expressionObject, result); - const paths = basePaths.concat(`[${entity.idValue}]`, expressionPropertyPaths); - const path = `/${paths.join(DEPENDENCY_SPLITER)}`; - const option: EffectOption = { path, message: expressionObject.message, messageType: expressionObject.messageType }; - effector.effect(expressionObject, convertedResult, option); - }); - } else { - console.warn('不支持跨两级表的表达式'); - } - } - private executeExpression(expressionObject: ExpressionObject, currentRows?: { bindingPath: string, primaryValue: string; }[]) { - const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module, currentRows); - return this.expressionExecutor.compile(expressionObject, expressionContext); - } - private filter(change: Change, expressionObjects: ExpressionObject[]) { - if (!expressionObjects || expressionObjects.length < 1) { - return null; - } - return expressionObjects.filter((expressionObject: ExpressionObject) => { - const { deps } = expressionObject; - if (!deps || deps.length < 1 || change.ns !== expressionObject.ns) { - return false; - } - const { entityPaths: changePaths } = this.resolveChangePath(change); - changePaths.splice(0, 0, ENTITY_TEMPLATE); - return deps.includes(changePaths.join('/')); - }); - } - private resolveChangePath(change: Change) { - const appendEntityChange = change.detail as RemoveEntityChange; - const changePath = appendEntityChange.path.toShortPath(); - return this.entityPathResolver.resolve(changePath); - } -} diff --git a/packages/renderer/src/change-handler/expression-context-builder.ts b/packages/renderer/src/change-handler/expression-context-builder.ts deleted file mode 100644 index 21119f39e49..00000000000 --- a/packages/renderer/src/change-handler/expression-context-builder.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Entity, EntityState, EntityStore, Module, ViewModel, ViewModelState } from "@farris/devkit-vue"; -import BigNumber from "bignumber.js"; -import { EntityResolver } from "../resolvers"; -import { ResolvedEntity } from "../types"; - -export class ExpressionContextBuilder { - constructor() { } - public buildContext(entityResolver: EntityResolver, entityStore: EntityStore> | null, module: Module, currentRows?: { bindingPath: string, primaryValue: string; }[]) { - const context = []; - const entityContext = this.buildEntityContext(entityResolver, entityStore, currentRows); - context.push(entityContext); - const stateContext = this.buildStateContext(module); - const entityCode = entityResolver.getEntityCode(); - let entity = null; - if (context.length === 1) { - entity = context.pop(); - } else { - entity = context[0]; - if (!entity['__type__']) { - entity['__type__'] = 'Entity'; - } - entity['__items__'] = context; - } - // const runtimeFrameworkContext = ExpressionUtil.buildRuntimeFrameworkContext(this.frameContext.appContext); - return { - // ...runtimeFrameworkContext, - [entityCode]: entity, - ...stateContext, - BigNumber, - CurrentLanguage: 'zh-CHS' - }; - } - private buildStateContext(module: Module) { - const viewModels = module.getViewModels(); - const rootViewModel = viewModels.find((viewModel: ViewModel) => !viewModel.getParent()); - const result: Record = {}; - if (rootViewModel) { - const uiState = rootViewModel.uiStore?.getState(); - if (uiState) { - const propertyNames = Object.getOwnPropertyNames(uiState) || []; - propertyNames.forEach((prop: string) => { - if (prop.match(/^[a-zA-Z0-9_$]+$/g) !== null) { - result[prop] = uiState[prop]; - } - }); - } - } - return result; - } - private buildEntityContext(entityResolver: EntityResolver, entityStore: EntityStore> | null, currentRows?: { bindingPath: string, primaryValue: string; }[]) { - const resolvedEntitys = entityResolver.resolve(); - const childrenEntityPaths = resolvedEntitys.map((resolvedEntity: ResolvedEntity) => resolvedEntity.bindingPaths).filter((paths: string[]) => paths.length > 0); - // 获取当前行 - const row = currentRows && currentRows.find((row) => row.bindingPath === '' || row.bindingPath === '/') || null; - const primaryValue = row && row.primaryValue || entityStore?.getCurrentEntity().idValue; - const entity = entityStore?.getEntityById(primaryValue); - if (!entity) { - return {}; - } - const entityContext = entity.toJSON(); - entityContext['__type__'] = 'Entity'; - // 至少包含一个主表的实体 - if (!childrenEntityPaths || childrenEntityPaths.length < 1) { - return entityContext; - } - childrenEntityPaths.sort((v1, v2) => v1.length - v2.length); - // 找到所有子表 - childrenEntityPaths.forEach((paths: string[]) => { - const bindingList = entityStore?.getEntityListByPath('/'+paths.join('/')); - let currentRowId = bindingList?.getCurrentEntity().idValue; - const propertyName = paths[paths.length - 1]; - // parent 为entity或entitylist或null - const parentNode = paths.slice(0, paths.length - 1).reduce((object: any, path: string) => { - return object && object[path] || null; - }, entityContext); - if (!parentNode) { - return; - } - let node: any = null; - if (!currentRowId) { - // 当前表没有数据 - node = { __items__: [], __type__: 'List' }; - node.length = () => node.__items__.length; - } else { - // 纠正当前行 - if (currentRows && currentRows.length > 0) { - // 是否指定了当前行 - const userAssignCurrentRow = currentRows.find((row) => { - const bindingPaths = row.bindingPath.split('/').filter((p) => p); - return bindingPaths.join('/') === paths.join('/'); - }); - if (userAssignCurrentRow) { - currentRowId = userAssignCurrentRow.primaryValue; - } - } - // 子表当前行 - const row = bindingList?.getEntityById(currentRowId); - // 找到子表当前行的上级 - const list = parentNode[propertyName]; - node = { __items__: [], ...row && row.toJSON() || {}, __type__: 'List' }; - node.length = () => node.__items__.length; - - if (list && Array.isArray(list)) { - node.__items__ = Array.from(list); - } - } - parentNode[propertyName] = node; - }); - return entityContext; - } - -} diff --git a/packages/renderer/src/change-handler/index.ts b/packages/renderer/src/change-handler/index.ts deleted file mode 100644 index dcad0420480..00000000000 --- a/packages/renderer/src/change-handler/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -export * from './types'; -export * from './tokens'; -export * from './providers'; -export * from './abstract-change-handler'; -export * from './entity-store-append-entity-change-handler'; -export * from './entity-store-load-entity-change-handler'; -export * from './entity-store-remove-entity-change-handler'; -export * from './entity-store-current-change-handler'; -export * from './entity-store-value-change-handler'; -export * from './entity-store-update-change-handler'; -export * from './state-store-value-change-handler'; diff --git a/packages/renderer/src/change-handler/providers.ts b/packages/renderer/src/change-handler/providers.ts deleted file mode 100644 index 5e4e871cbde..00000000000 --- a/packages/renderer/src/change-handler/providers.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Module, StaticProvider, ViewModel } from "@farris/devkit-vue"; -import { EntityStoreAppendEntityChangeHandler } from "./entity-store-append-entity-change-handler"; -import { CHANGE_HANDLERS_TOKEN } from "./tokens"; -import { ExpressionExecutor, ExpressionResult } from "../expression"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; -import { EntityStoreLoadEntityChangeHandler } from "./entity-store-load-entity-change-handler"; -import { EntityStoreRemoveEntityChangeHandler } from './entity-store-remove-entity-change-handler'; -import { EntityStoreCurrentChangeHandler } from "./entity-store-current-change-handler"; -import { EntityStoreValueChangeHandler } from "./entity-store-value-change-handler"; -import { EntityStoreUpdateChangeHandler } from "./entity-store-update-change-handler"; -import { StateStoreValueChangeHandler } from "./state-store-value-change-handler"; - -export const changeHandlerProviders: StaticProvider[] = [ - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreAppendEntityChangeHandler, deps: [ExpressionExecutor, EntityPathResolver, ExpressionResult, EntityResolver, Module], multi: true }, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreLoadEntityChangeHandler, deps: [ExpressionExecutor, EntityPathResolver, ExpressionResult, EntityResolver, Module], multi: true }, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreRemoveEntityChangeHandler, deps: [ExpressionExecutor, EntityPathResolver, ExpressionResult, EntityResolver, Module], multi: true }, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreCurrentChangeHandler, deps: [ExpressionExecutor, EntityPathResolver, ExpressionResult, EntityResolver, Module], multi: true }, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreValueChangeHandler, deps: [ExpressionExecutor, EntityPathResolver, ExpressionResult, EntityResolver, Module], multi: true}, - { provide: CHANGE_HANDLERS_TOKEN, useClass: EntityStoreUpdateChangeHandler, deps: [ExpressionExecutor, EntityPathResolver, ExpressionResult, EntityResolver, Module], multi: true}, - { provide: CHANGE_HANDLERS_TOKEN, useClass: StateStoreValueChangeHandler, deps: [ExpressionExecutor, EntityPathResolver, ExpressionResult, EntityResolver, Module], multi: true} -]; diff --git a/packages/renderer/src/change-handler/state-store-value-change-handler.ts b/packages/renderer/src/change-handler/state-store-value-change-handler.ts deleted file mode 100644 index 35cc5c877a8..00000000000 --- a/packages/renderer/src/change-handler/state-store-value-change-handler.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { Entity, EntityList, EntityState, EntityStore, Module, UIStateChangeType, UIStateValueChange } from "@farris/devkit-vue"; -import { Change, ChangeSource } from "../change-observer"; -import { ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; -import { DEPENDENCY_SPLITER, STATE_TEMPLATE } from "../expression-dependency-resolver"; -import { AbstractChangeHandler } from "./abstract-change-handler"; -import { EntityPathResolver, EntityResolver } from "../resolvers"; -import { ExpressionContextBuilder } from "./expression-context-builder"; -import { EffectOption, EffectorFactory } from "../effector"; - -export class StateStoreValueChangeHandler extends AbstractChangeHandler { - constructor( - public expressionExecutor: ExpressionExecutor, - private entityPathResolver: EntityPathResolver, - private expressionResult: ExpressionResult, - private entityResolver: EntityResolver, - private module: Module, - protected effectorFactory: EffectorFactory - ) { - super(expressionExecutor, effectorFactory); - } - handle(change: Change, expressionObjects: ExpressionObject[]): void { - if (!(change.source === ChangeSource.UIState && change.type === UIStateChangeType.ValueChange)) { - return; - } - const matches = this.filter(change, expressionObjects); - if (!matches || matches.length < 1) { - return; - } - matches.forEach((expressionObject: ExpressionObject) => { - const expressionContextBuilder = new ExpressionContextBuilder(); - const entityStores = this.module.getEntityStores(); - const expressionContext = expressionContextBuilder.buildContext(this.entityResolver, entityStores[0], this.module); - const result = this.expressionExecutor.compile(expressionObject, expressionContext); - if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { - return; - } - expressionObject.result = this.convertBooleanTypeExpressionResult(expressionObject, result); - if (expressionObject.id) { - this.expressionResult.set(expressionObject.id, expressionObject.result); - } - if (this.isElementExpression(expressionObject)) { - return; - } - // 可见、只读、必填表达式不需要副作用器 - if (expressionObject.type === ExpressionType.Readonly || expressionObject.type === ExpressionType.Visible || expressionObject.type === ExpressionType.Required) { - return; - } - // 不支持变量表达式 - if (this.isStateExpression(expressionObject)) { - return; - } - this.effect(change, expressionObject); - }); - } - private effect(change: Change, expressionObject: ExpressionObject) { - const effector = this.getEffector(expressionObject); - if (!effector) { - return; - } - // 目前仅支持实体表达式,没有变量表达式 - const { entityPaths: expressionPaths, propertyPaths: expressionPropertyPaths } = this.entityPathResolver.resolve(expressionObject.path); - const entityStores = this.module.getEntityStores(); - const entityStore = entityStores[0]; - const entities = entityStore.getEntities(); - const paths = this.buildPaths(entityStore, entities); - // 仅处理计算、校验表达式 - paths.forEach((path: string) => { - const fullPath = path + '/' + expressionPropertyPaths.join(DEPENDENCY_SPLITER); - const option: EffectOption = { path: fullPath, message: expressionObject.message, messageType: expressionObject.messageType }; - effector.effect(expressionObject, expressionObject.result, option); - }); - } - - private buildPaths(entityStore: EntityStore>, entities: Entity[], paths = []) { - const results: string[] = []; - function traverse(item: Entity, parentPath = '', pathIndex = 0) { - // 如果没有paths或已经处理完所有paths,则只添加id - if (!paths || !paths.length) { - results.push(`${parentPath}/[${item.idValue}]`); - return; - } - const currentPath = paths[pathIndex]; - const currentEntities = entityStore.getEntitiesByPath(`${parentPath}/[${item.idValue}]/${currentPath}`); - // 如果当前item包含paths中指定的key,且该key对应的值是数组 - if (currentEntities && currentEntities.length > 0) { - // 遍历数组中的每个元素 - const path = `${parentPath}/[${item.idValue}]/${currentPath}`; - currentEntities.forEach(subItem => { - traverse(subItem, path, pathIndex + 1); - }); - } else { - // 如果不是数组或没有该key,则直接添加当前路径 - results.push(`${parentPath}/[${item.idValue}]`); - } - } - // 遍历输入数组的每一项 - entities.forEach(item => traverse(item)); - - return results; - } - private filter(change: Change, expressionObjects: ExpressionObject[]) { - if (!expressionObjects || expressionObjects.length < 1) { - return null; - } - const stateChange = change.detail as UIStateValueChange; - return expressionObjects.filter((expressionObject: ExpressionObject) => { - const { deps } = expressionObject; - if (!deps || deps.length < 1 || change.ns !== expressionObject.ns) { - return false; - } - const changePaths = stateChange.path.split('/').filter((path) => path); - changePaths.splice(0, 0, STATE_TEMPLATE); - const eventPath = changePaths.join('/'); - return deps.includes(eventPath); - }); - } -} diff --git a/packages/renderer/src/change-handler/tokens.ts b/packages/renderer/src/change-handler/tokens.ts deleted file mode 100644 index 6f1a7efa550..00000000000 --- a/packages/renderer/src/change-handler/tokens.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { InjectionToken } from "@farris/devkit-vue"; -import { ChangeHandler } from "./types"; - -export const CHANGE_HANDLERS_TOKEN = new InjectionToken('@farris/change-handler'); diff --git a/packages/renderer/src/change-handler/types.ts b/packages/renderer/src/change-handler/types.ts deleted file mode 100644 index 27c73e503d7..00000000000 --- a/packages/renderer/src/change-handler/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Change } from "../change-observer"; -import { ExpressionObject } from "../expression"; - -export interface ChangeHandler { - handle(change: Change, expressionObjects: ExpressionObject[]): void; -} diff --git a/packages/renderer/src/change-observer/change-observer-registry.ts b/packages/renderer/src/change-observer/change-observer-registry.ts deleted file mode 100644 index 44b2964f6eb..00000000000 --- a/packages/renderer/src/change-observer/change-observer-registry.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Injector } from "@farris/devkit-vue"; -import { ChangeObserver } from "./change-observer"; -import { CHANGE_OBSERVER_TOKEN } from "../tokens"; - -export class ChangeObserverRegistry { - public observers: ChangeObserver[]; - - constructor(private injector: Injector) { - this.observers = this.injector.get(CHANGE_OBSERVER_TOKEN); - } -} diff --git a/packages/renderer/src/change-observer/change-observer.ts b/packages/renderer/src/change-observer/change-observer.ts deleted file mode 100644 index ab5e8bdfeed..00000000000 --- a/packages/renderer/src/change-observer/change-observer.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Callable } from "../common"; - -export abstract class ChangeObserver { - public abstract observe(callback: Callable): void; -} diff --git a/packages/renderer/src/change-observer/entity-state-change-observer.ts b/packages/renderer/src/change-observer/entity-state-change-observer.ts deleted file mode 100644 index 9af3198d3bc..00000000000 --- a/packages/renderer/src/change-observer/entity-state-change-observer.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Entity, EntityChange, EntityState, Injector, Module, StateChange } from "@farris/devkit-vue"; -import { Callable } from "../common"; -import { ChangeObserver } from "./change-observer"; -import { Change, ChangeSource } from "./types"; -import { MODULE_CONFIG_ID_TOKEN } from "../tokens"; -import { ENTITY_STORE_SUFFIX } from "../types"; - -export class EntityStateChangeObserver extends ChangeObserver { - constructor(private module: Module, private injector: Injector) { - super(); - } - public observe(callback: Callable): void { - if (!this.module) { - return; - } - const moduleConfigId = this.injector.get(MODULE_CONFIG_ID_TOKEN); - const entityStore = this.module.getEntityStore(`${moduleConfigId}${ENTITY_STORE_SUFFIX}`); - if (!entityStore) { - return; - } - entityStore.watchChange((change: StateChange>) => { - const entityChange = change as EntityChange; - const entityStateChange: Change> = { - // TODO: namespace应与组合表单ns一致 - ns: '', - source: ChangeSource.EntityState, - detail: change, - type: entityChange.type - }; - callback(entityStateChange); - }); - } -} diff --git a/packages/renderer/src/change-observer/index.ts b/packages/renderer/src/change-observer/index.ts deleted file mode 100644 index a0e032cbc32..00000000000 --- a/packages/renderer/src/change-observer/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from './change-observer'; -export * from './state-machine-observer'; -export * from './entity-state-change-observer'; -export * from './ui-state-change-observer'; -export * from './types'; -export * from './change-observer-registry'; -export * from './providers'; diff --git a/packages/renderer/src/change-observer/providers.ts b/packages/renderer/src/change-observer/providers.ts deleted file mode 100644 index 8abebd75ed4..00000000000 --- a/packages/renderer/src/change-observer/providers.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Injector, Module, StaticProvider } from "@farris/devkit-vue"; -import { StateMachineObserver } from "./state-machine-observer"; -import { CHANGE_OBSERVER_TOKEN } from "../tokens"; -import { ChangeObserverRegistry } from "./change-observer-registry"; -import { EntityStateChangeObserver } from "./entity-state-change-observer"; -import { UIStateChangeObserver } from "./ui-state-change-observer"; - -export const changeObserverProviders: StaticProvider[] = [ - { provide: CHANGE_OBSERVER_TOKEN, useClass: StateMachineObserver, deps: [Module], multi: true }, - { provide: CHANGE_OBSERVER_TOKEN, useClass: EntityStateChangeObserver, deps: [Module, Injector], multi: true }, - { provide: CHANGE_OBSERVER_TOKEN, useClass: UIStateChangeObserver, deps: [Module], multi: true }, - { provide: ChangeObserverRegistry, useClass: ChangeObserverRegistry, deps: [Injector] } -]; diff --git a/packages/renderer/src/change-observer/state-machine-observer.ts b/packages/renderer/src/change-observer/state-machine-observer.ts deleted file mode 100644 index 45bd1c1ffc8..00000000000 --- a/packages/renderer/src/change-observer/state-machine-observer.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Module, StateChange, StateMachine, StateMachineState, ViewModel, ViewModelState } from "@farris/devkit-vue"; -import { ChangeObserver } from "./change-observer"; -import { Change, ChangeSource, ChangeType, StateMachineChangeType } from "./types"; -import { Callable } from "../common"; - -export class StateMachineObserver extends ChangeObserver { - - constructor(private module: Module) { - super(); - } - - public observe(callback: Callable) { - if (!this.module) { - return; - } - const stateMachine = this.module.getStateMachines()[0]; - if (!stateMachine) { - return; - } - stateMachine.watchChange((change: StateChange) => { - const stateMachineChange: Change = { - // TODO: namespace应与组合表单ns一致 - ns: '', - source: ChangeSource.StateMachine, - detail: change, - type: StateMachineChangeType.StateMachineChange - }; - callback(stateMachineChange); - }); - } -} diff --git a/packages/renderer/src/change-observer/types.ts b/packages/renderer/src/change-observer/types.ts deleted file mode 100644 index 3b1fbeaebac..00000000000 --- a/packages/renderer/src/change-observer/types.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { EntityChangeType, StateChange, UIStateChangeType } from "@farris/devkit-vue"; - -export enum ChangeSource { - StateMachine = 'StateMachine', - UIState = 'UIState', - EntityState = 'EntityState', - Expression = 'Expression' -} -export enum StateMachineChangeType { - StateMachineChange = 'StateMachineChange' -} -export enum ExpressionResultChangeType { - ExpressionResultChange = 'ExpressionResultChange' -} -export type ChangeType = EntityChangeType | StateMachineChangeType | UIStateChangeType | ExpressionResultChangeType; -export interface Change { - /** - * 命名空间,组合表单场景使用 - */ - ns?: string; - source: ChangeSource; - type?: ChangeType; - detail: StateChange; - /** - * 视图模型id,仅变量变更场景有效 - */ - viewModelId?: string; -} diff --git a/packages/renderer/src/change-observer/ui-state-change-observer.ts b/packages/renderer/src/change-observer/ui-state-change-observer.ts deleted file mode 100644 index f100aa45421..00000000000 --- a/packages/renderer/src/change-observer/ui-state-change-observer.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Module, StateChange, UIState, UIStateChange, ViewModel, ViewModelState } from "@farris/devkit-vue"; -import { Callable } from "../common"; -import { ChangeObserver } from "./change-observer"; -import { Change, ChangeSource } from "./types"; - -export class UIStateChangeObserver extends ChangeObserver { - - constructor(private module: Module) { - super(); - } - - public observe(callback: Callable): void { - if (!this.module) { - return; - } - const viewModels = this.module.getViewModels(); - viewModels.forEach((viewModel: ViewModel) => { - const { uiStore } = viewModel; - if (!uiStore) { - return; - } - uiStore.watchChange((change: StateChange) => { - const stateChange = change as UIStateChange; - const uiStateChange: Change> = { - // TODO: namespace应与组合表单ns一致 - ns: '', - source: ChangeSource.UIState, - detail: change, - viewModelId: viewModel.id, - type: stateChange.type - }; - callback(uiStateChange); - }); - }); - } -} diff --git a/packages/renderer/src/change-resolver/change-resolve-service.ts b/packages/renderer/src/change-resolver/change-resolve-service.ts index 3fabfb4e8de..8838651e8e2 100644 --- a/packages/renderer/src/change-resolver/change-resolve-service.ts +++ b/packages/renderer/src/change-resolver/change-resolve-service.ts @@ -1,4 +1,4 @@ -import { Change } from "../change-observer"; +import { Change } from "@farris/devkit-vue"; import { Config } from "../config"; import { ChangeResolver } from "./change-resolver"; import { ChangeResolverRegistry } from "./change-resolver-registry"; diff --git a/packages/renderer/src/change-resolver/entity-store-change-resolver.ts b/packages/renderer/src/change-resolver/entity-store-change-resolver.ts index 182d731c29a..6091ee1653b 100644 --- a/packages/renderer/src/change-resolver/entity-store-change-resolver.ts +++ b/packages/renderer/src/change-resolver/entity-store-change-resolver.ts @@ -1,6 +1,6 @@ import { Entity, EntityState } from "@farris/devkit-vue"; import { ChangeResolver } from "./change-resolver"; -import { Change, ChangeSource } from "../change-observer"; +import { Change, ChangeSource } from "@farris/devkit-vue"; import { ComponentConfigDependencyRegistry, Config, ConfigDependency, DependencyType } from "../config"; export class EntityStoreChangeResolver extends ChangeResolver> { diff --git a/packages/renderer/src/change-resolver/state-machine-change-resolver.ts b/packages/renderer/src/change-resolver/state-machine-change-resolver.ts index 5df37f6db3d..3cad2d558a4 100644 --- a/packages/renderer/src/change-resolver/state-machine-change-resolver.ts +++ b/packages/renderer/src/change-resolver/state-machine-change-resolver.ts @@ -1,5 +1,5 @@ import { StateMachine, StateMachineState } from "@farris/devkit-vue"; -import { Change, ChangeSource } from "../change-observer"; +import { Change, ChangeSource } from "@farris/devkit-vue"; import { ComponentConfigDependencyRegistry, Config, ConfigDependency, DependencyType } from "../config"; import { ChangeResolver } from "./change-resolver"; diff --git a/packages/renderer/src/change-resolver/ui-state-change-resolver.ts b/packages/renderer/src/change-resolver/ui-state-change-resolver.ts index f33a9167360..e5ffe8de0d3 100644 --- a/packages/renderer/src/change-resolver/ui-state-change-resolver.ts +++ b/packages/renderer/src/change-resolver/ui-state-change-resolver.ts @@ -1,7 +1,7 @@ import { UIState } from "@farris/devkit-vue"; import { ComponentConfigDependencyRegistry, Config, ConfigDependency, DependencyType } from "../config"; import { ChangeResolver } from "./change-resolver"; -import { Change, ChangeSource } from "../change-observer"; +import { Change, ChangeSource } from "@farris/devkit-vue"; export class UIStateChangeResolver extends ChangeResolver { diff --git a/packages/renderer/src/composition/index.ts b/packages/renderer/src/composition/index.ts index a7e808b5d38..bb5ef61216b 100644 --- a/packages/renderer/src/composition/index.ts +++ b/packages/renderer/src/composition/index.ts @@ -23,4 +23,3 @@ export * from './use-module-config'; export * from './use-model-value'; export * from './use-session'; export * from './use-callback-handler-registry'; -export * from './use-expression'; diff --git a/packages/renderer/src/composition/use-expression.ts b/packages/renderer/src/composition/use-expression.ts deleted file mode 100644 index 6afefc75a83..00000000000 --- a/packages/renderer/src/composition/use-expression.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Injector } from "@farris/devkit-vue"; -import { ExpressionEngineProxy } from "../expression/expression-engine-proxy"; - -export function useExpression(injector: Injector) { - const expressionEngine = injector.get(ExpressionEngineProxy); -} diff --git a/packages/renderer/src/composition/use-form-injector.ts b/packages/renderer/src/composition/use-form-injector.ts index 3a89cdff2c7..77ca8f085a5 100644 --- a/packages/renderer/src/composition/use-form-injector.ts +++ b/packages/renderer/src/composition/use-form-injector.ts @@ -1,47 +1,9 @@ import { createInjector, Module, StaticProvider } from "@farris/devkit-vue"; -import { MODULE_CONFIG_ID_TOKEN, FORM_METADATA_TOKEN } from "../tokens"; -import { configProviders } from "../config"; -import { configDependencyResolverProviders } from "../config-dependency-resolver"; -import { componentConfigResolverProviders } from "../component-config-resolver"; -import { componentConfigDependencyResolverProviders } from "../component-config-dependency-resolver"; -import { changeObserverProviders } from "../change-observer"; -import { changeResolverProviders } from "../change-resolver"; -import { renderEngineProviders } from "../render-engine"; -import { formEngineProviders } from "../form-engine"; -import { eventEmitterProviders } from "../common/providers"; -import { serviceProviders } from "../service"; -import { eventHanderProviders } from "../event-handler"; -import { resolverProviders } from "../resolvers"; -import { Ref } from "vue"; -import { callbackHandlerProviders } from "../callback-handler"; -import { expressionDependencyResolverProviders } from '../expression-dependency-resolver'; -import { changeHandlerProviders } from '../change-handler'; -import { expressionProviders } from '../expression'; -export function useFormInjector(metadata: Ref, module: Module, moduleConfigId: string) { - const providers: StaticProvider[] = [ - { provide: FORM_METADATA_TOKEN, useValue: metadata?.value.form.content, deps: [] }, - { provide: MODULE_CONFIG_ID_TOKEN, useValue: moduleConfigId, deps: [] }, - ...configProviders, - ...configDependencyResolverProviders, - ...componentConfigResolverProviders, - ...componentConfigDependencyResolverProviders, - ...changeObserverProviders, - ...changeResolverProviders, - ...renderEngineProviders, - ...formEngineProviders, - ...eventEmitterProviders, - ...serviceProviders, - ...eventHanderProviders, - ...resolverProviders, - ...callbackHandlerProviders, - ...expressionDependencyResolverProviders, - ...changeHandlerProviders, - ...expressionProviders - ]; +export function useFormInjector(module: Module) { const formInjector = createInjector({ - providers, - parent: module.getInjector() + providers: [], + parent: module.getRootViewModel().getInjector() }); return formInjector; } diff --git a/packages/renderer/src/composition/use-module-config.ts b/packages/renderer/src/composition/use-module-config.ts index ed3dd47d04e..31ef6f050c3 100644 --- a/packages/renderer/src/composition/use-module-config.ts +++ b/packages/renderer/src/composition/use-module-config.ts @@ -4,8 +4,19 @@ import { Injector, ModuleConfig, RENDER_ENGINE_TOKEN, StaticProvider } from "@fa import { Ref } from "vue"; import { ModuleConfigBuilder } from "../config-builders"; import { RenderEngineImpl } from "../render-engine"; -import { RENDER_TOKEN } from "../tokens"; -import { effectorProviders } from '../effector'; +import { FORM_METADATA_TOKEN, MODULE_CONFIG_ID_TOKEN, RENDER_TOKEN } from "../tokens"; +import { configProviders } from "../config"; +import { configDependencyResolverProviders } from "../config-dependency-resolver"; +import { componentConfigResolverProviders } from "../component-config-resolver"; +import { componentConfigDependencyResolverProviders } from "../component-config-dependency-resolver"; +import { changeResolverProviders } from "../change-resolver"; +import { renderEngineProviders } from "../render-engine"; +import { formEngineProviders } from "../form-engine"; +import { eventEmitterProviders } from "../common/providers"; +import { serviceProviders } from "../service"; +import { eventHanderProviders } from "../event-handler"; +import { resolverProviders } from "../resolvers"; +import { callbackHandlerProviders } from "../callback-handler"; export function useModuleConfig(metadata: Ref, uiProviders: StaticProvider[], render: Ref): ModuleConfig { const moduleMetaContext: any = { @@ -17,13 +28,26 @@ export function useModuleConfig(metadata: Ref, uiProviders: StaticProvider[], re ...uiProviders, ...commandServiceRootProviders, ...befRootProviders, - ...effectorProviders, + { provide: FORM_METADATA_TOKEN, useValue: metadata?.value.form.content, deps: [] }, + { provide: MODULE_CONFIG_ID_TOKEN, useValue: metadata.value.form.content.module.code, deps: [] }, { provide: RENDER_TOKEN, useValue: render, deps: [] }, { provide: RENDER_ENGINE_TOKEN, useClass: RenderEngineImpl, deps: [Injector] } ], viewModelProviders: [ ...befProviders, ...commandServiceProviders, + ...configProviders, + ...configDependencyResolverProviders, + ...componentConfigResolverProviders, + ...componentConfigDependencyResolverProviders, + ...changeResolverProviders, + ...renderEngineProviders, + ...formEngineProviders, + ...eventEmitterProviders, + ...serviceProviders, + ...eventHanderProviders, + ...resolverProviders, + ...callbackHandlerProviders ], }; const moduleConfigBuilder = new ModuleConfigBuilder(moduleMetaContext); diff --git a/packages/renderer/src/debug.vue b/packages/renderer/src/debug.vue index c759508c807..6b52c195729 100644 --- a/packages/renderer/src/debug.vue +++ b/packages/renderer/src/debug.vue @@ -11,7 +11,7 @@ useMetadataRefine(metadata?.value); const moduleConfig = useModuleConfig(metadata, providers, render); const module = useModuleCreator(metadata, moduleConfig); -const formInjector = useFormInjector(metadata, module, moduleConfig.id); +const formInjector = useFormInjector(module); useSession(formInjector); useEventHandlers(formInjector); useNavigation(formInjector); diff --git a/packages/renderer/src/effector/effector-factory.ts b/packages/renderer/src/effector/effector-factory.ts deleted file mode 100644 index 7f23b407b60..00000000000 --- a/packages/renderer/src/effector/effector-factory.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { ExpressionBindingType, ExpressionObject, ExpressionType } from "../expression"; -import { EffectorRegistry } from "./effector-registry"; -import { Effector } from "./types"; -import { ValidateEffector } from "./validate-effector"; -import { EntityStoreEffector } from "./entity-store-effector"; - -export class EffectorFactory { - constructor(private effectorRegistry: EffectorRegistry) { - } - public getEffector(expressionObject: ExpressionObject) { - const namespace = expressionObject.ns; - const { bindingType, type } = expressionObject; - const nsEffectors = this.effectorRegistry.effectors.filter((effector: Effector) => effector.namespace === namespace); - // 计算表达式 - if (type === ExpressionType.Compute || type === ExpressionType.Dependency) { - if (bindingType === ExpressionBindingType.Field) { - return nsEffectors.find((effector: Effector) => effector instanceof EntityStoreEffector); - } else { - throw new Error(`不支持的绑定字段类型:${bindingType}`); - } - } else if (type === ExpressionType.Validate) { - // 校验表达式 - return nsEffectors.find((effector: Effector) => effector instanceof ValidateEffector); - } else { - console.warn(`EffectorFactory 没有找到对应的副作用器 ${type}`); - return null; - } - } -} diff --git a/packages/renderer/src/effector/effector-registry.ts b/packages/renderer/src/effector/effector-registry.ts deleted file mode 100644 index 99a3758fb1c..00000000000 --- a/packages/renderer/src/effector/effector-registry.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Effector } from "./types"; - -export class EffectorRegistry { - constructor(public effectors: Effector[]) { - } -} diff --git a/packages/renderer/src/effector/entity-store-effector.ts b/packages/renderer/src/effector/entity-store-effector.ts deleted file mode 100644 index a956cbc635b..00000000000 --- a/packages/renderer/src/effector/entity-store-effector.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ViewModel, ViewModelState } from "@farris/devkit-vue"; -import { ExpressionBindingType, ExpressionObject, ExpressionType } from "../expression"; -import { EffectOption, Effector } from "./types"; - -export class EntityStoreEffector implements Effector { - constructor(public namespace: string, private viewModel: ViewModel) { - this.namespace = namespace; - } - public effect(expressionObject: ExpressionObject, value: any, option?: EffectOption) { - const { path } = option || {}; - if (this.namespace !== expressionObject.ns) { - return; - } - // 只处理字段表达式 - if (!expressionObject || expressionObject.bindingType !== ExpressionBindingType.Field) { - return; - } - // 只处理计算表达式和依赖表达式 - if (expressionObject.type !== ExpressionType.Compute && expressionObject.type !== ExpressionType.Dependency) { - return; - } - // 表达式结果可能作用于多条数据或单条数据,作用于多条数据时则应有paths属性,单条数据时默认使用当前行 - const realPath = path ? path : expressionObject.path; - this.viewModel.entityStore?.setValueByPath(realPath, value); - } -} diff --git a/packages/renderer/src/effector/index.ts b/packages/renderer/src/effector/index.ts deleted file mode 100644 index 921db7ad7be..00000000000 --- a/packages/renderer/src/effector/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from './types'; -export * from './tokens'; -export * from './entity-store-effector'; -export * from './validate-effector'; -export * from './effector-registry'; -export * from './effector-factory'; -export * from './providers'; diff --git a/packages/renderer/src/effector/providers.ts b/packages/renderer/src/effector/providers.ts deleted file mode 100644 index 1e3eec12645..00000000000 --- a/packages/renderer/src/effector/providers.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { NAMESPACE_TOKEN, StaticProvider, ViewModel } from "@farris/devkit-vue"; -import { EFFECTORS_TOKEN } from "./tokens"; -import { EntityStoreEffector } from "./entity-store-effector"; -import { ValidateEffector } from "./validate-effector"; -import { EffectorRegistry } from "./effector-registry"; -import { EffectorFactory } from "./effector-factory"; - -export const effectorProviders: StaticProvider[] = [ - { provide: EFFECTORS_TOKEN, useClass: EntityStoreEffector, deps: [NAMESPACE_TOKEN, ViewModel] }, - { provide: EFFECTORS_TOKEN, useClass: ValidateEffector, deps: [NAMESPACE_TOKEN, ViewModel] }, - { provide: EffectorRegistry, useClass: EffectorRegistry, deps: [EFFECTORS_TOKEN] }, - { provide: EffectorFactory, useClass: EffectorFactory, deps: [EffectorRegistry] }, -]; diff --git a/packages/renderer/src/effector/tokens.ts b/packages/renderer/src/effector/tokens.ts deleted file mode 100644 index bc5ac9966a5..00000000000 --- a/packages/renderer/src/effector/tokens.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { InjectionToken } from "@farris/devkit-vue"; -import { Effector } from "./types"; - -export const EFFECTORS_TOKEN = new InjectionToken('@farris/effectors_token'); diff --git a/packages/renderer/src/effector/types.ts b/packages/renderer/src/effector/types.ts deleted file mode 100644 index 4610fb8daa3..00000000000 --- a/packages/renderer/src/effector/types.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { ExpressionObject, ExpressionMessageType } from "../expression"; - -export enum EffectMessageType { - error = 'error', - info = 'info', - warning = 'warning' -} -export interface EffectOption { - /** - * 作用路径 - */ - path?: string | null; - /** - * 消息 - */ - message?: string | null; - /** - * 消息提示类型 - */ - messageType?: ExpressionMessageType | null; -} - -export interface Effector { - /** - * namespace - */ - namespace: string; - /** - * 作用 - */ - effect(expressionObject: ExpressionObject, value: any, option?: EffectOption): void; -} diff --git a/packages/renderer/src/effector/validate-effector.ts b/packages/renderer/src/effector/validate-effector.ts deleted file mode 100644 index a5748c043cc..00000000000 --- a/packages/renderer/src/effector/validate-effector.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ViewModel, ViewModelState } from "@farris/devkit-vue"; -import { ExpressionBindingType, ExpressionObject, ExpressionType } from "../expression"; -import { EffectOption, Effector } from "./types"; - -export class ValidateEffector implements Effector { - constructor(public namespace: string, private viewModel: ViewModel) { - this.namespace = namespace; - } - public effect(expressionObject: ExpressionObject, value: boolean, option?: EffectOption) { - if (this.namespace !== expressionObject.ns) { - return; - } - // 只处理字段表达式 - if (!expressionObject || expressionObject.bindingType !== ExpressionBindingType.Field) { - return; - } - // 只处理验证表达式 - if (expressionObject.type !== ExpressionType.Validate) { - return; - } - const { message, messageType, path: paths } = option || {}; - console.warn(`${expressionObject.path}验证${value ? '通过' : '不通过'},${message}, ${messageType}, ${paths}`); - } -} diff --git a/packages/renderer/src/expression-dependency-resolver/comment-expression-dependency-resolver.ts b/packages/renderer/src/expression-dependency-resolver/comment-expression-dependency-resolver.ts deleted file mode 100644 index 0cb0db86ecc..00000000000 --- a/packages/renderer/src/expression-dependency-resolver/comment-expression-dependency-resolver.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Resolver } from "./types"; - -export class CommentExpressionDependencyResolver implements Resolver { - public resolve(expr: string): string[] { - const dependencies: string[] = []; - if (!expr || expr.length < 1) { - return dependencies; - } - const defineRegex = /\/\*\*\s*__define__\((.*)\)\s*\*\//; - const defineMatchArray: RegExpMatchArray | null = expr.match(defineRegex); - if (defineMatchArray && defineMatchArray.length === 2) { - const defineString: string = defineMatchArray[1].trim(); - let defineObject = null; - try { - defineObject = JSON.parse(defineString); - } catch (e) { console.warn(`自定义依赖解析失败:${defineString}`); } - // eslint-disable-next-line no-prototype-builtins - if (defineObject && defineObject.hasOwnProperty('deps') && Array.isArray(defineObject['deps'])) { - dependencies.push(...defineObject['deps']); - } - } - return dependencies; - } -} diff --git a/packages/renderer/src/expression-dependency-resolver/entity-expression-dependency-resolver.ts b/packages/renderer/src/expression-dependency-resolver/entity-expression-dependency-resolver.ts deleted file mode 100644 index a35e0c01942..00000000000 --- a/packages/renderer/src/expression-dependency-resolver/entity-expression-dependency-resolver.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { EntityPathResolver } from '../resolvers'; -import { FormMetadataService } from '../service'; -import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE, GROUP_FUNCTIONS, Resolver } from './types'; - -export class EntityExpressionDependencyResolver implements Resolver { - constructor(private formMetadataService: FormMetadataService, private entityPathResolver: EntityPathResolver) { - } - /** - * 解析用户表达式中的实体依赖 - * @param expression 用户配置的完整表达式 - * @returns - */ - public resolve(expression: string): string[] { - const groupFunctionDependencies = this.getGroupFunctionDependency(expression); - const entityDependencies = this.getEntityDependency(expression); - // 去除错误的到子表的依赖 - if (groupFunctionDependencies && groupFunctionDependencies.length > 0 && entityDependencies && entityDependencies.length > 0) { - groupFunctionDependencies.forEach((dep: string) => { - const index = entityDependencies.findIndex((item) => dep.startsWith(item)); - if (index !== -1) { - entityDependencies.splice(index, 1); - } - }); - } - // 去重 - const merged = [...groupFunctionDependencies, ...entityDependencies]; - const deps = [...new Set(merged)]; - return deps; - } - /** - * 获取所有实体依赖 - * @param expression 表达式字符串 - * @returns - */ - private getEntityDependency(expression: string): string[] { - const dependencies: string[] = []; - // 使用正则匹配出所有实体 - const entity = this.formMetadataService.getEntity(); - const regex = new RegExp(`[\\'\\"]?\\s*(${entity.code}|${entity.label})[\\.\\[\\]a-zA-Z0-9_]+\\s*[\\'\\"]?`, 'g'); - const entityPropertyExpressions: RegExpMatchArray | null = expression.match(regex); - if (Array.isArray(entityPropertyExpressions) && entityPropertyExpressions.length > 0) { - // 解析出所有实体相关的字符串,以主实体名字开头,包含主实体属性或子表 - entityPropertyExpressions.forEach((item: string) => { - if (item.indexOf('.') === -1) { - return; - } - // 去掉主实体编号 - const fullPaths = item.split('.').slice(1).map((propertyName: string) => propertyName.trim()); - const entityPath = this.getEntityPaths(fullPaths); - if (entityPath && entityPath.length > 0) { - // 此处必须加上主实体的名字来区分依赖的是实体还是其他类型的数据 - entityPath.splice(0, 0, ENTITY_TEMPLATE); - dependencies.push(entityPath.join(DEPENDENCY_SPLITER)); - } - }); - } - return dependencies; - } - private getGroupFunctionDependency(expr: string): string[] { - const deps: string[] = []; - // 获取聚合函数依赖项 - const groupFunctionRegex = new RegExp(`DefaultFunction\\.(${GROUP_FUNCTIONS.join('|')})\\s*\\([^\\r\\n\\)]*\\)`, 'g'); - const groupFunctions: RegExpMatchArray | null = expr.match(groupFunctionRegex); - if (groupFunctions && groupFunctions.length > 0) { - const argumentsRegex = /\(([^\r\n)]*)\)/; - const methodNameRegex = /DefaultFunction\.(\S*)\(/; - groupFunctions.forEach((groupFunction: string) => { - const argumentMatchResult = groupFunction.match(argumentsRegex); - const methodNameMatchResult = groupFunction.match(methodNameRegex); - let methodName = null; - if (methodNameMatchResult && methodNameMatchResult.length === 2) { - methodName = methodNameMatchResult[1]; - } - if (methodName && argumentMatchResult && argumentMatchResult.length === 2) { - const argument = argumentMatchResult[1]; - const args = argument.replace(/[\\"\\']/g, '').split(','); - if (args && args.length === 2) { - const item: any = args.join('.'); - const fullPaths = item.split('.').slice(1).map((propertyName: string) => propertyName.trim()); - const entityPath = this.getEntityPaths(fullPaths); - if (entityPath && entityPath.length > 0) { - entityPath.splice(0, 0, ENTITY_TEMPLATE); - deps.push(entityPath.join(DEPENDENCY_SPLITER)); - } - } else if (args && args.length === 3) { - if (methodName === 'MultiplyChildNumber') { - // support MultiplyChildNumber - // [Entity.childrens,prop1,prop2] - const prefix = args[0]; // like Entity.childrens - const prop1FullPath = `${prefix}.${args[1]}`; - const prop2FullPath = `${prefix}.${args[2]}`; - [prop1FullPath, prop2FullPath].forEach((item) => { - const fullPaths = item.split('.').slice(1).map((propertyName: string) => propertyName.trim()); - const entityPath = this.getEntityPaths(fullPaths); - if (entityPath && entityPath.length > 0) { - entityPath.splice(0, 0, ENTITY_TEMPLATE); - deps.push(entityPath.join(DEPENDENCY_SPLITER)); - } - }); - } else if (methodName === 'IsContainMatch' || methodName === 'SortChildData') { - // [Entity.childrens,prop1,prop2] - const prefix = args[0]; // like Entity.childrens - const item = `${prefix}.${args[1]}`; - const fullPaths = item.split('.').slice(1).map((propertyName: string) => propertyName.trim()); - const entityPath = this.getEntityPaths(fullPaths); - if (entityPath && entityPath.length > 0) { - entityPath.splice(0, 0, ENTITY_TEMPLATE); - deps.push(entityPath.join(DEPENDENCY_SPLITER)); - } - } - } else if (args && args.length === 4) { /* empty */ } else if (args && args.length === 5) { - if (['MinValueOfPeriod', 'MaxValueOfPeriod', 'AvgValueOfPeriod'].includes(methodName)) { - // [Entity.childrens,prop1,prop2] - const prefix = args[0]; // like Entity.childrens - const prop1FullPath = `${prefix}.${args[1]}`; - const prop2FullPath = `${prefix}.${args[2]}`; - [prop1FullPath, prop2FullPath].forEach((item) => { - const fullPaths = item.split('.').slice(1).map((propertyName: string) => propertyName.trim()); - const entityPath = this.getEntityPaths(fullPaths); - if (entityPath && entityPath.length > 0) { - entityPath.splice(0, 0, ENTITY_TEMPLATE); - deps.push(entityPath.join(DEPENDENCY_SPLITER)); - } - }); - } - } else { - throw new Error(`无法解析参数: ${JSON.stringify(argument)}`); - } - } - }); - } - return deps; - } - private getEntityPaths(fullPaths: string[]): string[] { - const resolvedPath = this.entityPathResolver.resolve(fullPaths); - if (!resolvedPath) { - return []; - } - const { entityPaths = [], propertyPaths = [] } = resolvedPath; - return entityPaths.concat(propertyPaths); - } -} diff --git a/packages/renderer/src/expression-dependency-resolver/expression-dependency-resolve-service.ts b/packages/renderer/src/expression-dependency-resolver/expression-dependency-resolve-service.ts deleted file mode 100644 index 86b2f4f8667..00000000000 --- a/packages/renderer/src/expression-dependency-resolver/expression-dependency-resolve-service.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { CommentExpressionDependencyResolver } from "./comment-expression-dependency-resolver"; -import { ExpressionDependencyResolverRegistry } from "./expression-dependency-resolver-registry"; -import { Resolver } from "./types"; - -export class ExpressionDependencyResolveService { - constructor(private expressionDependencyResolverRegistry: ExpressionDependencyResolverRegistry) { - } - public resolve(expression: string) { - const deps: string[] = []; - if (!this.expressionDependencyResolverRegistry || !this.expressionDependencyResolverRegistry.resolvers || this.expressionDependencyResolverRegistry.resolvers.length < 1) { - return; - } - // 优先使用用户自定义的依赖 - const commentDependencyResolver = this.expressionDependencyResolverRegistry.resolvers.find((resolver: Resolver) => resolver instanceof CommentExpressionDependencyResolver); - if (commentDependencyResolver) { - const commentDependencies = commentDependencyResolver.resolve(expression); - if (commentDependencies && Array.isArray(commentDependencies) && commentDependencies.length > 0) { - deps.push(...commentDependencies); - } - } - // 如果用户已经自定义了依赖,则不再计算 - if (deps && deps.length > 0) { - return deps; - } - this.expressionDependencyResolverRegistry.resolvers.forEach((resolver: Resolver) => { - // 再解析一次也可以,返回的依然是空数组 - if (resolver instanceof CommentExpressionDependencyResolver) { - return; - } - const dependency = resolver.resolve(expression); - if (dependency && dependency.length > 0) { - deps.push(...dependency); - } - }); - // 去重 - return [...new Set(deps)]; - } -} diff --git a/packages/renderer/src/expression-dependency-resolver/expression-dependency-resolver-registry.ts b/packages/renderer/src/expression-dependency-resolver/expression-dependency-resolver-registry.ts deleted file mode 100644 index d1fb35e4c6b..00000000000 --- a/packages/renderer/src/expression-dependency-resolver/expression-dependency-resolver-registry.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Injector } from "@farris/devkit-vue"; -import { Resolver, RESOLVER_TOKEN } from "./types"; - - -export class ExpressionDependencyResolverRegistry { - public resolvers: Array; - constructor(private injector: Injector) { - this.resolvers = this.injector.get(RESOLVER_TOKEN); - } -} diff --git a/packages/renderer/src/expression-dependency-resolver/index.ts b/packages/renderer/src/expression-dependency-resolver/index.ts deleted file mode 100644 index 15fd0a65405..00000000000 --- a/packages/renderer/src/expression-dependency-resolver/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from './types'; -export * from './comment-expression-dependency-resolver'; -export * from './entity-expression-dependency-resolver'; -export * from './ui-state-expression-dependency-resolver'; -export * from './expression-dependency-resolver-registry'; -export * from './expression-dependency-resolve-service'; -export * from './providers'; diff --git a/packages/renderer/src/expression-dependency-resolver/providers.ts b/packages/renderer/src/expression-dependency-resolver/providers.ts deleted file mode 100644 index aca2b632ef2..00000000000 --- a/packages/renderer/src/expression-dependency-resolver/providers.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Injector, StaticProvider } from "@farris/devkit-vue"; -import { UIStateExpressionDependencyResolver } from "./ui-state-expression-dependency-resolver"; -import { EntityExpressionDependencyResolver } from "./entity-expression-dependency-resolver"; -import { FormMetadataService } from "../service"; -import { CommentExpressionDependencyResolver } from "./comment-expression-dependency-resolver"; -import { ExpressionDependencyResolverRegistry } from "./expression-dependency-resolver-registry"; -import { RESOLVER_TOKEN } from "./types"; -import { EntityPathResolver } from "../resolvers"; -import { ExpressionDependencyResolveService } from "./expression-dependency-resolve-service"; - -export const expressionDependencyResolverProviders: StaticProvider[] = [ - { provide: RESOLVER_TOKEN, useClass: UIStateExpressionDependencyResolver, deps: [], multi: true }, - { provide: RESOLVER_TOKEN, useClass: EntityExpressionDependencyResolver, deps: [FormMetadataService, EntityPathResolver], multi: true }, - { provide: RESOLVER_TOKEN, useClass: CommentExpressionDependencyResolver, deps: [], multi: true }, - { provide: ExpressionDependencyResolverRegistry, useClass: ExpressionDependencyResolverRegistry, deps: [Injector] }, - { provide: ExpressionDependencyResolveService, useClass: ExpressionDependencyResolveService, deps: [ExpressionDependencyResolverRegistry] } -]; diff --git a/packages/renderer/src/expression-dependency-resolver/types.ts b/packages/renderer/src/expression-dependency-resolver/types.ts deleted file mode 100644 index 3b768202f7b..00000000000 --- a/packages/renderer/src/expression-dependency-resolver/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { InjectionToken } from "@farris/devkit-vue"; - -export interface Resolver { - resolve(expression: string): string[]; -} -export const RESOLVER_TOKEN = new InjectionToken('@farris_resolver_token'); -export const ENTITY_TEMPLATE = 'ENTITY~'; -export const STATE_TEMPLATE = 'STATE~'; -export const DEPENDENCY_SPLITER = '/'; -export const GROUP_FUNCTIONS = ['SumByProp', 'CountByProp', 'AvgByProp', 'MaxByProp', 'MinByProp', 'IsExistRecord', 'ListContains', 'ListGreaterThan', 'ListLessThan', 'ListStartWith', 'ListEndWith', 'MultiplyChildNumber', 'SortChildData', 'IsContainMatch', 'MinValueOfPeriod', 'MaxValueOfPeriod', 'AvgValueOfPeriod']; diff --git a/packages/renderer/src/expression-dependency-resolver/ui-state-expression-dependency-resolver.ts b/packages/renderer/src/expression-dependency-resolver/ui-state-expression-dependency-resolver.ts deleted file mode 100644 index 02c946b2e5e..00000000000 --- a/packages/renderer/src/expression-dependency-resolver/ui-state-expression-dependency-resolver.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { DEPENDENCY_SPLITER, Resolver, STATE_TEMPLATE } from "./types"; -const CONTEXT_FUNCTIONS = ['GetContextParameter', 'GetSessionValue']; -export class UIStateExpressionDependencyResolver implements Resolver { - public resolve(expression: string): string[] { - const dependencies: string[] = []; - const regex = new RegExp(`DefaultFunction\\.(${CONTEXT_FUNCTIONS.join('|')})\\s*\\([^\\r\\n\\)]*\\)`, 'g'); - const contextFunctions: RegExpMatchArray | null = expression.match(regex); - if (contextFunctions && contextFunctions.length > 0) { - // todo: 使用正则匹配时可能会因为参数中有逗号导致问题,后续使用ast解析 - const argumentsRegex = /\(([^\r\n)]*)\)/; - contextFunctions.forEach((groupFunction: string) => { - const argumentMatchResult = groupFunction.match(argumentsRegex); - if (argumentMatchResult && argumentMatchResult.length === 2) { - const argument = argumentMatchResult[1].trim().replace(/[\\"\\']/g, ''); - const dep = [STATE_TEMPLATE]; - dep.push(argument); - dependencies.push(dep.join(DEPENDENCY_SPLITER)); - } - }); - } - return dependencies; - } -} diff --git a/packages/renderer/src/expression/expression-engine-proxy.ts b/packages/renderer/src/expression/expression-engine-proxy.ts deleted file mode 100644 index 7fec85c9a66..00000000000 --- a/packages/renderer/src/expression/expression-engine-proxy.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Injector } from "@farris/devkit-vue"; -import { Change } from "../change-observer"; -import { ExpressionEventEmitter } from "./expression-event-emitter"; -import { ExpressionExecutor } from "./expression-executor"; -import { ExpressionRegistry } from "./expression-registry"; -import { ExpressionDependencyResolverRegistry, ExpressionDependencyResolveService } from "../expression-dependency-resolver"; -import { ExpressionObject } from "./types"; -import { CHANGE_HANDLERS_TOKEN, ChangeHandler } from "../change-handler"; - -export class ExpressionEngineProxy { - constructor( - private injector: Injector, - private expressionEventEmitter: ExpressionEventEmitter, - private expressionExecutor: ExpressionExecutor, - private expressionRegistry: ExpressionRegistry, - private expressionDependencyResolverRegistry: ExpressionDependencyResolverRegistry, - private expressionDependencyResolveService: ExpressionDependencyResolveService, - ) { - const { expressions } = this.expressionRegistry; - this.resolveDependency(expressions); - console.log(expressions); - this.attachEvent(expressions); - } - private attachEvent(expressions: ExpressionObject[]) { - this.expressionEventEmitter.attach().subscribe((changes: Change[]) => { - changes.forEach((change: Change) => { - const changeHandlers = this.injector.get(CHANGE_HANDLERS_TOKEN); - changeHandlers.forEach((handler: ChangeHandler) => { - handler.handle(change, expressions); - }); - }); - }); - } - private resolveDependency(expressionObjects: ExpressionObject[]) { - if (!expressionObjects || expressionObjects.length < 1 || !this.expressionDependencyResolverRegistry.resolvers || this.expressionDependencyResolverRegistry.resolvers.length < 1) { - return; - } - expressionObjects.forEach((expressionObject: ExpressionObject) => { - const { expression } = expressionObject; - const dependencies = this.expressionDependencyResolveService.resolve(expression); - expressionObject.deps = dependencies; - }); - } -} diff --git a/packages/renderer/src/expression/expression-event-emitter.ts b/packages/renderer/src/expression/expression-event-emitter.ts deleted file mode 100644 index 09f99865616..00000000000 --- a/packages/renderer/src/expression/expression-event-emitter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Injector } from "@farris/devkit-vue"; -import { BehaviorSubject, Observable } from 'rxjs'; -import { Change, ChangeObserver, ChangeObserverRegistry } from "../change-observer"; - -/** - * 监听所有表单事件并暂存,待有消费者时一次返回给消费者 - */ -export class ExpressionEventEmitter { - private onEvent: BehaviorSubject>> | undefined; - private events: Array>; - constructor(private injector: Injector) { - const changeObserverRegistry = this.injector.get(ChangeObserverRegistry); - this.events = new Array>(); - changeObserverRegistry.observers.forEach((observer: ChangeObserver) => { - observer.observe((change: Change) => { - if (this.onEvent && this.onEvent.observers.length > 0) { - let events: any[] = []; - if (this.events.length > 0) { - events = [...this.events]; - } - events.push(change); - this.events = []; - this.onEvent.next(events); - } else { - this.events.push(change); - } - }); - }); - } - public attach(): Observable>> { - if (!this.onEvent) { - const events = Array.from(this.events); - this.events = []; - this.onEvent = new BehaviorSubject>>(events); - } - return this.onEvent.asObservable(); - } -} diff --git a/packages/renderer/src/expression/expression-executor.ts b/packages/renderer/src/expression/expression-executor.ts deleted file mode 100644 index af55f5cdef3..00000000000 --- a/packages/renderer/src/expression/expression-executor.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Expression, ExpressionContext, ExpressionEngine } from '@farris/expression-engine-vue'; -import { Executor, ExpressionObject } from './types'; - -export class ExpressionExecutor implements Executor { - /** - * 编译执行 - * @param expression - * @param context - * @returns - */ - public compile(expressionObject: ExpressionObject, context?: Record): any { - if (Object.prototype.toString.call(context) !== '[object Object]') { - throw new Error('上下文必须为对象!'); - } - const expressionContext = this.buildContext(context); - if (!expressionObject.factory) { - const expression = new Expression(expressionObject.expression, expressionContext); - expressionObject.factory = expression.compile(); - } - const expression: Expression = expressionObject.factory; - return expression.eval(expressionContext); - } - /** - * 解析 - * @param expression - * @param context - * @returns - */ - public eval(expression: string, context?: { [prop: string]: any; }) { - if (Object.prototype.toString.call(context) !== '[object Object]') { - throw new Error('上下文必须为对象!'); - } - const expressionContext = this.buildContext(context); - const expressionEngine = new ExpressionEngine(expressionContext); - return expressionEngine.eval(expression); - } - /** - * 构造表达式上下文 - * @param context - * @returns - */ - private buildContext(context?: Record): ExpressionContext { - const expressionContext = new ExpressionContext(); - if (context && Object.keys(context).length > 0) { - Object.keys(context).forEach((key: string) => { - expressionContext.set(key, context[key]); - }); - } - return expressionContext; - } -} diff --git a/packages/renderer/src/expression/expression-registry.ts b/packages/renderer/src/expression/expression-registry.ts deleted file mode 100644 index d91f8760ed7..00000000000 --- a/packages/renderer/src/expression/expression-registry.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { DataSourceResolver, FieldResolver } from "../resolvers"; -import { FormMetadataService } from "../service"; -import { DEFAULT_EXPRESSION_VALIDATE_MESSAGE, ElementExpressionMetadata, ExpressionMetadata, ExpressionObject, ExpressionType } from "./types"; - -export class ExpressionRegistry { - constructor(private formMetadataService: FormMetadataService, private fieldResolver: FieldResolver, private dataSourceResolver: DataSourceResolver) { - } - public get expressions(): ExpressionObject[] { - const expressions: ElementExpressionMetadata[] = this.formMetadataService.getExpressions(); - const expressionObjects: ExpressionObject[] = []; - expressions.forEach((elementExpression: ElementExpressionMetadata) => { - const { expression: elementExpressions, elementId, elementType } = elementExpression; - if (!elementId || !elementType || !elementExpressions || elementExpressions.length < 1) { - return; - } - elementExpressions.forEach((expression: ExpressionMetadata) => { - let path = expression.id; - if (elementExpression.elementType === 'Field') { - const resolvedField = this.fieldResolver.resolve(elementExpression.elementId); - if (!resolvedField) { - return; - } - const { dataSource, bindingPath } = resolvedField; - const resolvedDataSource = this.dataSourceResolver.resolve(dataSource); - if (!resolvedDataSource) { - return; - } - const { bindingPaths } = resolvedDataSource; - const fullPaths = bindingPaths.concat(bindingPath.split('.')); - path = fullPaths.join('/'); - } - const expressionValue = this.cleanSpecialCharacters(expression.value); - const expressionObject: ExpressionObject = { - id: expression.id, - ns: '', - path: path, - bindingType: elementExpression.elementType, - type: expression.type, - expression: expressionValue, - message: expression.message, - deps: [] - }; - // 构造表达式提示信息 - if ((expression.type === ExpressionType.Required || expression.type === ExpressionType.Validate || expression.type === ExpressionType.DataPicking)) { - if (!expression.message) { - expressionObject.message = this.getExpressionMessage(expression.type); - } - } - expressionObjects.push(expressionObject); - }); - }); - return expressionObjects; - } - private getExpressionMessage(expressionType: ExpressionType, defaultValue?: string) { - if (!(expressionType === ExpressionType.Validate || expressionType === ExpressionType.Required || expressionType === ExpressionType.DataPicking)) { - return null; - } - return DEFAULT_EXPRESSION_VALIDATE_MESSAGE['zh-CHS'][expressionType]; - } - private cleanSpecialCharacters(expression: string) { - const mainEntity = this.formMetadataService.getEntity(); - const regex = new RegExp(`[\\'\\"]?\\s*(${mainEntity.code}|${mainEntity.label})[\\.\\[\\]a-zA-Z0-9_]+\\s*[\\'\\"]?`, 'g'); - const entityPropertyExpressions: RegExpMatchArray | null = expression.match(regex); - if (Array.isArray(entityPropertyExpressions) && entityPropertyExpressions.length > 0) { - // 解析出所有实体相关的字符串,以主实体名字开头,包含主实体属性或子表 - entityPropertyExpressions.forEach((item: string) => { - if (item.indexOf('.') === -1) { - return; - } - // 去数组 - if (/\[\d\]/g.test(item)) { - const replacer = item.replace(/\[\d\]/g, ''); - expression = this.replaceAll(expression, item, replacer); - } - // 去星号 - if (/\*/g.test(item)) { - const replacer = item.replace(/\*/g, ''); - expression = this.replaceAll(expression, item, replacer); - } - }); - } - return expression; - } - private replaceAll(originalValue: string, search: string, replacer: string) { - return originalValue.split(search).join(replacer); - } -} diff --git a/packages/renderer/src/expression/expression-result.ts b/packages/renderer/src/expression/expression-result.ts deleted file mode 100644 index 18ab2bcbdd9..00000000000 --- a/packages/renderer/src/expression/expression-result.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Subject } from "rxjs"; -import { ExpressionResultChange } from "./types"; - -export class ExpressionResult { - [key: string]: any; - public changes: Subject = new Subject(); - constructor() { - } - /** - * 更新表达式的值 - * @param expressionId - 表达式id - * @param result - 表达式结果 - */ - public set(expressionId: string, result: any) { - if (result === this[expressionId]) { - return; - } - this[expressionId] = result; - this.changes.next({ id: expressionId, result }); - } -} diff --git a/packages/renderer/src/expression/index.ts b/packages/renderer/src/expression/index.ts deleted file mode 100644 index 23aae3d671a..00000000000 --- a/packages/renderer/src/expression/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './types'; -export * from './expression-engine-proxy'; -export * from './expression-event-emitter'; -export * from './expression-executor'; -export * from './expression-result'; -export * from './providers'; diff --git a/packages/renderer/src/expression/providers.ts b/packages/renderer/src/expression/providers.ts deleted file mode 100644 index ef8f9190ead..00000000000 --- a/packages/renderer/src/expression/providers.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Injector, StaticProvider } from '@farris/devkit-vue'; -import { ExpressionEventEmitter } from './expression-event-emitter'; -import { ExpressionEngineProxy } from './expression-engine-proxy'; -import { ExpressionExecutor } from './expression-executor'; -import { ExpressionRegistry } from './expression-registry'; -import { FormMetadataService } from '../service'; -import { DataSourceResolver, FieldResolver } from '../resolvers'; -import { ExpressionDependencyResolverRegistry, ExpressionDependencyResolveService } from '../expression-dependency-resolver'; -import { ExpressionResult } from './expression-result'; - -export const expressionProviders: StaticProvider[] = [ - { provide: ExpressionEventEmitter, useClass: ExpressionEventEmitter, deps: [Injector] }, - { provide: ExpressionEngineProxy, useClass: ExpressionEngineProxy, deps: [Injector, ExpressionEventEmitter, ExpressionExecutor, ExpressionRegistry, ExpressionDependencyResolverRegistry, ExpressionDependencyResolveService] }, - { provide: ExpressionExecutor, useClass: ExpressionExecutor, deps: [] }, - { provide: ExpressionRegistry, useClass: ExpressionRegistry, deps: [FormMetadataService, FieldResolver, DataSourceResolver] }, - { provide: ExpressionResult, useClass: ExpressionResult, deps: [] } -]; diff --git a/packages/renderer/src/expression/types.ts b/packages/renderer/src/expression/types.ts deleted file mode 100644 index 98f8e11b5b9..00000000000 --- a/packages/renderer/src/expression/types.ts +++ /dev/null @@ -1,149 +0,0 @@ - -/** - * 表达式绑定字段类型(表达式绑定到实体、UIState?) - */ -export enum ExpressionBindingType { - State = 'State', - Field = 'Field', - Button = 'Button', - Container = 'Container' -} -/** - * 表达式类型 - */ -export enum ExpressionType { - /** - * 必填表达式 - */ - Required = 'require', - /** - * 只读表达式 - */ - Readonly = 'readonly', - /** - * 计算表达式 - */ - Compute = 'compute', - /** - * 依赖表达式 - */ - Dependency = 'dependency', - /** - * 是否可见 - */ - Visible = 'visible', - /** - * 关联表达式 - */ - Relative = 'relative', - /** - * 校验表达式 - */ - Validate = 'validate', - /** - * 帮助前 - */ - DataPicking = 'dataPicking', - /** - * 禁用 - */ - Disable = 'disable', -} -export enum ExpressionMessageType { - error = 'error', - info = 'info', - warning = 'warning' -} -/** - * 表达式对象 - */ -export interface ExpressionObject { - /** - * 表达式唯一标识 - */ - id?: string; - /** - * 表达式绑定的路径 - */ - path: string; - /** - * 表达式绑定类型State|Entity|Element - */ - bindingType: ExpressionBindingType; - /** - * 表达式类型 - */ - type: ExpressionType; - /** - * 表达式 - */ - expression: string; - /** - * 表达式依赖 - */ - deps?: string[] | null; - /** - * 表达式namespace - */ - ns: string; - /** - * 表达式计算结果 - */ - result?: any; - /** - * 结果作用路径 - */ - effectPaths?: string[], - /** - * 提示信息 - */ - message?: string | null; - /** - * 提示消息类型 - */ - messageType?: ExpressionMessageType; - /** - * 表达式计算函数 - */ - factory?: any; -} - -/** - * 表达式执行器 - */ -export interface Executor { - compile(expressionObject: ExpressionObject, context?: { [prop: string]: any; }): any; -} - -export interface ExpressionMetadata { - id: string; - type: ExpressionType; - value: string; - message?: string | null | undefined; -} -export interface ElementExpressionMetadata { - elementId: string; - elementType: ExpressionBindingType; - expression: ExpressionMetadata[]; -} -export const DEFAULT_EXPRESSION_VALIDATE_MESSAGE = { - 'zh-CHS': { - require: `请输入'$property'`, - validate: `'$property'校验不通过`, - dataPicking: '帮助前表达式校验不通过' - }, - 'en': { - require: `Please input '$property'`, - validate: `'$property' calibration failed`, - dataPicking: 'Failed to verify the expression before help' - }, - 'zh-CHT': { - require: `請輸入'$property'`, - validate: `'$property'校驗不通過`, - dataPicking: '幫助前表達式校驗不通過' - } -}; -export interface ExpressionResultChange { - id: string; - result: any - } diff --git a/packages/renderer/src/form-engine/form-engine.ts b/packages/renderer/src/form-engine/form-engine.ts index bd45b32651b..4b04563a09e 100644 --- a/packages/renderer/src/form-engine/form-engine.ts +++ b/packages/renderer/src/form-engine/form-engine.ts @@ -1,5 +1,5 @@ import { cloneDeep, merge, mergeWith } from "lodash-es"; -import { Change, ChangeObserver, ChangeObserverRegistry } from "../change-observer"; +import { Change, ChangeObserver, ChangeObserverRegistry } from "@farris/devkit-vue"; import { ChangeResolveService } from "../change-resolver"; import { ComponentConfigResolveService } from "../component-config-resolver"; import { RenderEngineImpl } from "../render-engine"; diff --git a/packages/renderer/src/form-engine/providers.ts b/packages/renderer/src/form-engine/providers.ts index b8bbb340068..984723d9c05 100644 --- a/packages/renderer/src/form-engine/providers.ts +++ b/packages/renderer/src/form-engine/providers.ts @@ -1,11 +1,10 @@ - import { StaticProvider } from "@farris/devkit-vue"; + import { ChangeObserverRegistry, StaticProvider } from "@farris/devkit-vue"; import { FormEngine } from "./form-engine"; -import { ChangeObserverRegistry } from "../change-observer"; import { ChangeResolveService } from "../change-resolver"; import { ComponentConfigResolveService } from "../component-config-resolver"; import { RenderEngineImpl } from "../render-engine"; import { FormMetadataService } from "../service"; export const formEngineProviders: StaticProvider[] = [ - { provide: FormEngine, useClass: FormEngine, deps: [ChangeObserverRegistry, ChangeResolveService, ComponentConfigResolveService, RenderEngineImpl, FormMetadataService] } + { provide: FormEngine, useClass: FormEngine, deps: [ChangeObserverRegistry ,ChangeResolveService, ComponentConfigResolveService, RenderEngineImpl, FormMetadataService] } ]; diff --git a/packages/renderer/src/preview.vue b/packages/renderer/src/preview.vue index f9477606874..4b40597d3a2 100644 --- a/packages/renderer/src/preview.vue +++ b/packages/renderer/src/preview.vue @@ -2,7 +2,7 @@ diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx b/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx index 592eaeebd00..847d529078f 100644 --- a/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx +++ b/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx @@ -18,7 +18,8 @@ const FDynamicView = defineComponent({ [() => props.config], ([newConfig]) => { config.value = newConfig; - } + }, + { deep: true } ); setupContext.expose({}); diff --git a/packages/mobile-ui-vue/components/input-group/src/schema/input-group.schema.json b/packages/mobile-ui-vue/components/input-group/src/schema/input-group.schema.json index 260621d8ecf..e867f1daace 100644 --- a/packages/mobile-ui-vue/components/input-group/src/schema/input-group.schema.json +++ b/packages/mobile-ui-vue/components/input-group/src/schema/input-group.schema.json @@ -79,7 +79,6 @@ "ignore": [ "id", "appearance", - "binding", "visible" ] } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 19ec8c00454..9460f5db90d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -366,10 +366,10 @@ importers: version: 7.18.0(eslint@9.19.0(jiti@1.21.6))(typescript@4.9.5) '@vitejs/plugin-vue': specifier: ^4.0.0 - version: 4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) + version: 4.6.2(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) '@vitejs/plugin-vue-jsx': specifier: ^3.0.0 - version: 3.1.0(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) + version: 3.1.0(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) '@vue/babel-plugin-jsx': specifier: ^1.1.1 version: 1.2.5(@babel/core@7.25.8) @@ -408,7 +408,7 @@ importers: version: 9.3.7 jest: specifier: ^29.0.0 - version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) + version: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) lodash: specifier: ^4.17.21 version: 4.17.21 @@ -444,19 +444,19 @@ importers: version: 4.9.5 vite: specifier: ^4.1.4 - version: 4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0) + version: 4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0) vite-plugin-dts: specifier: ^2.1.0 - version: 2.3.0(@types/node@20.5.1)(rollup@4.24.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) + version: 2.3.0(@types/node@18.19.57)(rollup@4.24.0)(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0)) vite-plugin-md: specifier: ^0.20.0 - version: 0.20.6(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) + version: 0.20.6(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0)) vite-svg-loader: specifier: ^4.0.0 version: 4.0.0 vitepress: specifier: 1.0.0-alpha.8 - version: 1.0.0-alpha.8(@algolia/client-search@4.24.0)(@types/node@20.5.1)(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(search-insights@2.17.2)(terser@5.36.0)(typescript@4.9.5) + version: 1.0.0-alpha.8(@algolia/client-search@4.24.0)(@types/node@18.19.57)(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(search-insights@2.17.2)(terser@5.36.0)(typescript@4.9.5) vitepress-theme-demoblock: specifier: 1.4.2 version: 1.4.2(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(typescript@4.9.5) @@ -983,10 +983,10 @@ importers: version: 7.18.0(eslint@9.19.0(jiti@1.21.6))(typescript@4.9.5) '@vitejs/plugin-vue': specifier: ^4.0.0 - version: 4.6.2(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) + version: 4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) '@vitejs/plugin-vue-jsx': specifier: ^3.0.0 - version: 3.1.0(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) + version: 3.1.0(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) '@vue/babel-plugin-jsx': specifier: ^1.1.1 version: 1.2.5(@babel/core@7.25.8) @@ -1025,7 +1025,7 @@ importers: version: 9.3.7 jest: specifier: ^29.0.0 - version: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) lodash: specifier: ^4.17.21 version: 4.17.21 @@ -1061,19 +1061,19 @@ importers: version: 4.9.5 vite: specifier: ^4.1.4 - version: 4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0) + version: 4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0) vite-plugin-dts: specifier: ^2.1.0 - version: 2.3.0(@types/node@18.19.57)(rollup@4.24.0)(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0)) + version: 2.3.0(@types/node@20.5.1)(rollup@4.24.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) vite-plugin-md: specifier: ^0.20.0 - version: 0.20.6(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0)) + version: 0.20.6(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) vite-svg-loader: specifier: ^4.0.0 version: 4.0.0 vitepress: specifier: 1.0.0-alpha.8 - version: 1.0.0-alpha.8(@algolia/client-search@4.24.0)(@types/node@18.19.57)(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(search-insights@2.17.2)(terser@5.36.0)(typescript@4.9.5) + version: 1.0.0-alpha.8(@algolia/client-search@4.24.0)(@types/node@20.5.1)(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(search-insights@2.17.2)(terser@5.36.0)(typescript@4.9.5) vitepress-theme-demoblock: specifier: 1.4.2 version: 1.4.2(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(typescript@4.9.5) @@ -1499,6 +1499,166 @@ importers: specifier: ^1.2.0 version: 1.8.27(typescript@4.9.5) + packages/mobile-render: + dependencies: + '@farris/bef-vue': + specifier: workspace:^ + version: link:../bef + '@farris/devkit-vue': + specifier: workspace:^ + version: link:../devkit + '@farris/mobile-command-services-vue': + specifier: workspace:^ + version: link:../mobile-command-services + '@farris/mobile-ui-vue': + specifier: workspace:^ + version: link:../mobile-ui-vue + axios: + specifier: ^1.7.2 + version: 1.7.7 + vue: + specifier: ^3.4.29 + version: 3.5.12(typescript@4.9.5) + vue-router: + specifier: ^4.3.0 + version: 4.4.5(vue@3.5.12(typescript@4.9.5)) + devDependencies: + '@babel/parser': + specifier: ^7.19.0 + version: 7.25.8 + '@babel/preset-env': + specifier: ^7.19.0 + version: 7.25.8(@babel/core@7.25.8) + '@babel/preset-typescript': + specifier: ^7.18.0 + version: 7.25.7(@babel/core@7.25.8) + '@babel/traverse': + specifier: ^7.19.0 + version: 7.25.7 + '@commitlint/cli': + specifier: ^17.1.0 + version: 17.8.1 + '@commitlint/config-conventional': + specifier: ^17.1.0 + version: 17.8.1 + '@farris/cli': + specifier: workspace:^ + version: link:../cli + '@rushstack/eslint-patch': + specifier: ^1.8.0 + version: 1.11.0 + '@testing-library/vue': + specifier: ^7.0.0 + version: 7.0.0(@vue/compiler-sfc@3.5.12)(vue@3.5.12(typescript@4.9.5)) + '@types/jest': + specifier: ^26.0.24 + version: 26.0.24 + '@typescript-eslint/eslint-plugin': + specifier: ^7.15.0 + version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: ^7.15.0 + version: 7.18.0(eslint@8.57.1)(typescript@4.9.5) + '@vitejs/plugin-vue': + specifier: ^4.0.0 + version: 4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) + '@vitejs/plugin-vue-jsx': + specifier: ^3.0.0 + version: 3.1.0(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) + '@vue/babel-plugin-jsx': + specifier: ^1.1.1 + version: 1.2.5(@babel/core@7.25.8) + '@vue/compiler-sfc': + specifier: ^3.2.0 + version: 3.5.12 + '@vue/eslint-config-prettier': + specifier: ^9.0.0 + version: 9.0.0(eslint@8.57.1)(prettier@3.5.3) + '@vue/eslint-config-typescript': + specifier: ^13.0.0 + version: 13.0.0(eslint-plugin-vue@9.29.1(eslint@8.57.1))(eslint@8.57.1)(typescript@4.9.5) + '@vue/test-utils': + specifier: ^2.0.0 + version: 2.4.6 + '@vue/tsconfig': + specifier: ^0.5.1 + version: 0.5.1 + '@vuedx/typecheck': + specifier: ^0.7.5 + version: 0.7.6 + '@vuedx/typescript-plugin-vue': + specifier: ^0.7.5 + version: 0.7.6 + babel-jest: + specifier: ^29.0.3 + version: 29.7.0(@babel/core@7.25.8) + chalk: + specifier: ^5.0.0 + version: 5.3.0 + commander: + specifier: ^9.4.0 + version: 9.5.0 + conventional-changelog-cli: + specifier: ^2.2.2 + version: 2.2.2 + eslint: + specifier: ^8.57.0 + version: 8.57.1 + eslint-plugin-vue: + specifier: ^9.23.0 + version: 9.29.1(eslint@8.57.1) + happy-dom: + specifier: ^8.9.0 + version: 8.9.0 + inquirer: + specifier: ^9.1.1 + version: 9.3.7 + jest: + specifier: ^29.0.0 + version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) + ora: + specifier: ^6.1.2 + version: 6.3.1 + patch-vue-directive-ssr: + specifier: ^0.0.1 + version: 0.0.1 + prettier: + specifier: ^3.2.5 + version: 3.5.3 + shelljs: + specifier: ^0.8.4 + version: 0.8.5 + typescript: + specifier: ^4.6.4 + version: 4.9.5 + vite: + specifier: ^4.1.4 + version: 4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0) + vite-plugin-banner: + specifier: ^0.8.0 + version: 0.8.0 + vite-plugin-dts: + specifier: ^2.1.0 + version: 2.3.0(@types/node@20.5.1)(rollup@4.24.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) + vite-plugin-md: + specifier: ^0.20.0 + version: 0.20.6(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) + vite-svg-loader: + specifier: ^4.0.0 + version: 4.0.0 + vitepress: + specifier: 1.0.0-alpha.8 + version: 1.0.0-alpha.8(@algolia/client-search@4.24.0)(@types/node@20.5.1)(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(search-insights@2.17.2)(terser@5.36.0)(typescript@4.9.5) + vitepress-theme-demoblock: + specifier: 1.4.2 + version: 1.4.2(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(typescript@4.9.5) + vitest: + specifier: ^0.29.2 + version: 0.29.8(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) + vue-tsc: + specifier: ^1.2.0 + version: 1.8.27(typescript@4.9.5) + packages/mobile-ui-vue: dependencies: bignumber.js: @@ -3447,10 +3607,18 @@ packages: resolution: {integrity: sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/eslintrc@3.2.0': resolution: {integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/js@9.19.0': resolution: {integrity: sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3483,10 +3651,19 @@ packages: resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} engines: {node: '>=18.18.0'} + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + '@humanwhocodes/retry@0.3.1': resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} engines: {node: '>=18.18'} @@ -3619,7 +3796,6 @@ packages: '@ls-lint/ls-lint@2.2.3': resolution: {integrity: sha512-ekM12jNm/7O2I/hsRv9HvYkRdfrHpiV1epVuI2NP+eTIcEgdIdKkKCs9KgQydu/8R5YXTov9aHdOgplmCHLupw==} - cpu: [x64, arm64, s390x] os: [darwin, linux, win32] hasBin: true @@ -3766,6 +3942,10 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@pnpm/types@8.10.0': resolution: {integrity: sha512-A4pcNNvFJdkMXArEjTCOIYNL2VxD4uBynWZ6cBIELXb5qJ0tUzwKsaSz4J953I0rQFqnsFpUYqaWIquI10W1sw==} engines: {node: '>=14.6'} @@ -3930,6 +4110,9 @@ packages: '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + '@rushstack/eslint-patch@1.11.0': + resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==} + '@rushstack/node-core-library@3.66.1': resolution: {integrity: sha512-ker69cVKAoar7MMtDFZC4CzcDxjwqIhFzqEnYI5NRN/8M3om6saWCVx/A7vL2t/jFCJsnzQplRDqA7c78pytng==} peerDependencies: @@ -4327,6 +4510,9 @@ packages: resolution: {integrity: sha512-pCh/qEA8Lb1wVIqNvBke8UaRjJ6wrAWkJO5yyIbs8Yx6TNGYyfNjOo61tLv+WwLvoLPp4BQ8B7AHKijl8NGUfw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + '@vitejs/plugin-vue-jsx@2.1.1': resolution: {integrity: sha512-JgDhxstQlwnHBvZ1BSnU5mbmyQ14/t5JhREc6YH5kWyu2QdAAOsLF6xgHoIWarj8tddaiwFrNzLbWJPudpXKYA==} engines: {node: ^14.18.0 || >=16.0.0} @@ -4470,6 +4656,23 @@ packages: '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + '@vue/eslint-config-prettier@9.0.0': + resolution: {integrity: sha512-z1ZIAAUS9pKzo/ANEfd2sO+v2IUalz7cM/cTLOZ7vRFOPk5/xuRKQteOu1DErFLAh/lYGXMVZ0IfYKlyInuDVg==} + peerDependencies: + eslint: '>= 8.0.0' + prettier: '>= 3.0.0' + + '@vue/eslint-config-typescript@13.0.0': + resolution: {integrity: sha512-MHh9SncG/sfqjVqjcuFLOLD6Ed4dRAis4HNt0dXASeAuLqIAx4YMB1/m2o4pUKK1vCt8fUvYG8KKX2Ot3BVZTg==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + eslint-plugin-vue: ^9.0.0 + typescript: '>=4.7.4' + peerDependenciesMeta: + typescript: + optional: true + '@vue/language-core@1.8.27': resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==} peerDependencies: @@ -4512,6 +4715,9 @@ packages: '@vue/test-utils@2.4.6': resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==} + '@vue/tsconfig@0.5.1': + resolution: {integrity: sha512-VcZK7MvpjuTPx2w6blwnwZAu5/LgBUtejFOi3pPGQFXQN5Ela03FUtd2Qtg4yWGGissVL0dr6Ro1LfOFh+PCuQ==} + '@vuedx/compiler-sfc@0.7.2': resolution: {integrity: sha512-20u9gN1OjAWPuJcBqvF0AOvjI76Zl/s+Q50e1oQhpjIxSsHM7+wprtLV2kiyOR3b49ABszTYWeGAkPoEHAtTyw==} @@ -5996,6 +6202,10 @@ packages: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} @@ -6477,6 +6687,12 @@ packages: peerDependencies: eslint: '>=7.0.0' + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} @@ -6511,6 +6727,20 @@ packages: '@typescript-eslint/parser': optional: true + eslint-plugin-prettier@5.2.3: + resolution: {integrity: sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '*' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + eslint-plugin-vue@9.29.1: resolution: {integrity: sha512-MH/MbVae4HV/tM8gKAVWMPJbYgW04CK7SuzYRrlNERpxbO0P3+Zdsa2oAcFBW6xNu7W6lIkGOsFAMCRTYmrlWQ==} engines: {node: ^14.17.0 || >=16.0.0} @@ -6533,6 +6763,12 @@ packages: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + eslint@9.19.0: resolution: {integrity: sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -6678,6 +6914,9 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -6715,6 +6954,10 @@ packages: picomatch: optional: true + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -6797,6 +7040,10 @@ packages: resolution: {integrity: sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==} engines: {node: '>= 0.10'} + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} @@ -7597,6 +7844,10 @@ packages: resolution: {integrity: sha512-kyiNFFLU0Ampr6SDZitD/DwUo4Zs1nSdnygUBqsu3LooL00Qvb5j+UnvApUn/TTj1J3OuE6BTdQ5rudKmU2ZaA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + is-path-inside@4.0.0: resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} engines: {node: '>=12'} @@ -9219,11 +9470,20 @@ packages: resolution: {integrity: sha512-s/46sYeylUfHNjI+sA/78FAHlmIuKqI9wNnzEOGehAlUUYeObv5C2mOinXBjyUyWmJ2SfcS2/ydApH4hTF4WXQ==} engines: {node: '>=0.10.0'} + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} hasBin: true + prettier@3.5.3: + resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + engines: {node: '>=14'} + hasBin: true + pretty-format@26.6.2: resolution: {integrity: sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==} engines: {node: '>= 10'} @@ -10300,6 +10560,10 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + synckit@0.9.2: + resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} + engines: {node: ^14.18.0 || >=16.0.0} + table@6.8.2: resolution: {integrity: sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==} engines: {node: '>=10.0.0'} @@ -10349,6 +10613,9 @@ packages: resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} engines: {node: '>=8'} + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + through2-filter@3.0.0: resolution: {integrity: sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==} @@ -12512,7 +12779,7 @@ snapshots: '@types/node': 20.5.1 chalk: 4.1.2 cosmiconfig: 8.3.6(typescript@5.6.3) - cosmiconfig-typescript-loader: 4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6(typescript@4.9.5))(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3))(typescript@5.6.3) + cosmiconfig-typescript-loader: 4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6(typescript@5.6.3))(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5))(typescript@5.6.3) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -12547,7 +12814,7 @@ snapshots: '@commitlint/types': 19.5.0 chalk: 5.3.0 cosmiconfig: 9.0.0(typescript@4.9.5) - cosmiconfig-typescript-loader: 5.1.0(@types/node@20.5.1)(cosmiconfig@9.0.0(typescript@5.6.3))(typescript@4.9.5) + cosmiconfig-typescript-loader: 5.1.0(@types/node@20.5.1)(cosmiconfig@9.0.0(typescript@4.9.5))(typescript@4.9.5) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -12962,6 +13229,11 @@ snapshots: '@esbuild/win32-x64@0.23.1': optional: true + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)': + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.4.0(eslint@9.19.0(jiti@1.21.6))': dependencies: eslint: 9.19.0(jiti@1.21.6) @@ -12983,6 +13255,20 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.3.7 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + '@eslint/eslintrc@3.2.0': dependencies: ajv: 6.12.6 @@ -12997,6 +13283,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@eslint/js@8.57.1': {} + '@eslint/js@9.19.0': {} '@eslint/object-schema@2.1.6': {} @@ -13025,8 +13313,18 @@ snapshots: '@humanfs/core': 0.19.1 '@humanwhocodes/retry': 0.3.1 + '@humanwhocodes/config-array@0.13.0': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.7 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + '@humanwhocodes/module-importer@1.0.1': {} + '@humanwhocodes/object-schema@2.0.3': {} + '@humanwhocodes/retry@0.3.1': {} '@humanwhocodes/retry@0.4.1': {} @@ -13065,7 +13363,7 @@ snapshots: jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3))': + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -13079,7 +13377,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -13100,7 +13398,7 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5))': + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -13114,7 +13412,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) + jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -13135,7 +13433,7 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3))': + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -13149,7 +13447,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -13326,7 +13624,7 @@ snapshots: '@jsdevtools/ez-spawn@3.0.4': dependencies: call-me-maybe: 1.0.2 - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 string-argv: 0.3.2 type-detect: 4.1.0 @@ -13553,6 +13851,8 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@pkgr/core@0.1.1': {} + '@pnpm/types@8.10.0': {} '@polka/url@0.5.0': {} @@ -13669,6 +13969,8 @@ snapshots: '@rtsao/scc@1.1.0': {} + '@rushstack/eslint-patch@1.11.0': {} + '@rushstack/node-core-library@3.66.1(@types/node@18.19.57)': dependencies: colors: 1.2.5 @@ -14103,6 +14405,24 @@ snapshots: '@types/zrender@4.0.6': {} + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@eslint-community/regexpp': 4.11.1 + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/visitor-keys': 7.18.0 + eslint: 8.57.1 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.19.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.19.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: '@eslint-community/regexpp': 4.11.1 @@ -14141,7 +14461,7 @@ snapshots: '@typescript-eslint/eslint-plugin@8.18.0(@typescript-eslint/parser@8.18.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.19.0(jiti@1.21.6))(typescript@5.6.3)': dependencies: - '@eslint-community/regexpp': 4.11.1 + '@eslint-community/regexpp': 4.12.1 '@typescript-eslint/parser': 8.18.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.6.3) '@typescript-eslint/scope-manager': 8.18.0 '@typescript-eslint/type-utils': 8.18.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.6.3) @@ -14156,6 +14476,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@4.9.5) + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.3.7 + eslint: 8.57.1 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/parser@7.18.0(eslint@9.19.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: '@typescript-eslint/scope-manager': 7.18.0 @@ -14204,6 +14537,18 @@ snapshots: '@typescript-eslint/types': 8.18.0 '@typescript-eslint/visitor-keys': 8.18.0 + '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/typescript-estree': 7.18.0(typescript@4.9.5) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@4.9.5) + debug: 4.3.7 + eslint: 8.57.1 + ts-api-utils: 1.3.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/type-utils@7.18.0(eslint@9.19.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: '@typescript-eslint/typescript-estree': 7.18.0(typescript@4.9.5) @@ -14287,6 +14632,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@4.9.5) + eslint: 8.57.1 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/utils@7.18.0(eslint@9.19.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@9.19.0(jiti@1.21.6)) @@ -14330,6 +14686,8 @@ snapshots: '@typescript-eslint/types': 8.18.0 eslint-visitor-keys: 4.2.0 + '@ungap/structured-clone@1.3.0': {} + '@vitejs/plugin-vue-jsx@2.1.1(vite@3.2.11(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5))': dependencies: '@babel/core': 7.25.8 @@ -14601,6 +14959,27 @@ snapshots: '@vue/devtools-api@6.6.4': {} + '@vue/eslint-config-prettier@9.0.0(eslint@8.57.1)(prettier@3.5.3)': + dependencies: + eslint: 8.57.1 + eslint-config-prettier: 9.1.0(eslint@8.57.1) + eslint-plugin-prettier: 5.2.3(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.5.3) + prettier: 3.5.3 + transitivePeerDependencies: + - '@types/eslint' + + '@vue/eslint-config-typescript@13.0.0(eslint-plugin-vue@9.29.1(eslint@8.57.1))(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 + eslint-plugin-vue: 9.29.1(eslint@8.57.1) + vue-eslint-parser: 9.4.3(eslint@8.57.1) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + '@vue/language-core@1.8.27(typescript@4.9.5)': dependencies: '@volar/language-core': 1.11.1 @@ -14683,6 +15062,8 @@ snapshots: js-beautify: 1.15.1 vue-component-type-helpers: 2.1.6 + '@vue/tsconfig@0.5.1': {} + '@vuedx/compiler-sfc@0.7.2': dependencies: '@vue/compiler-core': 3.5.12 @@ -14839,7 +15220,7 @@ snapshots: fp-ts: 2.16.9 inferred-types: 0.37.6(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) markdown-it: 13.0.2 - vite-plugin-md: 0.22.5(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) + vite-plugin-md: 0.22.5(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) transitivePeerDependencies: - '@edge-runtime/vm' - '@vitejs/plugin-vue' @@ -14864,7 +15245,7 @@ snapshots: fp-ts: 2.16.9 inferred-types: 0.37.6(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) markdown-it: 13.0.2 - vite-plugin-md: 0.22.5(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) + vite-plugin-md: 0.22.5(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) transitivePeerDependencies: - '@edge-runtime/vm' - '@vitejs/plugin-vue' @@ -14889,7 +15270,7 @@ snapshots: fp-ts: 2.16.9 inferred-types: 0.37.6(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) markdown-it: 13.0.2 - vite-plugin-md: 0.22.5(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) + vite-plugin-md: 0.22.5(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) transitivePeerDependencies: - '@edge-runtime/vm' - '@vitejs/plugin-vue' @@ -14907,28 +15288,6 @@ snapshots: - terser - vite - '@yankeeinlondon/builder-api@1.4.1(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)': - dependencies: - '@types/markdown-it': 12.2.3 - '@yankeeinlondon/happy-wrapper': 2.10.1(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) - fp-ts: 2.16.9 - inferred-types: 0.37.6(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) - markdown-it: 13.0.2 - vite-plugin-md: 0.22.5(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) - transitivePeerDependencies: - - '@edge-runtime/vm' - - '@vitest/browser' - - '@vitest/ui' - - encoding - - jsdom - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - '@yankeeinlondon/gray-matter@6.2.1(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)': dependencies: inferred-types: 0.37.6(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) @@ -15009,10 +15368,6 @@ snapshots: acorn: 8.14.0 acorn-walk: 8.3.4 - acorn-jsx@5.3.2(acorn@8.13.0): - dependencies: - acorn: 8.13.0 - acorn-jsx@5.3.2(acorn@8.14.0): dependencies: acorn: 8.14.0 @@ -15675,7 +16030,7 @@ snapshots: dependencies: bumpp: 8.2.1 callsites: 4.2.0 - inferred-types: 0.37.6(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) + inferred-types: 0.37.6(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) vitest: 0.25.8(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) transitivePeerDependencies: - '@edge-runtime/vm' @@ -16429,7 +16784,7 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 - cosmiconfig-typescript-loader@4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6(typescript@4.9.5))(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3))(typescript@5.6.3): + cosmiconfig-typescript-loader@4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6(typescript@5.6.3))(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5))(typescript@5.6.3): dependencies: '@types/node': 20.5.1 cosmiconfig: 8.3.6(typescript@5.6.3) @@ -16443,10 +16798,10 @@ snapshots: jiti: 1.21.6 typescript: 5.6.3 - cosmiconfig-typescript-loader@5.1.0(@types/node@20.5.1)(cosmiconfig@9.0.0(typescript@5.6.3))(typescript@4.9.5): + cosmiconfig-typescript-loader@5.1.0(@types/node@20.5.1)(cosmiconfig@9.0.0(typescript@4.9.5))(typescript@4.9.5): dependencies: '@types/node': 20.5.1 - cosmiconfig: 9.0.0(typescript@5.6.3) + cosmiconfig: 9.0.0(typescript@4.9.5) jiti: 1.21.6 typescript: 4.9.5 @@ -16499,13 +16854,13 @@ snapshots: p-filter: 3.0.0 p-map: 6.0.0 - create-jest@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)): + create-jest@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -16514,13 +16869,13 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)): + create-jest@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -16833,6 +17188,10 @@ snapshots: dependencies: esutils: 2.0.3 + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + dom-accessibility-api@0.5.16: {} dom-serializer@2.0.0: @@ -17354,6 +17713,10 @@ snapshots: dependencies: eslint: 9.19.0(jiti@1.21.6) + eslint-config-prettier@9.1.0(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-import-resolver-node@0.3.9: dependencies: debug: 3.2.7 @@ -17440,6 +17803,29 @@ snapshots: - eslint-import-resolver-webpack - supports-color + eslint-plugin-prettier@5.2.3(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.5.3): + dependencies: + eslint: 8.57.1 + prettier: 3.5.3 + prettier-linter-helpers: 1.0.0 + synckit: 0.9.2 + optionalDependencies: + eslint-config-prettier: 9.1.0(eslint@8.57.1) + + eslint-plugin-vue@9.29.1(eslint@8.57.1): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + eslint: 8.57.1 + globals: 13.24.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.1.2 + semver: 7.6.3 + vue-eslint-parser: 9.4.3(eslint@8.57.1) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + eslint-plugin-vue@9.29.1(eslint@9.19.0(jiti@1.21.6)): dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@9.19.0(jiti@1.21.6)) @@ -17468,6 +17854,49 @@ snapshots: eslint-visitor-keys@4.2.0: {} + eslint@8.57.1: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@eslint-community/regexpp': 4.12.1 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.3.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.3.7 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + eslint@9.19.0(jiti@1.21.6): dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@9.19.0(jiti@1.21.6)) @@ -17524,8 +17953,8 @@ snapshots: espree@9.6.1: dependencies: - acorn: 8.13.0 - acorn-jsx: 5.3.2(acorn@8.13.0) + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) eslint-visitor-keys: 3.4.3 esprima@4.0.1: {} @@ -17588,7 +18017,7 @@ snapshots: execa@8.0.1: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 get-stream: 8.0.1 human-signals: 5.0.0 is-stream: 3.0.0 @@ -17724,6 +18153,8 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-diff@1.3.0: {} + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -17758,6 +18189,10 @@ snapshots: optionalDependencies: picomatch: 4.0.2 + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -17876,6 +18311,12 @@ snapshots: flagged-respawn@1.0.1: {} + flat-cache@3.2.0: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + flat-cache@4.0.1: dependencies: flatted: 3.3.1 @@ -17914,7 +18355,7 @@ snapshots: foreground-child@3.3.0: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 signal-exit: 4.1.0 form-data@4.0.1: @@ -18778,6 +19219,8 @@ snapshots: is-path-cwd@3.0.0: {} + is-path-inside@3.0.3: {} + is-path-inside@4.0.0: {} is-plain-obj@1.1.0: {} @@ -18978,16 +19421,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)): + jest-cli@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) + create-jest: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -18997,16 +19440,16 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)): + jest-cli@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + create-jest: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -19037,7 +19480,7 @@ snapshots: jest-cli@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 @@ -19054,7 +19497,7 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)): + jest-config@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)): dependencies: '@babel/core': 7.25.8 '@jest/test-sequencer': 29.7.0 @@ -19080,12 +19523,12 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 18.19.57 - ts-node: 10.9.2(@types/node@18.19.57)(typescript@5.6.3) + ts-node: 10.9.2(@types/node@20.5.1)(typescript@5.6.3) transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)): + jest-config@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)): dependencies: '@babel/core': 7.25.8 '@jest/test-sequencer': 29.7.0 @@ -19111,12 +19554,12 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 18.19.57 - ts-node: 10.9.2(@types/node@20.5.1)(typescript@4.9.5) + ts-node: 10.9.2(@types/node@18.19.57)(typescript@5.6.3) transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)): + jest-config@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)): dependencies: '@babel/core': 7.25.8 '@jest/test-sequencer': 29.7.0 @@ -19142,7 +19585,7 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 18.19.57 - ts-node: 10.9.2(@types/node@20.5.1)(typescript@5.6.3) + ts-node: 10.9.2(@types/node@20.5.1)(typescript@4.9.5) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -19448,24 +19891,24 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)): + jest@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) + jest-cli: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros - supports-color - ts-node - jest@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)): + jest@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + jest-cli: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -19486,7 +19929,7 @@ snapshots: jest@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) '@jest/types': 29.6.3 import-local: 3.2.0 jest-cli: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) @@ -20178,7 +20621,7 @@ snapshots: mlly@1.7.2: dependencies: - acorn: 8.13.0 + acorn: 8.14.0 pathe: 1.1.2 pkg-types: 1.2.1 ufo: 1.5.4 @@ -20841,8 +21284,14 @@ snapshots: preserve@0.2.0: optional: true + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + prettier@2.8.8: {} + prettier@3.5.3: {} + pretty-format@26.6.2: dependencies: '@jest/types': 26.6.2 @@ -22022,6 +22471,11 @@ snapshots: symbol-tree@3.2.4: {} + synckit@0.9.2: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.8.0 + table@6.8.2: dependencies: ajv: 8.17.1 @@ -22074,6 +22528,8 @@ snapshots: text-extensions@2.4.0: {} + text-table@0.2.0: {} + through2-filter@3.0.0: dependencies: through2: 2.0.5 @@ -22863,11 +23319,11 @@ snapshots: - supports-color - terser - vite-plugin-md@0.22.5(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)): + vite-plugin-md@0.22.5(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)): dependencies: '@vitejs/plugin-vue': 4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) - '@yankeeinlondon/builder-api': 1.4.1(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) - '@yankeeinlondon/gray-matter': 6.2.1(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) + '@yankeeinlondon/builder-api': 1.4.1(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) + '@yankeeinlondon/gray-matter': 6.2.1(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) '@yankeeinlondon/happy-wrapper': 2.10.1(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) markdown-it: 13.0.2 source-map-js: 1.2.1 @@ -22877,6 +23333,7 @@ snapshots: - '@vitest/browser' - '@vitest/ui' - encoding + - happy-dom - jsdom - less - lightningcss @@ -22886,11 +23343,11 @@ snapshots: - supports-color - terser - vite-plugin-md@0.22.5(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)): + vite-plugin-md@0.22.5(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)): dependencies: '@vitejs/plugin-vue': 4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)) - '@yankeeinlondon/builder-api': 1.4.1(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) - '@yankeeinlondon/gray-matter': 6.2.1(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) + '@yankeeinlondon/builder-api': 1.4.1(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) + '@yankeeinlondon/gray-matter': 6.2.1(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) '@yankeeinlondon/happy-wrapper': 2.10.1(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) markdown-it: 13.0.2 source-map-js: 1.2.1 @@ -22900,6 +23357,7 @@ snapshots: - '@vitest/browser' - '@vitest/ui' - encoding + - happy-dom - jsdom - less - lightningcss @@ -22909,7 +23367,7 @@ snapshots: - supports-color - terser - vite-plugin-md@0.22.5(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)): + vite-plugin-md@0.22.5(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)): dependencies: '@vitejs/plugin-vue': 5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)) '@yankeeinlondon/builder-api': 1.4.1(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) @@ -22923,6 +23381,7 @@ snapshots: - '@vitest/browser' - '@vitest/ui' - encoding + - happy-dom - jsdom - less - lightningcss @@ -23271,7 +23730,7 @@ snapshots: '@types/chai': 4.3.20 '@types/chai-subset': 1.3.5 '@types/node': 18.19.57 - acorn: 8.13.0 + acorn: 8.14.0 acorn-walk: 8.3.4 chai: 4.5.0 debug: 4.3.7 @@ -23299,7 +23758,7 @@ snapshots: '@types/chai': 4.3.20 '@types/chai-subset': 1.3.5 '@types/node': 18.19.57 - acorn: 8.13.0 + acorn: 8.14.0 acorn-walk: 8.3.4 chai: 4.5.0 debug: 4.3.7 @@ -23490,6 +23949,19 @@ snapshots: dependencies: vue: 3.5.12(typescript@5.6.3) + vue-eslint-parser@9.4.3(eslint@8.57.1): + dependencies: + debug: 4.3.7 + eslint: 8.57.1 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + lodash: 4.17.21 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + vue-eslint-parser@9.4.3(eslint@9.19.0(jiti@1.21.6)): dependencies: debug: 4.3.7 -- Gitee From ecfd593607c48346b6727f548fb9426b95014dcc Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Mon, 17 Mar 2025 20:31:49 +0800 Subject: [PATCH 059/153] =?UTF-8?q?fix:=20verifyDetail=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/verify-detail.component.tsx | 31 +++++++++---------- .../verify-detail/src/verify-detail.props.ts | 30 +++--------------- 2 files changed, 19 insertions(+), 42 deletions(-) diff --git a/packages/ui-vue/components/verify-detail/src/verify-detail.component.tsx b/packages/ui-vue/components/verify-detail/src/verify-detail.component.tsx index a49989ed494..09be3291a1b 100644 --- a/packages/ui-vue/components/verify-detail/src/verify-detail.component.tsx +++ b/packages/ui-vue/components/verify-detail/src/verify-detail.component.tsx @@ -1,6 +1,6 @@ /* eslint-disable prefer-destructuring */ -import { SetupContext, computed, defineComponent, onBeforeMount, ref } from 'vue'; +import { SetupContext, computed, defineComponent, onBeforeMount, ref, watch } from 'vue'; import { verifyDetailProps, VerifyDetailProps } from './verify-detail.props'; export default defineComponent({ @@ -11,15 +11,14 @@ export default defineComponent({ let _errorLists: any = []; /** 是否默认显示验证信息列表 */ const showList = ref(props.showList); - /** 列表部分最大高度 */ - const maxHeight = ref(props.maxHeight); - /** 默认传入的表单验证信息数组 */ - const verifyList = ref(props.verifyList); - /** 表单验证默认显示的分组信息 */ - const showType = ref(props.showType); + watch(()=> props.showList, ()=> { + showList.value = props.showList; + }); /** 表单验证的种类 */ const verifyType = ref(props.verifyType); - const customClass = ref(props.customClass); + watch(()=> props.verifyType, ()=> { + verifyType.value = props.verifyType; + }); /** 显示详情 */ function show() { @@ -84,7 +83,7 @@ export default defineComponent({ )); } const validator = computed(() => { - return verifyList.value?.length > 0; + return props.verifyList?.length > 0; }); function btnStateClass(tab: any): Record { @@ -110,7 +109,7 @@ export default defineComponent({ return (
- {verifyList.value?.length} + {props.verifyList?.length}
); }); @@ -120,7 +119,7 @@ export default defineComponent({ if (verifyType.value && verifyType.value?.length) { verifyType.value.map((typeItem: any) => { const listObj = { - list: typeItem.type === 'all' ? verifyList.value : [], + list: typeItem.type === 'all' ? props.verifyList : [], show: false, type: typeItem.type }; @@ -128,7 +127,7 @@ export default defineComponent({ }); errorlist.map((errorlistItem: any, index: number) => { - const matchingItem = verifyList.value.filter((verifyListItem: any) => verifyListItem.type === errorlistItem.type); + const matchingItem = props.verifyList.filter((verifyListItem: any) => verifyListItem.type === errorlistItem.type); errorlist[index].list = index !== 0 ? matchingItem : errorlist[index].list; }); @@ -141,13 +140,13 @@ export default defineComponent({ onBeforeMount(() => { handleDisplayText(); - handleShowType(showType.value); - handleActiveList(showType.value); + handleShowType(props.showType); + handleActiveList(props.showType); }); return () => { return ( -
+
{validator.value ? (
{verifyNums.value}
-
+
{renderListContent()}
diff --git a/packages/ui-vue/components/verify-detail/src/verify-detail.props.ts b/packages/ui-vue/components/verify-detail/src/verify-detail.props.ts index 696bca95843..a719cfd5f1d 100644 --- a/packages/ui-vue/components/verify-detail/src/verify-detail.props.ts +++ b/packages/ui-vue/components/verify-detail/src/verify-detail.props.ts @@ -18,38 +18,16 @@ export const verifyDetailProps = { /** 表单验证列表 */ verifyList: { type: Array, - default: [{ - id: '111', - title: '单据信息[销售组织]', - msg: '字段值不能为空', - type: 'empty' - }, - { - id: '222', - title: '单据信息[销售组织]', - msg: '字段值不能为空', - type: 'empty' - }] + default: ()=> [] }, verifyType: { type: Array, - default: [ - { - id: 'vertifyType1', - type: 'all', - title: '全部' - }, - { - id: 'vertifyType3', - type: 'empty', - title: '值为空' - } - ] + default: ()=> [] }, customClass: { type: String, default:'' }, maxHeight: { type: Number, default: 200 } -} as Record; +}; export type VerifyDetailProps = ExtractPropTypes; -export const propsResolver = createPropsResolver(verifyDetailProps, verifyDetailSchema, schemaMapper, schemaResolver, propertyConfig); +export const propsResolver = createPropsResolver(verifyDetailProps, verifyDetailSchema, schemaMapper, schemaResolver, propertyConfig); -- Gitee From 067435ef0e997808681a7c9105160bede32a014a Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 18 Mar 2025 11:28:01 +0800 Subject: [PATCH 060/153] =?UTF-8?q?chore:=20=E5=A2=9E=E5=8A=A0=E5=BF=85?= =?UTF-8?q?=E5=A1=AB=E5=89=AF=E4=BD=9C=E7=94=A8=E5=99=A8=EF=BC=9B=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=AE=9E=E4=BD=93=E3=80=81=E5=AD=97=E6=AE=B5=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E5=99=A8=E4=B8=BA=E9=9D=99=E6=80=81=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...tity-store-append-entity-change-handler.ts | 9 +- .../entity-store-value-change-handler.ts | 17 ++-- .../expression-context-builder.ts | 4 +- .../devkit/lib/effector/effector-factory.ts | 4 + packages/devkit/lib/effector/index.ts | 1 + packages/devkit/lib/effector/providers.ts | 6 +- .../devkit/lib/effector/required-effector.ts | 13 +++ .../lib/expression/expression-registry.ts | 29 +------ packages/devkit/lib/expression/types.ts | 2 +- .../lib/module/configs/module-config.ts | 2 +- .../entity-schema/entity-schema.ts | 2 +- packages/devkit/rollup.config.js | 12 +-- .../before-edit-cell-callback-handler.ts | 11 +-- .../src/callback-handler/providers.ts | 3 +- packages/renderer/src/composition/index.ts | 2 - .../src/composition/use-entity-resolver.ts | 10 --- .../src/composition/use-field-resolver.ts | 10 --- .../src/composition/use-module-config.ts | 2 +- .../src/composition/use-pagination.ts | 5 +- .../src/composition/use-ui-binding.ts | 9 +- .../expression-config-builder.ts | 82 +++++++++++++++++++ .../config-builders/module-config-builder.ts | 29 +++++-- .../end-edit-cell-event-handler.ts | 11 +-- .../model-value-update-event-handler.ts | 10 ++- .../renderer/src/event-handler/providers.ts | 17 ++-- .../src/resolvers/data-source-resolver.ts | 12 +-- .../src/resolvers/entity-path-resolver.ts | 10 +-- .../renderer/src/resolvers/entity-resolver.ts | 16 ++-- .../renderer/src/resolvers/field-resolver.ts | 15 +--- .../src/resolvers/model-value-resolver.ts | 13 +-- packages/renderer/src/resolvers/providers.ts | 11 +-- packages/renderer/src/types.ts | 44 +++------- 32 files changed, 216 insertions(+), 207 deletions(-) create mode 100644 packages/devkit/lib/effector/required-effector.ts delete mode 100644 packages/renderer/src/composition/use-entity-resolver.ts delete mode 100644 packages/renderer/src/composition/use-field-resolver.ts create mode 100644 packages/renderer/src/config-builders/expression-config-builder.ts diff --git a/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts index ad223c1b931..0d68080ffd2 100644 --- a/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts @@ -40,8 +40,8 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler if (this.isElementExpression(expressionObject) || this.isStateExpression(expressionObject)) { return; } - // 如果是可见、必填、只读表达式,则路径中不需要拼接数据id,这些表达式只与界面相关。或者说这些表达式只需要依赖表达式结果,不需要副作用器 - if (expressionObject.type === ExpressionType.Visible || expressionObject.type === ExpressionType.Required || expressionObject.type === ExpressionType.Readonly) { + // 如果是可见、只读表达式,则路径中不需要拼接数据id,这些表达式只与界面相关。或者说这些表达式只需要依赖表达式结果,不需要副作用器 + if (expressionObject.type === ExpressionType.Visible || expressionObject.type === ExpressionType.Readonly) { return; } this.effect(change, expressionObject, result); @@ -52,11 +52,6 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler if (!effector) { return; } - // 需要处理校验、聚合类计算表达式 - if (expressionObject.type === ExpressionType.Validate) { - // 校验场景仅处理当前行场景,多条数据场景不处理,再保存时触发校验 - return null; - } const paths = this.buildEffectPaths(change, expressionObject); const option: EffectOption = { path: paths, message: expressionObject.message, messageType: expressionObject.messageType }; effector.effect(expressionObject, result, option); diff --git a/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts index 21a062435cf..2cce5b76bc9 100644 --- a/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts @@ -29,7 +29,9 @@ export class EntityStoreValueChangeHandler extends AbstractChangeHandler { return; } matches.forEach((expressionObject: ExpressionObject) => { - if (this.isElementExpression(expressionObject)) { + // 只读表达式,卡片场景依赖结果集、表格场景需要在编辑前重新计算,因此只需要更新结果集 + // 可见表达式,卡片场景依赖结果集、表格场景列可见和行数据没有关系,因此只需要更新结果集 + if (this.isElementExpression(expressionObject) || expressionObject.type === ExpressionType.Visible || expressionObject.type === ExpressionType.Readonly) { const expressionContextBuilder = new ExpressionContextBuilder(); const expressionContext = expressionContextBuilder.buildContext(this.viewModel); const result = this.expressionExecutor.compile(expressionObject, expressionContext); @@ -101,16 +103,6 @@ export class EntityStoreValueChangeHandler extends AbstractChangeHandler { if ((!childrenEntities || childrenEntities.getEntities().length < 1) && (expressionObject.type === ExpressionType.Compute || expressionObject.type === ExpressionType.Dependency)) { return; } - if (expressionObject.type === ExpressionType.Readonly || expressionObject.type === ExpressionType.Visible || expressionObject.type === ExpressionType.Required) { - // 只读、显隐、必填表达式不需要逐行处理 - const result = this.executeExpression(expressionObject, currentRows); - const convertedResult = this.convertBooleanTypeExpressionResult(expressionObject, result); - expressionObject.result = convertedResult; - if (expressionObject.id) { - this.expressionResult.set(expressionObject.id, expressionObject.result); - } - return; - } childrenEntities?.getEntities().forEach((entity) => { const childrenCurrentRows = currentRows.concat({ bindingPath: `/${changePaths.concat(expressionEntityPath).join('/')}`, primaryValue: entity.idValue }); const result = this.executeExpression(expressionObject, childrenCurrentRows); @@ -138,7 +130,8 @@ export class EntityStoreValueChangeHandler extends AbstractChangeHandler { if (!deps || deps.length < 1 || change.ns !== expressionObject.ns) { return false; } - const { entityPaths: changePaths } = this.resolveChangePath(change); + const { entityPaths, propertyPaths } = this.resolveChangePath(change); + const changePaths = entityPaths.concat(propertyPaths); changePaths.splice(0, 0, ENTITY_TEMPLATE); return deps.includes(changePaths.join('/')); }); diff --git a/packages/devkit/lib/change-handler/expression-context-builder.ts b/packages/devkit/lib/change-handler/expression-context-builder.ts index d5352005839..b5444c99e39 100644 --- a/packages/devkit/lib/change-handler/expression-context-builder.ts +++ b/packages/devkit/lib/change-handler/expression-context-builder.ts @@ -31,7 +31,7 @@ export class ExpressionContextBuilder { return result; } private buildEntityContext(entitySchema: EntitySchema, entityStore: EntityStore> | null, currentRows?: { bindingPath: string, primaryValue: string; }[]) { - function traverse(currentContext: any, schema: EntityListFieldSchema, paths: string[] = []) { + const traverse = (currentContext: any, schema: EntityListFieldSchema, paths: string[] = []) => { const fullPath = paths.concat(schema.name).join('/'); const bindingList = entityStore?.getEntityListByPath('/' + fullPath); if (!bindingList || bindingList.getEntities().length < 1) { @@ -54,7 +54,7 @@ export class ExpressionContextBuilder { traverse(node, subSchema, paths.concat(schema.name)); }); } - } + }; const row = currentRows && currentRows.find((row) => row.bindingPath === '' || row.bindingPath === '/') || null; const primaryValue = row && row.primaryValue || entityStore?.getCurrentEntity().idValue; const entity = entityStore?.getEntityById(primaryValue); diff --git a/packages/devkit/lib/effector/effector-factory.ts b/packages/devkit/lib/effector/effector-factory.ts index 7f23b407b60..5f61a57e7ce 100644 --- a/packages/devkit/lib/effector/effector-factory.ts +++ b/packages/devkit/lib/effector/effector-factory.ts @@ -3,6 +3,7 @@ import { EffectorRegistry } from "./effector-registry"; import { Effector } from "./types"; import { ValidateEffector } from "./validate-effector"; import { EntityStoreEffector } from "./entity-store-effector"; +import { RequiredValidator } from "../store/form/validation/validators/required-validator"; export class EffectorFactory { constructor(private effectorRegistry: EffectorRegistry) { @@ -21,6 +22,9 @@ export class EffectorFactory { } else if (type === ExpressionType.Validate) { // 校验表达式 return nsEffectors.find((effector: Effector) => effector instanceof ValidateEffector); + } else if (type === ExpressionType.Required) { + // 必填表达式 + return nsEffectors.find((effector: Effector) => effector instanceof RequiredValidator); } else { console.warn(`EffectorFactory 没有找到对应的副作用器 ${type}`); return null; diff --git a/packages/devkit/lib/effector/index.ts b/packages/devkit/lib/effector/index.ts index 921db7ad7be..6c52abbc967 100644 --- a/packages/devkit/lib/effector/index.ts +++ b/packages/devkit/lib/effector/index.ts @@ -2,6 +2,7 @@ export * from './types'; export * from './tokens'; export * from './entity-store-effector'; export * from './validate-effector'; +export * from './required-effector'; export * from './effector-registry'; export * from './effector-factory'; export * from './providers'; diff --git a/packages/devkit/lib/effector/providers.ts b/packages/devkit/lib/effector/providers.ts index ed4be7187f5..a1cb92e4c8f 100644 --- a/packages/devkit/lib/effector/providers.ts +++ b/packages/devkit/lib/effector/providers.ts @@ -5,10 +5,12 @@ import { ValidateEffector } from "./validate-effector"; import { EffectorRegistry } from "./effector-registry"; import { EffectorFactory } from "./effector-factory"; import { ViewModel } from "../viewmodel/index"; +import { RequiredValidator } from "../store/form/validation/validators/required-validator"; export const effectorProviders: StaticProvider[] = [ - { provide: EFFECTORS_TOKEN, useClass: EntityStoreEffector, deps: [/*NAMESPACE_TOKEN,*/ forwardRef(() => ViewModel)] }, - { provide: EFFECTORS_TOKEN, useClass: ValidateEffector, deps: [/*NAMESPACE_TOKEN,*/ forwardRef(() => ViewModel)] }, + { provide: EFFECTORS_TOKEN, useClass: EntityStoreEffector, deps: [/*NAMESPACE_TOKEN,*/ forwardRef(() => ViewModel)], multi: true }, + { provide: EFFECTORS_TOKEN, useClass: ValidateEffector, deps: [/*NAMESPACE_TOKEN,*/ forwardRef(() => ViewModel)], multi: true }, + { provide: EFFECTORS_TOKEN, useClass: RequiredValidator, deps: [/*NAMESPACE_TOKEN,*/ forwardRef(() => ViewModel)], multi: true }, { provide: EffectorRegistry, useClass: EffectorRegistry, deps: [EFFECTORS_TOKEN] }, { provide: EffectorFactory, useClass: EffectorFactory, deps: [EffectorRegistry] }, ]; diff --git a/packages/devkit/lib/effector/required-effector.ts b/packages/devkit/lib/effector/required-effector.ts new file mode 100644 index 00000000000..463a0ddf369 --- /dev/null +++ b/packages/devkit/lib/effector/required-effector.ts @@ -0,0 +1,13 @@ +import { ExpressionObject } from '../expression'; +import { ViewModel, ViewModelState } from '../viewmodel'; +import { EffectOption, Effector } from './types'; +export class RequiredEffector implements Effector { + public namespace: string; + constructor(/*public namespace: string, */private viewModel: ViewModel) { + this.namespace = ''; + } + public effect(expressionObject: ExpressionObject, value: any, option?: EffectOption): void { + // 需要根据option中的paths处理 + console.log('RequiredEffector', expressionObject, value, option); + } +} \ No newline at end of file diff --git a/packages/devkit/lib/expression/expression-registry.ts b/packages/devkit/lib/expression/expression-registry.ts index f9e43a00c2d..49be50e6a23 100644 --- a/packages/devkit/lib/expression/expression-registry.ts +++ b/packages/devkit/lib/expression/expression-registry.ts @@ -17,7 +17,7 @@ export class ExpressionRegistry { if (expressionConfig.targetType === 'Field') { path = expressionConfig.target; } - const expressionValue = this.cleanSpecialCharacters(rule.expression); + const expressionValue = rule.value; const expressionObject: ExpressionObject = { id: rule.id, ns: '', @@ -45,31 +45,4 @@ export class ExpressionRegistry { } return DEFAULT_EXPRESSION_VALIDATE_MESSAGE['zh-CHS'][expressionType]; } - private cleanSpecialCharacters(expression: string) { - const entityCode = this.viewModel.entityStore.getEntitySchema().getCode(); - const regex = new RegExp(`[\\'\\"]?\\s*(${entityCode})[\\.\\[\\]a-zA-Z0-9_]+\\s*[\\'\\"]?`, 'g'); - const entityPropertyExpressions: RegExpMatchArray | null = expression.match(regex); - if (Array.isArray(entityPropertyExpressions) && entityPropertyExpressions.length > 0) { - // 解析出所有实体相关的字符串,以主实体名字开头,包含主实体属性或子表 - entityPropertyExpressions.forEach((item: string) => { - if (item.indexOf('.') === -1) { - return; - } - // 去数组 - if (/\[\d\]/g.test(item)) { - const replacer = item.replace(/\[\d\]/g, ''); - expression = this.replaceAll(expression, item, replacer); - } - // 去星号 - if (/\*/g.test(item)) { - const replacer = item.replace(/\*/g, ''); - expression = this.replaceAll(expression, item, replacer); - } - }); - } - return expression; - } - private replaceAll(originalValue: string, search: string, replacer: string) { - return originalValue.split(search).join(replacer); - } } diff --git a/packages/devkit/lib/expression/types.ts b/packages/devkit/lib/expression/types.ts index a76fc8cf7b4..bcc20ef998e 100644 --- a/packages/devkit/lib/expression/types.ts +++ b/packages/devkit/lib/expression/types.ts @@ -57,7 +57,7 @@ export enum ExpressionMessageType { export interface ExpressionRule { id: string; type: ExpressionType; - expression: string; + value: string; message?: string; } export interface ExpressionConfig { diff --git a/packages/devkit/lib/module/configs/module-config.ts b/packages/devkit/lib/module/configs/module-config.ts index fcf942ee29b..9fcf75701b2 100644 --- a/packages/devkit/lib/module/configs/module-config.ts +++ b/packages/devkit/lib/module/configs/module-config.ts @@ -23,7 +23,7 @@ interface ModuleConfig { formArrayStores: FormArrayStoreConfig[]; viewModels: ViewModelConfig[]; - expressions?: ExpressionConfig[]; + expressions?: ExpressionConfig[] | null; } export { ModuleConfig }; \ No newline at end of file diff --git a/packages/devkit/lib/store/entity-store/entity-schema/entity-schema.ts b/packages/devkit/lib/store/entity-store/entity-schema/entity-schema.ts index 6b172d0eda6..014d2e0ccfb 100644 --- a/packages/devkit/lib/store/entity-store/entity-schema/entity-schema.ts +++ b/packages/devkit/lib/store/entity-store/entity-schema/entity-schema.ts @@ -138,7 +138,7 @@ class EntitySchema { break; } propertyPaths.push(fieldSchema.name); - if (!(fieldSchema.type !== FieldType.Entity)) { + if (fieldSchema.type !== FieldType.Entity) { break; } const entityFieldSchema = fieldSchema as EntityFieldSchema; diff --git a/packages/devkit/rollup.config.js b/packages/devkit/rollup.config.js index 498fe32f67a..3c276c14e50 100644 --- a/packages/devkit/rollup.config.js +++ b/packages/devkit/rollup.config.js @@ -57,11 +57,11 @@ export default { template: "sunburst", filename: process.cwd() + `/dist-rollup/@farris/devkit-vue.html`, }), - terser({ - keep_fnames: true, - format: { - comments: /^!/ - } - }) + // terser({ + // keep_fnames: true, + // format: { + // comments: /^!/ + // } + // }) ], }; diff --git a/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts b/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts index 01e7f0c057c..003f58552ec 100644 --- a/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts +++ b/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts @@ -9,9 +9,7 @@ export class BeforeEditCallCallbackHandler extends CallbackHandler { public callbackType: string | null = 'beforeEditCell'; constructor( private module: Module, - private formMetadataService: FormMetadataService, - private entityResolver: DataSourceResolver, - private fieldResolver: FieldResolver, + private formMetadataService: FormMetadataService ) { super(); } @@ -40,11 +38,11 @@ export class BeforeEditCallCallbackHandler extends CallbackHandler { if (!field) { return true; } - const { dataSource: entitySource } = this.fieldResolver.resolve(field) || {}; + const { dataSource: entitySource } = FieldResolver.resolve(this.entitySchema, field) || {}; if (!entitySource) { return true; } - const { bindingPaths = [], primaryKey = 'id' } = this.entityResolver.resolve(entitySource) || {}; + const { bindingPaths = [], primaryKey = 'id' } = DataSourceResolver.resolve(this.entitySchema, entitySource) || {}; const entityListPath = `/${bindingPaths.join('/')}`; const entityList = entityStore?.getEntityListByPath(entityListPath); const primaryValue = rawData[primaryKey]; @@ -55,4 +53,7 @@ export class BeforeEditCallCallbackHandler extends CallbackHandler { editor.idValue = get(entity, valueField); return true; } + private get entitySchema() { + return this.formMetadataService.getEntity(); + } } diff --git a/packages/renderer/src/callback-handler/providers.ts b/packages/renderer/src/callback-handler/providers.ts index 15afc00e44e..78b26cf45de 100644 --- a/packages/renderer/src/callback-handler/providers.ts +++ b/packages/renderer/src/callback-handler/providers.ts @@ -3,10 +3,9 @@ import { CALLBACK_HANDLER_TOKEN } from "../tokens"; import { BeforeEditCallCallbackHandler } from "./before-edit-cell-callback-handler"; import { CallbackHandlerRegistry } from "./callback-handler-registry"; import { FormMetadataService } from "../service"; -import { DataSourceResolver, FieldResolver } from "../resolvers"; export const callbackHandlerProviders: StaticProvider[] = [ - { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeEditCallCallbackHandler, deps: [Module, FormMetadataService, DataSourceResolver, FieldResolver], multi: true }, + { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeEditCallCallbackHandler, deps: [Module, FormMetadataService], multi: true }, { provide: CallbackHandlerRegistry, useClass: CallbackHandlerRegistry, deps: [Injector] } ]; diff --git a/packages/renderer/src/composition/index.ts b/packages/renderer/src/composition/index.ts index bb5ef61216b..fdda018542f 100644 --- a/packages/renderer/src/composition/index.ts +++ b/packages/renderer/src/composition/index.ts @@ -1,5 +1,3 @@ -export * from './use-entity-resolver'; -export * from './use-field-resolver'; export * from './use-model-value-resolver'; export * from './use-lookup-provide'; export * from './use-component-providers'; diff --git a/packages/renderer/src/composition/use-entity-resolver.ts b/packages/renderer/src/composition/use-entity-resolver.ts deleted file mode 100644 index 81b039e35d4..00000000000 --- a/packages/renderer/src/composition/use-entity-resolver.ts +++ /dev/null @@ -1,10 +0,0 @@ - - -import { Injector } from "@farris/devkit-vue"; -import { UseEntityResolver } from "../types"; -import { DataSourceResolver } from "../resolvers"; - -export function useEntityResolver(injector: Injector): UseEntityResolver { - const entityResolver = injector.get(DataSourceResolver, undefined); - return entityResolver; -} diff --git a/packages/renderer/src/composition/use-field-resolver.ts b/packages/renderer/src/composition/use-field-resolver.ts deleted file mode 100644 index d34c323966d..00000000000 --- a/packages/renderer/src/composition/use-field-resolver.ts +++ /dev/null @@ -1,10 +0,0 @@ - - -import { Injector } from "@farris/devkit-vue"; -import { UseFieldResolver } from "../types"; -import { FieldResolver } from "../resolvers"; - -export function useFieldResolver(injector: Injector): UseFieldResolver { - const fieldResolver = injector.get(FieldResolver, undefined); - return fieldResolver; -} diff --git a/packages/renderer/src/composition/use-module-config.ts b/packages/renderer/src/composition/use-module-config.ts index 31ef6f050c3..a983a7871fe 100644 --- a/packages/renderer/src/composition/use-module-config.ts +++ b/packages/renderer/src/composition/use-module-config.ts @@ -48,7 +48,7 @@ export function useModuleConfig(metadata: Ref, uiProviders: StaticProvider[], re ...eventHanderProviders, ...resolverProviders, ...callbackHandlerProviders - ], + ] }; const moduleConfigBuilder = new ModuleConfigBuilder(moduleMetaContext); const moduleConfig = moduleConfigBuilder.build(); diff --git a/packages/renderer/src/composition/use-pagination.ts b/packages/renderer/src/composition/use-pagination.ts index c717ab9d911..f02df21102d 100644 --- a/packages/renderer/src/composition/use-pagination.ts +++ b/packages/renderer/src/composition/use-pagination.ts @@ -2,20 +2,19 @@ import { Injector } from "@farris/devkit-vue"; import { useFormMetadataService } from "./use-form-metadata-service"; import { useModule } from "./use-module"; import { ENTITY_STORE_SUFFIX, MetadataType } from "../types"; -import { useEntityResolver } from "./use-entity-resolver"; import { MODULE_CONFIG_ID_TOKEN } from "../tokens"; +import { DataSourceResolver } from "../resolvers"; export function usePagination(injector: Injector) { const formMetadata = useFormMetadataService(injector); const module = useModule(injector); - const entityResolver = useEntityResolver(injector); const datagridComponents = formMetadata.getMetadataByType(MetadataType.DataGrid); datagridComponents.forEach((metadata: Record) => { const { pagination = {}, dataSource = '' } = metadata.schema; const { enable, mode, size: pageSize = 20 } = pagination; if (enable && mode === 'server' && dataSource) { - const { bindingPaths } = entityResolver.resolve(dataSource) || {}; + const { bindingPaths } = DataSourceResolver.resolve(formMetadata.getEntity() ,dataSource) || {}; if (bindingPaths) { const moduleConfigId = injector.get(MODULE_CONFIG_ID_TOKEN); const storeId = moduleConfigId + ENTITY_STORE_SUFFIX; diff --git a/packages/renderer/src/composition/use-ui-binding.ts b/packages/renderer/src/composition/use-ui-binding.ts index 4b20dd34873..1b3d9aed07b 100644 --- a/packages/renderer/src/composition/use-ui-binding.ts +++ b/packages/renderer/src/composition/use-ui-binding.ts @@ -2,14 +2,11 @@ import { Injector } from '@farris/devkit-vue'; import { useDataGridBinding, useFormGroupBinding, useLookupBinding, useTreeGridBinding } from '@farris/ui-binding-vue'; import { useFormMetadataService } from './use-form-metadata-service'; -import { useEntityResolver } from './use-entity-resolver'; import { useModule } from './use-module'; -import { useFieldResolver } from './use-field-resolver'; +import { DataSourceResolver, FieldResolver } from '../resolvers'; export function useUIBinding(injector: Injector) { const formMetadata = useFormMetadataService(injector); - const entityResolver = useEntityResolver(injector); - const fieldResolver = useFieldResolver(injector); const module = useModule(injector); function onComponentReady(payload: any) { @@ -39,7 +36,7 @@ export function useUIBinding(injector: Injector) { if (!field) { return; } - const { dataSource } = fieldResolver.resolve(field) || {}; + const { dataSource } = FieldResolver.resolve(formMetadata.getEntity(),field) || {}; if (!dataSource) { return; } @@ -59,7 +56,7 @@ export function useUIBinding(injector: Injector) { if (!dataSource) { return null; } - const entity = entityResolver.resolve(dataSource); + const entity = DataSourceResolver.resolve(formMetadata.getEntity(), dataSource); if (!entity) { return null; } diff --git a/packages/renderer/src/config-builders/expression-config-builder.ts b/packages/renderer/src/config-builders/expression-config-builder.ts new file mode 100644 index 00000000000..ef26fc03b3d --- /dev/null +++ b/packages/renderer/src/config-builders/expression-config-builder.ts @@ -0,0 +1,82 @@ +import { ExpressionBindingType } from "@farris/devkit-vue"; +import { DataSourceResolver, FieldResolver } from "../resolvers"; +import { ExpressionMetadata } from "../types"; + +export class ExpressionConfigBuilder { + constructor(private formMeta: any) { } + public build(expression: ExpressionMetadata) { + this.convertFieldExpression(expression); + this.buildRules(expression); + return expression; + } + private convertFieldExpression(expression: ExpressionMetadata) { + if (expression.targetType === ExpressionBindingType.Field) { + const path = this.convertFieldIdToPath(expression.target); + if (!path) { + console.warn(`expression target ${expression.target} not found`); + return; + } + expression.target = path; + } + } + private buildRules(expression: ExpressionMetadata) { + const { rules } = expression; + if (!rules || rules.length < 1) { + return; + } + rules.forEach((rule) => { + if (!rule.value) { + return; + } + const config = JSON.parse(rule.value); + const expression = config.expr; + rule.value = this.cleanSpecialCharacters(expression); + }); + } + private cleanSpecialCharacters(expression: string) { + const regex = new RegExp(`[\\'\\"]?\\s*(${this.entityCode})[\\.\\[\\]a-zA-Z0-9_]+\\s*[\\'\\"]?`, 'g'); + const entityPropertyExpressions: RegExpMatchArray | null = expression.match(regex); + if (Array.isArray(entityPropertyExpressions) && entityPropertyExpressions.length > 0) { + // 解析出所有实体相关的字符串,以主实体名字开头,包含主实体属性或子表 + entityPropertyExpressions.forEach((item: string) => { + if (item.indexOf('.') === -1) { + return; + } + // 去数组 + if (/\[\d\]/g.test(item)) { + const replacer = item.replace(/\[\d\]/g, ''); + expression = this.replaceAll(expression, item, replacer); + } + // 去星号 + if (/\*/g.test(item)) { + const replacer = item.replace(/\*/g, ''); + expression = this.replaceAll(expression, item, replacer); + } + }); + } + return expression; + } + private convertFieldIdToPath(id: string): string | null { + const resolvedField = FieldResolver.resolve(this.entitySchema, id); + if (!resolvedField) { + return null; + } + const { dataSource, bindingPath } = resolvedField; + const resolvedDataSource = DataSourceResolver.resolve(this.entitySchema, dataSource); + if (!resolvedDataSource) { + return null; + } + const { bindingPaths } = resolvedDataSource; + const fullPaths = bindingPaths.concat(bindingPath.split('.')); + return fullPaths.join('/'); + } + private get entitySchema() { + return this.formMeta.module.entity[0].entities[0]; + } + private get entityCode() { + return this.entitySchema.code; + } + private replaceAll(originalValue: string, search: string, replacer: string) { + return originalValue.split(search).join(replacer); + } +} diff --git a/packages/renderer/src/config-builders/module-config-builder.ts b/packages/renderer/src/config-builders/module-config-builder.ts index 539989003ed..2b839fb44fd 100644 --- a/packages/renderer/src/config-builders/module-config-builder.ts +++ b/packages/renderer/src/config-builders/module-config-builder.ts @@ -1,14 +1,17 @@ import { StaticProvider, - EntityStoreConfig, UIStateConfig, StateMachineConfig, RepositoryConfig, + EntityStoreConfig, StateMachineConfig, RepositoryConfig, ViewModelConfig, ModuleConfig, UIStoreConfig, + ExpressionConfig } from '@farris/devkit-vue'; import { EntityStoreConfigBuilder } from './entity-store-config-builder'; import { RepositoryConfigBuilder } from './repository-config-builder'; import { UIStoreConfigBuilder } from './ui-store-config-builder'; import { StateMachineConfigBuilder } from './state-machine-config-builder'; import { ViewModelConfigBuilder } from './viewmodel-config-builder'; +import { ExpressionMetadata } from '../types'; +import { ExpressionConfigBuilder } from './expression-config-builder'; /** * 模块配置构造器 @@ -42,8 +45,9 @@ class ModuleConfigBuilder { const uiStoreConfigs = this.buildUIStoreConfigs(formMeta); const stateMachineConfigs = this.buildStateMachineConfigs(formMeta, smMetas); const repositoryConfigs = this.buildRepositoryConfigs(formMeta); - const viewModelConfigs = this.buildViewModelConfigs(formMeta, webCmdMetas,webComponentMetadatas, this.context.viewModelProviders); - + const viewModelConfigs = this.buildViewModelConfigs(formMeta, webCmdMetas, webComponentMetadatas, this.context.viewModelProviders); + const expressionConfigs = this.buildExpressions(formMeta); + const moduleConfig: ModuleConfig = { id, providers, @@ -52,7 +56,7 @@ class ModuleConfigBuilder { stateMachines: stateMachineConfigs, repositories: repositoryConfigs, viewModels: viewModelConfigs, - expressions: formMeta.module.expressions, + expressions: expressionConfigs }; return moduleConfig; @@ -124,8 +128,8 @@ class ModuleConfigBuilder { /** * 构造视图模型配置 */ - public buildViewModelConfigs(formMeta: any, webCmdMetas: any[],webComponentMetadatas: any[], viewModelProviders: any[]): ViewModelConfig[] { - const builder = new ViewModelConfigBuilder(formMeta, webCmdMetas,webComponentMetadatas, viewModelProviders); + public buildViewModelConfigs(formMeta: any, webCmdMetas: any[], webComponentMetadatas: any[], viewModelProviders: any[]): ViewModelConfig[] { + const builder = new ViewModelConfigBuilder(formMeta, webCmdMetas, webComponentMetadatas, viewModelProviders); const configs: ViewModelConfig[] = []; const viewModelNodes = formMeta.module.viewmodels as any[]; viewModelNodes.forEach((viewModelNode) => { @@ -138,6 +142,19 @@ class ModuleConfigBuilder { return configs; } + + private buildExpressions(formMeta: any): ExpressionConfig[] | null { + const { expressions } = formMeta.module; + if (!expressions || !Array.isArray(expressions) || expressions.length < 1) { + return null; + } + const expressionConfigBuilder = new ExpressionConfigBuilder(formMeta); + expressions.forEach((expression: ExpressionMetadata) => { + expressionConfigBuilder.build(expression); + }); + return expressions; + } + } export { ModuleConfigBuilder }; diff --git a/packages/renderer/src/event-handler/end-edit-cell-event-handler.ts b/packages/renderer/src/event-handler/end-edit-cell-event-handler.ts index 123a52c9be2..793c02841ab 100644 --- a/packages/renderer/src/event-handler/end-edit-cell-event-handler.ts +++ b/packages/renderer/src/event-handler/end-edit-cell-event-handler.ts @@ -2,17 +2,15 @@ import { EntityPathBuilder, EntityPathNode, EntityPathNodeType, Injector, Module import { EventEmitter } from "../common"; import { ComponentService, FormMetadataService } from "../service"; import { EventHandler } from "./types"; -import { DataSourceResolver, FieldResolver } from "../resolvers"; import { ENTITY_STORE_SUFFIX, ViewEvent } from "../types"; import { get } from "lodash-es"; +import { DataSourceResolver, FieldResolver } from "../resolvers"; export class EndEditCellEventHandler implements EventHandler { constructor( private emitter: EventEmitter, private formMetadataService: FormMetadataService, private module: Module, - private entityResolver: DataSourceResolver, - private fieldResolver: FieldResolver, private componentService: ComponentService, private injector: Injector) { } @@ -34,11 +32,11 @@ export class EndEditCellEventHandler implements EventHandler { if (!field) { return; } - const { bindingPath, dataSource } = this.fieldResolver.resolve(field) || {}; + const { bindingPath, dataSource } = FieldResolver.resolve(this.entitySchema, field) || {}; if (!dataSource || !bindingPath) { return; } - const { bindingPaths = [], primaryKey = 'id' } = this.entityResolver.resolve(dataSource) || {}; + const { bindingPaths = [], primaryKey = 'id' } = DataSourceResolver.resolve(this.entitySchema, dataSource) || {}; const primaryValue = row?.raw[primaryKey]; const fieldPath = bindingPath.split('.'); @@ -99,4 +97,7 @@ export class EndEditCellEventHandler implements EventHandler { dispose(): void { this.emitter.off('endEditCell', (payload: ViewEvent) => this.onEndEditCell(payload)); } + private get entitySchema() { + return this.formMetadataService.getEntity(); + } } diff --git a/packages/renderer/src/event-handler/model-value-update-event-handler.ts b/packages/renderer/src/event-handler/model-value-update-event-handler.ts index 8ff0a54ce21..463e7541a39 100644 --- a/packages/renderer/src/event-handler/model-value-update-event-handler.ts +++ b/packages/renderer/src/event-handler/model-value-update-event-handler.ts @@ -9,7 +9,7 @@ import { DataSourceResolver, FieldResolver } from "../resolvers"; export class ModelValueUpdateEventHandler implements EventHandler { - constructor(private emitter: EventEmitter, private formMetadataService: FormMetadataService, private module: Module, private entityResolver: DataSourceResolver, private fieldResolver: FieldResolver, private injector: Injector) { + constructor(private emitter: EventEmitter, private formMetadataService: FormMetadataService, private module: Module, private injector: Injector) { } private onModelValueUpdate(payload: any) { @@ -20,7 +20,7 @@ export class ModelValueUpdateEventHandler implements EventHandler { if (!fieldId) { return; } - const field = this.fieldResolver.resolve(fieldId); + const field = FieldResolver.resolve(this.entitySchema, fieldId); if (!field) { return; } @@ -29,7 +29,7 @@ export class ModelValueUpdateEventHandler implements EventHandler { console.error(`Invalid field: ${JSON.stringify(field)}`); return; } - const entity = this.entityResolver.resolve(dataSource); + const entity = DataSourceResolver.resolve(this.entitySchema, dataSource); if (!entity) { console.error(`Invalid datasource: ${dataSource}`); return; @@ -49,7 +49,9 @@ export class ModelValueUpdateEventHandler implements EventHandler { } viewModel?.entityStore?.setValueByPath(entityPath, value); } - + private get entitySchema() { + return this.formMetadataService.getEntity(); + } public bind() { this.emitter.on('update:modelValue', (payload: ViewEvent) => this.onModelValueUpdate(payload)); } diff --git a/packages/renderer/src/event-handler/providers.ts b/packages/renderer/src/event-handler/providers.ts index 367b657b0b1..298fbc9d4b3 100644 --- a/packages/renderer/src/event-handler/providers.ts +++ b/packages/renderer/src/event-handler/providers.ts @@ -3,7 +3,6 @@ import { EventEmitter } from "../common"; import { ComponentService, FormMetadataService } from "../service"; import { EVENT_HANDLERS_TOKEN } from "../tokens"; import { LookupDataMappingEventHandler } from "./lookup-data-mapping-event-handler"; -import { DataSourceResolver, FieldResolver } from "../resolvers"; import { ModelValueUpdateEventHandler } from "./model-value-update-event-handler"; import { EndEditCellEventHandler } from "./end-edit-cell-event-handler"; import { DataViewRowClickEventHandler } from "./data-view-row-click-event-handler"; @@ -15,12 +14,12 @@ import { QuerySolutionConditionChangeEventHandler } from "./query-solution-condi export const eventHanderProviders: StaticProvider[] = [ { provide: EVENT_HANDLERS_TOKEN, useClass: LookupDataMappingEventHandler, deps: [EventEmitter, FormMetadataService, Module, Injector], multi: true }, - { provide: EVENT_HANDLERS_TOKEN, useClass: ModelValueUpdateEventHandler, deps: [EventEmitter, FormMetadataService, Module, DataSourceResolver, FieldResolver, Injector], multi: true }, - { provide: EVENT_HANDLERS_TOKEN, useClass: EndEditCellEventHandler, deps: [EventEmitter, FormMetadataService, Module, DataSourceResolver, FieldResolver, ComponentService, Injector], multi: true }, - { provide: EVENT_HANDLERS_TOKEN, useClass: DataViewRowClickEventHandler, deps: [EventEmitter, FormMetadataService, Module, DataSourceResolver, FieldResolver, Injector], multi: true }, - { provide: EVENT_HANDLERS_TOKEN, useClass: LookupClearEventHandler, deps: [EventEmitter, FormMetadataService, Module, DataSourceResolver, FieldResolver, Injector], multi: true }, - { provide: EVENT_HANDLERS_TOKEN, useClass: DataGridPageIndexChangeEventHandler, deps: [EventEmitter, FormMetadataService, Module, DataSourceResolver, FieldResolver, Injector], multi: true }, - { provide: EVENT_HANDLERS_TOKEN, useClass: DataGridPageSizeChangeEventHandler, deps: [EventEmitter, FormMetadataService, Module, DataSourceResolver, FieldResolver, Injector], multi: true }, - { provide: EVENT_HANDLERS_TOKEN, useClass: DataGridSelectionChangeEventHandler, deps: [EventEmitter, FormMetadataService, Module, DataSourceResolver, FieldResolver, Injector], multi: true }, - { provide: EVENT_HANDLERS_TOKEN, useClass: QuerySolutionConditionChangeEventHandler, deps: [EventEmitter, FormMetadataService, Module, DataSourceResolver, FieldResolver, Injector], multi: true } + { provide: EVENT_HANDLERS_TOKEN, useClass: ModelValueUpdateEventHandler, deps: [EventEmitter, FormMetadataService, Module, Injector], multi: true }, + { provide: EVENT_HANDLERS_TOKEN, useClass: EndEditCellEventHandler, deps: [EventEmitter, FormMetadataService, Module, ComponentService, Injector], multi: true }, + { provide: EVENT_HANDLERS_TOKEN, useClass: DataViewRowClickEventHandler, deps: [EventEmitter, FormMetadataService, Module, Injector], multi: true }, + { provide: EVENT_HANDLERS_TOKEN, useClass: LookupClearEventHandler, deps: [EventEmitter, FormMetadataService, Module, Injector], multi: true }, + { provide: EVENT_HANDLERS_TOKEN, useClass: DataGridPageIndexChangeEventHandler, deps: [EventEmitter, FormMetadataService, Module, Injector], multi: true }, + { provide: EVENT_HANDLERS_TOKEN, useClass: DataGridPageSizeChangeEventHandler, deps: [EventEmitter, FormMetadataService, Module, Injector], multi: true }, + { provide: EVENT_HANDLERS_TOKEN, useClass: DataGridSelectionChangeEventHandler, deps: [EventEmitter, FormMetadataService, Module, Injector], multi: true }, + { provide: EVENT_HANDLERS_TOKEN, useClass: QuerySolutionConditionChangeEventHandler, deps: [EventEmitter, FormMetadataService, Module, Injector], multi: true } ]; diff --git a/packages/renderer/src/resolvers/data-source-resolver.ts b/packages/renderer/src/resolvers/data-source-resolver.ts index 9a118939a5c..31d553b4c39 100644 --- a/packages/renderer/src/resolvers/data-source-resolver.ts +++ b/packages/renderer/src/resolvers/data-source-resolver.ts @@ -1,15 +1,11 @@ -import { FormMetadataService } from "../service"; +import { EntityMetadata } from "../types"; import { ResolvedEntity } from "./types"; - export class DataSourceResolver { - constructor(private formMetadataService: FormMetadataService) { } - - public resolve(dataSource: string): ResolvedEntity | null { - const entity = this.formMetadataService.getEntity(); - const entityInfo = this.resolveEntity(entity, dataSource); + public static resolve(entityMetadata: EntityMetadata, dataSource: string): ResolvedEntity | null { + const entityInfo = this.resolveEntity(entityMetadata, dataSource); return entityInfo; } - private resolveEntity(entity: Record, entityLabel: string, isRoot: boolean = true): ResolvedEntity | null { + private static resolveEntity(entity: Record, entityLabel: string, isRoot: boolean = true): ResolvedEntity | null { const currentPath = isRoot ? [] : [entity.label]; if (entity.label === entityLabel) { return { diff --git a/packages/renderer/src/resolvers/entity-path-resolver.ts b/packages/renderer/src/resolvers/entity-path-resolver.ts index 386fd259cc2..4ce6642dff2 100644 --- a/packages/renderer/src/resolvers/entity-path-resolver.ts +++ b/packages/renderer/src/resolvers/entity-path-resolver.ts @@ -1,20 +1,18 @@ -import { FormMetadataService } from "../service"; import { EntityFieldMetadata, EntityMetadata } from "../types"; export class EntityPathResolver { - constructor(private formMetadataService: FormMetadataService) { } /** * 解析实体路径,返回实体路径,属性路径 * @param path 字符串,形如/ch1s/username */ - public resolve(path: string | string[]) { + public static resolve(entityMetadata: EntityMetadata, path: string | string[]) { const paths = typeof path === 'string' ? path.split('/').filter((p) => p) : path; const entityPaths = []; const propertyPaths = []; if (!paths) { throw new Error(`Invalid argument: path=${JSON.stringify(path)}`); } - let currentNode: Record = this.formMetadataService.getEntity(); + let currentNode: Record = entityMetadata; for (let index = 0; index < paths.length; index++) { const path = paths[index]; const entity = this.getEntityProperty(currentNode, path); @@ -39,10 +37,10 @@ export class EntityPathResolver { propertyPaths }; } - private getEntityProperty(entity: Record, propertyName: string) { + private static getEntityProperty(entity: Record, propertyName: string) { return entity.type?.entities?.find((p: EntityMetadata) => p.label === propertyName); } - private getFieldProperty(entity: Record, propertyName: string) { + private static getFieldProperty(entity: Record, propertyName: string) { return entity.type?.fields?.find((p: EntityFieldMetadata) => p.label === propertyName); } } diff --git a/packages/renderer/src/resolvers/entity-resolver.ts b/packages/renderer/src/resolvers/entity-resolver.ts index 5e28a7c1165..7dbb3fe8e36 100644 --- a/packages/renderer/src/resolvers/entity-resolver.ts +++ b/packages/renderer/src/resolvers/entity-resolver.ts @@ -1,14 +1,11 @@ -import { FormMetadataService } from "../service"; import { EntityMetadata, ResolvedEntity } from "../types"; export class EntityResolver { - constructor(private formMetadataService: FormMetadataService) { } - public resolve(): ResolvedEntity[] { - const entitySchema = this.formMetadataService.getEntity(); + public resolve(entityMetadata: EntityMetadata): ResolvedEntity[] { const result: ResolvedEntity[] = []; function traverse(entity: EntityMetadata, path: string[]) { const currentPath = [...path, entity.label]; - const primary = entitySchema?.type?.primary || null; + const primary = entityMetadata?.type?.primary || null; if (primary) { result.push({ bindingPaths: currentPath, @@ -19,21 +16,18 @@ export class EntityResolver { traverse(childEntity, currentPath); }); } - const primary = entitySchema?.type?.primary || null; + const primary = entityMetadata?.type?.primary || null; if (!primary) { return result; } result.push({ bindingPaths: [], - primaryKey: entitySchema.type.primary + primaryKey: entityMetadata.type.primary }); - const childEntities = entitySchema?.type?.entities || []; + const childEntities = entityMetadata?.type?.entities || []; childEntities.forEach((entity) => { traverse(entity, []); }); return result; } - public getEntityCode(): string { - return this.formMetadataService.getEntity().code; - } } diff --git a/packages/renderer/src/resolvers/field-resolver.ts b/packages/renderer/src/resolvers/field-resolver.ts index 6f10e4f3aa4..3b339f933c9 100644 --- a/packages/renderer/src/resolvers/field-resolver.ts +++ b/packages/renderer/src/resolvers/field-resolver.ts @@ -1,18 +1,11 @@ - - -import { FormMetadataService } from "../service"; -import { ResolvedEntityField } from "../types"; - +import { EntityMetadata, ResolvedEntityField } from "../types"; export class FieldResolver { - constructor(private formMetadataService: FormMetadataService) { } - - public resolve(fieldId: string): ResolvedEntityField | null { - const entity = this.formMetadataService.getEntity(); - const fieldInfo = this.resolveField(entity, fieldId); + public static resolve(entityMetadata: EntityMetadata, fieldId: string): ResolvedEntityField | null { + const fieldInfo = this.resolveField(entityMetadata, fieldId); return fieldInfo; } - private resolveField(entitySchema: Record, fieldId: string): ResolvedEntityField | null { + private static resolveField(entitySchema: Record, fieldId: string): ResolvedEntityField | null { const { fields } = entitySchema.type; for (const field of fields) { if (field.id === fieldId) { diff --git a/packages/renderer/src/resolvers/model-value-resolver.ts b/packages/renderer/src/resolvers/model-value-resolver.ts index 7f047792e00..3f89189d5e1 100644 --- a/packages/renderer/src/resolvers/model-value-resolver.ts +++ b/packages/renderer/src/resolvers/model-value-resolver.ts @@ -1,5 +1,3 @@ - - import { Injector, Module } from "@farris/devkit-vue"; import { FormMetadataService } from "../service"; import { DataSourceResolver } from "./data-source-resolver"; @@ -10,7 +8,7 @@ import { ENTITY_STORE_SUFFIX } from "../types"; export class ModelValueResolver { private modelValue: Record = {}; - constructor(private entityResolver: DataSourceResolver, private fieldResolver: FieldResolver, private formMetadataService: FormMetadataService, private module: Module, private injector: Injector) { } + constructor(private formMetadataService: FormMetadataService, private module: Module, private injector: Injector) { } public resolve() { this.modelValue = {}; @@ -46,13 +44,13 @@ export class ModelValueResolver { public resolveBindingValue(viewSchema: Record) { const { binding } = viewSchema; const { field } = binding; - const resolvedField = this.fieldResolver.resolve(field); + const resolvedField = FieldResolver.resolve(this.entityMetadata, field); if (!resolvedField) { console.warn(`Invalid field: ${field}`); return null; } const { dataSource, bindingPath } = resolvedField; - const resolvedEntity = this.entityResolver.resolve(dataSource); + const resolvedEntity = DataSourceResolver.resolve(this.entityMetadata, dataSource); if (!resolvedEntity) { console.warn(`Invalid entity dataSource: ${dataSource}`); return null; @@ -72,7 +70,7 @@ export class ModelValueResolver { public resolveDataSourceValue(viewSchema: Record) { const { dataSource } = viewSchema; - const resolvedEntity = this.entityResolver.resolve(dataSource); + const resolvedEntity = DataSourceResolver.resolve(this.entityMetadata, dataSource); if (!resolvedEntity) { console.warn(`Invalid entity dataSource: ${dataSource}`); return null; @@ -87,4 +85,7 @@ export class ModelValueResolver { const configId = this.injector.get(MODULE_CONFIG_ID_TOKEN, undefined); return this.module.getEntityStore(`${configId}${ENTITY_STORE_SUFFIX}`); } + private get entityMetadata() { + return this.formMetadataService.getEntity(); + } } diff --git a/packages/renderer/src/resolvers/providers.ts b/packages/renderer/src/resolvers/providers.ts index af847f2778e..a17a61867fc 100644 --- a/packages/renderer/src/resolvers/providers.ts +++ b/packages/renderer/src/resolvers/providers.ts @@ -1,16 +1,7 @@ - import { Injector, Module, StaticProvider } from "@farris/devkit-vue"; -import { DataSourceResolver } from "./data-source-resolver"; import { FormMetadataService } from "../service"; -import { FieldResolver } from "./field-resolver"; import { ModelValueResolver } from "./model-value-resolver"; -import { EntityPathResolver } from "./entity-path-resolver"; -import { EntityResolver } from "./entity-resolver"; export const resolverProviders: StaticProvider[] = [ - { provide: DataSourceResolver, useClass: DataSourceResolver, deps: [FormMetadataService] }, - { provide: FieldResolver, useClass: FieldResolver, deps: [FormMetadataService] }, - { provide: ModelValueResolver, useClass: ModelValueResolver, deps: [DataSourceResolver, FieldResolver, FormMetadataService, Module, Injector] }, - { provide: EntityPathResolver, useClass: EntityPathResolver, deps: [FormMetadataService] }, - { provide: EntityResolver, useClass: EntityResolver, deps: [FormMetadataService] } + { provide: ModelValueResolver, useClass: ModelValueResolver, deps: [FormMetadataService, Module, Injector] }, ]; diff --git a/packages/renderer/src/types.ts b/packages/renderer/src/types.ts index 321846c7b02..e6867a9e20a 100644 --- a/packages/renderer/src/types.ts +++ b/packages/renderer/src/types.ts @@ -1,3 +1,4 @@ +import { ExpressionBindingType, ExpressionType } from "@farris/devkit-vue"; import { EventEmitter } from "./common"; /* eslint-disable no-use-before-define */ @@ -249,43 +250,11 @@ export interface Metadata { content: any; refs: any[]; } -export interface UseMetadata { - setup(): void; - getViewModels(): ViewModelMetadata[]; - getFrameComponent(): ComponentMetadata | null; - getEntity(): EntityMetadata; - getMetadataById(id: string): any; - getComponents(): any[]; - getRelatedComponent(metadataId: string): Record; - getViewModelById(id: string): ViewModelMetadata | null; - getModuleId(): string; -} - -export interface UseSession { - sessionId: string; - metadataId: string; - version: string; - mode: string; -} - -export interface UseCache { - get(key: string): any; - set(key: string, value: any): void; - remove(key: string): boolean; -} - -export interface UseSchemas { - form: Metadata; - stateMachine: Metadata; - webcmd: Metadata[]; - resource: Metadata[]; -} export enum MetadataType { Component = 'component', DataGrid = 'data-grid', TreeGrid = 'tree-grid' } - export interface ViewEvent { token: string; eventName: string; @@ -294,3 +263,14 @@ export interface ViewEvent { } export const ENTITY_STORE_SUFFIX = '-entitystore'; +export interface RuleMetadata { + id: string; + type: ExpressionType; + value: string; + message?: string | null | undefined; +} +export interface ExpressionMetadata { + target: string; + targetType: ExpressionBindingType; + rules: RuleMetadata[]; +} -- Gitee From 947013ac907d47468f67417c53c596f763e66311 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 18 Mar 2025 19:32:42 +0800 Subject: [PATCH 061/153] =?UTF-8?q?chore:=20=E4=BF=AE=E5=A4=8D=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=95=B0=E6=8D=AE=E5=9C=BA=E6=99=AF=E8=81=9A=E5=90=88?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=9C=AA=E9=87=8D=E6=96=B0=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...entity-store-append-entity-change-handler.ts | 17 +++++++++-------- ...entity-store-remove-entity-change-handler.ts | 10 +++------- .../entity-store-value-change-handler.ts | 2 +- .../expression-config-builder.ts | 2 +- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts index 0d68080ffd2..cf0224733df 100644 --- a/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts @@ -6,6 +6,7 @@ import { AbstractChangeHandler } from "./abstract-change-handler"; import { ExpressionContextBuilder } from "./expression-context-builder"; import { EffectOption, EffectorFactory } from "../effector"; import { ViewModel, ViewModelState } from "../viewmodel"; +import { isEqual } from "lodash-es"; export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler { constructor( @@ -41,7 +42,7 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler return; } // 如果是可见、只读表达式,则路径中不需要拼接数据id,这些表达式只与界面相关。或者说这些表达式只需要依赖表达式结果,不需要副作用器 - if (expressionObject.type === ExpressionType.Visible || expressionObject.type === ExpressionType.Readonly) { + if (expressionObject.type === ExpressionType.Visible || expressionObject.type === ExpressionType.Readonly) { return; } this.effect(change, expressionObject, result); @@ -146,6 +147,12 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler return index === -1 ? false : true; } private filterChangeSourceExpressions(change: Change, expressionObject: ExpressionObject) { + const { entityPaths: expressionPaths } = this.resolvePath(expressionObject.path); + const { entityPaths: changePaths } = this.resolveChangePath(change); + // 过滤掉非当前表的表达式 + if (!isEqual(expressionPaths, changePaths)) { + return false; + } // 没有依赖的表达式 if (!expressionObject.deps || expressionObject.deps.length < 1) { return true; @@ -155,12 +162,6 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler if (onlyDependOnState) { return true; } - const { entityPaths: expressionPaths } = this.resolvePath(expressionObject.path); - const { entityPaths: changePaths } = this.resolveChangePath(change); - // 过滤掉非当前表的表达式 - if (expressionPaths.join(DEPENDENCY_SPLITER) !== changePaths.join(DEPENDENCY_SPLITER)) { - return false; - } // TODO: 需支持树分层加载场景 // 表达式是计算或依赖表达式不计算,仅当依赖变化时计算 if (expressionObject.type === ExpressionType.Compute || expressionObject.type === ExpressionType.Dependency) { @@ -192,5 +193,5 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler const changePath = appendEntityChange.path.toShortPath(); return this.viewModel.entityStore.getEntitySchema().resolvePath(changePath); } - + } diff --git a/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts index 5be64c081e6..f8157843a90 100644 --- a/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts @@ -63,7 +63,7 @@ export class EntityStoreRemoveEntityChangeHandler extends AbstractChangeHandler return false; } // event.path like [id:xxxx] or [id:xxxx,子表s] - const { entityPaths: changePaths } = this.resolveChangePath(change); + const { entityPaths: changePaths, propertyPaths } = this.resolveChangePath(change); // 主表删除 if (changePaths.length === 0 && (this.isFieldExpression(expressionObject) || this.isElementExpression(expressionObject))) { return false; @@ -82,13 +82,9 @@ export class EntityStoreRemoveEntityChangeHandler extends AbstractChangeHandler return false; } const index = expressionObject.deps.findIndex((dependency: string) => { - const fullChangePaths = Array.from(changePaths); - fullChangePaths.splice(0, 0, ENTITY_TEMPLATE); - if (!dependency.startsWith(fullChangePaths.join(DEPENDENCY_SPLITER))) { - return false; - } + const fullChangePaths = changePaths.concat(propertyPaths); const dependencyPaths = dependency.split(DEPENDENCY_SPLITER).filter((p) => p).slice(1); - return isEqual(dependencyPaths, changePaths); + return isEqual(dependencyPaths, fullChangePaths); }); return index === -1 ? false : true; }); diff --git a/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts index 2cce5b76bc9..b8c64fb0f52 100644 --- a/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts @@ -57,7 +57,7 @@ export class EntityStoreValueChangeHandler extends AbstractChangeHandler { if (isEqual(changePaths, expressionPaths) || changePaths.length === expressionPaths.length + 1) { // 1、表达式和变更路径相同,即一个实体的字段值变了,同实体的其他字段的表达式需要重新计算 // 2、表达式和变更路径不同,表达式绑定的字段在变更路径的上级,即一个实体的字段值变了,上级实体的字段的表达式需要重新计算 - const sliceLength = expressionPaths.length === 0 ? 1 : expressionPaths.length * 2; + const sliceLength = expressionPaths.length === 0 ? 1 : (expressionPaths.length * 2) + 1; const entityPaths = valueChange.path.getNodes().slice(0, sliceLength); const currentRows: { bindingPath: string, primaryValue: string; }[] = []; const fullPaths = entityPaths.reduce((paths: string[], node: EntityPathNode) => { diff --git a/packages/renderer/src/config-builders/expression-config-builder.ts b/packages/renderer/src/config-builders/expression-config-builder.ts index ef26fc03b3d..30211f2afce 100644 --- a/packages/renderer/src/config-builders/expression-config-builder.ts +++ b/packages/renderer/src/config-builders/expression-config-builder.ts @@ -68,7 +68,7 @@ export class ExpressionConfigBuilder { } const { bindingPaths } = resolvedDataSource; const fullPaths = bindingPaths.concat(bindingPath.split('.')); - return fullPaths.join('/'); + return '/' + fullPaths.join('/'); } private get entitySchema() { return this.formMeta.module.entity[0].entities[0]; -- Gitee From 3bafe705622b2bd4c958f93eda84a679fd4e4e93 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 18 Mar 2025 19:37:44 +0800 Subject: [PATCH 062/153] =?UTF-8?q?chore:=20=E4=BF=AE=E5=A4=8D=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=AD=90=E8=A1=A8=E6=97=B6=E4=B8=BB=E8=A1=A8=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=9C=AA=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity-store-remove-entity-change-handler.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts index f8157843a90..86b49c532f8 100644 --- a/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts @@ -63,7 +63,7 @@ export class EntityStoreRemoveEntityChangeHandler extends AbstractChangeHandler return false; } // event.path like [id:xxxx] or [id:xxxx,子表s] - const { entityPaths: changePaths, propertyPaths } = this.resolveChangePath(change); + const { entityPaths: changePaths } = this.resolveChangePath(change); // 主表删除 if (changePaths.length === 0 && (this.isFieldExpression(expressionObject) || this.isElementExpression(expressionObject))) { return false; @@ -82,9 +82,9 @@ export class EntityStoreRemoveEntityChangeHandler extends AbstractChangeHandler return false; } const index = expressionObject.deps.findIndex((dependency: string) => { - const fullChangePaths = changePaths.concat(propertyPaths); const dependencyPaths = dependency.split(DEPENDENCY_SPLITER).filter((p) => p).slice(1); - return isEqual(dependencyPaths, fullChangePaths); + const { entityPaths: dependencyEntityPaths } = this.resolvePath(dependencyPaths); + return isEqual(dependencyEntityPaths, changePaths); }); return index === -1 ? false : true; }); -- Gitee From 5c97fe3d82bfbf32491d9828ad23290d954d505d Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 18 Mar 2025 19:54:16 +0800 Subject: [PATCH 063/153] =?UTF-8?q?chore:=20=E4=BF=AE=E5=A4=8D=E6=9C=AA?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E8=A1=A8=E5=8D=95=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/devkit/lib/module/module-creator.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/devkit/lib/module/module-creator.ts b/packages/devkit/lib/module/module-creator.ts index 4570c09597c..ab5fe612ea2 100644 --- a/packages/devkit/lib/module/module-creator.ts +++ b/packages/devkit/lib/module/module-creator.ts @@ -44,11 +44,8 @@ function createRepositoryProviders(repositoryConfigs: RepositoryConfig[]) { return providers; } function createExpressionsProviders(expressions: ExpressionConfig[]) { - if (!expressions || !Array.isArray(expressions)) { - return []; - } const providers: StaticProvider[] = []; - providers.push({ provide: EXPRESSIONS_TOKEN, useValue: expressions }); + providers.push({ provide: EXPRESSIONS_TOKEN, useValue: expressions || [] }); return providers; } /** -- Gitee From 98792b00247097fa08420e18b2ec3c556f548881 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Tue, 18 Mar 2025 20:12:54 +0800 Subject: [PATCH 064/153] =?UTF-8?q?feature:=201=E3=80=81=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E6=96=B0=E5=A2=9Ekey=E5=B1=9E=E6=80=A7=E4=BD=9C=E4=B8=BA?= =?UTF-8?q?=E5=94=AF=E4=B8=80=E6=A0=87=E8=AF=86=EF=BC=9B2=E3=80=81?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AE=9E=E4=BD=93=E6=95=B0=E6=8D=AE=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2=E8=A1=A8=E5=8D=95=E6=95=B0=E6=8D=AE=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/devkit/index.html | 1 - .../store/form/configs/form-store-config.ts | 1 + .../form/form-array-store-initializer.ts | 59 ++++---- .../devkit/lib/store/form/form-array-store.ts | 6 +- .../devkit/lib/store/form/form-builder.ts | 16 +-- .../lib/store/form/form-data-builder.ts | 130 ++++++++++++++++++ .../lib/store/form/form-state-builder.ts | 1 + .../devkit/lib/store/form/form-state-util.ts | 2 + packages/devkit/lib/store/form/form-state.ts | 1 + .../lib/store/form/form-store-initializer.ts | 82 +++++++---- packages/devkit/lib/store/form/form-store.ts | 22 +++ packages/devkit/lib/store/form/form.ts | 20 ++- packages/devkit/lib/store/form/types.ts | 8 +- .../lib/data-services/validator.service.ts | 2 +- .../form/form-array-store-config-builder.ts | 68 ++++++++- .../form/form-store-config-builder.ts | 2 +- .../module-config/module-config-builder.ts | 1 + 17 files changed, 339 insertions(+), 83 deletions(-) create mode 100644 packages/devkit/lib/store/form/form-data-builder.ts diff --git a/packages/devkit/index.html b/packages/devkit/index.html index e92044b4d51..700835c0614 100644 --- a/packages/devkit/index.html +++ b/packages/devkit/index.html @@ -2,7 +2,6 @@ - Vite + Vue diff --git a/packages/devkit/lib/store/form/configs/form-store-config.ts b/packages/devkit/lib/store/form/configs/form-store-config.ts index d88c5d200c9..ec370ff0710 100644 --- a/packages/devkit/lib/store/form/configs/form-store-config.ts +++ b/packages/devkit/lib/store/form/configs/form-store-config.ts @@ -44,6 +44,7 @@ interface FormStateConfig { interface FormStoreConfig extends StoreConfig { id: string; type?: Type>; + bindingPath: string; state: FormStateConfig; }; diff --git a/packages/devkit/lib/store/form/form-array-store-initializer.ts b/packages/devkit/lib/store/form/form-array-store-initializer.ts index 114493dd501..cf77906086e 100644 --- a/packages/devkit/lib/store/form/form-array-store-initializer.ts +++ b/packages/devkit/lib/store/form/form-array-store-initializer.ts @@ -3,6 +3,7 @@ import { ViewModel, ViewModelState } from '../../viewmodel/index'; import { Entity } from '../entity-store/index'; import { FormControlConfig, FormArrayStoreConfigManager } from './configs/index'; import { FormBuilder } from './form-builder'; +import { FormDataBuilder } from './form-data-builder'; import { FormArrayState } from './form-state'; import { FormArrayStore } from './form-array-store' @@ -36,6 +37,11 @@ class FormArrayStoreInitializer { */ private formBuilder: FormBuilder; + /** + * 表单数据构造器 + */ + private formDataBuilder: FormDataBuilder; + /** * 构造函数 */ @@ -45,6 +51,7 @@ class FormArrayStoreInitializer { this.formArrayStore = formArrayStore; this.configManager = formArrayStore.getConfigManager(); this.formBuilder = new FormBuilder(); + this.formDataBuilder = new FormDataBuilder(this.viewModel); } /** @@ -60,7 +67,7 @@ class FormArrayStoreInitializer { */ private initFormArray() { const controlConfigs = this.configManager.getControlConfigs(); - const formArray = this.formBuilder.buildFormArray([], controlConfigs); + const formArray = this.formBuilder.buildFormArray([], [], controlConfigs); this.formArrayStore.initFormArray(formArray); } @@ -68,53 +75,43 @@ class FormArrayStoreInitializer { * 同步Form数据 */ private watchDataSource() { - const storeConfig = this.configManager.getStoreConfig(); - const controlConfigs = this.configManager.getControlConfigs(); - const bindingPath = storeConfig.bindingPath; - const { entityStore, uiStore } = this.viewModel; if (!entityStore || !uiStore) { return; } entityStore.watchChange((change: any) => { - const formDatas = this.getFormDatas(bindingPath, controlConfigs); - const forms = this.formBuilder.buildForms(formDatas, controlConfigs); - this.formArrayStore.loadForms(forms); + this.updateFormArrayStore(); }); } /** - * 获取表单数据集合 + * 全量更新表单数据 */ - private getFormDatas(bindingPath: string, controlConfigs: FormControlConfig[]): any[] { - const { entityStore } = this.viewModel; - if (!entityStore) { - return []; - } - - const entities = entityStore.getEntitiesByPath(bindingPath); - const formDatas = entities.map((entity) => { - return this.getFormData(bindingPath, entity, controlConfigs); - }); + private updateFormArrayStore() { + const controlConfigs = this.configManager.getControlConfigs(); + const entities = this.getEntities(); + const formKeys = this.formDataBuilder.buildFormKeys(entities); + const formDatas = this.formDataBuilder.buildFormArrayData(entities, controlConfigs); + const forms = this.formBuilder.buildForms(formKeys, formDatas, controlConfigs); - return formDatas; + this.formArrayStore.loadForms(forms); } /** - * 获取表单数据 + * 获取表单实体集合 */ - private getFormData(bindingPath: string, entity: Entity, controlConfigs: FormControlConfig[]) { - const formData = {}; - bindingPath = bindingPath === '/' ? '' : bindingPath; - controlConfigs.forEach((controlConfig: FormControlConfig) => { - const name = controlConfig.name; - const path = controlConfig.bindingPath.replace(bindingPath, ''); - const value = entity.getValueByPath(path); - formData[name] = value; - }); + private getEntities(): Entity[] { + const { entityStore } = this.viewModel; + if (!entityStore) { + return null; + } + + const storeConfig = this.configManager.getStoreConfig(); + const bindingPath = storeConfig.bindingPath; + const entities = entityStore.getEntitiesByPath(bindingPath); - return formData; + return entities; } /** diff --git a/packages/devkit/lib/store/form/form-array-store.ts b/packages/devkit/lib/store/form/form-array-store.ts index 974313863aa..fe86e00e78f 100644 --- a/packages/devkit/lib/store/form/form-array-store.ts +++ b/packages/devkit/lib/store/form/form-array-store.ts @@ -61,11 +61,15 @@ class FormArrayStore extends Store { * 获取错误集合 */ public getErrors(): ValidationErrors[] | null { + if (this.formArray.valid === true) { + return null; + } + return this.formArray.errors; } /** - * 初始化Formarray + * 初始化FormArray */ public initFormArray(formArray: FormArray): void { this.formArray = formArray; diff --git a/packages/devkit/lib/store/form/form-builder.ts b/packages/devkit/lib/store/form/form-builder.ts index d5ae86c4f55..5581c9977d9 100644 --- a/packages/devkit/lib/store/form/form-builder.ts +++ b/packages/devkit/lib/store/form/form-builder.ts @@ -11,20 +11,20 @@ class FormBuilder { /** * 创建表单数组 */ - public buildFormArray(formDatas: any[], controlConfigs: FormControlConfig[]) { - const forms = this.buildForms(formDatas, controlConfigs); + public buildFormArray(formKeys: string[],formDatas: any[], controlConfigs: FormControlConfig[]) { + const forms = this.buildForms(formKeys, formDatas, controlConfigs); const formArray = new FormArray(forms); return formArray; - } /** * 批量创建表单 */ - public buildForms(formDatas: any[], controlConfigs: FormControlConfig[]): Form[] { - const forms = formDatas.map((formData) => { - return this.buildForm(formData, controlConfigs); + public buildForms(formKeys: string[], formDatas: any[], controlConfigs: FormControlConfig[]): Form[] { + const forms = formDatas.map((formData, formIndex) => { + const formKey = formKeys[formIndex]; + return this.buildForm(formKey, formData, controlConfigs); }); return forms; @@ -33,9 +33,9 @@ class FormBuilder { /** * 创建表单 */ - public buildForm(formData: any, controlConfigs: FormControlConfig[]): Form { + public buildForm(formKey: string, formData: any, controlConfigs: FormControlConfig[]): Form { const controls = this.buildControls(formData, controlConfigs); - const form = new Form(controls); + const form = new Form(formKey, controls); return form } diff --git a/packages/devkit/lib/store/form/form-data-builder.ts b/packages/devkit/lib/store/form/form-data-builder.ts new file mode 100644 index 00000000000..ef2f5eab595 --- /dev/null +++ b/packages/devkit/lib/store/form/form-data-builder.ts @@ -0,0 +1,130 @@ +import { Module } from '../../module/index'; +import { ViewModel, ViewModelState } from '../../viewmodel/index'; +import { Entity, EntityState, EntityStore } from '../entity-store/index'; +import { UIState, UIStore } from '../ui-store/index'; +import { FormControlBindingType, FormData } from './types'; +import { FormControlConfig } from './configs/index'; + + + +/** + * 表单数据构造器 + */ +class FormDataBuilder { + + /** + * 模块 + */ + private module: Module; + + /** + * 视图模型 + */ + private viewModel: ViewModel; + + /** + * 实体仓库 + */ + private entityStore: EntityStore> | null; + + /** + * UI仓库 + */ + private uiStore: UIStore | null; + + /** + * 构造函数 + */ + constructor(viewModel: ViewModel) { + this.viewModel = viewModel; + this.module = viewModel.getModule(); + this.entityStore = viewModel.entityStore; + this.uiStore = viewModel.uiStore; + } + + /** + * 获取表单标志集合 + */ + public buildFormKeys(entities: Entity[]): string[] { + const keys = entities.map((entity: Entity) => { + return entity.idValue; + }); + + return keys; + } + + /** + * 构造表单标志 + */ + public buildFormKey(entity: Entity): string { + return entity.idValue; + } + + /** + * 获取表单数据集合 + */ + public buildFormArrayData(entities: Entity[], controlConfigs: FormControlConfig[]): FormData[] { + const formDatas = entities.map((entity) => { + return this.buildFormData(entity, controlConfigs); + }); + + return formDatas; + } + + /** + * 获取表单数据 + */ + public buildFormData(entity: Entity, controlConfigs: FormControlConfig[]): FormData { + const formData = {}; + controlConfigs.forEach((controlConfig: FormControlConfig) => { + const { name } = controlConfig; + const value = this.getControlValue(entity, controlConfig); + formData[name] = value; + }); + + return formData; + } + + /** + * 获取控件值 + */ + public getControlValue(entity: Entity, controlConfig: FormControlConfig): any { + let controlValue: any; + const { bindingType, bindingPath } = controlConfig; + if (bindingType === FormControlBindingType.EntityState) { + controlValue = entity ? entity.getValueByPath(bindingPath) : undefined; + } else if (bindingType === FormControlBindingType.UIState) { + controlValue = this.uiStore ? this.uiStore.getValueByPath(controlConfig.bindingPath) : undefined; + } else { + throw new Error(`BindingType(${controlConfig.bindingType}) not supported`); + } + + return controlValue; + } + + /** + * 获取实体 + */ + private getEntity(bindingPath: string): Entity | null { + if (!this.entityStore) { + return null; + } + const entity = this.entityStore.getCurrentEntityByPath(bindingPath); + + return entity; + } + + /** + * 获取实体集合 + */ + private getEntities(bindingPath: string) { + if (!this.entityStore) { + return null; + } + const entities = this.entityStore.getEntitiesByPath(bindingPath); + + return entities; + } +} + +export { FormDataBuilder }; \ No newline at end of file diff --git a/packages/devkit/lib/store/form/form-state-builder.ts b/packages/devkit/lib/store/form/form-state-builder.ts index e3a6c5f4c4c..1240b5aaac9 100644 --- a/packages/devkit/lib/store/form/form-state-builder.ts +++ b/packages/devkit/lib/store/form/form-state-builder.ts @@ -31,6 +31,7 @@ class FormStateBuilder { */ public buildFormState(form: Form): FormState { const formState: FormState = { + key: form.key, valid: form.valid, controlStates: {} } diff --git a/packages/devkit/lib/store/form/form-state-util.ts b/packages/devkit/lib/store/form/form-state-util.ts index 2e25783950e..ba042df78d9 100644 --- a/packages/devkit/lib/store/form/form-state-util.ts +++ b/packages/devkit/lib/store/form/form-state-util.ts @@ -36,6 +36,8 @@ class FormStateUtil { if (ObjectUtil.isEmpty(changedFormProps)) { return null; + } else { + changedFormProps.key = newFormState.key; } return changedFormProps; diff --git a/packages/devkit/lib/store/form/form-state.ts b/packages/devkit/lib/store/form/form-state.ts index 66537dc4de7..519abb66059 100644 --- a/packages/devkit/lib/store/form/form-state.ts +++ b/packages/devkit/lib/store/form/form-state.ts @@ -13,6 +13,7 @@ interface FormControlState { * 表单状态 */ interface FormState { + key: string; valid: boolean; controlStates: { [key: string]: FormControlState } } diff --git a/packages/devkit/lib/store/form/form-store-initializer.ts b/packages/devkit/lib/store/form/form-store-initializer.ts index 97b36427df1..5dbb3b8bcb6 100644 --- a/packages/devkit/lib/store/form/form-store-initializer.ts +++ b/packages/devkit/lib/store/form/form-store-initializer.ts @@ -1,8 +1,10 @@ import { Module } from '../../module/index'; -import { ViewModel, ViewModelState } from '../../viewmodel/index';; -import { FormControlConfig, FormStoreConfigManager } from './configs/index'; -import { FormControlBindingType } from './types'; +import { ViewModel, ViewModelState } from '../../viewmodel/index'; +import { Entity } from '../../store/index'; +import { FormStoreConfigManager } from './configs/index'; +import { FormData } from './types'; import { FormBuilder } from './form-builder'; +import { FormDataBuilder } from './form-data-builder'; import { FormState } from './form-state'; import { FormStore } from './form-store' @@ -36,6 +38,11 @@ class FormStoreInitializer { */ private formBuilder: FormBuilder; + /** + * 表单数据构造器 + */ + private formDataBuilder: FormDataBuilder; + /** * 构造函数 */ @@ -45,6 +52,7 @@ class FormStoreInitializer { this.formStore = formStore; this.configManager = formStore.configManager; this.formBuilder = new FormBuilder(); + this.formDataBuilder = new FormDataBuilder(this.viewModel); } /** @@ -60,16 +68,21 @@ class FormStoreInitializer { */ private initState() { const controlConfigs = this.configManager.getControlConfigs(); - - const formData = this.getFormData(); - this.formStore.form = this.formBuilder.buildForm(formData, controlConfigs);; + const currentEntity = this.getCurrentEntity(); + const formKey = this.formDataBuilder.buildFormKey(currentEntity); + const formData = this.formDataBuilder.buildFormData(currentEntity, controlConfigs); + this.formStore.form = this.formBuilder.buildForm(formKey, formData, controlConfigs);; } /** * 获取表单数据 */ - public getFormData() { - return {}; + private getFormData(): FormData { + const currentEntity = this.getCurrentEntity(); + const controlConfigs = this.configManager.getControlConfigs(); + const formData = this.formDataBuilder.buildFormData(currentEntity, controlConfigs); + + return formData; } /** @@ -85,45 +98,56 @@ class FormStoreInitializer { entityStore.watchChange((change: any) => { controlConfigs.forEach((controlConfig) => { - this.setControlValue(controlConfig); + this.updateFormStore(); }); }); uiStore.watchChange((change: any) => { controlConfigs.forEach((controlConfig) => { - this.setControlValue(controlConfig); + this.updateFormStore(); }); }); } /** - * 同步控件值 + * 全量更新表单 */ - private setControlValue(controlConfig: FormControlConfig): void { - const { name, bindingType, bindingPath } = controlConfig; - const controlValue = this.getControlValue(bindingType, bindingPath); - this.formStore.setValue(name, controlValue); + private updateFormStore() { + this.updateFormKey(); + this.updateControlValues(); } /** - * 获取控件值 + * 设置表单标志 */ - private getControlValue(bindingType: string, bindingPath: string): any { - const { entityStore, uiStore } = this.viewModel; - if (!entityStore || !uiStore) { - return; - } + private updateFormKey(): void { + const currentEntity = this.getCurrentEntity(); + const newKey = currentEntity.idValue; + this.formStore.setFormKey(newKey); + } + + /** + * 批量设置控件值 + */ + private updateControlValues() { + const formData = this.getFormData(); + this.formStore.setValues(formData); + } - let controlValue; - if (bindingType === FormControlBindingType.EntityState) { - controlValue = entityStore.getValueByPath(bindingPath); - } else if (bindingType === FormControlBindingType.UIState) { - controlValue = uiStore.getValueByPath(bindingPath); - } else { - throw new Error(`BindingType(${bindingType}) not supported`); + /** + * 获取实体数据 + */ + private getCurrentEntity(): Entity | null { + const { entityStore } = this.viewModel; + if (!entityStore) { + return null; } - return controlValue; + const storeConfig = this.configManager.getStoreConfig(); + const bindingPath = storeConfig.bindingPath; + const currentEntity = entityStore.getCurrentEntityByPath(bindingPath); + + return currentEntity; } /** diff --git a/packages/devkit/lib/store/form/form-store.ts b/packages/devkit/lib/store/form/form-store.ts index 475c3c16c35..7a419938f7d 100644 --- a/packages/devkit/lib/store/form/form-store.ts +++ b/packages/devkit/lib/store/form/form-store.ts @@ -51,6 +51,13 @@ class FormStore extends Store { this.refreshState(); } + /** + * 获取唯一标识 + */ + public getKey(): string { + return this.form.key; + } + /** * 获取错误值 */ @@ -85,6 +92,18 @@ class FormStore extends Store { this.refreshState(); } + /** + * 设置表单唯一标识 + */ + public setFormKey(key: string): void { + const oldKey = this.form.key; + if (oldKey === key) { + return; + } + + this.form.setKey(key); + } + /** * 校验整个表单 */ @@ -119,6 +138,9 @@ class FormStore extends Store { const change: any = { changedStates: changedStates }; + + console.log('----------FormStore change----------'); + console.log(change); this.triggerChange(change); } diff --git a/packages/devkit/lib/store/form/form.ts b/packages/devkit/lib/store/form/form.ts index 68f5541dd36..e5fb95911e6 100644 --- a/packages/devkit/lib/store/form/form.ts +++ b/packages/devkit/lib/store/form/form.ts @@ -6,6 +6,11 @@ import { ValidationErrors } from './validation'; */ class Form { + /** + * 表单唯一标识 + */ + public readonly key: string; + /** * 表单值 */ @@ -29,13 +34,21 @@ class Form { /** * 构造函数 */ - constructor(controls: { [key: string]: FormControl }) { + constructor(key: string, controls: { [key: string]: FormControl }) { this.values = {}; this.valid = true; this.errors = null; + this.key = key; this.controls = controls; } + /** + * 设置唯一标识 + */ + public setKey(key: string): void { + (this as any).key = key; + } + /** * 获取全部控件 */ @@ -56,7 +69,8 @@ class Form { public setValues(values: { [key: string]: any }) { Object.keys(values).forEach((name) => { const control = this.controls[name]; - control.setValue(name); + const value = values[name]; + control.setValue(value); }); this.refresh(); } @@ -64,7 +78,7 @@ class Form { /** * 设置控件值 */ - public setValue(name: string, value: any) { + public setValue(name: string, value: any): void { const control = this.controls[name]; control.setValue(value); this.refresh(); diff --git a/packages/devkit/lib/store/form/types.ts b/packages/devkit/lib/store/form/types.ts index 5fd2b13d379..c3efee1c278 100644 --- a/packages/devkit/lib/store/form/types.ts +++ b/packages/devkit/lib/store/form/types.ts @@ -14,4 +14,10 @@ enum FormControlBindingType { UIState = 'UIState' } -export { FormControlBindingType }; +/** + * 表单数据 + */ +type FormData = { [key: string]: any }; + + +export { FormControlBindingType, FormData }; diff --git a/packages/mobile-command-services/lib/data-services/validator.service.ts b/packages/mobile-command-services/lib/data-services/validator.service.ts index 74769f497ad..a209c5ff4f6 100644 --- a/packages/mobile-command-services/lib/data-services/validator.service.ts +++ b/packages/mobile-command-services/lib/data-services/validator.service.ts @@ -69,7 +69,7 @@ class ValidatorService extends BaseDataService { if (formArrayStore) { formArrayStore.validate(); const formArrayErrors = formArrayStore.getErrors() || []; - allErrors = formArrayErrors.concat(formArrayErrors); + allErrors = allErrors.concat(formArrayErrors); } return allErrors && allErrors.length > 0 ? allErrors : null; diff --git a/packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts b/packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts index b82ed8334b4..a653a11c0f5 100644 --- a/packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts +++ b/packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts @@ -1,4 +1,4 @@ -import { FormArrayStateConfig, FormArrayStoreConfig } from '@farris/devkit-vue'; +import { FormControlConfig, FormArrayStateConfig, FormArrayStoreConfig } from '@farris/devkit-vue'; import { FormMetadataQuery } from '../../metadata/index'; import { FormControlConfigBuilder } from './form-control-config-builder'; @@ -23,7 +23,7 @@ class FormArrayStoreConfigBuilder { * 构造配置 */ public build(viewModelNode: any): FormArrayStoreConfig { - const stateConfig = this.buildStateConfig(viewModelNode.states); + const stateConfig = this.buildStateConfig(viewModelNode); const storeConfig: FormArrayStoreConfig = { id: viewModelNode.code + '-form-array-store', bindingPath: viewModelNode.bindTo, @@ -37,18 +37,72 @@ class FormArrayStoreConfigBuilder { * 获取表单状态配置 */ private buildStateConfig(viewModelNode: any): FormArrayStateConfig { + const vmComponentNode = this.getVmComponentNode(viewModelNode); + if (!vmComponentNode) { + throw new Error(`Component(viewModel=${viewModelNode.id}) not found`); + } + + const controlConfigs = this.buildControlConfigs(vmComponentNode); const stateConfig: FormArrayStateConfig = { - controls: [] + controls: controlConfigs }; - return stateConfig; } /** - * 搜集控件 + * 获取列表对应卡片的表单组件 + */ + private getVmComponentNode(viewModelNode: any): any { + const listVmComponentNode = this.formMetaQuery.getVmComponentByVmId(viewModelNode.id); + + // 对用对应卡片的组件模拟批量编辑场景 + const vmComponentNodes = this.formMetaQuery.getVmComponents(); + const cardVmComponentNode = vmComponentNodes.find((vmComponentNode) => { + return vmComponentNode !== listVmComponentNode && vmComponentNode.bindTo === listVmComponentNode.bindTo; + }); + + if (!listVmComponentNode && !cardVmComponentNode) { + throw new Error(`Component(viewModel=${viewModelNode.id}) not found`); + } + + return cardVmComponentNode ? cardVmComponentNode : listVmComponentNode; + } + + /** + * 构造控件配置集合 */ - private collectControlNodes(): any[] { - return []; + private buildControlConfigs(vmComponentNode: any): FormControlConfig[] { + const wrappedControlNodes = this.collectWrappedControlNodes(vmComponentNode); + const controlConfigBuilder = new FormControlConfigBuilder(); + + const controlConfigs: FormControlConfig[] = []; + wrappedControlNodes.forEach((wrappedControlNode) => { + const controlNode = wrappedControlNode.component; + const controlConfig = controlConfigBuilder.build(controlNode.editor); + controlConfigs.push(controlConfig); + }); + + return controlConfigs; + } + + /** + * 搜集当前VM组件下的所有输入控件 + */ + private collectWrappedControlNodes(vmComponentNode: any): any[] { + const wrappedComponentNodes = this.formMetaQuery.getWrappedComponents(); + const wrappedControlNode = [] as any[]; + wrappedComponentNodes.forEach((wrappedComponentNode) => { + if (wrappedComponentNode.viewModelComponent !== vmComponentNode) { + return; + } + + const componentType = wrappedComponentNode.component.type; + if (componentType === 'form-item') { + wrappedControlNode.push(wrappedComponentNode); + } + }); + + return wrappedControlNode; } } diff --git a/packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts b/packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts index e25453a3647..4b272c5635c 100644 --- a/packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts +++ b/packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts @@ -1,7 +1,6 @@ import { FormControlConfig, FormStateConfig, FormStoreConfig } from '@farris/devkit-vue'; import { FormMetadataQuery } from '../../metadata/index'; import { FormControlConfigBuilder } from './form-control-config-builder'; -import { FormControl } from '@farris/devkit-vue/package/types/store/form/form-control'; /** * 表单仓库配置构造器 @@ -27,6 +26,7 @@ class FormStoreConfigBuilder { const stateConfig = this.buildStateConfig(viewModelNode); const storeConfig: FormStoreConfig = { id: viewModelNode.code + '-form-store', + bindingPath: viewModelNode.bindTo, state: stateConfig }; diff --git a/packages/mobile-render/src/services/module-config/module-config-builder.ts b/packages/mobile-render/src/services/module-config/module-config-builder.ts index 60e0c28c717..3ba92dd77e8 100644 --- a/packages/mobile-render/src/services/module-config/module-config-builder.ts +++ b/packages/mobile-render/src/services/module-config/module-config-builder.ts @@ -207,6 +207,7 @@ class ModuleConfigBuilder { if (config.state.controls.length === 0) { return; } + this.moduleConfig.formArrayStores.push(config); return config; } -- Gitee From 6fbee086f8a23d4b6e133a59ca59878c7892131b Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 18 Mar 2025 20:21:12 +0800 Subject: [PATCH 065/153] =?UTF-8?q?chore:=20=E5=89=AF=E4=BD=9C=E7=94=A8?= =?UTF-8?q?=E5=99=A8=E6=94=AF=E6=8C=81=E4=BE=9D=E8=B5=96=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity-store-append-entity-change-handler.ts | 7 ++++--- .../entity-store-remove-entity-change-handler.ts | 9 +++++---- .../change-handler/entity-store-update-change-handler.ts | 7 ++++--- packages/devkit/lib/effector/entity-store-effector.ts | 8 +++++++- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts index cf0224733df..dfc9d2a04e5 100644 --- a/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts @@ -30,10 +30,11 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler const expressionContextBuilder = new ExpressionContextBuilder(); const expressionContext = expressionContextBuilder.buildContext(this.viewModel); const result = this.expressionExecutor.compile(expressionObject, expressionContext); - if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { + const convertedResult = this.convertBooleanTypeExpressionResult(expressionObject, result); + if (convertedResult === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { return; } - expressionObject.result = this.convertBooleanTypeExpressionResult(expressionObject, result); + expressionObject.result = convertedResult; if (expressionObject.id) { this.expressionResult.set(expressionObject.id, expressionObject.result); } @@ -45,7 +46,7 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler if (expressionObject.type === ExpressionType.Visible || expressionObject.type === ExpressionType.Readonly) { return; } - this.effect(change, expressionObject, result); + this.effect(change, expressionObject, convertedResult); }); } private effect(change: Change, expressionObject: ExpressionObject, result: any) { diff --git a/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts index 86b49c532f8..982011eed63 100644 --- a/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts @@ -32,17 +32,18 @@ export class EntityStoreRemoveEntityChangeHandler extends AbstractChangeHandler const expressionContextBuilder = new ExpressionContextBuilder(); const expressionContext = expressionContextBuilder.buildContext(this.viewModel); const result = this.expressionExecutor.compile(expressionObject, expressionContext); - if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { + const convertedResult = this.convertBooleanTypeExpressionResult(expressionObject, result); + if (convertedResult === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { return; } - expressionObject.result = this.convertBooleanTypeExpressionResult(expressionObject, result); + expressionObject.result = convertedResult; if (expressionObject.id) { - this.expressionResult.set(expressionObject.id, expressionObject.result); + this.expressionResult.set(expressionObject.id, convertedResult); } if (this.isElementExpression(expressionObject)) { return; } - this.effect(change, expressionObject, result); + this.effect(change, expressionObject, convertedResult); }); } private effect(change: Change, expressionObject: ExpressionObject, result: any) { diff --git a/packages/devkit/lib/change-handler/entity-store-update-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-update-change-handler.ts index e3ea012fd0e..9530574b2b7 100644 --- a/packages/devkit/lib/change-handler/entity-store-update-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-update-change-handler.ts @@ -32,17 +32,18 @@ export class EntityStoreUpdateChangeHandler extends AbstractChangeHandler { const expressionContextBuilder = new ExpressionContextBuilder(); const expressionContext = expressionContextBuilder.buildContext(this.viewModel); const result = this.expressionExecutor.compile(expressionObject, expressionContext); - if (result === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { + const convertedResult = this.convertBooleanTypeExpressionResult(expressionObject, result); + if (convertedResult === undefined && !this.isValidateOrRequiredExpression(expressionObject)) { return; } - expressionObject.result = this.convertBooleanTypeExpressionResult(expressionObject, result); + expressionObject.result = convertedResult; if (expressionObject.id) { this.expressionResult.set(expressionObject.id, expressionObject.result); } if (this.isElementExpression(expressionObject)) { return; } - this.effect(change, expressionObject, result); + this.effect(change, expressionObject, convertedResult); }); } private effect(change: Change, expressionObject: ExpressionObject, result: any) { diff --git a/packages/devkit/lib/effector/entity-store-effector.ts b/packages/devkit/lib/effector/entity-store-effector.ts index 84f77dfebc1..f8d5087eddd 100644 --- a/packages/devkit/lib/effector/entity-store-effector.ts +++ b/packages/devkit/lib/effector/entity-store-effector.ts @@ -22,6 +22,12 @@ export class EntityStoreEffector implements Effector { } // 表达式结果可能作用于多条数据或单条数据,作用于多条数据时则应有paths属性,单条数据时默认使用当前行 const realPath = path ? path : expressionObject.path; - this.viewModel.entityStore?.setValueByPath(realPath, value); + if (expressionObject.type === ExpressionType.Dependency) { + if (value === true) { + this.viewModel.entityStore?.setValueByPath(realPath, null); + } + } else { + this.viewModel.entityStore?.setValueByPath(realPath, value); + } } } -- Gitee From f0f97680260918182ea59cc8f5494c22ea841808 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 18 Mar 2025 21:00:07 +0800 Subject: [PATCH 066/153] =?UTF-8?q?chore:=20=E6=94=AF=E6=8C=81=E8=A7=A3?= =?UTF-8?q?=E6=9E=90CountOfChild=E8=A1=A8=E8=BE=BE=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity-store-append-entity-change-handler.ts | 13 +------------ .../entity-expression-dependency-resolver.ts | 10 +++++++++- .../lib/expression-dependency-resolver/types.ts | 2 +- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts index dfc9d2a04e5..b360b56b09a 100644 --- a/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-append-entity-change-handler.ts @@ -54,20 +54,9 @@ export class EntityStoreAppendEntityChangeHandler extends AbstractChangeHandler if (!effector) { return; } - const paths = this.buildEffectPaths(change, expressionObject); - const option: EffectOption = { path: paths, message: expressionObject.message, messageType: expressionObject.messageType }; + const option: EffectOption = { message: expressionObject.message, messageType: expressionObject.messageType }; effector.effect(expressionObject, result, option); } - private buildEffectPaths(change: Change, expressionObject: ExpressionObject): string | null { - const { entityPaths: changePaths } = this.resolveChangePath(change); - const { entityPaths: expressionPaths } = this.viewModel.entityStore.getEntitySchema().resolvePath(expressionObject.path); - // 对表达式进行校验,只应出现上级聚合下级的情况 - if (changePaths.length !== expressionPaths.length + 1) { - console.warn(`表达式${expressionObject.id}聚合了自身或下级数据,不支持此类表达式`); - return null; - } - return null; - } private filter(change: Change, expressionObjects: ExpressionObject[]) { if (expressionObjects && expressionObjects.length > 0) { // 找到聚合相关表达式(依赖新增表的表达式),聚合的前提是表达式path位于事件路径的上方 diff --git a/packages/devkit/lib/expression-dependency-resolver/entity-expression-dependency-resolver.ts b/packages/devkit/lib/expression-dependency-resolver/entity-expression-dependency-resolver.ts index f87e0fe22cd..559ebd25ad9 100644 --- a/packages/devkit/lib/expression-dependency-resolver/entity-expression-dependency-resolver.ts +++ b/packages/devkit/lib/expression-dependency-resolver/entity-expression-dependency-resolver.ts @@ -73,7 +73,15 @@ export class EntityExpressionDependencyResolver implements Resolver { if (methodName && argumentMatchResult && argumentMatchResult.length === 2) { const argument = argumentMatchResult[1]; const args = argument.replace(/[\\"\\']/g, '').split(','); - if (args && args.length === 2) { + if (args && args.length === 1) { + const item: any = args[0]; + const fullPaths = item.split('.').slice(1).map((propertyName: string) => propertyName.trim()); + const entityPath = this.getEntityPaths(fullPaths); + if (entityPath && entityPath.length > 0) { + entityPath.splice(0, 0, ENTITY_TEMPLATE); + deps.push(entityPath.join(DEPENDENCY_SPLITER)); + } + } else if (args && args.length === 2) { const item: any = args.join('.'); const fullPaths = item.split('.').slice(1).map((propertyName: string) => propertyName.trim()); const entityPath = this.getEntityPaths(fullPaths); diff --git a/packages/devkit/lib/expression-dependency-resolver/types.ts b/packages/devkit/lib/expression-dependency-resolver/types.ts index cdfe0b3f490..9a91c994b99 100644 --- a/packages/devkit/lib/expression-dependency-resolver/types.ts +++ b/packages/devkit/lib/expression-dependency-resolver/types.ts @@ -7,4 +7,4 @@ export const RESOLVER_TOKEN = new InjectionToken('@farris_resolver_t export const ENTITY_TEMPLATE = 'ENTITY~'; export const STATE_TEMPLATE = 'STATE~'; export const DEPENDENCY_SPLITER = '/'; -export const GROUP_FUNCTIONS = ['SumByProp', 'CountByProp', 'AvgByProp', 'MaxByProp', 'MinByProp', 'IsExistRecord', 'ListContains', 'ListGreaterThan', 'ListLessThan', 'ListStartWith', 'ListEndWith', 'MultiplyChildNumber', 'SortChildData', 'IsContainMatch', 'MinValueOfPeriod', 'MaxValueOfPeriod', 'AvgValueOfPeriod']; +export const GROUP_FUNCTIONS = ['SumByProp', 'CountByProp', 'AvgByProp', 'MaxByProp', 'MinByProp', 'IsExistRecord', 'ListContains', 'ListGreaterThan', 'ListLessThan', 'ListStartWith', 'ListEndWith', 'MultiplyChildNumber', 'SortChildData', 'IsContainMatch', 'MinValueOfPeriod', 'MaxValueOfPeriod', 'AvgValueOfPeriod','CountOfChild']; -- Gitee From 0cb153b4e9ce5fadfcdbee4a6bcd613bc52f53d7 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 18 Mar 2025 21:54:03 +0800 Subject: [PATCH 067/153] =?UTF-8?q?chore:=20=E4=BF=AE=E5=A4=8D=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E6=9B=B4=E6=96=B0=E5=9C=BA=E6=99=AF=E6=9C=AA=E5=A4=84?= =?UTF-8?q?=E7=90=86=E5=89=AF=E4=BD=9C=E7=94=A8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/change-handler/entity-store-update-change-handler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devkit/lib/change-handler/entity-store-update-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-update-change-handler.ts index 9530574b2b7..b20ec202d9b 100644 --- a/packages/devkit/lib/change-handler/entity-store-update-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-update-change-handler.ts @@ -40,7 +40,7 @@ export class EntityStoreUpdateChangeHandler extends AbstractChangeHandler { if (expressionObject.id) { this.expressionResult.set(expressionObject.id, expressionObject.result); } - if (this.isElementExpression(expressionObject)) { + if (this.isElementExpression(expressionObject) || expressionObject.type === ExpressionType.Visible || expressionObject.type === ExpressionType.Readonly) { return; } this.effect(change, expressionObject, convertedResult); -- Gitee From 072f94e2736eaff4d03c0c21a6e145cb82c5e27b Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 18 Mar 2025 21:55:40 +0800 Subject: [PATCH 068/153] =?UTF-8?q?chore:=20=E5=AE=9E=E4=BD=93=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=9C=BA=E6=99=AF=E5=B1=8F=E8=94=BD=E4=B8=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E7=9A=84=E5=89=AF=E4=BD=9C=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity-store-remove-entity-change-handler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts index 982011eed63..c131ca025d5 100644 --- a/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-remove-entity-change-handler.ts @@ -1,6 +1,6 @@ import { EntityChangeType, RemoveEntityChange } from "../store"; import { Change, ChangeSource } from "../change-observer"; -import { ExpressionExecutor, ExpressionObject, ExpressionResult } from "../expression"; +import { ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType } from "../expression"; import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE } from "../expression-dependency-resolver"; import { AbstractChangeHandler } from "./abstract-change-handler"; import { ExpressionContextBuilder } from "./expression-context-builder"; @@ -40,7 +40,7 @@ export class EntityStoreRemoveEntityChangeHandler extends AbstractChangeHandler if (expressionObject.id) { this.expressionResult.set(expressionObject.id, convertedResult); } - if (this.isElementExpression(expressionObject)) { + if (this.isElementExpression(expressionObject) || expressionObject.type === ExpressionType.Visible || expressionObject.type === ExpressionType.Readonly) { return; } this.effect(change, expressionObject, convertedResult); -- Gitee From 94a9bf1ab52214b3bddb22bf7f6e5f99ef2aa858 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Wed, 19 Mar 2025 09:30:46 +0800 Subject: [PATCH 069/153] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9=E5=BF=85?= =?UTF-8?q?=E5=A1=AB=E5=89=AF=E4=BD=9C=E7=94=A8=E5=99=A8=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity-store-load-entity-change-handler.ts | 14 +++++++++++--- packages/devkit/lib/effector/providers.ts | 4 ++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/devkit/lib/change-handler/entity-store-load-entity-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-load-entity-change-handler.ts index ee88666f9f5..fea431377e9 100644 --- a/packages/devkit/lib/change-handler/entity-store-load-entity-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-load-entity-change-handler.ts @@ -5,7 +5,7 @@ import { ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType import { AbstractChangeHandler } from "./abstract-change-handler"; import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE } from "../expression-dependency-resolver"; import { ExpressionContextBuilder } from "./expression-context-builder"; -import { EffectorFactory } from "../effector"; +import { EffectOption, EffectorFactory } from "../effector"; import { ViewModel, ViewModelState } from "../viewmodel"; export class EntityStoreLoadEntityChangeHandler extends AbstractChangeHandler { @@ -37,12 +37,20 @@ export class EntityStoreLoadEntityChangeHandler extends AbstractChangeHandler { this.expressionResult.set(expressionObject.id, expressionObject.result); } // 界面元素表达式不需要使用副作用器 - if (this.isElementExpression(expressionObject)) { + if (this.isElementExpression(expressionObject) || expressionObject.type === ExpressionType.Visible || expressionObject.type === ExpressionType.Readonly) { return; } - // 不需要副作用器参与 + this.effect(change, expressionObject, expressionObject.result); }); } + private effect(change: Change, expressionObject: ExpressionObject, result: any) { + const effector = this.getEffector(expressionObject); + if (!effector) { + return; + } + const option: EffectOption = { message: expressionObject.message, messageType: expressionObject.messageType }; + effector.effect(expressionObject, result, option); + } private filter(change: Change, expressionObjects: ExpressionObject[]) { // 数据加载完成后需要计算当前绑定路径下的只读、显隐、必填、校验表达式 if (!expressionObjects || expressionObjects.length < 1) { diff --git a/packages/devkit/lib/effector/providers.ts b/packages/devkit/lib/effector/providers.ts index a1cb92e4c8f..3bf6cf641a3 100644 --- a/packages/devkit/lib/effector/providers.ts +++ b/packages/devkit/lib/effector/providers.ts @@ -5,12 +5,12 @@ import { ValidateEffector } from "./validate-effector"; import { EffectorRegistry } from "./effector-registry"; import { EffectorFactory } from "./effector-factory"; import { ViewModel } from "../viewmodel/index"; -import { RequiredValidator } from "../store/form/validation/validators/required-validator"; +import { RequiredEffector } from "./required-effector"; export const effectorProviders: StaticProvider[] = [ { provide: EFFECTORS_TOKEN, useClass: EntityStoreEffector, deps: [/*NAMESPACE_TOKEN,*/ forwardRef(() => ViewModel)], multi: true }, { provide: EFFECTORS_TOKEN, useClass: ValidateEffector, deps: [/*NAMESPACE_TOKEN,*/ forwardRef(() => ViewModel)], multi: true }, - { provide: EFFECTORS_TOKEN, useClass: RequiredValidator, deps: [/*NAMESPACE_TOKEN,*/ forwardRef(() => ViewModel)], multi: true }, + { provide: EFFECTORS_TOKEN, useClass: RequiredEffector, deps: [/*NAMESPACE_TOKEN,*/ forwardRef(() => ViewModel)], multi: true }, { provide: EffectorRegistry, useClass: EffectorRegistry, deps: [EFFECTORS_TOKEN] }, { provide: EffectorFactory, useClass: EffectorFactory, deps: [EffectorRegistry] }, ]; -- Gitee From e84e6f84761aa753388be6d6d87d110c2b05f9cc Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Wed, 19 Mar 2025 10:03:27 +0800 Subject: [PATCH 070/153] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E5=80=BC=E5=92=8C=E8=A1=A8=E5=8D=95=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84=E5=B5=8C=E5=A5=97=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devkit/lib/store/form/form-array-store.ts | 30 +++++-- packages/devkit/lib/store/form/form-array.ts | 71 ++++++++++----- .../devkit/lib/store/form/form-builder.ts | 21 ++--- .../lib/store/form/form-data-builder.ts | 8 +- .../devkit/lib/store/form/form-state-util.ts | 2 +- .../lib/store/form/form-store-initializer.ts | 8 +- packages/devkit/lib/store/form/form-store.ts | 58 ++++++------ packages/devkit/lib/store/form/form.ts | 90 +++++++++++-------- packages/devkit/lib/store/form/types.ts | 22 ++++- .../lib/data-services/validator.service.ts | 44 ++++----- 10 files changed, 216 insertions(+), 138 deletions(-) diff --git a/packages/devkit/lib/store/form/form-array-store.ts b/packages/devkit/lib/store/form/form-array-store.ts index fe86e00e78f..2db93444b98 100644 --- a/packages/devkit/lib/store/form/form-array-store.ts +++ b/packages/devkit/lib/store/form/form-array-store.ts @@ -1,6 +1,6 @@ import { Module } from '../../module/index'; import { Store } from '../store/index'; -import { ValidationErrors } from './validation/index'; +import { FormError, FormArrayValue, FormArrayError } from './types'; import { Form } from './form'; import { FormArray } from './form-array'; import { FormArrayState } from './form-state'; @@ -51,21 +51,21 @@ class FormArrayStore extends Store { } /** - * 获取错误值 + * 获取FormArray的值 */ - public getValues(): { [key: string]: any } { - return this.formArray.values; + public getValue(): FormArrayValue { + return this.formArray.value || []; } /** - * 获取错误集合 + * 获取FormArray的错误信息 */ - public getErrors(): ValidationErrors[] | null { + public getError(): FormArrayError | null { if (this.formArray.valid === true) { return null; } - return this.formArray.errors; + return this.formArray.error; } /** @@ -84,11 +84,23 @@ class FormArrayStore extends Store { } /** - * 执行验证 + * 校验FormArray */ - public validate(): void { + public validate(): FormArrayError | null { this.formArray.validate(); this.refreshState(); + + return this.formArray.error; + } + + /** + * 校验Form + */ + public validateForm(key: string): FormError | null { + const formError = this.formArray.validateForm(key); + this.refreshState(); + + return formError; } /** diff --git a/packages/devkit/lib/store/form/form-array.ts b/packages/devkit/lib/store/form/form-array.ts index 968556e09d6..d862a9f3b96 100644 --- a/packages/devkit/lib/store/form/form-array.ts +++ b/packages/devkit/lib/store/form/form-array.ts @@ -1,5 +1,5 @@ +import { FormError, FormArrayValue, FormArrayError } from './types'; import { Form } from './form'; -import { ValidationErrors } from './validation'; /** * 表单数组 @@ -7,19 +7,19 @@ import { ValidationErrors } from './validation'; class FormArray { /** - * 表单值 + * 表单数组值 */ - public readonly values: any[]; + public readonly value: FormArrayValue; /** - * 校验状态 + * 表单数组校验结果 */ public readonly valid: boolean; /** - * 校验错误 + * 表单数组校验错误 */ - public readonly errors: ValidationErrors[]; + public readonly error: FormArrayError | null; /** * 表单集合 @@ -30,19 +30,30 @@ class FormArray { * 构造函数 */ constructor(forms: Form[]) { - this.values = []; + this.value = []; this.valid = true; - this.errors = []; + this.error = []; this.forms = forms; } /** * 获取Form集合 */ - public getForms() { + public getForms(): Form[] { return this.forms; } + /** + * 获取Form + */ + public getForm(key: string): Form | null { + const form = this.forms.find((form) => { + return form.key === key; + }); + + return form || null; + } + /** * 加载Form集合 */ @@ -53,36 +64,50 @@ class FormArray { } /** - * 校验表单 + * 校验FormArray */ - public validate(): ValidationErrors[] | null { + public validate(): FormArrayError | null { this.forms.forEach((form) => { form.validate(); }); this.refresh(); - return this.errors; + return this.error; + } + + /** + * 校验下级Form + */ + public validateForm(key: string): FormError | null { + const form = this.getForm(key); + if (!form) { + return null; + } + + const formError = form.validate(); + this.refresh(); + + return formError; } /** * 刷新状态 */ public refresh(): void { - const values = []; - const errors = []; + const formArrayValue: FormArrayValue = []; + const formArrayError: FormArrayError = []; this.forms.forEach((form) => { - values.push(form.values); - errors.push(form.errors); - }); - - const invalid = this.forms.some((form) => { - return !form.valid; + const { key: formKey, value: formValue, error: formError } = form; + formArrayValue.push({ formKey, formValue }); + if (formError) { + formArrayError.push({ formKey, formError }); + } }); - (this.values as any) = values; - (this.valid as any) = !invalid; - (this.errors as any) = errors; + (this as any).value = formArrayValue; + (this as any).valid = formArrayError.length === 0; + (this as any).error = formArrayError.length === 0 ? null : formArrayError; } } diff --git a/packages/devkit/lib/store/form/form-builder.ts b/packages/devkit/lib/store/form/form-builder.ts index 5581c9977d9..e16fe37fd0c 100644 --- a/packages/devkit/lib/store/form/form-builder.ts +++ b/packages/devkit/lib/store/form/form-builder.ts @@ -1,4 +1,5 @@ import { FormControlConfig } from './configs/index'; +import { FormValue } from './types'; import { FormControl } from './form-control'; import { Form } from './form'; import { FormArray } from './form-array' @@ -11,8 +12,8 @@ class FormBuilder { /** * 创建表单数组 */ - public buildFormArray(formKeys: string[],formDatas: any[], controlConfigs: FormControlConfig[]) { - const forms = this.buildForms(formKeys, formDatas, controlConfigs); + public buildFormArray(formKeys: string[], formValues: FormValue[], controlConfigs: FormControlConfig[]) { + const forms = this.buildForms(formKeys, formValues, controlConfigs); const formArray = new FormArray(forms); return formArray; @@ -21,8 +22,8 @@ class FormBuilder { /** * 批量创建表单 */ - public buildForms(formKeys: string[], formDatas: any[], controlConfigs: FormControlConfig[]): Form[] { - const forms = formDatas.map((formData, formIndex) => { + public buildForms(formKeys: string[], formValues: FormValue[], controlConfigs: FormControlConfig[]): Form[] { + const forms = formValues.map((formData, formIndex) => { const formKey = formKeys[formIndex]; return this.buildForm(formKey, formData, controlConfigs); }); @@ -33,8 +34,8 @@ class FormBuilder { /** * 创建表单 */ - public buildForm(formKey: string, formData: any, controlConfigs: FormControlConfig[]): Form { - const controls = this.buildControls(formData, controlConfigs); + public buildForm(formKey: string, formValue: FormValue, controlConfigs: FormControlConfig[]): Form { + const controls = this.buildControls(formValue, controlConfigs); const form = new Form(formKey, controls); return form @@ -43,11 +44,11 @@ class FormBuilder { /** * 批量创建控件 */ - public buildControls(formData: any, controlConfigs: FormControlConfig[]): { [key: string]: FormControl } { + public buildControls(formValue: FormValue, controlConfigs: FormControlConfig[]): { [key: string]: FormControl } { const controls = {}; controlConfigs.forEach((controlConfig: FormControlConfig) => { const name = controlConfig.name; - const value = formData[name]; + const value = formValue[name]; controls[name] = this.buildControl(value, controlConfig); }); @@ -57,9 +58,9 @@ class FormBuilder { /** * 创建控件 */ - public buildControl(value: any, controlConfig: FormControlConfig): FormControl { + public buildControl(controlValue: any, controlConfig: FormControlConfig): FormControl { const validationRules = controlConfig.validationRules; - const control = new FormControl(value, validationRules); + const control = new FormControl(controlValue, validationRules); return control; } } diff --git a/packages/devkit/lib/store/form/form-data-builder.ts b/packages/devkit/lib/store/form/form-data-builder.ts index ef2f5eab595..200f81b78da 100644 --- a/packages/devkit/lib/store/form/form-data-builder.ts +++ b/packages/devkit/lib/store/form/form-data-builder.ts @@ -2,11 +2,9 @@ import { Module } from '../../module/index'; import { ViewModel, ViewModelState } from '../../viewmodel/index'; import { Entity, EntityState, EntityStore } from '../entity-store/index'; import { UIState, UIStore } from '../ui-store/index'; -import { FormControlBindingType, FormData } from './types'; +import { FormControlBindingType, FormValue } from './types'; import { FormControlConfig } from './configs/index'; - - /** * 表单数据构造器 */ @@ -63,7 +61,7 @@ class FormDataBuilder { /** * 获取表单数据集合 */ - public buildFormArrayData(entities: Entity[], controlConfigs: FormControlConfig[]): FormData[] { + public buildFormArrayData(entities: Entity[], controlConfigs: FormControlConfig[]): FormValue[] { const formDatas = entities.map((entity) => { return this.buildFormData(entity, controlConfigs); }); @@ -74,7 +72,7 @@ class FormDataBuilder { /** * 获取表单数据 */ - public buildFormData(entity: Entity, controlConfigs: FormControlConfig[]): FormData { + public buildFormData(entity: Entity, controlConfigs: FormControlConfig[]): FormValue { const formData = {}; controlConfigs.forEach((controlConfig: FormControlConfig) => { const { name } = controlConfig; diff --git a/packages/devkit/lib/store/form/form-state-util.ts b/packages/devkit/lib/store/form/form-state-util.ts index ba042df78d9..ad0df24280c 100644 --- a/packages/devkit/lib/store/form/form-state-util.ts +++ b/packages/devkit/lib/store/form/form-state-util.ts @@ -1,5 +1,5 @@ import { ObjectUtil } from '../../common/index'; -import { FormControlState, FormState, FormArrayState } from './form-state'; +import { FormControlState, FormState } from './form-state'; /** * 表单状态工具类 diff --git a/packages/devkit/lib/store/form/form-store-initializer.ts b/packages/devkit/lib/store/form/form-store-initializer.ts index 5dbb3b8bcb6..3614a76d78a 100644 --- a/packages/devkit/lib/store/form/form-store-initializer.ts +++ b/packages/devkit/lib/store/form/form-store-initializer.ts @@ -2,7 +2,7 @@ import { Module } from '../../module/index'; import { ViewModel, ViewModelState } from '../../viewmodel/index'; import { Entity } from '../../store/index'; import { FormStoreConfigManager } from './configs/index'; -import { FormData } from './types'; +import { FormValue } from './types'; import { FormBuilder } from './form-builder'; import { FormDataBuilder } from './form-data-builder'; import { FormState } from './form-state'; @@ -77,7 +77,7 @@ class FormStoreInitializer { /** * 获取表单数据 */ - private getFormData(): FormData { + private getFormValue(): FormValue { const currentEntity = this.getCurrentEntity(); const controlConfigs = this.configManager.getControlConfigs(); const formData = this.formDataBuilder.buildFormData(currentEntity, controlConfigs); @@ -130,8 +130,8 @@ class FormStoreInitializer { * 批量设置控件值 */ private updateControlValues() { - const formData = this.getFormData(); - this.formStore.setValues(formData); + const formData = this.getFormValue(); + this.formStore.setControlValues(formData); } /** diff --git a/packages/devkit/lib/store/form/form-store.ts b/packages/devkit/lib/store/form/form-store.ts index 7a419938f7d..8cff235d266 100644 --- a/packages/devkit/lib/store/form/form-store.ts +++ b/packages/devkit/lib/store/form/form-store.ts @@ -1,12 +1,13 @@ import { Module } from '../../module/index'; import { Store } from '../store/index'; import { FormStoreConfig, FormStoreConfigManager } from './configs/index'; +import { ValidationError } from './validation/index'; +import { FormValue, FormError } from './types'; import { Form } from './form'; import { FormStoreInitializer } from './form-store-initializer'; import { FormState } from './form-state'; import { FormStateBuilder } from './form-state-builder'; import { FormStateUtil } from './form-state-util'; -import { ValidationErrors } from './validation'; /** * Form仓库定义 @@ -61,64 +62,68 @@ class FormStore extends Store { /** * 获取错误值 */ - public getValues(): { [key: string]: any } { - return this.form.values; + public getValue(): FormValue { + return this.form.value; } /** * 获取错误集合 */ - public getErrors(): ValidationErrors | null { - return this.form.errors; + public getError(): FormError | null { + return this.form.error; } /** - * 设置表单值 + * 设置表单唯一标识 */ - public setValues(values: { [key: string]: any }) { - this.form.setValues(values); - this.refreshState(); + public setFormKey(key: string): void { + const oldKey = this.form.key; + if (oldKey === key) { + return; + } + + this.form.setKey(key); } /** - * 设置控件值 + * 设置表单值 */ - public setValue(name: string, value: any): void { - const oldValue = this.form.getValue(name); - if (oldValue === value) { - return; - } - this.form.setValue(name, value); + public setControlValues(values: FormValue) { + this.form.setControlValues(values); this.refreshState(); } /** - * 设置表单唯一标识 + * 设置控件值 */ - public setFormKey(key: string): void { - const oldKey = this.form.key; - if (oldKey === key) { + public setControlValue(name: string, value: any): void { + const oldValue = this.form.getControlValue(name); + if (oldValue === value) { return; } - - this.form.setKey(key); + this.form.setControlValue(name, value); + this.refreshState(); } /** * 校验整个表单 */ - public validate(): void { + public validate(): FormError | null { this.form.validate(); this.refreshState(); + + return this.form.error; } /** * 校验控件 */ - public validateControl(name: string): void { + public validateControl(name: string): ValidationError | null { const control = this.form.getControl(name); - control.validate() + const controlError = control.validate() this.refreshState(); + + return controlError; } /** @@ -138,9 +143,6 @@ class FormStore extends Store { const change: any = { changedStates: changedStates }; - - console.log('----------FormStore change----------'); - console.log(change); this.triggerChange(change); } diff --git a/packages/devkit/lib/store/form/form.ts b/packages/devkit/lib/store/form/form.ts index e5fb95911e6..67d3b43e7b3 100644 --- a/packages/devkit/lib/store/form/form.ts +++ b/packages/devkit/lib/store/form/form.ts @@ -1,5 +1,6 @@ +import { FormValue, FormError } from './types'; import { FormControl } from './form-control'; -import { ValidationErrors } from './validation'; +import { ValidationError } from './validation'; /** * Form定义 @@ -14,7 +15,7 @@ class Form { /** * 表单值 */ - public readonly values: { [key: string]: any }; + public readonly value: FormValue; /** * 校验状态 @@ -24,49 +25,56 @@ class Form { /** * 校验错误 */ - public readonly errors: ValidationErrors; + public readonly error: FormError | null; /** * 控件集合 */ - private controls: { [key: string]: FormControl } + private controls: { [key: string]: FormControl }; /** * 构造函数 */ constructor(key: string, controls: { [key: string]: FormControl }) { - this.values = {}; + this.value = {}; this.valid = true; - this.errors = null; + this.error = null; this.key = key; this.controls = controls; } /** - * 设置唯一标识 + * 获取全部控件 */ - public setKey(key: string): void { - (this as any).key = key; + public getControls(): { [key: string]: FormControl } { + return this.controls; } /** - * 获取全部控件 + * 获取单个控件 */ - public getControls() { - return this.controls; + public getControl(name: string): FormControl | null { + return this.controls[name] || null; } /** - * 获取单个控件 + * 获取控件值 */ - public getControl(name: string) { - return this.controls[name]; + public getControlValue(name: string): any { + return this.value[name]; } /** - * 设置控件值 + * 设置唯一标识 */ - public setValues(values: { [key: string]: any }) { + public setKey(key: string): void { + (this as any).key = key; + } + + /** + * 批量设置控件值 + */ + public setControlValues(values: FormValue) { Object.keys(values).forEach((name) => { const control = this.controls[name]; const value = values[name]; @@ -78,50 +86,62 @@ class Form { /** * 设置控件值 */ - public setValue(name: string, value: any): void { + public setControlValue(name: string, value: any): void { const control = this.controls[name]; control.setValue(value); this.refresh(); } - /** - * 获取控件值 - */ - public getValue(name: string): any { - return this.values[name]; - } - /** * 校验表单 */ - public validate(): ValidationErrors | null { + public validate(): FormError | null { Object.keys(this.controls).forEach((controlName) => { const control = this.controls[controlName]; control.validate(); }); this.refresh(); - return this.errors; + return this.error; + } + + /** + * 校验单个控件 + */ + public validateControl(name: string): ValidationError | null { + const control = this.getControl(name); + if (!control) { + return null; + } + + const controlError = control.validate() + this.refresh(); + + return controlError; } /** * 刷新表单 */ public refresh(): void { - (this as any).values = this.values || {}; - (this as any).errors = this.errors || {}; + const formValue = {}; + const formError = {};; Object.keys(this.controls).forEach((name) => { const control = this.controls[name]; - this.values[name] = control.value; - this.errors[name] = control.error; + formValue[name] = control.value; + if (control.error) { + formError[name] = control.error; + } }); - const invalid = Object.keys(this.errors).some((name: string) => { - return this.errors[name]; + const formInvalid = Object.keys(formError).some((name: string) => { + return formError[name]; }); - (this as any).valid = !invalid; - (this as any).errors = invalid ? this.errors : null; + + (this as any).value = formValue; + (this as any).valid = !formInvalid; + (this as any).error = formInvalid ? formError : null; } } diff --git a/packages/devkit/lib/store/form/types.ts b/packages/devkit/lib/store/form/types.ts index c3efee1c278..6ceaeb56436 100644 --- a/packages/devkit/lib/store/form/types.ts +++ b/packages/devkit/lib/store/form/types.ts @@ -1,3 +1,5 @@ +import { ValidationError } from './validation/index'; + /** * 绑定类型 */ @@ -15,9 +17,23 @@ enum FormControlBindingType { } /** - * 表单数据 + * 表单所有控件值 */ -type FormData = { [key: string]: any }; +type FormValue = { [controlName: string]: any }; +/** + * 表单所有控件的错误信息 + */ +type FormError = { [controlName: string]: ValidationError}; + +/** + * 表单数组内所有表单的值集合 + */ +type FormArrayValue = Array<{formKey: string, formValue: FormValue}>; + +/** + * 表单内所有表单 + */ +type FormArrayError = Array<{formKey: string, formError: FormError}>; -export { FormControlBindingType, FormData }; +export { FormControlBindingType, FormValue, FormError, FormArrayValue, FormArrayError }; diff --git a/packages/mobile-command-services/lib/data-services/validator.service.ts b/packages/mobile-command-services/lib/data-services/validator.service.ts index a209c5ff4f6..3402db5179e 100644 --- a/packages/mobile-command-services/lib/data-services/validator.service.ts +++ b/packages/mobile-command-services/lib/data-services/validator.service.ts @@ -1,4 +1,4 @@ -import { ViewModelState, ViewModel, ValidationErrors } from '@farris/devkit-vue'; +import { ViewModelState, ViewModel, FormError, FormArrayError } from '@farris/devkit-vue'; import { BaseDataService } from './base-data.service'; /** @@ -16,18 +16,19 @@ class ValidatorService extends BaseDataService { /** * 验证所有表单 */ - public validateAll(): Promise { + public validateAll(): Promise { const viewModels = this.module.getViewModels(); - let allErrors: ValidationErrors[] = []; + let allViewModelErrors: FormArrayError = []; viewModels.forEach((viewModel) => { - const errors = this.validateByViewModel(viewModel); - if (Array.isArray(errors)) { - allErrors = allErrors.concat(errors); + const viewModelError = this.validateByViewModel(viewModel) as FormArrayError; + if (viewModelError && Array.isArray(viewModelError)) { + allViewModelErrors = allViewModelErrors.concat(viewModelError); } }); - if (allErrors && allErrors.length > 0) { - return Promise.reject(allErrors) + if (allViewModelErrors.length > 0) { + this.toastService.error('存在校验不通过的项'); + return Promise.reject(allViewModelErrors) } return Promise.resolve(null); @@ -36,7 +37,7 @@ class ValidatorService extends BaseDataService { /** * 验证当前视图模型表单 */ - public validate(): Promise { + public validate(): Promise { const allErrors = this.validateByViewModel(this.viewModel); if (allErrors && allErrors.length > 0) { this.toastService.error('存在校验不通过的项'); @@ -49,33 +50,36 @@ class ValidatorService extends BaseDataService { /** * 处理字段验证 */ - public handleValidateFields(): Promise { - return this.validate(); + public handleValidateFields(): Promise { + // return this.validate(); + return this.validateAll(); } /** * 验证指定视图模型的表单 */ - private validateByViewModel(viewModel: ViewModel): ValidationErrors[] | null { + private validateByViewModel(viewModel: ViewModel): FormArrayError | null { const { formStore, formArrayStore } = viewModel; - let allErrors: ValidationErrors[] = []; + let allErrors: FormArrayError = []; if (formStore) { - formStore.validate(); - const formErrors = formStore.getErrors(); - allErrors = allErrors.concat(formErrors ? [formErrors] : []); + const formKey = formStore.getKey(); + const formError = formStore.validate(); + if (formError) { + allErrors.push({formKey, formError}); + } } if (formArrayStore) { - formArrayStore.validate(); - const formArrayErrors = formArrayStore.getErrors() || []; - allErrors = allErrors.concat(formArrayErrors); + const formArrayError = formArrayStore.validate(); + if (formArrayError && Array.isArray(formArrayError)) { + allErrors = allErrors.concat(formArrayError); + } } return allErrors && allErrors.length > 0 ? allErrors : null; } - /** * 重置验证状态 */ -- Gitee From d94c30c357f3cc432533124e1efe02ebe782c582 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Wed, 19 Mar 2025 11:52:33 +0800 Subject: [PATCH 071/153] =?UTF-8?q?chore:=20=E5=BF=85=E5=A1=AB=E5=89=AF?= =?UTF-8?q?=E4=BD=9C=E7=94=A8=E5=99=A8=E6=94=AF=E6=8C=81=E6=9E=84=E9=80=A0?= =?UTF-8?q?=E5=AE=8C=E6=95=B4=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../change-handler/abstract-change-handler.ts | 2 +- .../devkit/lib/effector/effector-factory.ts | 5 +- .../devkit/lib/effector/required-effector.ts | 55 ++++++++++++++++++- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/packages/devkit/lib/change-handler/abstract-change-handler.ts b/packages/devkit/lib/change-handler/abstract-change-handler.ts index 09b47a79e6c..0b41f537ef5 100644 --- a/packages/devkit/lib/change-handler/abstract-change-handler.ts +++ b/packages/devkit/lib/change-handler/abstract-change-handler.ts @@ -5,7 +5,7 @@ import { EffectorFactory } from "../effector"; import { ViewModel, ViewModelState } from "../viewmodel"; export abstract class AbstractChangeHandler implements ChangeHandler { - constructor(protected viewModel:ViewModel ,protected expressionExecutor: ExpressionExecutor, protected effectorFactory: EffectorFactory) { } + constructor(protected viewModel: ViewModel, protected expressionExecutor: ExpressionExecutor, protected effectorFactory: EffectorFactory) { } abstract handle(change: Change, expressionObjects: ExpressionObject[]): void; protected getEffector(expressionObject: ExpressionObject) { return this.effectorFactory.getEffector(expressionObject); diff --git a/packages/devkit/lib/effector/effector-factory.ts b/packages/devkit/lib/effector/effector-factory.ts index 5f61a57e7ce..8fdc31bf7b8 100644 --- a/packages/devkit/lib/effector/effector-factory.ts +++ b/packages/devkit/lib/effector/effector-factory.ts @@ -3,7 +3,8 @@ import { EffectorRegistry } from "./effector-registry"; import { Effector } from "./types"; import { ValidateEffector } from "./validate-effector"; import { EntityStoreEffector } from "./entity-store-effector"; -import { RequiredValidator } from "../store/form/validation/validators/required-validator"; +import { RequiredEffector } from "./required-effector"; + export class EffectorFactory { constructor(private effectorRegistry: EffectorRegistry) { @@ -24,7 +25,7 @@ export class EffectorFactory { return nsEffectors.find((effector: Effector) => effector instanceof ValidateEffector); } else if (type === ExpressionType.Required) { // 必填表达式 - return nsEffectors.find((effector: Effector) => effector instanceof RequiredValidator); + return nsEffectors.find((effector: Effector) => effector instanceof RequiredEffector); } else { console.warn(`EffectorFactory 没有找到对应的副作用器 ${type}`); return null; diff --git a/packages/devkit/lib/effector/required-effector.ts b/packages/devkit/lib/effector/required-effector.ts index 463a0ddf369..a09c90980f2 100644 --- a/packages/devkit/lib/effector/required-effector.ts +++ b/packages/devkit/lib/effector/required-effector.ts @@ -1,4 +1,5 @@ import { ExpressionObject } from '../expression'; +import { Entity, EntityList } from '../store'; import { ViewModel, ViewModelState } from '../viewmodel'; import { EffectOption, Effector } from './types'; export class RequiredEffector implements Effector { @@ -6,8 +7,58 @@ export class RequiredEffector implements Effector { constructor(/*public namespace: string, */private viewModel: ViewModel) { this.namespace = ''; } + public effect(expressionObject: ExpressionObject, value: any, option?: EffectOption): void { - // 需要根据option中的paths处理 - console.log('RequiredEffector', expressionObject, value, option); + const fullPath = this.resolveFullPath(expressionObject, option); + if (fullPath) { + this.updateFormState(fullPath, value); + } + } + + private resolveFullPath(expressionObject: ExpressionObject, option?: EffectOption): string | null { + // 如果选项中已提供路径,直接使用 + if (option?.path) { + return option.path; + } + + // 否则,尝试从当前行获取目标实体 + const targetEntity = this.getTargetEntity(expressionObject.path); + if (!targetEntity) { + return null; + } + + // 构建完整路径 + return this.buildPath(expressionObject.path); + } + + private getTargetEntity(path: string): Entity | null { + const { entityPaths } = this.viewModel.entityStore.getEntitySchema().resolvePath(path); + const entityPath = `/${entityPaths.join('/')}`; + const targetEntityList = this.viewModel.entityStore.getEntityListByPath(entityPath); + + if (!targetEntityList || targetEntityList.getEntities().length < 1) { + return null; + } + + return targetEntityList.getCurrentEntity(); + } + + private updateFormState(path: string, value: boolean) { + // 遍历formState,将所有required为true的字段的值设置为true + console.log('RequiredEffector', path, value); + } + + private buildPath(path: string) { + const { entityPaths, propertyPaths } = this.viewModel.entityStore.getEntitySchema().resolvePath(path); + const entityStore = this.viewModel.entityStore; + const id = entityStore.getCurrentEntity().idValue; + const entityEffectPaths: string[] = entityPaths.reduce((paths: string[], path: string, index: number) => { + paths.push(path); + const entityList = entityStore.getEntityListByPath(`/${paths.join('/')}`) as EntityList; + const currentEntity = entityList.getCurrentEntity(); + paths.push(`[${currentEntity.idValue}]`); + return paths; + }, [`[${id}]`]); + return `/${entityEffectPaths.concat(propertyPaths).join('/')}`; } } \ No newline at end of file -- Gitee From b40cf4a2d0b341925b4c73788aa26a8c3eff7443 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Wed, 19 Mar 2025 14:35:17 +0800 Subject: [PATCH 072/153] =?UTF-8?q?chore:=20=E6=96=B0=E5=A2=9E=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E5=8F=98=E6=9B=B4=E7=9B=91=E5=90=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../expression-result-change-observer.ts | 23 +++++++++++++++++++ packages/devkit/lib/change-observer/index.ts | 1 + .../devkit/lib/change-observer/providers.ts | 2 ++ packages/devkit/lib/change-observer/types.ts | 2 +- .../renderer/src/form-engine/form-engine.ts | 1 + 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 packages/devkit/lib/change-observer/expression-result-change-observer.ts diff --git a/packages/devkit/lib/change-observer/expression-result-change-observer.ts b/packages/devkit/lib/change-observer/expression-result-change-observer.ts new file mode 100644 index 00000000000..4f78bbf9c84 --- /dev/null +++ b/packages/devkit/lib/change-observer/expression-result-change-observer.ts @@ -0,0 +1,23 @@ +import { Callable } from '../common'; +import { ExpressionResult, ExpressionResultChange } from '../expression'; +import { ViewModel, ViewModelState } from '../viewmodel'; +import { ChangeObserver } from './change-observer'; +import { Change, ChangeSource, ExpressionResultChangeType } from './types'; +export class ExpressionResultChangeObserver extends ChangeObserver { + constructor(private viewModel: ViewModel) { + super(); + } + public observe(callback: Callable): void { + const injector = this.viewModel.getInjector(); + const expressionResult = injector.get(ExpressionResult); + expressionResult.changes.subscribe((change: ExpressionResultChange) => { + const expressionResultChange: Change = { + ns: '', + source: ChangeSource.Expression, + detail: change, + type: ExpressionResultChangeType.ExpressionResultChange, + }; + callback(expressionResultChange); + }); + } +} diff --git a/packages/devkit/lib/change-observer/index.ts b/packages/devkit/lib/change-observer/index.ts index c1fc6146775..4f087483e68 100644 --- a/packages/devkit/lib/change-observer/index.ts +++ b/packages/devkit/lib/change-observer/index.ts @@ -4,5 +4,6 @@ export * from './change-observer'; export * from './state-machine-observer'; export * from './entity-state-change-observer'; export * from './ui-state-change-observer'; +export * from './expression-result-change-observer'; export * from './change-observer-registry'; export * from './providers'; \ No newline at end of file diff --git a/packages/devkit/lib/change-observer/providers.ts b/packages/devkit/lib/change-observer/providers.ts index 791639c4022..41342ee27ed 100644 --- a/packages/devkit/lib/change-observer/providers.ts +++ b/packages/devkit/lib/change-observer/providers.ts @@ -5,10 +5,12 @@ import { ChangeObserverRegistry } from "./change-observer-registry"; import { EntityStateChangeObserver } from "./entity-state-change-observer"; import { UIStateChangeObserver } from "./ui-state-change-observer"; import { ViewModel } from "../viewmodel/index"; +import { ExpressionResultChangeObserver } from "./expression-result-change-observer"; export const changeObserverProviders: StaticProvider[] = [ { provide: CHANGE_OBSERVER_TOKEN, useClass: StateMachineObserver, deps: [forwardRef(() => ViewModel)], multi: true }, { provide: CHANGE_OBSERVER_TOKEN, useClass: EntityStateChangeObserver, deps: [forwardRef(() => ViewModel)], multi: true }, { provide: CHANGE_OBSERVER_TOKEN, useClass: UIStateChangeObserver, deps: [forwardRef(() => ViewModel)], multi: true }, + { provide: CHANGE_OBSERVER_TOKEN, useClass: ExpressionResultChangeObserver, deps: [forwardRef(() => ViewModel)], multi: true}, { provide: ChangeObserverRegistry, useClass: ChangeObserverRegistry, deps: [CHANGE_OBSERVER_TOKEN] } ]; diff --git a/packages/devkit/lib/change-observer/types.ts b/packages/devkit/lib/change-observer/types.ts index 09ad4190d21..f47308e974d 100644 --- a/packages/devkit/lib/change-observer/types.ts +++ b/packages/devkit/lib/change-observer/types.ts @@ -20,7 +20,7 @@ export interface Change { ns?: string; source: ChangeSource; type?: ChangeType; - detail: StateChange; + detail: StateChange | T; /** * 视图模型id,仅变量变更场景有效 */ diff --git a/packages/renderer/src/form-engine/form-engine.ts b/packages/renderer/src/form-engine/form-engine.ts index 4b04563a09e..ee62708695b 100644 --- a/packages/renderer/src/form-engine/form-engine.ts +++ b/packages/renderer/src/form-engine/form-engine.ts @@ -16,6 +16,7 @@ export class FormEngine { ) { this.changeObserverRegistry.observers.forEach((observer: ChangeObserver) => { observer.observe((change: Change) => { + console.log(change); const results: Map = this.changeResolveService.resolve(change); if (results && results.size > 0) { results.forEach((configs: Config[], componentId: string) => { -- Gitee From 2b9b1da5b83295b7382eeb81fbe2f6a8f2061336 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Wed, 19 Mar 2025 16:04:35 +0800 Subject: [PATCH 073/153] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3Form=E4=B8=AD?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=85=B3=E8=81=94=E5=AD=97=E6=AE=B5=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E9=97=AE=E9=A2=98=EF=BC=9B2=E3=80=81Form=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E8=B7=AF=E5=BE=84=E8=B0=83=E6=95=B4=E4=B8=BA=E7=9F=AD?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devkit/lib/store/entity-store/entity.ts | 12 +++++-- .../metadata/form/entity-schema-query.ts | 6 ++-- .../form/form-array-store-config-builder.ts | 36 +++++++++---------- .../form/form-control-config-builder.ts | 15 +++++--- .../form/form-store-config-builder.ts | 6 ++-- 5 files changed, 45 insertions(+), 30 deletions(-) diff --git a/packages/devkit/lib/store/entity-store/entity.ts b/packages/devkit/lib/store/entity-store/entity.ts index 7054bb97be9..fc2790f486b 100644 --- a/packages/devkit/lib/store/entity-store/entity.ts +++ b/packages/devkit/lib/store/entity-store/entity.ts @@ -72,8 +72,16 @@ class Entity extends EntityNode { * 根据路径获取属性值 */ public getValueByPath(path: string): any { - const name = path.split('/')[1]; - return this[name]; + const pathSegs = path.split('/').filter((pathSeg: string) => { + return pathSeg; + }); + + let currentValue = this; + pathSegs.forEach((pathSeg) => { + currentValue = currentValue ? currentValue[pathSeg] : undefined; + }); + + return currentValue; } /** diff --git a/packages/mobile-render/src/services/metadata/form/entity-schema-query.ts b/packages/mobile-render/src/services/metadata/form/entity-schema-query.ts index 8859760f241..c18593b55e0 100644 --- a/packages/mobile-render/src/services/metadata/form/entity-schema-query.ts +++ b/packages/mobile-render/src/services/metadata/form/entity-schema-query.ts @@ -139,13 +139,13 @@ class EntitySchemaQuery { * 获取字段绑定路径 */ private getFieldBindingPath(wrappedEntitySchema: any, fieldSchema: any): string { - const entityBindingPaht = wrappedEntitySchema.bindingPath; + const entityBindingPath = wrappedEntitySchema.bindingPath; const shortBindingPath = fieldSchema.bindingPath.split('.').join('/'); - if (entityBindingPaht === '/') { + if (entityBindingPath === '/') { return `/${shortBindingPath}`; } else { - return `${entityBindingPaht}/${shortBindingPath}`; + return `${entityBindingPath}/${shortBindingPath}`; } } } diff --git a/packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts b/packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts index a653a11c0f5..b7ff429bae0 100644 --- a/packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts +++ b/packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts @@ -42,13 +42,30 @@ class FormArrayStoreConfigBuilder { throw new Error(`Component(viewModel=${viewModelNode.id}) not found`); } - const controlConfigs = this.buildControlConfigs(vmComponentNode); + const controlConfigs = this.buildControlConfigs(viewModelNode, vmComponentNode); const stateConfig: FormArrayStateConfig = { controls: controlConfigs }; return stateConfig; } + /** + * 构造控件配置集合 + */ + private buildControlConfigs(viewModelNode: any, vmComponentNode: any): FormControlConfig[] { + const wrappedControlNodes = this.collectWrappedControlNodes(vmComponentNode); + const controlConfigBuilder = new FormControlConfigBuilder(); + + const controlConfigs: FormControlConfig[] = []; + wrappedControlNodes.forEach((wrappedControlNode) => { + const controlNode = wrappedControlNode.component; + const controlConfig = controlConfigBuilder.build(viewModelNode, controlNode.editor); + controlConfigs.push(controlConfig); + }); + + return controlConfigs; + } + /** * 获取列表对应卡片的表单组件 */ @@ -68,23 +85,6 @@ class FormArrayStoreConfigBuilder { return cardVmComponentNode ? cardVmComponentNode : listVmComponentNode; } - /** - * 构造控件配置集合 - */ - private buildControlConfigs(vmComponentNode: any): FormControlConfig[] { - const wrappedControlNodes = this.collectWrappedControlNodes(vmComponentNode); - const controlConfigBuilder = new FormControlConfigBuilder(); - - const controlConfigs: FormControlConfig[] = []; - wrappedControlNodes.forEach((wrappedControlNode) => { - const controlNode = wrappedControlNode.component; - const controlConfig = controlConfigBuilder.build(controlNode.editor); - controlConfigs.push(controlConfig); - }); - - return controlConfigs; - } - /** * 搜集当前VM组件下的所有输入控件 */ diff --git a/packages/mobile-render/src/services/module-config/form/form-control-config-builder.ts b/packages/mobile-render/src/services/module-config/form/form-control-config-builder.ts index 5c49c78d157..d85d8103b86 100644 --- a/packages/mobile-render/src/services/module-config/form/form-control-config-builder.ts +++ b/packages/mobile-render/src/services/module-config/form/form-control-config-builder.ts @@ -21,10 +21,10 @@ class FormControlConfigBuilder { /** * 构造控件配置 */ - public build(controlNode: any): FormControlConfig { + public build(viewModelNode: any, controlNode: any): FormControlConfig { const name = controlNode.id; const bindingType = this.getBindingType(controlNode); - const bindingPath = this.getBindingPath(controlNode); + const bindingPath = this.getBindingPath(viewModelNode, controlNode); const validationRules = this.getValidationRules(controlNode); const controlConfig = { name, bindingType, bindingPath, validationRules }; @@ -48,8 +48,15 @@ class FormControlConfigBuilder { /** * 获取绑定路径 */ - private getBindingPath(controlNode: any): string { - return controlNode.binding.path; + private getBindingPath(viewModelNode: any, controlNode: any): string { + const { bindTo } = viewModelNode; + + // Form和FormArray已经记录了实体路径,FormControl上使用相对短路径 + if (bindTo === '/') { + return controlNode.binding.path; + } else { + return controlNode.binding.path.replace(bindTo, ''); + } } /** diff --git a/packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts b/packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts index 4b272c5635c..e4c73b30000 100644 --- a/packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts +++ b/packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts @@ -42,7 +42,7 @@ class FormStoreConfigBuilder { throw new Error(`Component(viewModel=${viewModelNode.id}) not found`); } - const controlConfigs = this.buildControlConfigs(vmComponentNode); + const controlConfigs = this.buildControlConfigs(viewModelNode, vmComponentNode); const stateConfig: FormStateConfig = { controls: controlConfigs }; @@ -53,14 +53,14 @@ class FormStoreConfigBuilder { /** * 构造控件配置集合 */ - private buildControlConfigs(vmComponentNode: any): FormControlConfig[] { + private buildControlConfigs(viewModelNode: any, vmComponentNode: any): FormControlConfig[] { const wrappedControlNodes = this.collectWrappedControlNodes(vmComponentNode); const controlConfigBuilder = new FormControlConfigBuilder(); const controlConfigs: FormControlConfig[] = []; wrappedControlNodes.forEach((wrappedControlNode) => { const controlNode = wrappedControlNode.component; - const controlConfig = controlConfigBuilder.build(controlNode.editor); + const controlConfig = controlConfigBuilder.build(viewModelNode, controlNode.editor); controlConfigs.push(controlConfig); }); -- Gitee From 5c48d5152b85c213ad7053d5b1ea593c37860d17 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Wed, 19 Mar 2025 22:13:18 +0800 Subject: [PATCH 074/153] =?UTF-8?q?feature:=20=E8=A1=A8=E5=8D=95=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=8A=A8=E6=80=81=E6=94=B9=E5=8F=98=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form/form-array-store-initializer.ts | 28 ++++- .../devkit/lib/store/form/form-array-store.ts | 29 ++++- packages/devkit/lib/store/form/form-array.ts | 36 +++++- .../devkit/lib/store/form/form-control.ts | 16 +++ packages/devkit/lib/store/form/form-store.ts | 17 ++- packages/devkit/lib/store/form/form.ts | 34 +++++- .../devkit/lib/store/form/validation/types.ts | 10 +- .../validators/custom-function-validator.ts | 2 +- .../store/form/validation/validators/index.ts | 3 +- .../validators/max-length-validator.ts | 2 +- .../validators/pattern-validator.ts | 2 +- .../validators/required-validator.ts | 2 +- .../validation/validators/static-validator.ts | 29 +++++ .../src/views/dynamic-demo/DynamicDemo.vue | 14 ++- .../dynamic-demo/module/dynamic-module.ts | 45 ++++++- .../module/services/test.service.ts | 82 ------------- .../module/services/validation.service.ts | 110 ++++++++++++++++-- 17 files changed, 341 insertions(+), 120 deletions(-) create mode 100644 packages/devkit/lib/store/form/validation/validators/static-validator.ts diff --git a/packages/devkit/lib/store/form/form-array-store-initializer.ts b/packages/devkit/lib/store/form/form-array-store-initializer.ts index cf77906086e..5d190de4c06 100644 --- a/packages/devkit/lib/store/form/form-array-store-initializer.ts +++ b/packages/devkit/lib/store/form/form-array-store-initializer.ts @@ -1,9 +1,10 @@ import { Module } from '../../module/index'; import { ViewModel, ViewModelState } from '../../viewmodel/index'; import { Entity } from '../entity-store/index'; -import { FormControlConfig, FormArrayStoreConfigManager } from './configs/index'; -import { FormBuilder } from './form-builder'; +import { FormArrayStoreConfigManager } from './configs/index'; +import { Form } from './form'; import { FormDataBuilder } from './form-data-builder'; +import { FormBuilder } from './form-builder'; import { FormArrayState } from './form-state'; import { FormArrayStore } from './form-array-store' @@ -91,11 +92,26 @@ class FormArrayStoreInitializer { private updateFormArrayStore() { const controlConfigs = this.configManager.getControlConfigs(); const entities = this.getEntities(); - const formKeys = this.formDataBuilder.buildFormKeys(entities); - const formDatas = this.formDataBuilder.buildFormArrayData(entities, controlConfigs); - const forms = this.formBuilder.buildForms(formKeys, formDatas, controlConfigs); - this.formArrayStore.loadForms(forms); + const oldForms = this.formArrayStore.getForms(); + const newForms = []; + entities.forEach((entity: Entity) => { + const formKey = this.formDataBuilder.buildFormKey(entity); + const formData = this.formDataBuilder.buildFormData(entity, controlConfigs); + const oldForm = oldForms.find((oldForm: Form) => { + return oldForm.key === formKey; + }); + + if (oldForm) { + oldForm.setControlValues(formData); + newForms.push(oldForm); + } else { + const newForm = this.formBuilder.buildForm(formKey, formData, controlConfigs); + newForms.push(newForm); + } + }); + + this.formArrayStore.loadForms(newForms); } /** diff --git a/packages/devkit/lib/store/form/form-array-store.ts b/packages/devkit/lib/store/form/form-array-store.ts index 2db93444b98..44bc3588109 100644 --- a/packages/devkit/lib/store/form/form-array-store.ts +++ b/packages/devkit/lib/store/form/form-array-store.ts @@ -1,5 +1,6 @@ import { Module } from '../../module/index'; import { Store } from '../store/index'; +import { ValidationRule } from './validation/index'; import { FormError, FormArrayValue, FormArrayError } from './types'; import { Form } from './form'; import { FormArray } from './form-array'; @@ -50,6 +51,13 @@ class FormArrayStore extends Store { this.refreshState(); } + /** + * 初始化FormArray + */ + public initFormArray(formArray: FormArray): void { + this.formArray = formArray; + } + /** * 获取FormArray的值 */ @@ -69,10 +77,17 @@ class FormArrayStore extends Store { } /** - * 初始化FormArray + * 获取控件验证规则 */ - public initFormArray(formArray: FormArray): void { - this.formArray = formArray; + public getControlRules(formKey: string, controlName: string): ValidationRule[] { + return this.formArray.getControlRules(formKey, controlName); + } + + /** + * 获取表单数组 + */ + public getForms(): Form[] { + return this.formArray.getForms(); } /** @@ -83,6 +98,14 @@ class FormArrayStore extends Store { this.refreshState(); } + /** + * 设置控件验证规则 + */ + public setControlRules(formKey: string, controlName: string, rules: ValidationRule[]): void { + this.formArray.setControlRules(formKey, controlName, rules); + this.refreshState(); + } + /** * 校验FormArray */ diff --git a/packages/devkit/lib/store/form/form-array.ts b/packages/devkit/lib/store/form/form-array.ts index d862a9f3b96..cea1d4162c8 100644 --- a/packages/devkit/lib/store/form/form-array.ts +++ b/packages/devkit/lib/store/form/form-array.ts @@ -1,4 +1,5 @@ import { FormError, FormArrayValue, FormArrayError } from './types'; +import { ValidationRule } from './validation/index'; import { Form } from './form'; /** @@ -46,14 +47,26 @@ class FormArray { /** * 获取Form */ - public getForm(key: string): Form | null { + public getForm(formKey: string): Form | null { const form = this.forms.find((form) => { - return form.key === key; + return form.key === formKey; }); return form || null; } + /** + * 获取控件验证规则 + */ + public getControlRules(formKey: string, controlName: string): ValidationRule[] { + const form = this.getForm(formKey); + if (!form) { + throw new Error(`Form(key=${formKey}) not found`); + } + + return form.getControlRules(controlName); + } + /** * 加载Form集合 */ @@ -63,6 +76,21 @@ class FormArray { this.refresh(); } + /** + * 设置控件验证规则 + */ + public setControlRules(formKey: string, controlName: string, rules: ValidationRule[]) { + const form = this.getForm(formKey); + if (!form) { + throw new Error(`Form(key=${formKey}) not found`); + } + + form.setControlRules(controlName, rules); + form.validateControl(controlName); + + this.refresh(); + } + /** * 校验FormArray */ @@ -78,8 +106,8 @@ class FormArray { /** * 校验下级Form */ - public validateForm(key: string): FormError | null { - const form = this.getForm(key); + public validateForm(formKey: string): FormError | null { + const form = this.getForm(formKey); if (!form) { return null; } diff --git a/packages/devkit/lib/store/form/form-control.ts b/packages/devkit/lib/store/form/form-control.ts index d9de5b070dd..513d4ed964e 100644 --- a/packages/devkit/lib/store/form/form-control.ts +++ b/packages/devkit/lib/store/form/form-control.ts @@ -41,6 +41,14 @@ class FormControl { this.error = null; } + /** + * 获取验证规则 + */ + public getRules(): ValidationRule[] { + const rules = [...this.rules]; + return rules; + } + /** * 设置值 */ @@ -49,6 +57,14 @@ class FormControl { this.validate(); } + /** + * 设置控件验证规则 + */ + public setControlRules(rules: ValidationRule[]): void { + this.rules = rules; + this.validate(); + } + /** * 校验值 */ diff --git a/packages/devkit/lib/store/form/form-store.ts b/packages/devkit/lib/store/form/form-store.ts index 8cff235d266..e8523faeeeb 100644 --- a/packages/devkit/lib/store/form/form-store.ts +++ b/packages/devkit/lib/store/form/form-store.ts @@ -1,7 +1,7 @@ import { Module } from '../../module/index'; import { Store } from '../store/index'; import { FormStoreConfig, FormStoreConfigManager } from './configs/index'; -import { ValidationError } from './validation/index'; +import { ValidationRule, ValidationError } from './validation/index'; import { FormValue, FormError } from './types'; import { Form } from './form'; import { FormStoreInitializer } from './form-store-initializer'; @@ -73,6 +73,13 @@ class FormStore extends Store { return this.form.error; } + /** + * 获取控件验证规则 + */ + public getControlRules(name: string): ValidationRule[] { + return this.form.getControlRules(name); + } + /** * 设置表单唯一标识 */ @@ -105,6 +112,14 @@ class FormStore extends Store { this.refreshState(); } + /** + * 设置控件验证规则 + */ + public setControlRules(name: string, rules: ValidationRule[]): void { + this.form.setControlRules(name, rules); + this.refreshState(); + } + /** * 校验整个表单 */ diff --git a/packages/devkit/lib/store/form/form.ts b/packages/devkit/lib/store/form/form.ts index 67d3b43e7b3..4f99da50733 100644 --- a/packages/devkit/lib/store/form/form.ts +++ b/packages/devkit/lib/store/form/form.ts @@ -1,6 +1,6 @@ import { FormValue, FormError } from './types'; +import { ValidationRule, ValidationError } from './validation'; import { FormControl } from './form-control'; -import { ValidationError } from './validation'; /** * Form定义 @@ -61,7 +61,24 @@ class Form { * 获取控件值 */ public getControlValue(name: string): any { - return this.value[name]; + const control = this.getControl(name); + if (!control) { + throw new Error(`FormControl(name=${name}) not found`); + } + + return control.value; + } + + /** + * 获取控件验证规则 + */ + public getControlRules(name: string): ValidationRule[] { + const control = this.getControl(name); + if (!control) { + throw new Error(`FormControl(name=${name}) not found`); + } + + return control.getRules(); } /** @@ -92,6 +109,19 @@ class Form { this.refresh(); } + /** + * 设置控件规则 + */ + public setControlRules(name: string, rules: ValidationRule[]): void { + const control = this.getControl(name); + if (!control) { + throw new Error(`FormControl(name=${name}) not found`); + } + + control.setControlRules(rules); + this.refresh(); + } + /** * 校验表单 */ diff --git a/packages/devkit/lib/store/form/validation/types.ts b/packages/devkit/lib/store/form/validation/types.ts index a1522709b61..82b52b334a9 100644 --- a/packages/devkit/lib/store/form/validation/types.ts +++ b/packages/devkit/lib/store/form/validation/types.ts @@ -15,6 +15,14 @@ interface RequiredValidationRule extends ValidationRule { name: 'required' } +/** + * 静态验证 + */ +interface StaticValidationRule extends ValidationRule { + name: 'static', + valid: boolean; +} + /** * 字符串最大长度 */ @@ -108,7 +116,7 @@ interface Validator { } export { - ValidationRule, RequiredValidationRule, + ValidationRule, RequiredValidationRule, StaticValidationRule, MaxLengthValidationRule, MinLengthValidationRule, MaxValueValidationRule, MinValueValidationRule, MaxDateValidationRule, MinDateValidationRule, diff --git a/packages/devkit/lib/store/form/validation/validators/custom-function-validator.ts b/packages/devkit/lib/store/form/validation/validators/custom-function-validator.ts index bb81dcf21af..cc0346da08b 100644 --- a/packages/devkit/lib/store/form/validation/validators/custom-function-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/custom-function-validator.ts @@ -1,4 +1,4 @@ -import { ValidationError, CustomFunctionValidationRule, Validator } from '../types'; +import { ValidationError, CustomFunctionValidationRule } from '../types'; import { BaseValidator } from './base-validator'; /** diff --git a/packages/devkit/lib/store/form/validation/validators/index.ts b/packages/devkit/lib/store/form/validation/validators/index.ts index 861a6c27140..e7470ee42d1 100644 --- a/packages/devkit/lib/store/form/validation/validators/index.ts +++ b/packages/devkit/lib/store/form/validation/validators/index.ts @@ -1,4 +1,5 @@ import { RequiredValidator } from './required-validator'; +import { StaticValidator } from './static-validator'; import { MaxLengthValidator } from './max-length-validator'; import { MinLengthValidator } from './min-length-validator'; import { MaxValueValidator } from './max-value-validator'; @@ -9,7 +10,7 @@ import { PatternValidator } from './pattern-validator'; import { CustomFunctionValidator } from './custom-function-validator' const validatorTypes = [ - RequiredValidator, + RequiredValidator, StaticValidator, MaxLengthValidator, MinLengthValidator, MaxValueValidator, MinValueValidator, MaxDateValidator, MinDateValidator, diff --git a/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts b/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts index 2b616f06494..5ec79465197 100644 --- a/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts @@ -1,4 +1,4 @@ -import { ValidationError, MaxLengthValidationRule, Validator } from '../types'; +import { ValidationError, MaxLengthValidationRule } from '../types'; import { BaseValidator } from './base-validator'; /** diff --git a/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts b/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts index 1a12b3bf903..a74cbfba575 100644 --- a/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts @@ -1,4 +1,4 @@ -import { ValidationError, PatternValidationRule, Validator } from '../types'; +import { ValidationError, PatternValidationRule } from '../types'; import { BaseValidator } from './base-validator'; /** diff --git a/packages/devkit/lib/store/form/validation/validators/required-validator.ts b/packages/devkit/lib/store/form/validation/validators/required-validator.ts index 413b0e3fa7c..15f7aa27661 100644 --- a/packages/devkit/lib/store/form/validation/validators/required-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/required-validator.ts @@ -1,4 +1,4 @@ -import { ValidationError, ValidationRule, RequiredValidationRule, Validator } from '../types'; +import { ValidationError, RequiredValidationRule } from '../types'; import { BaseValidator } from './base-validator'; /** diff --git a/packages/devkit/lib/store/form/validation/validators/static-validator.ts b/packages/devkit/lib/store/form/validation/validators/static-validator.ts new file mode 100644 index 00000000000..b2b8a213997 --- /dev/null +++ b/packages/devkit/lib/store/form/validation/validators/static-validator.ts @@ -0,0 +1,29 @@ +import { ValidationError, StaticValidationRule } from '../types'; +import { BaseValidator } from './base-validator'; + +/** + * 静态验证器 + */ +class StaticValidator extends BaseValidator { + + /** + * 名称 + */ + public name: string = 'static'; + + /** + * 验证方法 + */ + public validate(value: any, rule: StaticValidationRule): ValidationError | null { + if (!rule.valid) { + const name = rule.name; + const message = rule.message || '输入的值不符合要求'; + const error = { name, message, actualValue: value }; + return error; + } + + return null; + } +} + +export { StaticValidator }; diff --git a/packages/devkit/src/views/dynamic-demo/DynamicDemo.vue b/packages/devkit/src/views/dynamic-demo/DynamicDemo.vue index 77d4012dac5..df1535d1ccc 100644 --- a/packages/devkit/src/views/dynamic-demo/DynamicDemo.vue +++ b/packages/devkit/src/views/dynamic-demo/DynamicDemo.vue @@ -42,6 +42,14 @@ const cancelSubmit = () => { entityStore.setValueByPath('/status', 'Billing'); }; +const validate = () => { + dynamicViewModel.validate(); +}; + +const changeRules = () => { + dynamicViewModel.changeRules(); +}; + const makeFormInvalid = () => { dynamicViewModel.makeFormInvalid(); }; @@ -75,8 +83,10 @@ const test = () => {

验证工具栏

- - + + + +
diff --git a/packages/devkit/src/views/dynamic-demo/module/dynamic-module.ts b/packages/devkit/src/views/dynamic-demo/module/dynamic-module.ts index a2a5a1285a2..40282609331 100644 --- a/packages/devkit/src/views/dynamic-demo/module/dynamic-module.ts +++ b/packages/devkit/src/views/dynamic-demo/module/dynamic-module.ts @@ -26,6 +26,14 @@ export const dynamicModuleConfig: ModuleConfig = { name: 'save', params: [] }, + { + name: 'validate', + params: [] + }, + { + name: 'changeRules', + params: [] + }, { name: 'makeFormInvalid', params: [] @@ -86,12 +94,24 @@ export const dynamicModuleConfig: ModuleConfig = { ] }, { - commandName: 'makeFormInvalid', + commandName: 'validate', tasks: [ { - name: 'makeFormInvalid', - service: 'TestService', - method: 'makeFormInvalid', + name: 'validate', + service: 'ValidationService', + method: 'validate', + params: [], + links: [] + }, + ] + }, + { + commandName: 'changeRules', + tasks: [ + { + name: 'changeRules', + service: 'ValidationService', + method: 'changeRules', params: [], links: [] }, @@ -102,13 +122,25 @@ export const dynamicModuleConfig: ModuleConfig = { tasks: [ { name: 'makeFormValid', - service: 'TestService', + service: 'ValidationService', method: 'makeFormValid', params: [], links: [] }, ] }, + { + commandName: 'makeFormInvalid', + tasks: [ + { + name: 'makeFormInvalid', + service: 'ValidationService', + method: 'makeFormInvalid', + params: [], + links: [] + }, + ] + }, { commandName: 'test', tasks: [ @@ -255,6 +287,7 @@ export const dynamicModuleConfig: ModuleConfig = { formStores: [ { id: 'dynamic-form-store', + bindingPath: '/', state: { controls: [ { @@ -266,6 +299,7 @@ export const dynamicModuleConfig: ModuleConfig = { { name: 'name', bindingType: 'EntityState', bindingPath: '/name', validationRules: [ + { name: 'required' }, { name: 'maxLength', maxLength: 4 }, { name: 'minLength', minLength: 2 } ] @@ -315,6 +349,7 @@ export const dynamicModuleConfig: ModuleConfig = { { name: 'name', bindingType: 'EntityState', bindingPath: '/name', validationRules: [ + { name: 'required' }, { name: 'maxLength', maxLength: 4 }, { name: 'minLength', minLength: 2 } ] diff --git a/packages/devkit/src/views/dynamic-demo/module/services/test.service.ts b/packages/devkit/src/views/dynamic-demo/module/services/test.service.ts index b7e5fe1441b..32caa4a6e29 100644 --- a/packages/devkit/src/views/dynamic-demo/module/services/test.service.ts +++ b/packages/devkit/src/views/dynamic-demo/module/services/test.service.ts @@ -30,88 +30,6 @@ class TestService extends BaseDataService { this.entityStore.setValueByPath('/name', newName); } - - /** - * 将数据设置为不合法 - */ - public makeFormInvalid() { - - // 必填 - this.entityStore.setValueByPath('/code', ''); - this.entityStore.setValueByPath('/code', null); - this.entityStore.setValueByPath('/code', undefined); - - // 最大长度、最小长度 - this.entityStore.setValueByPath('/name', '刘一刘二刘三'); - this.entityStore.setValueByPath('/name', '刘'); - this.entityStore.setValueByPath('/name', ''); - - // 最大值、最小值 - this.entityStore.setValueByPath('/age', 100); - this.entityStore.setValueByPath('/age', 10); - - // 最大日期、最小日期 - this.entityStore.setValueByPath('/birthday', '2099-12-30'); - this.entityStore.setValueByPath('/birthday', '1900-01-01'); - - // 正则验证 - this.entityStore.setValueByPath('/mobile', 'ABC'); - - // 自定义函数验证 - this.entityStore.setValueByPath('/address', '北京'); - } - - /** - * 将数据设置为合法 - */ - public makeFormValid() { - - // 必填 - this.entityStore.setValueByPath('/code', 'LiuYi'); - - - // 最大长度、最小长度:边界值 - // this.entityStore.setValueByPath('/name', '刘一刘一'); - this.entityStore.setValueByPath('/name', '刘一'); - - // 最大长度、最小长度:非法值 - // this.entityStore.setValueByPath('/name', null); - // this.entityStore.setValueByPath('/name', undefined); - // this.entityStore.setValueByPath('/name', 123); - // this.entityStore.setValueByPath('/name', new Date()); - - - // 最大值、最小值:边界值 - // this.entityStore.setValueByPath('/age', 65); - // this.entityStore.setValueByPath('/age', '65'); - // this.entityStore.setValueByPath('/age', 20); - this.entityStore.setValueByPath('/age', '20.00'); - - // 最大值、最小值:非法值 - // this.entityStore.setValueByPath('/age', 'abc'); - // this.entityStore.setValueByPath('/age', null); - // this.entityStore.setValueByPath('/age', undefined); - - - // 最大日期、最小日期:边界值 - // this.entityStore.setValueByPath('/birthday', '2025-01-01'); - this.entityStore.setValueByPath('/birthday', '1960-01-01'); - - // 最大日期、最小日期:非法值 - // this.entityStore.setValueByPath('/birthday', null); - // this.entityStore.setValueByPath('/birthday', undefined); - // this.entityStore.setValueByPath('/birthday', ''); - // this.entityStore.setValueByPath('/birthday', 'abcd'); - - - // 正则验证 - this.entityStore.setValueByPath('/mobile', '13011110001'); - - // 自定义函数验证 - this.entityStore.setValueByPath('/address', '山东济南'); - } - - public testA() { console.log('----------testA----------'); return true; diff --git a/packages/devkit/src/views/dynamic-demo/module/services/validation.service.ts b/packages/devkit/src/views/dynamic-demo/module/services/validation.service.ts index e291da820e7..7954ff07dcb 100644 --- a/packages/devkit/src/views/dynamic-demo/module/services/validation.service.ts +++ b/packages/devkit/src/views/dynamic-demo/module/services/validation.service.ts @@ -13,20 +13,112 @@ class ValidationService extends BaseDataService { super(viewModel); } - /** * 验证 */ public validate() { - const promise = new Promise((resolve, reject) => { - setTimeout(() => { - console.log('validated ...'); - resolve(true); - }, 2000); - }); - - return promise; + const { formStore, formArrayStore } = this.viewModel; + const formError = formStore.validate(); + console.log('----------formError----------'); + console.log(formError); + + console.log('----------formArrayError----------'); + const formArrayError = formArrayStore.validate(); + console.log(formArrayError); + } + + /** + * 改变验证规则 + */ + public changeRules() { + const { formStore, formArrayStore } = this.viewModel; + const rules = [{ name: 'static', valid: false }]; + formStore.setControlRules('name', rules); + formArrayStore.setControlRules('0001', 'name', rules); + formArrayStore.setControlRules('0002', 'name', rules); + + } + + /** + * 将数据设置为不合法 + */ + public makeFormInvalid() { + + // 必填 + this.entityStore.setValueByPath('/code', ''); + this.entityStore.setValueByPath('/code', null); + this.entityStore.setValueByPath('/code', undefined); + + // 最大长度、最小长度 + this.entityStore.setValueByPath('/name', '刘一刘二刘三'); + this.entityStore.setValueByPath('/name', '刘'); + this.entityStore.setValueByPath('/name', undefined); + + // 最大值、最小值 + this.entityStore.setValueByPath('/age', 100); + this.entityStore.setValueByPath('/age', 10); + + // 最大日期、最小日期 + this.entityStore.setValueByPath('/birthday', '2099-12-30'); + this.entityStore.setValueByPath('/birthday', '1900-01-01'); + + // 正则验证 + this.entityStore.setValueByPath('/mobile', 'ABC'); + + // 自定义函数验证 + this.entityStore.setValueByPath('/address', '北京'); } + + /** + * 将数据设置为合法 + */ + public makeFormValid() { + + // 必填 + this.entityStore.setValueByPath('/code', 'LiuYi'); + + + // 最大长度、最小长度:边界值 + // this.entityStore.setValueByPath('/name', '刘一刘一'); + this.entityStore.setValueByPath('/name', '刘一'); + + // 最大长度、最小长度:非法值 + // this.entityStore.setValueByPath('/name', null); + // this.entityStore.setValueByPath('/name', undefined); + // this.entityStore.setValueByPath('/name', 123); + // this.entityStore.setValueByPath('/name', new Date()); + + + // 最大值、最小值:边界值 + // this.entityStore.setValueByPath('/age', 65); + // this.entityStore.setValueByPath('/age', '65'); + // this.entityStore.setValueByPath('/age', 20); + this.entityStore.setValueByPath('/age', '20.00'); + + // 最大值、最小值:非法值 + // this.entityStore.setValueByPath('/age', 'abc'); + // this.entityStore.setValueByPath('/age', null); + // this.entityStore.setValueByPath('/age', undefined); + + + // 最大日期、最小日期:边界值 + // this.entityStore.setValueByPath('/birthday', '2025-01-01'); + this.entityStore.setValueByPath('/birthday', '1960-01-01'); + + // 最大日期、最小日期:非法值 + // this.entityStore.setValueByPath('/birthday', null); + // this.entityStore.setValueByPath('/birthday', undefined); + // this.entityStore.setValueByPath('/birthday', ''); + // this.entityStore.setValueByPath('/birthday', 'abcd'); + + + // 正则验证 + this.entityStore.setValueByPath('/mobile', '13011110001'); + + // 自定义函数验证 + this.entityStore.setValueByPath('/address', '山东济南'); + } + } export { ValidationService }; -- Gitee From 3e2c7ad9ddfc8d64e60a110cbd233e55b98ba546 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Thu, 20 Mar 2025 18:57:26 +0800 Subject: [PATCH 075/153] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=8F=8A=E9=85=8D=E7=BD=AE=E4=BE=9D=E8=B5=96=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=9E=9A=E4=B8=BE=E7=BC=96=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/expression/expression-engine-proxy.ts | 1 - .../change-resolver/change-resolve-service.ts | 6 +-- .../src/change-resolver/change-resolver.ts | 6 +-- .../entity-store-change-resolver.ts | 10 ++--- .../expression-result-change-resolver.ts | 28 ++++++++++++ .../state-machine-change-resolver.ts | 10 ++--- .../ui-state-change-resolver.ts | 10 ++--- ...onent-config-dependency-resolve-service.ts | 6 +-- .../component-config-dependency-resolver.ts | 4 +- ...id-component-config-dependency-resolver.ts | 8 ++-- ...up-component-config-dependency-resolver.ts | 4 +- ...er-component-config-dependency-resolver.ts | 6 +-- ...ar-component-config-dependency-resolver.ts | 6 +-- ...on-component-config-dependency-resolver.ts | 6 +-- ...ge-component-config-dependency-resolver.ts | 6 +-- ...id-component-config-dependency-resolver.ts | 8 ++-- .../empty-config-dependency-resolver.ts | 4 +- ...entity-state-config-dependency-resolver.ts | 4 +- .../src/config-dependency-resolver/index.ts | 1 + .../config-dependency-resolver/providers.ts | 2 + .../standard-config-dependency-resolver.ts | 44 +++++++++++++++++++ ...tate-machine-config-dependency-resolver.ts | 4 +- .../static-config-dependency-resolver.ts | 6 +-- .../src/config-dependency-resolver/types.ts | 19 +++++++- .../ui-state-config-dependency-resolver.ts | 4 +- .../component-config-dependency-registry.ts | 8 ++-- packages/renderer/src/config/types.ts | 7 +-- .../renderer/src/form-engine/form-engine.ts | 10 ++--- 28 files changed, 165 insertions(+), 73 deletions(-) create mode 100644 packages/renderer/src/change-resolver/expression-result-change-resolver.ts create mode 100644 packages/renderer/src/config-dependency-resolver/standard-config-dependency-resolver.ts diff --git a/packages/devkit/lib/expression/expression-engine-proxy.ts b/packages/devkit/lib/expression/expression-engine-proxy.ts index de2fd1c17b2..1890f1fd880 100644 --- a/packages/devkit/lib/expression/expression-engine-proxy.ts +++ b/packages/devkit/lib/expression/expression-engine-proxy.ts @@ -22,7 +22,6 @@ export class ExpressionEngineProxy { if (!changes || changes.length < 1) { return; } - console.log(changes); changes.forEach((change: Change) => { this.changeHandlers.forEach((handler: ChangeHandler) => { handler.handle(change, expressions); diff --git a/packages/renderer/src/change-resolver/change-resolve-service.ts b/packages/renderer/src/change-resolver/change-resolve-service.ts index 8838651e8e2..f5f26974c84 100644 --- a/packages/renderer/src/change-resolver/change-resolve-service.ts +++ b/packages/renderer/src/change-resolver/change-resolve-service.ts @@ -1,13 +1,13 @@ import { Change } from "@farris/devkit-vue"; -import { Config } from "../config"; +import { Configuration } from "../config"; import { ChangeResolver } from "./change-resolver"; import { ChangeResolverRegistry } from "./change-resolver-registry"; export class ChangeResolveService { constructor(private changeResolverRegistry: ChangeResolverRegistry) { } - public resolve(change: Change): Map { - return this.changeResolverRegistry.registry.reduce((results: Map, resolver: ChangeResolver) => { + public resolve(change: Change): Map { + return this.changeResolverRegistry.registry.reduce((results: Map, resolver: ChangeResolver) => { const result = resolver.resolve(change); if (result && result.size > 0) { Array.from(result.keys()).forEach((componentId: string)=>{ diff --git a/packages/renderer/src/change-resolver/change-resolver.ts b/packages/renderer/src/change-resolver/change-resolver.ts index e39366bb141..8f7d8896983 100644 --- a/packages/renderer/src/change-resolver/change-resolver.ts +++ b/packages/renderer/src/change-resolver/change-resolver.ts @@ -1,6 +1,6 @@ -import { Change } from "../change-observer"; -import { Config } from "../config"; +import { Change } from "@farris/devkit-vue"; +import { Configuration } from "../config"; export abstract class ChangeResolver { - public abstract resolve(change: Change): Map | null; + public abstract resolve(change: Change | T): Map | null; } diff --git a/packages/renderer/src/change-resolver/entity-store-change-resolver.ts b/packages/renderer/src/change-resolver/entity-store-change-resolver.ts index 6091ee1653b..a919cf2691a 100644 --- a/packages/renderer/src/change-resolver/entity-store-change-resolver.ts +++ b/packages/renderer/src/change-resolver/entity-store-change-resolver.ts @@ -1,7 +1,7 @@ import { Entity, EntityState } from "@farris/devkit-vue"; import { ChangeResolver } from "./change-resolver"; import { Change, ChangeSource } from "@farris/devkit-vue"; -import { ComponentConfigDependencyRegistry, Config, ConfigDependency, DependencyType } from "../config"; +import { ComponentConfigDependencyRegistry, Configuration, ConfigDependency, DependencyKind } from "../config"; export class EntityStoreChangeResolver extends ChangeResolver> { @@ -9,16 +9,16 @@ export class EntityStoreChangeResolver extends ChangeResolver>): Map | null { + public resolve(change: Change>): Map | null { if (change.source !== ChangeSource.EntityState) { return null; } const registry = this.componentConfigDependencyRegistry.getComponents(); - const result: Map = new Map(); + const result: Map = new Map(); Array.from(registry.entries()).forEach(([id, configs]) => { - const matchedConfigs = configs.filter((config: Config) => { + const matchedConfigs = configs.filter((config: Configuration) => { const match = config.deps.find((dependency: ConfigDependency) => { - return dependency.type === DependencyType.EntityState; + return dependency.type === DependencyKind.EntityState; }); return !!match; }); diff --git a/packages/renderer/src/change-resolver/expression-result-change-resolver.ts b/packages/renderer/src/change-resolver/expression-result-change-resolver.ts new file mode 100644 index 00000000000..9cffdc8afa6 --- /dev/null +++ b/packages/renderer/src/change-resolver/expression-result-change-resolver.ts @@ -0,0 +1,28 @@ +import { Change, ChangeSource, ExpressionResultChange } from "@farris/devkit-vue"; +import { ChangeResolver } from "./change-resolver"; +import { ComponentConfigDependencyRegistry, Configuration, ConfigDependency, DependencyKind } from "../config"; + +export class ExpressionResultChangeResolver extends ChangeResolver { + constructor(private componentConfigDependencyRegistry: ComponentConfigDependencyRegistry) { + super(); + } + public resolve(change: Change): Map | null { + if (change.source !== ChangeSource.Expression) { + return null; + } + const registry = this.componentConfigDependencyRegistry.getComponents(); + const result: Map = new Map(); + Array.from(registry.entries()).forEach(([id, configs]) => { + const matchedConfigs = configs.filter((config: Configuration) => { + const match = config.deps.find((dependency: ConfigDependency) => { + return dependency.type === DependencyKind.ExpressionResult; + }); + return !!match;; + }); + if (matchedConfigs && matchedConfigs.length > 0) { + result.set(id, matchedConfigs); + } + }); + return result; + } +} diff --git a/packages/renderer/src/change-resolver/state-machine-change-resolver.ts b/packages/renderer/src/change-resolver/state-machine-change-resolver.ts index 3cad2d558a4..c444120f5a8 100644 --- a/packages/renderer/src/change-resolver/state-machine-change-resolver.ts +++ b/packages/renderer/src/change-resolver/state-machine-change-resolver.ts @@ -1,6 +1,6 @@ import { StateMachine, StateMachineState } from "@farris/devkit-vue"; import { Change, ChangeSource } from "@farris/devkit-vue"; -import { ComponentConfigDependencyRegistry, Config, ConfigDependency, DependencyType } from "../config"; +import { ComponentConfigDependencyRegistry, Configuration, ConfigDependency, DependencyKind } from "../config"; import { ChangeResolver } from "./change-resolver"; export class StateMachineChangeResolver extends ChangeResolver> { @@ -9,16 +9,16 @@ export class StateMachineChangeResolver extends ChangeResolver>): Map | null{ + public resolve(change: Change>): Map | null{ if (change.source !== ChangeSource.StateMachine) { return null; } const registry = this.componentConfigDependencyRegistry.getComponents(); - const result: Map = new Map(); + const result: Map = new Map(); Array.from(registry.entries()).forEach(([id, configs]) => { - const matchedConfigs = configs.filter((config: Config) => { + const matchedConfigs = configs.filter((config: Configuration) => { const match = config.deps.find((dependency: ConfigDependency) => { - return dependency.type === DependencyType.StateMachine; + return dependency.type === DependencyKind.StateMachine; }); return !!match; }); diff --git a/packages/renderer/src/change-resolver/ui-state-change-resolver.ts b/packages/renderer/src/change-resolver/ui-state-change-resolver.ts index e5ffe8de0d3..9353141c081 100644 --- a/packages/renderer/src/change-resolver/ui-state-change-resolver.ts +++ b/packages/renderer/src/change-resolver/ui-state-change-resolver.ts @@ -1,5 +1,5 @@ import { UIState } from "@farris/devkit-vue"; -import { ComponentConfigDependencyRegistry, Config, ConfigDependency, DependencyType } from "../config"; +import { ComponentConfigDependencyRegistry, Configuration, ConfigDependency, DependencyKind } from "../config"; import { ChangeResolver } from "./change-resolver"; import { Change, ChangeSource } from "@farris/devkit-vue"; @@ -9,16 +9,16 @@ export class UIStateChangeResolver extends ChangeResolver { super(); } - public resolve(change: Change): Map | null { + public resolve(change: Change): Map | null { if (change.source !== ChangeSource.UIState) { return null; } const registry = this.componentConfigDependencyRegistry.getComponents(); - const result: Map = new Map(); + const result: Map = new Map(); Array.from(registry.entries()).forEach(([id, configs]) => { - const matchedConfigs = configs.filter((config: Config) => { + const matchedConfigs = configs.filter((config: Configuration) => { const match = config.deps.find((dependency: ConfigDependency) => { - return dependency.type === DependencyType.UIState; + return dependency.type === DependencyKind.UIState; }); return !!match;; }); diff --git a/packages/renderer/src/component-config-dependency-resolver/component-config-dependency-resolve-service.ts b/packages/renderer/src/component-config-dependency-resolver/component-config-dependency-resolve-service.ts index 846e735a856..90ece801907 100644 --- a/packages/renderer/src/component-config-dependency-resolver/component-config-dependency-resolve-service.ts +++ b/packages/renderer/src/component-config-dependency-resolver/component-config-dependency-resolve-service.ts @@ -1,12 +1,12 @@ - import { Config } from "../config"; + import { Configuration } from "../config"; import { ComponentConfigDependencyResolver } from "./component-config-dependency-resolver"; import { ComponentConfigDependencyResolverRegistry } from "./component-config-dependency-resolver-registry"; export class ComponentConfigDependencyResolveService { constructor(private componentConfigDependencyResolveRegistry: ComponentConfigDependencyResolverRegistry) { } - public resolve(schema: Record): Config[] { - return this.componentConfigDependencyResolveRegistry.resolvers.reduce((dependencies: Config[], resolver: ComponentConfigDependencyResolver) => { + public resolve(schema: Record): Configuration[] { + return this.componentConfigDependencyResolveRegistry.resolvers.reduce((dependencies: Configuration[], resolver: ComponentConfigDependencyResolver) => { const configs = resolver.resolve(schema); if (configs) { dependencies.push(...configs); diff --git a/packages/renderer/src/component-config-dependency-resolver/component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/component-config-dependency-resolver.ts index 27bbeeb7080..5b00ad35b6b 100644 --- a/packages/renderer/src/component-config-dependency-resolver/component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/component-config-dependency-resolver.ts @@ -1,5 +1,5 @@ -import { Config } from "../config"; +import { Configuration } from "../config"; export abstract class ComponentConfigDependencyResolver { - public abstract resolve(schema: Record): Config[] | null; + public abstract resolve(schema: Record): Configuration[] | null; } diff --git a/packages/renderer/src/component-config-dependency-resolver/data-grid-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/data-grid-component-config-dependency-resolver.ts index 7ae74d01d8f..08662404c36 100644 --- a/packages/renderer/src/component-config-dependency-resolver/data-grid-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/data-grid-component-config-dependency-resolver.ts @@ -1,4 +1,4 @@ -import { Config } from "../config"; +import { Configuration } from "../config"; import { ConfigDependencyResolveService } from "../config-dependency-resolver"; import { ComponentConfigDependencyResolver } from "./component-config-dependency-resolver"; @@ -8,12 +8,12 @@ export class DataGridComponentConfigDependencyResolver extends ComponentConfigDe super(); } - public resolve(schema: Record): Config[] | null { + public resolve(schema: Record): Configuration[] | null { if (!schema || schema.type !== 'data-grid') { return null; } const { id, columns: fields, editable, disabled, pagination } = schema; - const configs: Config[] = []; + const configs: Configuration[] = []; const editableConfigDeps = this.configDepencencyResolveService.resolve(editable); if (editableConfigDeps) { configs.push({ deps: editableConfigDeps, config: editable, path: '/editable' }); @@ -33,7 +33,7 @@ export class DataGridComponentConfigDependencyResolver extends ComponentConfigDe if (!id || !fields || !Array.isArray(fields) || fields.length < 1) { return configs && configs.length > 0 ? configs : null; } - return fields.reduce((configs: Config[], field: Record) => { + return fields.reduce((configs: Configuration[], field: Record) => { const { visible, editor, id } = field; const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); if (visibleConfigDeps) { diff --git a/packages/renderer/src/component-config-dependency-resolver/form-group-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/form-group-component-config-dependency-resolver.ts index ad786a97c3a..35e74cc5abd 100644 --- a/packages/renderer/src/component-config-dependency-resolver/form-group-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/form-group-component-config-dependency-resolver.ts @@ -1,4 +1,4 @@ -import { Config } from "../config"; +import { Configuration } from "../config"; import { ConfigDependencyResolveService } from "../config-dependency-resolver"; import { ComponentConfigDependencyResolver } from "./component-config-dependency-resolver"; @@ -8,7 +8,7 @@ export class FormGroupComponentConfigDependencyResolver extends ComponentConfigD super(); } - public resolve(schema: Record): Config[] | null { + public resolve(schema: Record): Configuration[] | null { if (!schema || schema.type !== 'form-group') { return null; } diff --git a/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts index bb39af9d3da..e1f330dd264 100644 --- a/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts @@ -1,4 +1,4 @@ - import { Config } from "../config"; + import { Configuration } from "../config"; import { ConfigDependencyResolveService } from "../config-dependency-resolver"; import { ComponentConfigDependencyResolver } from "./component-config-dependency-resolver"; @@ -8,7 +8,7 @@ export class PageHeaderComponentConfigDependencyResolver extends ComponentConfig super(); } - public resolve(schema: Record): Config[] | null { + public resolve(schema: Record): Configuration[] | null { if (!schema || schema.type !== 'page-header') { return null; } @@ -20,7 +20,7 @@ export class PageHeaderComponentConfigDependencyResolver extends ComponentConfig if (!buttons || !Array.isArray(buttons) || buttons.length < 1) { return null; } - const configs: Config[] = []; + const configs: Configuration[] = []; buttons.forEach((button: Record) => { const { disabled, visible } = button; const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); diff --git a/packages/renderer/src/component-config-dependency-resolver/response-toolbar-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/response-toolbar-component-config-dependency-resolver.ts index 28085db3955..24877643ecd 100644 --- a/packages/renderer/src/component-config-dependency-resolver/response-toolbar-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/response-toolbar-component-config-dependency-resolver.ts @@ -1,4 +1,4 @@ - import { Config } from "../config"; + import { Configuration } from "../config"; import { ConfigDependencyResolveService } from "../config-dependency-resolver"; import { ComponentConfigDependencyResolver } from "./component-config-dependency-resolver"; @@ -8,7 +8,7 @@ export class ResponseToolbarComponentConfigDependencyResolver extends ComponentC super(); } - public resolve(schema: Record): Config[] | null { + public resolve(schema: Record): Configuration[] | null { if (!schema || schema.type !== 'response-toolbar') { return null; } @@ -19,7 +19,7 @@ export class ResponseToolbarComponentConfigDependencyResolver extends ComponentC if (!buttons || !Array.isArray(buttons) || buttons.length < 1) { return null; } - const configs: Config[] = []; + const configs: Configuration[] = []; buttons.forEach((button: Record) => { const { disabled, visible } = button; const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); diff --git a/packages/renderer/src/component-config-dependency-resolver/section-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/section-component-config-dependency-resolver.ts index 5c9aabe711e..997b2f32a1d 100644 --- a/packages/renderer/src/component-config-dependency-resolver/section-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/section-component-config-dependency-resolver.ts @@ -1,4 +1,4 @@ -import { Config } from "../config"; +import { Configuration } from "../config"; import { ConfigDependencyResolveService } from "../config-dependency-resolver"; import { ComponentConfigDependencyResolver } from "./component-config-dependency-resolver"; @@ -7,7 +7,7 @@ export class SectionComponentConfigDependencyResolver extends ComponentConfigDep super(); } - public resolve(schema: Record): Config[] | null { + public resolve(schema: Record): Configuration[] | null { if (!schema || schema.type !== 'section') { return null; } @@ -19,7 +19,7 @@ export class SectionComponentConfigDependencyResolver extends ComponentConfigDep if (!buttons || !Array.isArray(buttons) || buttons.length < 1) { return null; } - const configs: Config[] = []; + const configs: Configuration[] = []; buttons.forEach((button: Record) => { const { disabled, visible } = button; const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); diff --git a/packages/renderer/src/component-config-dependency-resolver/tab-page-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/tab-page-component-config-dependency-resolver.ts index a3e36aca7e0..f66be110a8d 100644 --- a/packages/renderer/src/component-config-dependency-resolver/tab-page-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/tab-page-component-config-dependency-resolver.ts @@ -1,4 +1,4 @@ -import { Config } from "../config"; +import { Configuration } from "../config"; import { ConfigDependencyResolveService } from "../config-dependency-resolver"; import { ComponentConfigDependencyResolver } from "./component-config-dependency-resolver"; @@ -7,7 +7,7 @@ export class TabPageComponentConfigDependencyResolver extends ComponentConfigDep super(); } - public resolve(schema: Record): Config[] | null { + public resolve(schema: Record): Configuration[] | null { if (!schema || schema.type !== 'tab-page') { return null; } @@ -19,7 +19,7 @@ export class TabPageComponentConfigDependencyResolver extends ComponentConfigDep if (!buttons || !Array.isArray(buttons) || buttons.length < 1) { return null; } - const configs: Config[] = []; + const configs: Configuration[] = []; buttons.forEach((button: Record) => { const { disabled, visible } = button; const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); diff --git a/packages/renderer/src/component-config-dependency-resolver/tree-grid-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/tree-grid-component-config-dependency-resolver.ts index 6157aa7566a..b9ddf9c0d65 100644 --- a/packages/renderer/src/component-config-dependency-resolver/tree-grid-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/tree-grid-component-config-dependency-resolver.ts @@ -1,4 +1,4 @@ -import { Config } from "../config"; +import { Configuration } from "../config"; import { ConfigDependencyResolveService } from "../config-dependency-resolver"; import { ComponentConfigDependencyResolver } from "./component-config-dependency-resolver"; @@ -8,12 +8,12 @@ export class TreeGridComponentConfigDependencyResolver extends ComponentConfigDe super(); } - public resolve(schema: Record): Config[] | null { + public resolve(schema: Record): Configuration[] | null { if (!schema || schema.type !== 'tree-grid') { return null; } const { id, columns: fields, editable, disabled } = schema; - const configs: Config[] = []; + const configs: Configuration[] = []; const editableConfigDeps = this.configDepencencyResolveService.resolve(editable); if (editableConfigDeps) { configs.push({ deps: editableConfigDeps, config: editable, path: '/editable' }); @@ -25,7 +25,7 @@ export class TreeGridComponentConfigDependencyResolver extends ComponentConfigDe if (!id || !fields || !Array.isArray(fields) || fields.length < 1) { return configs && configs.length > 0 ? configs : null; } - return fields.reduce((configs: Config[], field: Record) => { + return fields.reduce((configs: Configuration[], field: Record) => { const { visible, editor } = field; const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); if (visibleConfigDeps) { diff --git a/packages/renderer/src/config-dependency-resolver/empty-config-dependency-resolver.ts b/packages/renderer/src/config-dependency-resolver/empty-config-dependency-resolver.ts index c7ea4a8ed2d..e2ae4af4acb 100644 --- a/packages/renderer/src/config-dependency-resolver/empty-config-dependency-resolver.ts +++ b/packages/renderer/src/config-dependency-resolver/empty-config-dependency-resolver.ts @@ -1,10 +1,10 @@ -import { ConfigDependency, DependencyType } from '../config'; +import { ConfigDependency, DependencyKind } from '../config'; import { ConfigDependencyResolver } from './types'; export class EmptyConfigDependencyResolver implements ConfigDependencyResolver { resolve(config: string): ConfigDependency[] | null { if (config === '' || config === null || config === undefined) { - return [{ type: DependencyType.Empty }]; + return [{ type: DependencyKind.Empty }]; } return null; } diff --git a/packages/renderer/src/config-dependency-resolver/entity-state-config-dependency-resolver.ts b/packages/renderer/src/config-dependency-resolver/entity-state-config-dependency-resolver.ts index e7a6491ee32..562d01f9af4 100644 --- a/packages/renderer/src/config-dependency-resolver/entity-state-config-dependency-resolver.ts +++ b/packages/renderer/src/config-dependency-resolver/entity-state-config-dependency-resolver.ts @@ -1,4 +1,4 @@ -import { ConfigDependency, DependencyType } from "../config"; +import { ConfigDependency, DependencyKind } from "../config"; import { ConfigDependencyResolver } from "./types"; export class EntityStateConfigDependencyResolver implements ConfigDependencyResolver { @@ -22,7 +22,7 @@ export class EntityStateConfigDependencyResolver implements ConfigDependencyReso return null; } return results.map((path: string) => { - return { path, type: DependencyType.EntityState }; + return { path, type: DependencyKind.EntityState }; }); } } diff --git a/packages/renderer/src/config-dependency-resolver/index.ts b/packages/renderer/src/config-dependency-resolver/index.ts index df31dc5667a..fd6aec812bd 100644 --- a/packages/renderer/src/config-dependency-resolver/index.ts +++ b/packages/renderer/src/config-dependency-resolver/index.ts @@ -4,6 +4,7 @@ export * from './static-config-dependency-resolver'; export * from './ui-state-config-dependency-resolver'; export * from './empty-config-dependency-resolver'; export * from './entity-state-config-dependency-resolver'; +export * from './standard-config-dependency-resolver'; export * from './config-dependency-resolve-service'; export * from './config-dependency-resolver-registry'; export * from './providers'; diff --git a/packages/renderer/src/config-dependency-resolver/providers.ts b/packages/renderer/src/config-dependency-resolver/providers.ts index abdd525d7e2..293c5444065 100644 --- a/packages/renderer/src/config-dependency-resolver/providers.ts +++ b/packages/renderer/src/config-dependency-resolver/providers.ts @@ -7,6 +7,7 @@ import { StaticConfigDependencyResolver } from "./static-config-dependency-resol import { EmptyConfigDependencyResolver } from "./empty-config-dependency-resolver"; import { EntityStateConfigDependencyResolver } from "./entity-state-config-dependency-resolver"; import { ConfigDependencyResolverRegistry } from "./config-dependency-resolver-registry"; +import { StandardConfigDependencyResolver } from "./standard-config-dependency-resolver"; export const configDependencyResolverProviders: StaticProvider[] = [ { provide: CONFIG_DEPENDENCY_RESOLVER_TOKEN, useClass: StateMachineConfigDependencyResolver, deps: [], multi: true }, @@ -14,6 +15,7 @@ export const configDependencyResolverProviders: StaticProvider[] = [ { provide: CONFIG_DEPENDENCY_RESOLVER_TOKEN, useClass: StaticConfigDependencyResolver, deps: [], multi: true }, { provide: CONFIG_DEPENDENCY_RESOLVER_TOKEN, useClass: EmptyConfigDependencyResolver, deps: [], multi: true }, { provide: CONFIG_DEPENDENCY_RESOLVER_TOKEN, useClass: EntityStateConfigDependencyResolver, deps: [], multi: true }, + { provide: CONFIG_DEPENDENCY_RESOLVER_TOKEN, useClass: StandardConfigDependencyResolver, deps: [], multi: true}, { provide: ConfigDependencyResolverRegistry, useClass: ConfigDependencyResolverRegistry, deps: [Injector] }, { provide: ConfigDependencyResolveService, useClass: ConfigDependencyResolveService, deps: [ConfigDependencyResolverRegistry] } ]; diff --git a/packages/renderer/src/config-dependency-resolver/standard-config-dependency-resolver.ts b/packages/renderer/src/config-dependency-resolver/standard-config-dependency-resolver.ts new file mode 100644 index 00000000000..cb0152528ce --- /dev/null +++ b/packages/renderer/src/config-dependency-resolver/standard-config-dependency-resolver.ts @@ -0,0 +1,44 @@ +import { ConfigDependency, DependencyKind } from "../config/types"; +import { ConfigDependencyResolver, ExpressionConfig, StandardPropertyConfig, VariableConfig } from "./types"; + +export class StandardConfigDependencyResolver implements ConfigDependencyResolver { + resolve(config: string | boolean | StandardPropertyConfig): ConfigDependency[] | null { + // 处理基本类型 + if (typeof config === 'string' || typeof config === 'boolean') { + return null; + } + + // 验证是否为有效的配置对象 + if (!this.isValidConfig(config)) { + return null; + } + + // 根据配置类型分发到对应的处理方法 + switch (config.type) { + case 'Expression': + return this.resolveExpressionConfig(config as ExpressionConfig); + case 'Variable': + return this.resolveVariableConfig(config as VariableConfig); + default: + return null; + } + } + + private isValidConfig(config: any): config is StandardPropertyConfig { + return config && typeof config === 'object' && 'type' in config; + } + + private resolveExpressionConfig(config: ExpressionConfig): ConfigDependency[] { + return [{ + type: DependencyKind.ExpressionResult, + path: config.expressionId + }]; + } + + private resolveVariableConfig(config: VariableConfig): ConfigDependency[] { + return [{ + type: DependencyKind.UIState, + path: config.path + }]; + } +} diff --git a/packages/renderer/src/config-dependency-resolver/state-machine-config-dependency-resolver.ts b/packages/renderer/src/config-dependency-resolver/state-machine-config-dependency-resolver.ts index 8d841fd3937..8ee6b6adc02 100644 --- a/packages/renderer/src/config-dependency-resolver/state-machine-config-dependency-resolver.ts +++ b/packages/renderer/src/config-dependency-resolver/state-machine-config-dependency-resolver.ts @@ -1,4 +1,4 @@ -import { ConfigDependency, DependencyType } from "../config"; +import { ConfigDependency, DependencyKind } from "../config"; import { ConfigDependencyResolver } from "./types"; @@ -21,7 +21,7 @@ export class StateMachineConfigDependencyResolver implements ConfigDependencyRes return null; } return results.map((path: string) => { - return { type: DependencyType.StateMachine, path }; + return { type: DependencyKind.StateMachine, path }; }); } } diff --git a/packages/renderer/src/config-dependency-resolver/static-config-dependency-resolver.ts b/packages/renderer/src/config-dependency-resolver/static-config-dependency-resolver.ts index 400d2169db0..b522a7fc708 100644 --- a/packages/renderer/src/config-dependency-resolver/static-config-dependency-resolver.ts +++ b/packages/renderer/src/config-dependency-resolver/static-config-dependency-resolver.ts @@ -1,13 +1,13 @@ -import { ConfigDependency, DependencyType } from "../config/types"; +import { ConfigDependency, DependencyKind } from "../config/types"; import { ConfigDependencyResolver } from "./types"; export class StaticConfigDependencyResolver implements ConfigDependencyResolver { public resolve(config: string): ConfigDependency[] | null { if (typeof config === 'boolean') { - return [{ type: DependencyType.Static }]; + return [{ type: DependencyKind.Static }]; } if (typeof config === 'string' && config.match(/true|false/g)) { - return [{ type: DependencyType.Static }]; + return [{ type: DependencyKind.Static }]; } return null; } diff --git a/packages/renderer/src/config-dependency-resolver/types.ts b/packages/renderer/src/config-dependency-resolver/types.ts index 3d6d707d3cb..b6025967495 100644 --- a/packages/renderer/src/config-dependency-resolver/types.ts +++ b/packages/renderer/src/config-dependency-resolver/types.ts @@ -1,5 +1,22 @@ import { ConfigDependency } from "../config"; +export enum ConfigType { + Expression = 'Expression', + Variable = 'Variable', +} +export interface StandardPropertyConfig { + type: ConfigType; +} +export interface ExpressionConfig extends StandardPropertyConfig { + type: ConfigType.Expression; + expressionId: string; +} +export interface VariableConfig extends StandardPropertyConfig { + type: ConfigType.Variable; + path: string; + fullPath: string; + field: string; +} export interface ConfigDependencyResolver { - resolve(config: string | boolean): ConfigDependency[] | null; + resolve(config: string | boolean | StandardPropertyConfig): ConfigDependency[] | null; } diff --git a/packages/renderer/src/config-dependency-resolver/ui-state-config-dependency-resolver.ts b/packages/renderer/src/config-dependency-resolver/ui-state-config-dependency-resolver.ts index 4a4e6e2e858..a2b70437724 100644 --- a/packages/renderer/src/config-dependency-resolver/ui-state-config-dependency-resolver.ts +++ b/packages/renderer/src/config-dependency-resolver/ui-state-config-dependency-resolver.ts @@ -1,4 +1,4 @@ -import { ConfigDependency, DependencyType } from "../config"; +import { ConfigDependency, DependencyKind } from "../config"; import { ConfigDependencyResolver } from "./types"; export class UIStateConfigDependencyResolver implements ConfigDependencyResolver { @@ -19,7 +19,7 @@ export class UIStateConfigDependencyResolver implements ConfigDependencyResolver return null; } return results.map((path: string) => { - return { path, type: DependencyType.UIState }; + return { path, type: DependencyKind.UIState }; }); } } diff --git a/packages/renderer/src/config/component-config-dependency-registry.ts b/packages/renderer/src/config/component-config-dependency-registry.ts index 9cd7edd626a..ee8c7a8c3a2 100644 --- a/packages/renderer/src/config/component-config-dependency-registry.ts +++ b/packages/renderer/src/config/component-config-dependency-registry.ts @@ -1,13 +1,13 @@ -import { Config } from "./types"; +import { Configuration } from "./types"; export class ComponentConfigDependencyRegistry { - private registry: Map; + private registry: Map; constructor() { - this.registry = new Map(); + this.registry = new Map(); } - public setConfigs(componentId: string, configs: Config[]) { + public setConfigs(componentId: string, configs: Configuration[]) { this.registry.set(componentId, configs); } diff --git a/packages/renderer/src/config/types.ts b/packages/renderer/src/config/types.ts index 2231120e8d2..cb4a4927ee7 100644 --- a/packages/renderer/src/config/types.ts +++ b/packages/renderer/src/config/types.ts @@ -1,16 +1,17 @@ -export enum DependencyType { +export enum DependencyKind { StateMachine = 'StateMachine', EntityState = 'EntityState', UIState = 'UIState', + ExpressionResult = 'ExpressionResult', Static = 'Static', Empty = 'Empty' } export interface ConfigDependency { - type: DependencyType; + type: DependencyKind; path?: string; } -export interface Config { +export interface Configuration { config: string | boolean; deps: ConfigDependency[]; path: string; diff --git a/packages/renderer/src/form-engine/form-engine.ts b/packages/renderer/src/form-engine/form-engine.ts index ee62708695b..c20cda8a943 100644 --- a/packages/renderer/src/form-engine/form-engine.ts +++ b/packages/renderer/src/form-engine/form-engine.ts @@ -4,7 +4,7 @@ import { ChangeResolveService } from "../change-resolver"; import { ComponentConfigResolveService } from "../component-config-resolver"; import { RenderEngineImpl } from "../render-engine"; import { FormMetadataService } from "../service"; -import { Config } from "../config"; +import { Configuration } from "../config"; export class FormEngine { constructor( @@ -17,9 +17,9 @@ export class FormEngine { this.changeObserverRegistry.observers.forEach((observer: ChangeObserver) => { observer.observe((change: Change) => { console.log(change); - const results: Map = this.changeResolveService.resolve(change); + const results: Map = this.changeResolveService.resolve(change); if (results && results.size > 0) { - results.forEach((configs: Config[], componentId: string) => { + results.forEach((configs: Configuration[], componentId: string) => { const metadata = this.formMetadataService.getMetadataById(componentId); if (!metadata) { return; @@ -28,7 +28,7 @@ export class FormEngine { const resolvedSchema = this.componentConfigResolveService.resolve(schema); // 过滤schema属性,仅解析发生变化的属性 const changedSchema = {}; - configs.forEach((config: Config) => { + configs.forEach((config: Configuration) => { const filteredSchema = this.filterSchema(resolvedSchema, config); mergeWith(changedSchema, filteredSchema, this.mergeArray); }); @@ -47,7 +47,7 @@ export class FormEngine { } }); } - filterSchema(schema: any, config: Config): Record { + filterSchema(schema: any, config: Configuration): Record { const filteredSchema: Record = {}; // configs.forEach((config: Config) => { -- Gitee From 9d1421cdfd60a8a973c1c0d8c45430e70e182934 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Thu, 20 Mar 2025 19:06:45 +0800 Subject: [PATCH 076/153] =?UTF-8?q?chore:=20=E5=88=A0=E9=99=A4=E5=86=97?= =?UTF-8?q?=E4=BD=99=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config-dependency-resolver-factory.ts | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 packages/renderer/src/config-dependency-resolver/config-dependency-resolver-factory.ts diff --git a/packages/renderer/src/config-dependency-resolver/config-dependency-resolver-factory.ts b/packages/renderer/src/config-dependency-resolver/config-dependency-resolver-factory.ts deleted file mode 100644 index 33ba3935a96..00000000000 --- a/packages/renderer/src/config-dependency-resolver/config-dependency-resolver-factory.ts +++ /dev/null @@ -1,16 +0,0 @@ - -import { ConfigDependency } from "../config/types"; -import { ConfigDependencyResolverRegistry } from "./config-dependency-resolver-registry"; -import { ConfigDependencyResolver } from "./types"; - -export class ConfigDependencyResolverFactory { - public static resolve(config: string) { - return ConfigDependencyResolverRegistry.reduce((dependencies: ConfigDependency[], resolver: ConfigDependencyResolver) => { - const rules = resolver.resolve(config); - if (rules) { - dependencies.push(...rules); - } - return dependencies; - }, []); - } -} -- Gitee From 304ee4cfa88d37bc88b18d8fc7ff91ab0cb4c60f Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Thu, 20 Mar 2025 19:46:28 +0800 Subject: [PATCH 077/153] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9change-resol?= =?UTF-8?q?ver=E4=B8=BAchange-effect-resolver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../change-effect-resolve-service.ts} | 8 ++++---- .../change-effect-resolver-registry.ts} | 8 ++++---- .../change-effect-resolver.ts} | 2 +- .../entity-store-change-effect-resolver.ts} | 4 ++-- ...pression-result-change-effect-resolver.ts} | 4 ++-- .../src/change-effect-resolver/index.ts | 7 +++++++ .../providers.ts | 20 +++++++++---------- .../state-machine-change-effect-resolver.ts} | 4 ++-- .../ui-state-change-effect-resolver.ts} | 6 +++--- .../renderer/src/change-resolver/index.ts | 7 ------- .../src/composition/use-module-config.ts | 2 +- .../renderer/src/form-engine/form-engine.ts | 2 +- .../renderer/src/form-engine/providers.ts | 2 +- packages/renderer/src/tokens.ts | 4 ++-- 14 files changed, 40 insertions(+), 40 deletions(-) rename packages/renderer/src/{change-resolver/change-resolve-service.ts => change-effect-resolver/change-effect-resolve-service.ts} (72%) rename packages/renderer/src/{change-resolver/change-resolver-registry.ts => change-effect-resolver/change-effect-resolver-registry.ts} (37%) rename packages/renderer/src/{change-resolver/change-resolver.ts => change-effect-resolver/change-effect-resolver.ts} (78%) rename packages/renderer/src/{change-resolver/entity-store-change-resolver.ts => change-effect-resolver/entity-store-change-effect-resolver.ts} (88%) rename packages/renderer/src/{change-resolver/expression-result-change-resolver.ts => change-effect-resolver/expression-result-change-effect-resolver.ts} (87%) create mode 100644 packages/renderer/src/change-effect-resolver/index.ts rename packages/renderer/src/{change-resolver => change-effect-resolver}/providers.ts (33%) rename packages/renderer/src/{change-resolver/state-machine-change-resolver.ts => change-effect-resolver/state-machine-change-effect-resolver.ts} (87%) rename packages/renderer/src/{change-resolver/ui-state-change-resolver.ts => change-effect-resolver/ui-state-change-effect-resolver.ts} (84%) delete mode 100644 packages/renderer/src/change-resolver/index.ts diff --git a/packages/renderer/src/change-resolver/change-resolve-service.ts b/packages/renderer/src/change-effect-resolver/change-effect-resolve-service.ts similarity index 72% rename from packages/renderer/src/change-resolver/change-resolve-service.ts rename to packages/renderer/src/change-effect-resolver/change-effect-resolve-service.ts index f5f26974c84..e36cfa7a25d 100644 --- a/packages/renderer/src/change-resolver/change-resolve-service.ts +++ b/packages/renderer/src/change-effect-resolver/change-effect-resolve-service.ts @@ -1,13 +1,13 @@ import { Change } from "@farris/devkit-vue"; import { Configuration } from "../config"; -import { ChangeResolver } from "./change-resolver"; -import { ChangeResolverRegistry } from "./change-resolver-registry"; +import { ChangeEffectResolver } from "./change-effect-resolver"; +import { ChangeEffectResolverRegistry } from "./change-effect-resolver-registry"; export class ChangeResolveService { - constructor(private changeResolverRegistry: ChangeResolverRegistry) { } + constructor(private changeResolverRegistry: ChangeEffectResolverRegistry) { } public resolve(change: Change): Map { - return this.changeResolverRegistry.registry.reduce((results: Map, resolver: ChangeResolver) => { + return this.changeResolverRegistry.registry.reduce((results: Map, resolver: ChangeEffectResolver) => { const result = resolver.resolve(change); if (result && result.size > 0) { Array.from(result.keys()).forEach((componentId: string)=>{ diff --git a/packages/renderer/src/change-resolver/change-resolver-registry.ts b/packages/renderer/src/change-effect-resolver/change-effect-resolver-registry.ts similarity index 37% rename from packages/renderer/src/change-resolver/change-resolver-registry.ts rename to packages/renderer/src/change-effect-resolver/change-effect-resolver-registry.ts index 9aee3bf9e41..4dda1dd6537 100644 --- a/packages/renderer/src/change-resolver/change-resolver-registry.ts +++ b/packages/renderer/src/change-effect-resolver/change-effect-resolver-registry.ts @@ -1,11 +1,11 @@ import { Injector } from "@farris/devkit-vue"; -import { ChangeResolver } from "./change-resolver"; +import { ChangeEffectResolver } from "./change-effect-resolver"; import { CHANGE_RESOLVER_TOKEN } from "../tokens"; -export class ChangeResolverRegistry { - public registry: ChangeResolver[]; +export class ChangeEffectResolverRegistry { + public registry: ChangeEffectResolver[]; constructor(private injector: Injector) { - this.registry = this.injector.get[]>(CHANGE_RESOLVER_TOKEN); + this.registry = this.injector.get[]>(CHANGE_RESOLVER_TOKEN); } } diff --git a/packages/renderer/src/change-resolver/change-resolver.ts b/packages/renderer/src/change-effect-resolver/change-effect-resolver.ts similarity index 78% rename from packages/renderer/src/change-resolver/change-resolver.ts rename to packages/renderer/src/change-effect-resolver/change-effect-resolver.ts index 8f7d8896983..7637fed1b7e 100644 --- a/packages/renderer/src/change-resolver/change-resolver.ts +++ b/packages/renderer/src/change-effect-resolver/change-effect-resolver.ts @@ -1,6 +1,6 @@ import { Change } from "@farris/devkit-vue"; import { Configuration } from "../config"; -export abstract class ChangeResolver { +export abstract class ChangeEffectResolver { public abstract resolve(change: Change | T): Map | null; } diff --git a/packages/renderer/src/change-resolver/entity-store-change-resolver.ts b/packages/renderer/src/change-effect-resolver/entity-store-change-effect-resolver.ts similarity index 88% rename from packages/renderer/src/change-resolver/entity-store-change-resolver.ts rename to packages/renderer/src/change-effect-resolver/entity-store-change-effect-resolver.ts index a919cf2691a..2117d01ab01 100644 --- a/packages/renderer/src/change-resolver/entity-store-change-resolver.ts +++ b/packages/renderer/src/change-effect-resolver/entity-store-change-effect-resolver.ts @@ -1,9 +1,9 @@ import { Entity, EntityState } from "@farris/devkit-vue"; -import { ChangeResolver } from "./change-resolver"; +import { ChangeEffectResolver } from "./change-effect-resolver"; import { Change, ChangeSource } from "@farris/devkit-vue"; import { ComponentConfigDependencyRegistry, Configuration, ConfigDependency, DependencyKind } from "../config"; -export class EntityStoreChangeResolver extends ChangeResolver> { +export class EntityStoreChangeEffectResolver extends ChangeEffectResolver> { constructor(private componentConfigDependencyRegistry: ComponentConfigDependencyRegistry) { super(); diff --git a/packages/renderer/src/change-resolver/expression-result-change-resolver.ts b/packages/renderer/src/change-effect-resolver/expression-result-change-effect-resolver.ts similarity index 87% rename from packages/renderer/src/change-resolver/expression-result-change-resolver.ts rename to packages/renderer/src/change-effect-resolver/expression-result-change-effect-resolver.ts index 9cffdc8afa6..9600e702737 100644 --- a/packages/renderer/src/change-resolver/expression-result-change-resolver.ts +++ b/packages/renderer/src/change-effect-resolver/expression-result-change-effect-resolver.ts @@ -1,8 +1,8 @@ import { Change, ChangeSource, ExpressionResultChange } from "@farris/devkit-vue"; -import { ChangeResolver } from "./change-resolver"; +import { ChangeEffectResolver } from "./change-effect-resolver"; import { ComponentConfigDependencyRegistry, Configuration, ConfigDependency, DependencyKind } from "../config"; -export class ExpressionResultChangeResolver extends ChangeResolver { +export class ExpressionResultChangeEffectResolver extends ChangeEffectResolver { constructor(private componentConfigDependencyRegistry: ComponentConfigDependencyRegistry) { super(); } diff --git a/packages/renderer/src/change-effect-resolver/index.ts b/packages/renderer/src/change-effect-resolver/index.ts new file mode 100644 index 00000000000..b5bbe6b9b4a --- /dev/null +++ b/packages/renderer/src/change-effect-resolver/index.ts @@ -0,0 +1,7 @@ +export * from './change-effect-resolver'; +export * from './state-machine-change-effect-resolver'; +export * from './entity-store-change-effect-resolver'; +export * from './ui-state-change-effect-resolver'; +export * from './change-effect-resolver-registry'; +export * from './change-effect-resolve-service'; +export * from './providers'; diff --git a/packages/renderer/src/change-resolver/providers.ts b/packages/renderer/src/change-effect-resolver/providers.ts similarity index 33% rename from packages/renderer/src/change-resolver/providers.ts rename to packages/renderer/src/change-effect-resolver/providers.ts index d5e0a4d5d62..e2d90f838f9 100644 --- a/packages/renderer/src/change-resolver/providers.ts +++ b/packages/renderer/src/change-effect-resolver/providers.ts @@ -1,16 +1,16 @@ import { Injector, StaticProvider } from "@farris/devkit-vue"; -import { StateMachineChangeResolver } from "./state-machine-change-resolver"; +import { StateMachineChangeEffectResolver } from "./state-machine-change-effect-resolver"; import { CHANGE_RESOLVER_TOKEN } from "../tokens"; import { ComponentConfigDependencyRegistry } from "../config"; -import { ChangeResolverRegistry } from "./change-resolver-registry"; -import { ChangeResolveService } from "./change-resolve-service"; -import { EntityStoreChangeResolver } from "./entity-store-change-resolver"; -import { UIStateChangeResolver } from "./ui-state-change-resolver"; +import { ChangeEffectResolverRegistry } from "./change-effect-resolver-registry"; +import { ChangeResolveService } from "./change-effect-resolve-service"; +import { EntityStoreChangeEffectResolver } from "./entity-store-change-effect-resolver"; +import { UIStateChangeEffectResolver } from "./ui-state-change-effect-resolver"; export const changeResolverProviders: StaticProvider[] = [ - { provide: CHANGE_RESOLVER_TOKEN, useClass: StateMachineChangeResolver, deps: [ComponentConfigDependencyRegistry], multi: true }, - { provide: CHANGE_RESOLVER_TOKEN, useClass: EntityStoreChangeResolver, deps: [ComponentConfigDependencyRegistry], multi: true }, - { provide: CHANGE_RESOLVER_TOKEN, useClass: UIStateChangeResolver, deps: [ComponentConfigDependencyRegistry], multi: true }, - { provide: ChangeResolverRegistry, useClass: ChangeResolverRegistry, deps: [Injector] }, - { provide: ChangeResolveService, useClass: ChangeResolveService, deps: [ChangeResolverRegistry] } + { provide: CHANGE_RESOLVER_TOKEN, useClass: StateMachineChangeEffectResolver, deps: [ComponentConfigDependencyRegistry], multi: true }, + { provide: CHANGE_RESOLVER_TOKEN, useClass: EntityStoreChangeEffectResolver, deps: [ComponentConfigDependencyRegistry], multi: true }, + { provide: CHANGE_RESOLVER_TOKEN, useClass: UIStateChangeEffectResolver, deps: [ComponentConfigDependencyRegistry], multi: true }, + { provide: ChangeEffectResolverRegistry, useClass: ChangeEffectResolverRegistry, deps: [Injector] }, + { provide: ChangeResolveService, useClass: ChangeResolveService, deps: [ChangeEffectResolverRegistry] } ]; diff --git a/packages/renderer/src/change-resolver/state-machine-change-resolver.ts b/packages/renderer/src/change-effect-resolver/state-machine-change-effect-resolver.ts similarity index 87% rename from packages/renderer/src/change-resolver/state-machine-change-resolver.ts rename to packages/renderer/src/change-effect-resolver/state-machine-change-effect-resolver.ts index c444120f5a8..beb3e748099 100644 --- a/packages/renderer/src/change-resolver/state-machine-change-resolver.ts +++ b/packages/renderer/src/change-effect-resolver/state-machine-change-effect-resolver.ts @@ -1,9 +1,9 @@ import { StateMachine, StateMachineState } from "@farris/devkit-vue"; import { Change, ChangeSource } from "@farris/devkit-vue"; import { ComponentConfigDependencyRegistry, Configuration, ConfigDependency, DependencyKind } from "../config"; -import { ChangeResolver } from "./change-resolver"; +import { ChangeEffectResolver } from "./change-effect-resolver"; -export class StateMachineChangeResolver extends ChangeResolver> { +export class StateMachineChangeEffectResolver extends ChangeEffectResolver> { constructor(private componentConfigDependencyRegistry: ComponentConfigDependencyRegistry) { super(); diff --git a/packages/renderer/src/change-resolver/ui-state-change-resolver.ts b/packages/renderer/src/change-effect-resolver/ui-state-change-effect-resolver.ts similarity index 84% rename from packages/renderer/src/change-resolver/ui-state-change-resolver.ts rename to packages/renderer/src/change-effect-resolver/ui-state-change-effect-resolver.ts index 9353141c081..552188a62db 100644 --- a/packages/renderer/src/change-resolver/ui-state-change-resolver.ts +++ b/packages/renderer/src/change-effect-resolver/ui-state-change-effect-resolver.ts @@ -1,9 +1,9 @@ -import { UIState } from "@farris/devkit-vue"; +import { UIState, UIStateChange } from "@farris/devkit-vue"; import { ComponentConfigDependencyRegistry, Configuration, ConfigDependency, DependencyKind } from "../config"; -import { ChangeResolver } from "./change-resolver"; +import { ChangeEffectResolver } from "./change-effect-resolver"; import { Change, ChangeSource } from "@farris/devkit-vue"; -export class UIStateChangeResolver extends ChangeResolver { +export class UIStateChangeEffectResolver extends ChangeEffectResolver { constructor(private componentConfigDependencyRegistry: ComponentConfigDependencyRegistry) { super(); diff --git a/packages/renderer/src/change-resolver/index.ts b/packages/renderer/src/change-resolver/index.ts deleted file mode 100644 index 7c3936bf347..00000000000 --- a/packages/renderer/src/change-resolver/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from './change-resolver'; -export * from './state-machine-change-resolver'; -export * from './entity-store-change-resolver'; -export * from './ui-state-change-resolver'; -export * from './change-resolver-registry'; -export * from './change-resolve-service'; -export * from './providers'; diff --git a/packages/renderer/src/composition/use-module-config.ts b/packages/renderer/src/composition/use-module-config.ts index a983a7871fe..5adc64c7808 100644 --- a/packages/renderer/src/composition/use-module-config.ts +++ b/packages/renderer/src/composition/use-module-config.ts @@ -9,7 +9,7 @@ import { configProviders } from "../config"; import { configDependencyResolverProviders } from "../config-dependency-resolver"; import { componentConfigResolverProviders } from "../component-config-resolver"; import { componentConfigDependencyResolverProviders } from "../component-config-dependency-resolver"; -import { changeResolverProviders } from "../change-resolver"; +import { changeResolverProviders } from "../change-effect-resolver"; import { renderEngineProviders } from "../render-engine"; import { formEngineProviders } from "../form-engine"; import { eventEmitterProviders } from "../common/providers"; diff --git a/packages/renderer/src/form-engine/form-engine.ts b/packages/renderer/src/form-engine/form-engine.ts index c20cda8a943..374660e00f0 100644 --- a/packages/renderer/src/form-engine/form-engine.ts +++ b/packages/renderer/src/form-engine/form-engine.ts @@ -1,6 +1,6 @@ import { cloneDeep, merge, mergeWith } from "lodash-es"; import { Change, ChangeObserver, ChangeObserverRegistry } from "@farris/devkit-vue"; -import { ChangeResolveService } from "../change-resolver"; +import { ChangeResolveService } from "../change-effect-resolver"; import { ComponentConfigResolveService } from "../component-config-resolver"; import { RenderEngineImpl } from "../render-engine"; import { FormMetadataService } from "../service"; diff --git a/packages/renderer/src/form-engine/providers.ts b/packages/renderer/src/form-engine/providers.ts index 984723d9c05..6a2af73cced 100644 --- a/packages/renderer/src/form-engine/providers.ts +++ b/packages/renderer/src/form-engine/providers.ts @@ -1,6 +1,6 @@ import { ChangeObserverRegistry, StaticProvider } from "@farris/devkit-vue"; import { FormEngine } from "./form-engine"; -import { ChangeResolveService } from "../change-resolver"; +import { ChangeResolveService } from "../change-effect-resolver"; import { ComponentConfigResolveService } from "../component-config-resolver"; import { RenderEngineImpl } from "../render-engine"; import { FormMetadataService } from "../service"; diff --git a/packages/renderer/src/tokens.ts b/packages/renderer/src/tokens.ts index f555fa8479e..6b23604305d 100644 --- a/packages/renderer/src/tokens.ts +++ b/packages/renderer/src/tokens.ts @@ -3,7 +3,7 @@ import { FormMetadata } from "./types"; import { ComponentConfigResolver } from "./component-config-resolver"; import { ComponentConfigDependencyResolver } from "./component-config-dependency-resolver"; import { ConfigDependencyResolver } from "./config-dependency-resolver"; -import { ChangeResolver } from "./change-resolver"; +import { ChangeEffectResolver } from "./change-effect-resolver"; import { Ref } from "vue"; import { CallbackHandler } from "./callback-handler"; @@ -15,5 +15,5 @@ export const CONFIG_DEPENDENCY_RESOLVER_TOKEN = new InjectionToken('@farris/component_config_resolver_token'); export const COMPONENT_CONFIG_DEPENDENCY_RESOLVER_TOKEN = new InjectionToken('@farris/component_config_dependency_resolver_token'); -export const CHANGE_RESOLVER_TOKEN = new InjectionToken[]>('@farris/change_resolver_token'); +export const CHANGE_RESOLVER_TOKEN = new InjectionToken[]>('@farris/change_resolver_token'); export const CALLBACK_HANDLER_TOKEN = new InjectionToken('@farris/callback_handler_token'); -- Gitee From 840c13cba368801a3fa95b99e9f675bc298fe4b6 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Thu, 20 Mar 2025 19:52:25 +0800 Subject: [PATCH 078/153] =?UTF-8?q?feature:=20PC=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=A0=B9=E6=8D=AE=E8=A1=A8=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=94=9F=E6=88=90=E8=A1=A8=E5=8D=95=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form/form-array-store-config-builder.ts | 109 ++++++++++ .../form/form-control-config-builder.ts | 70 +++++++ .../form/form-store-config-builder.ts | 91 +++++++++ .../src/config-builders/form/index.ts | 4 + .../form/validation-rule-creator.ts | 131 ++++++++++++ .../config-builders/module-config-builder.ts | 170 +++++++++++----- .../src/service/entity-schema-query.ts | 153 ++++++++++++++ .../src/service/form-metadata-query.ts | 192 ++++++++++++++++++ packages/renderer/src/service/index.ts | 2 + 9 files changed, 872 insertions(+), 50 deletions(-) create mode 100644 packages/renderer/src/config-builders/form/form-array-store-config-builder.ts create mode 100644 packages/renderer/src/config-builders/form/form-control-config-builder.ts create mode 100644 packages/renderer/src/config-builders/form/form-store-config-builder.ts create mode 100644 packages/renderer/src/config-builders/form/index.ts create mode 100644 packages/renderer/src/config-builders/form/validation-rule-creator.ts create mode 100644 packages/renderer/src/service/entity-schema-query.ts create mode 100644 packages/renderer/src/service/form-metadata-query.ts diff --git a/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts b/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts new file mode 100644 index 00000000000..b2f193d78c8 --- /dev/null +++ b/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts @@ -0,0 +1,109 @@ +import { FormControlConfig, FormArrayStateConfig, FormArrayStoreConfig } from '@farris/devkit-vue'; +import { FormMetadataQuery } from '../../service/index'; +import { FormControlConfigBuilder } from './form-control-config-builder'; + +/** + * 表单数组仓库配置构造器 + */ +class FormArrayStoreConfigBuilder { + + /** + * 表单元数据查询 + */ + private formMetaQuery: FormMetadataQuery; + + /** + * 构造函数 + */ + public constructor(formMetaQuery: FormMetadataQuery) { + this.formMetaQuery = formMetaQuery; + } + + /** + * 构造配置 + */ + public build(viewModelNode: any): FormArrayStoreConfig { + const stateConfig = this.buildStateConfig(viewModelNode); + const storeConfig: FormArrayStoreConfig = { + id: viewModelNode.code + '-form-array-store', + bindingPath: viewModelNode.bindTo, + state: stateConfig + }; + + return storeConfig; + } + + /** + * 获取表单状态配置 + */ + private buildStateConfig(viewModelNode: any): FormArrayStateConfig { + const vmComponentNode = this.getVmComponentNode(viewModelNode); + if (!vmComponentNode) { + throw new Error(`Component(viewModel=${viewModelNode.id}) not found`); + } + + const controlConfigs = this.buildControlConfigs(viewModelNode, vmComponentNode); + const stateConfig: FormArrayStateConfig = { + controls: controlConfigs + }; + return stateConfig; + } + + /** + * 构造控件配置集合 + */ + private buildControlConfigs(viewModelNode: any, vmComponentNode: any): FormControlConfig[] { + const wrappedControlNodes = this.collectWrappedControlNodes(vmComponentNode); + const controlConfigBuilder = new FormControlConfigBuilder(); + + const controlConfigs: FormControlConfig[] = []; + wrappedControlNodes.forEach((wrappedControlNode) => { + const controlNode = wrappedControlNode.component; + const controlConfig = controlConfigBuilder.build(viewModelNode, controlNode.editor); + controlConfigs.push(controlConfig); + }); + + return controlConfigs; + } + + /** + * 获取列表对应卡片的表单组件 + */ + private getVmComponentNode(viewModelNode: any): any { + const listVmComponentNode = this.formMetaQuery.getVmComponentByVmId(viewModelNode.id); + + // 对用对应卡片的组件模拟批量编辑场景 + const vmComponentNodes = this.formMetaQuery.getVmComponents(); + const cardVmComponentNode = vmComponentNodes.find((vmComponentNode) => { + return vmComponentNode !== listVmComponentNode && vmComponentNode.bindTo === listVmComponentNode.bindTo; + }); + + if (!listVmComponentNode && !cardVmComponentNode) { + throw new Error(`Component(viewModel=${viewModelNode.id}) not found`); + } + + return cardVmComponentNode ? cardVmComponentNode : listVmComponentNode; + } + + /** + * 搜集当前VM组件下的所有输入控件 + */ + private collectWrappedControlNodes(vmComponentNode: any): any[] { + const wrappedComponentNodes = this.formMetaQuery.getWrappedComponents(); + const wrappedControlNode = [] as any[]; + wrappedComponentNodes.forEach((wrappedComponentNode) => { + if (wrappedComponentNode.viewModelComponent !== vmComponentNode) { + return; + } + + const componentType = wrappedComponentNode.component.type; + if (componentType === 'form-item') { + wrappedControlNode.push(wrappedComponentNode); + } + }); + + return wrappedControlNode; + } +} + +export { FormArrayStoreConfigBuilder }; diff --git a/packages/renderer/src/config-builders/form/form-control-config-builder.ts b/packages/renderer/src/config-builders/form/form-control-config-builder.ts new file mode 100644 index 00000000000..d85d8103b86 --- /dev/null +++ b/packages/renderer/src/config-builders/form/form-control-config-builder.ts @@ -0,0 +1,70 @@ +import { FormControlConfig } from '@farris/devkit-vue'; +import { ValidationRuleCreator } from './validation-rule-creator'; + +/** + * 表单控件配置构造器 + */ +class FormControlConfigBuilder { + + /** + * 验证规则创建器 + */ + private validationRuleCreator: ValidationRuleCreator; + + /** + * 构造函数 + */ + constructor() { + this.validationRuleCreator = new ValidationRuleCreator(); + } + + /** + * 构造控件配置 + */ + public build(viewModelNode: any, controlNode: any): FormControlConfig { + const name = controlNode.id; + const bindingType = this.getBindingType(controlNode); + const bindingPath = this.getBindingPath(viewModelNode, controlNode); + const validationRules = this.getValidationRules(controlNode); + const controlConfig = { name, bindingType, bindingPath, validationRules }; + + return controlConfig; + } + + /** + * 获取绑定类型 + */ + private getBindingType(controlNode: any): string { + const bindingType = controlNode.binding.type; + if (bindingType === 'EntityField') { + return 'EntityState'; + } else if (bindingType === 'Variable') { + return 'UIState'; + } + + throw new Error(`BindingType(type=${bindingType}) unsupported`); + } + + /** + * 获取绑定路径 + */ + private getBindingPath(viewModelNode: any, controlNode: any): string { + const { bindTo } = viewModelNode; + + // Form和FormArray已经记录了实体路径,FormControl上使用相对短路径 + if (bindTo === '/') { + return controlNode.binding.path; + } else { + return controlNode.binding.path.replace(bindTo, ''); + } + } + + /** + * 获取绑定路径 + */ + private getValidationRules(controlNode: any) { + return this.validationRuleCreator.createRules(controlNode); + } +} + +export { FormControlConfigBuilder }; diff --git a/packages/renderer/src/config-builders/form/form-store-config-builder.ts b/packages/renderer/src/config-builders/form/form-store-config-builder.ts new file mode 100644 index 00000000000..cb6f53153fa --- /dev/null +++ b/packages/renderer/src/config-builders/form/form-store-config-builder.ts @@ -0,0 +1,91 @@ +import { FormControlConfig, FormStateConfig, FormStoreConfig } from '@farris/devkit-vue'; +import { FormMetadataQuery } from '../../service/index'; +import { FormControlConfigBuilder } from './form-control-config-builder'; + +/** + * 表单仓库配置构造器 + */ +class FormStoreConfigBuilder { + + /** + * 表单元数据查询 + */ + private formMetaQuery: FormMetadataQuery; + + /** + * 构造函数 + */ + public constructor(formMetaQuery: FormMetadataQuery) { + this.formMetaQuery = formMetaQuery; + } + + /** + * 构造配置 + */ + public build(viewModelNode: any): FormStoreConfig { + const stateConfig = this.buildStateConfig(viewModelNode); + const storeConfig: FormStoreConfig = { + id: viewModelNode.code + '-form-store', + bindingPath: viewModelNode.bindTo, + state: stateConfig + }; + + return storeConfig; + } + + /** + * 获取表单状态配置 + */ + private buildStateConfig(viewModelNode: any): FormStateConfig { + const vmComponentNode = this.formMetaQuery.getVmComponentByVmId(viewModelNode.id); + if (!vmComponentNode) { + throw new Error(`Component(viewModel=${viewModelNode.id}) not found`); + } + + const controlConfigs = this.buildControlConfigs(viewModelNode, vmComponentNode); + const stateConfig: FormStateConfig = { + controls: controlConfigs + }; + + return stateConfig; + } + + /** + * 构造控件配置集合 + */ + private buildControlConfigs(viewModelNode: any, vmComponentNode: any): FormControlConfig[] { + const wrappedControlNodes = this.collectWrappedControlNodes(vmComponentNode); + const controlConfigBuilder = new FormControlConfigBuilder(); + + const controlConfigs: FormControlConfig[] = []; + wrappedControlNodes.forEach((wrappedControlNode) => { + const controlNode = wrappedControlNode.component; + const controlConfig = controlConfigBuilder.build(viewModelNode, controlNode.editor); + controlConfigs.push(controlConfig); + }); + + return controlConfigs; + } + + /** + * 搜集当前VM组件下的所有输入控件 + */ + private collectWrappedControlNodes(vmComponentNode: any): any[] { + const wrappedComponentNodes = this.formMetaQuery.getWrappedComponents(); + const wrappedControlNode = [] as any[]; + wrappedComponentNodes.forEach((wrappedComponentNode) => { + if (wrappedComponentNode.viewModelComponent !== vmComponentNode) { + return; + } + + const componentType = wrappedComponentNode.component.type; + if (componentType === 'form-item') { + wrappedControlNode.push(wrappedComponentNode); + } + }); + + return wrappedControlNode; + } +} + +export { FormStoreConfigBuilder }; diff --git a/packages/renderer/src/config-builders/form/index.ts b/packages/renderer/src/config-builders/form/index.ts new file mode 100644 index 00000000000..8eb0779ca30 --- /dev/null +++ b/packages/renderer/src/config-builders/form/index.ts @@ -0,0 +1,4 @@ +export * from './validation-rule-creator'; +export * from './form-control-config-builder'; +export * from './form-store-config-builder'; +export * from './form-array-store-config-builder'; diff --git a/packages/renderer/src/config-builders/form/validation-rule-creator.ts b/packages/renderer/src/config-builders/form/validation-rule-creator.ts new file mode 100644 index 00000000000..342e9a0a595 --- /dev/null +++ b/packages/renderer/src/config-builders/form/validation-rule-creator.ts @@ -0,0 +1,131 @@ +import { + ValidationRule, RequiredValidationRule, MaxLengthValidationRule, MinLengthValidationRule, + MaxValueValidationRule, MinValueValidationRule, MaxDateValidationRule, MinDateValidationRule, + PatternValidationRule, CustomFunctionValidationRule, +} from '@farris/devkit-vue'; + +/** + * 创建验证规则 + */ +class ValidationRuleCreator { + + /** + * 内置规则名称 + */ + public buildInRuleNames = [ + 'required', 'maxLength', 'minLength', 'maxValue', 'minValue', + 'maxDate', 'minDate', 'pattern', 'customFunction' + ]; + + /** + * 创建验证规则 + */ + public createRules(controlNode: any): ValidationRule[] { + const rules: any[] = []; + this.buildInRuleNames.forEach((name) => { + const rule = (this as any)[name](controlNode); + if (rule) { + rules.push(rule); + } + }); + + return rules as ValidationRule[]; + } + + /** + * 最大长度 + */ + public required(controlNode: any): RequiredValidationRule | undefined { + if (!controlNode.require) { + return; + } + + return { name: 'required' }; + } + + /** + * 最大长度 + */ + public maxLength(controlNode: any): MaxLengthValidationRule | undefined { + if (!controlNode.maxLength) { + return; + } + + return { name: 'maxLength', maxLength: controlNode.maxLength }; + } + + /** + * 最小长度 + */ + public minLength(controlNode: any): MinLengthValidationRule | undefined { + if (!controlNode.minLength) { + return; + } + + return { name: 'minLength', minLength: controlNode.minLength }; + } + + /** + * 最大值 + */ + public maxValue(controlNode: any): MaxValueValidationRule | undefined { + if (!controlNode.maxValue) { + return; + } + + return { name: 'maxValue', maxValue: controlNode.maxValue }; + } + + /** + * 最小值 + */ + public minValue(controlNode: any): MinValueValidationRule | undefined { + if (!controlNode.minValue) { + return; + } + + return { name: 'minValue', minValue: controlNode.minValue }; + } + + /** + * 最大日期 + */ + public maxDate(controlNode: any): MaxDateValidationRule | undefined { + if (!controlNode.maxDate) { + return; + } + + return { name: 'maxDate', maxDate: controlNode.maxDate }; + } + + /** + * 最小日期 + */ + public minDate(controlNode: any): MinDateValidationRule | undefined { + if (!controlNode.minDate) { + return; + } + + return { name: 'minDate', minDate: controlNode.minDate }; + } + + /** + * 正则表达式 + */ + public pattern(controlNode: any): PatternValidationRule | undefined { + if (!controlNode.formatValidation) { + return; + } + + return { name: 'pattern', pattern: controlNode.expression }; + } + + /** + * 自定义函数 + */ + public customFunction(controlNode: any): CustomFunctionValidationRule | null { + return null; + } +} + +export { ValidationRuleCreator }; diff --git a/packages/renderer/src/config-builders/module-config-builder.ts b/packages/renderer/src/config-builders/module-config-builder.ts index 9751e5286e8..35dbb6400bf 100644 --- a/packages/renderer/src/config-builders/module-config-builder.ts +++ b/packages/renderer/src/config-builders/module-config-builder.ts @@ -1,12 +1,12 @@ import { - StaticProvider, - EntityStoreConfig, UIStateConfig, StateMachineConfig, RepositoryConfig, - ViewModelConfig, ModuleConfig, - UIStoreConfig, + StaticProvider, EntityStoreConfig, UIStoreConfig, FormStoreConfig, FormArrayStoreConfig, + StateMachineConfig, RepositoryConfig, ViewModelConfig, ModuleConfig, } from '@farris/devkit-vue'; -import { EntityStoreConfigBuilder } from './entity-store-config-builder'; +import { FormMetadataQuery } from '../service/index'; import { RepositoryConfigBuilder } from './repository-config-builder'; +import { EntityStoreConfigBuilder } from './entity-store-config-builder'; import { UIStoreConfigBuilder } from './ui-store-config-builder'; +import { FormStoreConfigBuilder, FormArrayStoreConfigBuilder } from './form/index'; import { StateMachineConfigBuilder } from './state-machine-config-builder'; import { ViewModelConfigBuilder } from './viewmodel-config-builder'; @@ -20,57 +20,73 @@ class ModuleConfigBuilder { */ private context: any; + /** + * 表单元数据 + */ + private formMeta: any; + + /** + * 表单元数据查询 + */ + private formMetaQuery: FormMetadataQuery; + + /** + * 状态机元数据集合 + */ + private smMetas: any; + + /** + * 命令构件集合 + */ + private webCmdMetas: any[]; + + /** + * 服务构件集合 + */ + private webCmpMetas: any[]; + + /** + * 模块配置 + */ + private moduleConfig: ModuleConfig; + /** * 构造函数 */ constructor(context: any) { this.context = context; + this.context = context; + this.formMeta = this.context.form; + this.formMetaQuery = new FormMetadataQuery({ content: this.formMeta }); + this.smMetas = this.context.stateMachines; + this.webCmdMetas = this.context.webcmds; + this.webCmpMetas = this.context.webComponents; + this.moduleConfig = { + id: '', + providers: [], + entityStores: [], + uiStores: [], + formStores: [], + formArrayStores: [], + stateMachines: [], + repositories: [], + viewModels: [] + }; } /** * 构造模块配置 */ public build() { - const formMeta = this.context.form; - const webCmdMetas = this.context.webcmds; - const smMetas = this.context.stateMachines; - const webComponentMetadatas = this.context.webComponents; - - const id = formMeta.module.code; - const providers: StaticProvider[] = this.context.moduleProviders; - const entityStoreConfigs = this.buildEntityStoreConfigs(formMeta); - const uiStoreConfigs = this.buildUIStoreConfigs(formMeta); - const stateMachineConfigs = this.buildStateMachineConfigs(formMeta, smMetas); - const repositoryConfigs = this.buildRepositoryConfigs(formMeta); - const viewModelConfigs = this.buildViewModelConfigs(formMeta, webCmdMetas,webComponentMetadatas, this.context.viewModelProviders); - - const moduleConfig: ModuleConfig = { - id, - providers, - entityStores: entityStoreConfigs, - uiStores: uiStoreConfigs, - stateMachines: stateMachineConfigs, - repositories: repositoryConfigs, - viewModels: viewModelConfigs - }; - - return moduleConfig; - } + this.buildRepositoryConfigs(this.formMeta); + this.buildEntityStoreConfigs(this.formMeta); + this.buildStateMachineConfigs(this.formMeta, this.smMetas); + this.buildViewModelConfigs(this.formMeta, this.webCmdMetas, this.webCmpMetas, this.context.viewModelProviders); - /** - * 构造实体仓库配置 - */ - private buildEntityStoreConfigs(formMeta: any): EntityStoreConfig[] { - const builder = new EntityStoreConfigBuilder(formMeta); - const configs: EntityStoreConfig[] = []; - - const schemaNodes = formMeta.module.entity; - schemaNodes.forEach((schema: any) => { - const config = builder.build(schema); - configs.push(config); - }); + this.moduleConfig.id = this.formMeta.module.code; + this.moduleConfig.providers = this.context.moduleProviders; - return configs; + return this.moduleConfig; } /** @@ -84,21 +100,24 @@ class ModuleConfigBuilder { const config = builder.build(schemaNode); configs.push(config); }); + this.moduleConfig.repositories = configs; return configs; } /** - * 构造UI仓库配置 + * 构造实体仓库配置 */ - private buildUIStoreConfigs(formMeta: any): UIStoreConfig[] { - const builder = new UIStoreConfigBuilder(formMeta); - const configs: UIStoreConfig[] = []; - const viewModelNodes = formMeta.module.viewmodels as any[]; - viewModelNodes.forEach((viewModelNode) => { - const config = builder.build(viewModelNode); + private buildEntityStoreConfigs(formMeta: any): EntityStoreConfig[] { + const builder = new EntityStoreConfigBuilder(formMeta); + const configs: EntityStoreConfig[] = []; + + const schemaNodes = formMeta.module.entity; + schemaNodes.forEach((schema: any) => { + const config = builder.build(schema); configs.push(config); }); + this.moduleConfig.entityStores = configs; return configs; } @@ -116,6 +135,7 @@ class ModuleConfigBuilder { } configs.push(config); }); + this.moduleConfig.stateMachines = configs; return configs; } @@ -132,11 +152,61 @@ class ModuleConfigBuilder { if (!config) { return; } + + const uiStoreConfig = this.buildUIStoreConfig(viewModelNode); + config.uiStore = uiStoreConfig ? uiStoreConfig.id: undefined; + + const formStoreConfig = this.buildFormStoreConfig(viewModelNode); + config.formStore = formStoreConfig ? formStoreConfig.id : undefined; + + const formArrayStoreConfig = this.buildFormArrayStoreConfig(viewModelNode); + config.formArrayStore = formArrayStoreConfig ? formArrayStoreConfig.id : undefined; + configs.push(config); }); + this.moduleConfig.viewModels = configs; return configs; } + + /** + * 构造UI仓库配置 + */ + public buildUIStoreConfig(viewModelNode: any): UIStoreConfig { + const builder = new UIStoreConfigBuilder(this.formMeta); + const config = builder.build(viewModelNode); + this.moduleConfig.uiStores.push(config); + + return config; + } + + /** + * 构造表单仓库 + */ + public buildFormStoreConfig(viewModelNode: any): FormStoreConfig | undefined { + const builder = new FormStoreConfigBuilder(this.formMetaQuery); + const config = builder.build(viewModelNode); + if (config.state.controls.length === 0) { + return; + } + this.moduleConfig.formStores.push(config); + + return config; + } + + /** + * 构造表单数组仓库配置 + */ + public buildFormArrayStoreConfig(viewModelNode: any): FormArrayStoreConfig | undefined { + const builder = new FormArrayStoreConfigBuilder(this.formMetaQuery); + const config = builder.build(viewModelNode); + if (config.state.controls.length === 0) { + return; + } + this.moduleConfig.formArrayStores.push(config); + + return config; + } } export { ModuleConfigBuilder }; diff --git a/packages/renderer/src/service/entity-schema-query.ts b/packages/renderer/src/service/entity-schema-query.ts new file mode 100644 index 00000000000..217844f2c8f --- /dev/null +++ b/packages/renderer/src/service/entity-schema-query.ts @@ -0,0 +1,153 @@ +/** + * 包装后的实体描述 + */ +interface WrappedEntitySchema { + bindingPath: string; + entitySchema: any; + parentWrappedEntitySchema: WrappedEntitySchema; +} + + +/** + * 包装后的字段描述 + */ +interface WrappedFieldSchema { + bindingPath: string; + fieldSchema: any; +} + +/** + * EntitySchema查询服务 + */ +class EntitySchemaQuery { + + /** + * 表单Schema + */ + private rootEntitySchema: any; + + /** + * 实体标签和实体描述Map + */ + private labelAndEntitySchemaMap: Map; + + /** + * 字段ID和字段描述Map + */ + private idAndFieldSchemaMap: Map; + + /** + * 实体Schema查询服务 + */ + constructor(formModule:any) { + this.rootEntitySchema = formModule.entity[0].entities[0]; + this.labelAndEntitySchemaMap = new Map(); + this.idAndFieldSchemaMap = new Map(); + this.collectEntitySchema(this.rootEntitySchema, null); + } + + /** + * 根据Label获取WrappedEntitySchema + */ + public getWrappedEntitySchemaByLabel(label: string): WrappedEntitySchema { + if (!this.labelAndEntitySchemaMap.has(label)) { + throw new Error(`EntitySchema(label=${label}) not found`); + } + + return this.labelAndEntitySchemaMap.get(label); + } + + /** + * 根据ID获取WrappedFieldSchema + */ + public getWrappedFieldSchemaById(id: string): WrappedFieldSchema { + if (!this.idAndFieldSchemaMap.has(id)) { + throw new Error(`FieldSchema(id=${id}) not found`); + } + + return this.idAndFieldSchemaMap.get(id); + } + + /** + * 搜集所有实体信息 + */ + private collectEntitySchema(entitySchema: any, wrappedParentEntitySchema: any) { + const bindingPath = this.getEntityBindingPath(wrappedParentEntitySchema, entitySchema); + const wrappedEntitySchema = { + entitySchema, + bindingPath, + wrappedParentEntitySchema, + }; + + this.labelAndEntitySchemaMap.set(entitySchema.label, wrappedEntitySchema); + this.collectFieldSchemas(entitySchema.type.fields, wrappedEntitySchema); + + const childEntitySchemas = entitySchema.type.entities as any[]; + if (Array.isArray(childEntitySchemas)) { + childEntitySchemas.forEach((childEntitySchema: any) => { + this.collectEntitySchema(childEntitySchema, wrappedEntitySchema); + }); + } + } + + /** + * 搜集所有字段信息 + */ + private collectFieldSchemas(fieldSchemas: any[], wrappedEntitySchema: any) { + fieldSchemas.forEach((fieldSchema: any) => { + this.collectFieldSchema(fieldSchema, wrappedEntitySchema); + }); + } + + /** + * 搜集字段信息 + */ + private collectFieldSchema(fieldSchema: any, wrappedEntitySchema: any) { + const bindingPath = this.getFieldBindingPath(wrappedEntitySchema, fieldSchema); + const wrappedFieldSchema = { bindingPath, fieldSchema }; + this.idAndFieldSchemaMap.set(fieldSchema.id, wrappedFieldSchema); + + if (fieldSchema.$type === 'ComplexField') { + + // 关联字段 + if (fieldSchema.type.$type === 'EntityType') { + const assoFieldSchemas = fieldSchema.type.fields; + this.collectFieldSchemas(assoFieldSchemas, wrappedEntitySchema); + } + + // 业务字段 + if (fieldSchema.type.$type === 'ObjectType') { + const udtFieldSchemas = fieldSchema.type.fields; + this.collectFieldSchemas(udtFieldSchemas, wrappedEntitySchema); + } + } + } + + /** + * 获取实体绑定路径 + */ + private getEntityBindingPath(wrappedParentEntitySchema: any, entitySchema: any) { + if (!wrappedParentEntitySchema) { + return `/`; + } + + const parentBindingPath = wrappedParentEntitySchema.bindingPath; + return `${parentBindingPath}/${entitySchema.label}`; + } + + /** + * 获取字段绑定路径 + */ + private getFieldBindingPath(wrappedEntitySchema: any, fieldSchema: any): string { + const entityBindingPath = wrappedEntitySchema.bindingPath; + const shortBindingPath = fieldSchema.bindingPath.split('.').join('/'); + + if (entityBindingPath === '/') { + return `/${shortBindingPath}`; + } else { + return `${entityBindingPath}/${shortBindingPath}`; + } + } +} + +export { WrappedEntitySchema, WrappedFieldSchema, EntitySchemaQuery }; diff --git a/packages/renderer/src/service/form-metadata-query.ts b/packages/renderer/src/service/form-metadata-query.ts new file mode 100644 index 00000000000..c44be3e813a --- /dev/null +++ b/packages/renderer/src/service/form-metadata-query.ts @@ -0,0 +1,192 @@ +import { WrappedEntitySchema, WrappedFieldSchema, EntitySchemaQuery } from './entity-schema-query'; + +/** + * 包装后的组件 + */ +export interface WrappedComponent { + component: any, + componentSchema: any, + viewModel: any, + viewModelComponent: any +} + + +/** + * 表单元数据查询 + */ +class FormMetadataQuery { + + /** + * 表单元数据 + */ + private formMetadata: any; + + /** + * 表单模块 + */ + private formModule: any; + + /** + * 视图模型Map + */ + private viewModelMap!: Map; + + /** + * 视图模型组件Map + */ + private vmComponentMap!: Map; + + /** + * 包装后的组件Map + */ + private wrappedComponentMap!: Map; + + /** + * EntitySchema查询 + */ + private entitySchemaQuery: EntitySchemaQuery; + + /** + * 构造函数 + */ + constructor(formMetadata: any) { + this.formMetadata = formMetadata; + this.formModule = formMetadata.content.module; + this.entitySchemaQuery = new EntitySchemaQuery(this.formModule); + this.initViewModelMap(); + this.initVmComponentMap(); + this.initWrappedComponentMap(); + } + + /** + * 根据label获取EntitySchema + */ + public getWrappedEntitySchemaByLabel(label: string): WrappedEntitySchema { + return this.entitySchemaQuery.getWrappedEntitySchemaByLabel(label); + } + + /** + * 根据ID获取FieldSchema + */ + public getWrappedFieldSchemaById(id: string): WrappedFieldSchema { + return this.entitySchemaQuery.getWrappedFieldSchemaById(id); + } + + /** + * 获取视图模型集合 + */ + public getViewModels() { + return this.formModule.viewmodels; + } + + /** + * 根据ID获取视图模型 + */ + public getViewModelById(id: string): any | undefined { + const viewModel = this.viewModelMap.get(id); + return viewModel; + } + + /** + * 获取VM组件集合 + */ + public getVmComponents(): any[] { + return this.formModule.components; + } + + /** + * 根据ID获取获取VM组件 + */ + public getVmComponentById(id: string): any | undefined { + return this.vmComponentMap.get(id); + } + + /** + * 根据视图模型ID获取VM组件 + */ + public getVmComponentByVmId(viewModelId: string): any | undefined { + const vmComponents = this.getVmComponents(); + const targetVmComponent = vmComponents.find((vmComponent) => { + return vmComponent.viewModel === viewModelId; + }); + + return targetVmComponent; + } + + /** + * 根据ID获取包装组件 + */ + public getWrappedComponentById(id: string): WrappedComponent | undefined { + const wrappedComponent = this.wrappedComponentMap.get(id); + return wrappedComponent; + } + + /** + * 获取全部包装组件 + */ + public getWrappedComponents(): WrappedComponent[] { + const wrappedComponents = Array.from(this.wrappedComponentMap.values()); + return wrappedComponents; + } + + /** + * 初始化视图模型Map + */ + private initViewModelMap() { + this.viewModelMap = new Map(); + const viewModels = this.formModule.viewmodels as any[]; + viewModels.forEach((viewModel) => { + this.viewModelMap.set(viewModel.id, viewModel); + }); + } + + /** + * 初始化VM组件Map + */ + private initVmComponentMap() { + this.vmComponentMap = new Map(); + const vmComponents = this.formModule.components as any[]; + vmComponents.forEach((vmComponent) => { + this.vmComponentMap.set(vmComponent.id, vmComponent); + }); + } + + /** + * 初始化包装组件Map + */ + private initWrappedComponentMap() { + this.wrappedComponentMap = new Map(); + const vmComponents = this.formModule.components as any[]; + vmComponents.forEach((vmComponent) => { + const currentViewModel = this.getViewModelById(vmComponent.viewModel); + this.appendWrappedComponentToMap(vmComponent, currentViewModel, vmComponent); + }); + } + + /** + * 追加组件到组件Map + */ + private appendWrappedComponentToMap(component: any, currentViewModel: any, currentViewModelComponent: any) { + // const componentSchema = schemaMap[component.type]; + const componentSchema = null; + const wrappedComponent = { + component: component, + componentSchema: componentSchema, + viewModel: currentViewModel, + viewModelComponent: currentViewModelComponent + }; + this.wrappedComponentMap.set(component.id, wrappedComponent); + + if (component.editor) { + this.appendWrappedComponentToMap(component.editor, currentViewModel, currentViewModelComponent); + } + + if (Array.isArray(component.contents)) { + component.contents.forEach((childComponent: any) => { + this.appendWrappedComponentToMap(childComponent, currentViewModel, currentViewModelComponent); + }); + } + } +} + +export { FormMetadataQuery }; diff --git a/packages/renderer/src/service/index.ts b/packages/renderer/src/service/index.ts index b2442fc32c0..189fa4a964c 100644 --- a/packages/renderer/src/service/index.ts +++ b/packages/renderer/src/service/index.ts @@ -1,3 +1,5 @@ export * from './form-metadata-service'; +export * from './form-metadata-query'; +export * from './entity-schema-query'; export * from './component-service'; export * from './providers'; -- Gitee From ed78463264b0042505d5f7c3d4707eff1cbbd198 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Thu, 20 Mar 2025 20:11:15 +0800 Subject: [PATCH 079/153] =?UTF-8?q?chore:=20=E7=BB=86=E5=8C=96=E5=8F=98?= =?UTF-8?q?=E6=9B=B4=E5=BD=B1=E5=93=8D=E5=8C=B9=E9=85=8D=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity-store-change-effect-resolver.ts | 6 ++++-- .../expression-result-change-effect-resolver.ts | 4 +++- .../ui-state-change-effect-resolver.ts | 4 +++- .../entity-state-config-dependency-resolver.ts | 1 + 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/renderer/src/change-effect-resolver/entity-store-change-effect-resolver.ts b/packages/renderer/src/change-effect-resolver/entity-store-change-effect-resolver.ts index 2117d01ab01..bb3e38acfe4 100644 --- a/packages/renderer/src/change-effect-resolver/entity-store-change-effect-resolver.ts +++ b/packages/renderer/src/change-effect-resolver/entity-store-change-effect-resolver.ts @@ -1,4 +1,4 @@ -import { Entity, EntityState } from "@farris/devkit-vue"; +import { Entity, EntityChange, EntityState } from "@farris/devkit-vue"; import { ChangeEffectResolver } from "./change-effect-resolver"; import { Change, ChangeSource } from "@farris/devkit-vue"; import { ComponentConfigDependencyRegistry, Configuration, ConfigDependency, DependencyKind } from "../config"; @@ -15,10 +15,12 @@ export class EntityStoreChangeEffectResolver extends ChangeEffectResolver = new Map(); + const entityStateChange = change.detail as EntityChange; + const entityPath = entityStateChange.path.toShortPath(); Array.from(registry.entries()).forEach(([id, configs]) => { const matchedConfigs = configs.filter((config: Configuration) => { const match = config.deps.find((dependency: ConfigDependency) => { - return dependency.type === DependencyKind.EntityState; + return dependency.type === DependencyKind.EntityState && dependency.path === entityPath; }); return !!match; }); diff --git a/packages/renderer/src/change-effect-resolver/expression-result-change-effect-resolver.ts b/packages/renderer/src/change-effect-resolver/expression-result-change-effect-resolver.ts index 9600e702737..94de38c8568 100644 --- a/packages/renderer/src/change-effect-resolver/expression-result-change-effect-resolver.ts +++ b/packages/renderer/src/change-effect-resolver/expression-result-change-effect-resolver.ts @@ -12,10 +12,12 @@ export class ExpressionResultChangeEffectResolver extends ChangeEffectResolver = new Map(); + const expressionResultChange = change.detail as ExpressionResultChange; + Array.from(registry.entries()).forEach(([id, configs]) => { const matchedConfigs = configs.filter((config: Configuration) => { const match = config.deps.find((dependency: ConfigDependency) => { - return dependency.type === DependencyKind.ExpressionResult; + return dependency.type === DependencyKind.ExpressionResult && dependency.path === expressionResultChange.id; }); return !!match;; }); diff --git a/packages/renderer/src/change-effect-resolver/ui-state-change-effect-resolver.ts b/packages/renderer/src/change-effect-resolver/ui-state-change-effect-resolver.ts index 552188a62db..b3764e3bf4d 100644 --- a/packages/renderer/src/change-effect-resolver/ui-state-change-effect-resolver.ts +++ b/packages/renderer/src/change-effect-resolver/ui-state-change-effect-resolver.ts @@ -15,10 +15,12 @@ export class UIStateChangeEffectResolver extends ChangeEffectResolver { } const registry = this.componentConfigDependencyRegistry.getComponents(); const result: Map = new Map(); + const uiStateChange = change.detail as UIStateChange; Array.from(registry.entries()).forEach(([id, configs]) => { const matchedConfigs = configs.filter((config: Configuration) => { const match = config.deps.find((dependency: ConfigDependency) => { - return dependency.type === DependencyKind.UIState; + const dependencyPath = `/${dependency.path}`; + return dependency.type === DependencyKind.UIState && dependencyPath === uiStateChange.path; }); return !!match;; }); diff --git a/packages/renderer/src/config-dependency-resolver/entity-state-config-dependency-resolver.ts b/packages/renderer/src/config-dependency-resolver/entity-state-config-dependency-resolver.ts index 562d01f9af4..695717f95eb 100644 --- a/packages/renderer/src/config-dependency-resolver/entity-state-config-dependency-resolver.ts +++ b/packages/renderer/src/config-dependency-resolver/entity-state-config-dependency-resolver.ts @@ -22,6 +22,7 @@ export class EntityStateConfigDependencyResolver implements ConfigDependencyReso return null; } return results.map((path: string) => { + path = '/' + path.split('.').join('/'); return { path, type: DependencyKind.EntityState }; }); } -- Gitee From 73ebe13384cd3912e659cd46b72da9429e94468a Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Thu, 20 Mar 2025 20:45:44 +0800 Subject: [PATCH 080/153] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9ChangeResolv?= =?UTF-8?q?eService=E4=B8=BAChangeEffectResolveService?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../change-effect-resolve-service.ts | 2 +- .../change-effect-resolver-registry.ts | 4 ++-- .../renderer/src/change-effect-resolver/providers.ts | 12 ++++++------ packages/renderer/src/form-engine/form-engine.ts | 4 ++-- packages/renderer/src/form-engine/providers.ts | 4 ++-- packages/renderer/src/tokens.ts | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/renderer/src/change-effect-resolver/change-effect-resolve-service.ts b/packages/renderer/src/change-effect-resolver/change-effect-resolve-service.ts index e36cfa7a25d..d3fbc3f53c7 100644 --- a/packages/renderer/src/change-effect-resolver/change-effect-resolve-service.ts +++ b/packages/renderer/src/change-effect-resolver/change-effect-resolve-service.ts @@ -3,7 +3,7 @@ import { Configuration } from "../config"; import { ChangeEffectResolver } from "./change-effect-resolver"; import { ChangeEffectResolverRegistry } from "./change-effect-resolver-registry"; -export class ChangeResolveService { +export class ChangeEffectResolveService { constructor(private changeResolverRegistry: ChangeEffectResolverRegistry) { } public resolve(change: Change): Map { diff --git a/packages/renderer/src/change-effect-resolver/change-effect-resolver-registry.ts b/packages/renderer/src/change-effect-resolver/change-effect-resolver-registry.ts index 4dda1dd6537..c501d632347 100644 --- a/packages/renderer/src/change-effect-resolver/change-effect-resolver-registry.ts +++ b/packages/renderer/src/change-effect-resolver/change-effect-resolver-registry.ts @@ -1,11 +1,11 @@ import { Injector } from "@farris/devkit-vue"; import { ChangeEffectResolver } from "./change-effect-resolver"; -import { CHANGE_RESOLVER_TOKEN } from "../tokens"; +import { CHANGE_EFFECT_RESOLVER_TOKEN } from "../tokens"; export class ChangeEffectResolverRegistry { public registry: ChangeEffectResolver[]; constructor(private injector: Injector) { - this.registry = this.injector.get[]>(CHANGE_RESOLVER_TOKEN); + this.registry = this.injector.get[]>(CHANGE_EFFECT_RESOLVER_TOKEN); } } diff --git a/packages/renderer/src/change-effect-resolver/providers.ts b/packages/renderer/src/change-effect-resolver/providers.ts index e2d90f838f9..3ada62c3ec6 100644 --- a/packages/renderer/src/change-effect-resolver/providers.ts +++ b/packages/renderer/src/change-effect-resolver/providers.ts @@ -1,16 +1,16 @@ import { Injector, StaticProvider } from "@farris/devkit-vue"; import { StateMachineChangeEffectResolver } from "./state-machine-change-effect-resolver"; -import { CHANGE_RESOLVER_TOKEN } from "../tokens"; +import { CHANGE_EFFECT_RESOLVER_TOKEN } from "../tokens"; import { ComponentConfigDependencyRegistry } from "../config"; import { ChangeEffectResolverRegistry } from "./change-effect-resolver-registry"; -import { ChangeResolveService } from "./change-effect-resolve-service"; +import { ChangeEffectResolveService } from "./change-effect-resolve-service"; import { EntityStoreChangeEffectResolver } from "./entity-store-change-effect-resolver"; import { UIStateChangeEffectResolver } from "./ui-state-change-effect-resolver"; export const changeResolverProviders: StaticProvider[] = [ - { provide: CHANGE_RESOLVER_TOKEN, useClass: StateMachineChangeEffectResolver, deps: [ComponentConfigDependencyRegistry], multi: true }, - { provide: CHANGE_RESOLVER_TOKEN, useClass: EntityStoreChangeEffectResolver, deps: [ComponentConfigDependencyRegistry], multi: true }, - { provide: CHANGE_RESOLVER_TOKEN, useClass: UIStateChangeEffectResolver, deps: [ComponentConfigDependencyRegistry], multi: true }, + { provide: CHANGE_EFFECT_RESOLVER_TOKEN, useClass: StateMachineChangeEffectResolver, deps: [ComponentConfigDependencyRegistry], multi: true }, + { provide: CHANGE_EFFECT_RESOLVER_TOKEN, useClass: EntityStoreChangeEffectResolver, deps: [ComponentConfigDependencyRegistry], multi: true }, + { provide: CHANGE_EFFECT_RESOLVER_TOKEN, useClass: UIStateChangeEffectResolver, deps: [ComponentConfigDependencyRegistry], multi: true }, { provide: ChangeEffectResolverRegistry, useClass: ChangeEffectResolverRegistry, deps: [Injector] }, - { provide: ChangeResolveService, useClass: ChangeResolveService, deps: [ChangeEffectResolverRegistry] } + { provide: ChangeEffectResolveService, useClass: ChangeEffectResolveService, deps: [ChangeEffectResolverRegistry] } ]; diff --git a/packages/renderer/src/form-engine/form-engine.ts b/packages/renderer/src/form-engine/form-engine.ts index 374660e00f0..eb50a877d46 100644 --- a/packages/renderer/src/form-engine/form-engine.ts +++ b/packages/renderer/src/form-engine/form-engine.ts @@ -1,6 +1,6 @@ import { cloneDeep, merge, mergeWith } from "lodash-es"; import { Change, ChangeObserver, ChangeObserverRegistry } from "@farris/devkit-vue"; -import { ChangeResolveService } from "../change-effect-resolver"; +import { ChangeEffectResolveService } from "../change-effect-resolver"; import { ComponentConfigResolveService } from "../component-config-resolver"; import { RenderEngineImpl } from "../render-engine"; import { FormMetadataService } from "../service"; @@ -9,7 +9,7 @@ import { Configuration } from "../config"; export class FormEngine { constructor( private changeObserverRegistry: ChangeObserverRegistry, - private changeResolveService: ChangeResolveService, + private changeResolveService: ChangeEffectResolveService, private componentConfigResolveService: ComponentConfigResolveService, private renderEngineImpl: RenderEngineImpl, private formMetadataService: FormMetadataService diff --git a/packages/renderer/src/form-engine/providers.ts b/packages/renderer/src/form-engine/providers.ts index 6a2af73cced..808462beb26 100644 --- a/packages/renderer/src/form-engine/providers.ts +++ b/packages/renderer/src/form-engine/providers.ts @@ -1,10 +1,10 @@ import { ChangeObserverRegistry, StaticProvider } from "@farris/devkit-vue"; import { FormEngine } from "./form-engine"; -import { ChangeResolveService } from "../change-effect-resolver"; +import { ChangeEffectResolveService } from "../change-effect-resolver"; import { ComponentConfigResolveService } from "../component-config-resolver"; import { RenderEngineImpl } from "../render-engine"; import { FormMetadataService } from "../service"; export const formEngineProviders: StaticProvider[] = [ - { provide: FormEngine, useClass: FormEngine, deps: [ChangeObserverRegistry ,ChangeResolveService, ComponentConfigResolveService, RenderEngineImpl, FormMetadataService] } + { provide: FormEngine, useClass: FormEngine, deps: [ChangeObserverRegistry ,ChangeEffectResolveService, ComponentConfigResolveService, RenderEngineImpl, FormMetadataService] } ]; diff --git a/packages/renderer/src/tokens.ts b/packages/renderer/src/tokens.ts index 6b23604305d..c05e8064321 100644 --- a/packages/renderer/src/tokens.ts +++ b/packages/renderer/src/tokens.ts @@ -15,5 +15,5 @@ export const CONFIG_DEPENDENCY_RESOLVER_TOKEN = new InjectionToken('@farris/component_config_resolver_token'); export const COMPONENT_CONFIG_DEPENDENCY_RESOLVER_TOKEN = new InjectionToken('@farris/component_config_dependency_resolver_token'); -export const CHANGE_RESOLVER_TOKEN = new InjectionToken[]>('@farris/change_resolver_token'); +export const CHANGE_EFFECT_RESOLVER_TOKEN = new InjectionToken[]>('@farris/change_effect_resolver_token'); export const CALLBACK_HANDLER_TOKEN = new InjectionToken('@farris/callback_handler_token'); -- Gitee From 7925ed78fa421ea43f485c81f138bd447dd50d2b Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Fri, 21 Mar 2025 17:18:07 +0800 Subject: [PATCH 081/153] =?UTF-8?q?feature:=20PC=E7=AB=AF=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=BA=93=E6=96=B0=E5=A2=9E=E8=A1=A8=E5=8D=95=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/data-services/base-data.service.ts | 8 +- .../lib/validation.service.ts | 66 ++++++++++++++- .../lib/verify-detail.service.ts | 38 +++++++++ packages/command-services/rollup.config.js | 6 -- .../scripts/commands/vite.config.cjs | 1 + packages/renderer/farris.config.mjs | 2 +- packages/renderer/package.json | 2 +- .../form/form-array-store-config-builder.ts | 63 ++++++++------ .../form/form-control-config-builder.ts | 39 ++++++--- .../form/form-store-config-builder.ts | 29 +++---- .../form/validation-rule-creator.ts | 19 +++-- .../config-builders/module-config-builder.ts | 1 + .../renderer/src/store/form-metadata-store.ts | 84 ------------------- 13 files changed, 202 insertions(+), 156 deletions(-) delete mode 100644 packages/renderer/src/store/form-metadata-store.ts diff --git a/packages/command-services/lib/data-services/base-data.service.ts b/packages/command-services/lib/data-services/base-data.service.ts index b93f7a2fc9a..48e87973a96 100644 --- a/packages/command-services/lib/data-services/base-data.service.ts +++ b/packages/command-services/lib/data-services/base-data.service.ts @@ -1,4 +1,4 @@ -import { ViewModel, Entity, EntityState, ViewModelState, EntityStore } from '@farris/devkit-vue'; +import { Module, ViewModel, Entity, EntityState, ViewModelState, EntityStore } from '@farris/devkit-vue'; import { BefRepository } from '@farris/bef-vue'; import { inject } from 'vue'; import { FormNotifyService } from '../form-notify.service'; @@ -7,6 +7,11 @@ import { FormNotifyService } from '../form-notify.service'; * 基础数据服务 */ class BaseDataService { + + /** + * 模块 + */ + protected module: Module; /** * 视图模型 */ @@ -31,6 +36,7 @@ class BaseDataService { * 构造函数 */ constructor(viewModel: ViewModel) { + this.module = viewModel.getModule(); this.viewModel = viewModel; this.repository = viewModel.repository as unknown as BefRepository; this.entityState = viewModel.entityStore as EntityStore>; diff --git a/packages/command-services/lib/validation.service.ts b/packages/command-services/lib/validation.service.ts index c15ffe13421..c9b6e88f090 100644 --- a/packages/command-services/lib/validation.service.ts +++ b/packages/command-services/lib/validation.service.ts @@ -1,22 +1,84 @@ -import { ViewModel, ViewModelState } from "@farris/devkit-vue"; +import { ViewModel, ViewModelState, FormError, FormArrayError } from "@farris/devkit-vue"; import { BaseDataService } from "./data-services/base-data.service"; +import { VerifyDetailService } from './verify-detail.service'; export class ValidationService extends BaseDataService { + + /** + * 错误提示服务 + */ + private verifyDetailService: VerifyDetailService; + + /** + * 构造函数 + */ constructor(viewModel: ViewModel) { super(viewModel); + this.verifyDetailService = this.getService(VerifyDetailService); } + /** + * 表单验证 + */ public validate() { } + + /** + * 验证当前行 + */ public validateCurrentRow() { return Promise.resolve(); } - public validateAll(){} + /** + * 验证全部 + */ + public validateAll(){ + const viewModels = this.module.getViewModels(); + let allViewModelErrors: FormArrayError = []; + viewModels.forEach((viewModel) => { + const viewModelError = this.validateByViewModel(viewModel) as FormArrayError; + if (viewModelError && Array.isArray(viewModelError)) { + allViewModelErrors = allViewModelErrors.concat(viewModelError); + } + }); + + if (allViewModelErrors.length > 0) { + this.verifyDetailService.show({}); + return Promise.reject(allViewModelErrors) + } + + return Promise.resolve(null); + } public resetValidation(){ return Promise.resolve(); } + /** + * 验证指定视图模型的表单 + */ + private validateByViewModel(viewModel: ViewModel): FormArrayError | null { + const { formStore, formArrayStore } = viewModel; + let allErrors: FormArrayError = []; + + if (formStore) { + const formKey = formStore.getKey(); + const formError = formStore.validate(); + if (formError) { + allErrors.push({formKey, formError}); + } + } + + if (formArrayStore) { + const formArrayError = formArrayStore.validate(); + if (formArrayError && Array.isArray(formArrayError)) { + allErrors = allErrors.concat(formArrayError); + } + } + + return allErrors && allErrors.length > 0 ? allErrors : null; + } + } \ No newline at end of file diff --git a/packages/command-services/lib/verify-detail.service.ts b/packages/command-services/lib/verify-detail.service.ts index 8a612176ff1..f14527839ce 100644 --- a/packages/command-services/lib/verify-detail.service.ts +++ b/packages/command-services/lib/verify-detail.service.ts @@ -1,15 +1,53 @@ import { FVerifyDetailService, VerifyDetailProps } from '@farris/ui-vue'; +/** + * 验证配置 + */ type VerifyDetailOptions = Partial; +/** + * 验证错误提示服务 + */ export class VerifyDetailService { + /** + * 显示验证信息 + */ public show(options: VerifyDetailOptions, parentElement?: HTMLElement): void { + options = this.buildOptions(); FVerifyDetailService.show(options as any, parentElement); } + /** + * 清空验证信息 + */ public clear(): void { FVerifyDetailService.clear(); } + /** + * 构造验证配置信息 + */ + public buildOptions() { + const verifyTypes = [ + { id: '1', type: 'all', title: '全部' }, + { id: '2', type: 'error', title: '错填', iconCls: 'f-icon-default', iconStyle: 'color:pink;' }, + { id: '3', type: 'empty', title: '漏填', iconStyle: 'color:pink;' }, + ]; + + const verifyList = [ + { id: '1', title: '单据信息01[销售组织]', msg: '字段值不能为空', type: 'empty' }, + { id: '2', title: '单据信息02[销售组织]', msg: '字段值不能为空', type: 'empty' }, + { id: '3', title: '单据信息03[销售组织]', msg: '字段值填写错误', type: 'error' }, + { id: '4', title: '单据信息04[销售组织]', msg: '字段值填写问题', type: 'error' }, + ]; + + const options: VerifyDetailOptions = { + showList: true, + verifyType: verifyTypes, + verifyList: verifyList, + }; + + return options; + } } diff --git a/packages/command-services/rollup.config.js b/packages/command-services/rollup.config.js index 01ed4295ff7..a0deffe32be 100644 --- a/packages/command-services/rollup.config.js +++ b/packages/command-services/rollup.config.js @@ -58,12 +58,6 @@ export default { visualizer({ template: "sunburst", filename: process.cwd() + `/dist-rollup/@farris/command-services-vue.html`, - }), - terser({ - keep_fnames: true, - format: { - comments: /^!/ - } }) ], }; diff --git a/packages/command-services/scripts/commands/vite.config.cjs b/packages/command-services/scripts/commands/vite.config.cjs index 50142d268e6..ccb5c263176 100644 --- a/packages/command-services/scripts/commands/vite.config.cjs +++ b/packages/command-services/scripts/commands/vite.config.cjs @@ -31,6 +31,7 @@ module.exports = function (options) { "@vue/shared", "dayjs", "@/components", + "@farris/ui-vue", "@farris/devkit-vue", "@farris/bef", "moment" diff --git a/packages/renderer/farris.config.mjs b/packages/renderer/farris.config.mjs index 7b27e66514b..4a7168faf5f 100644 --- a/packages/renderer/farris.config.mjs +++ b/packages/renderer/farris.config.mjs @@ -27,7 +27,7 @@ export default { } }, manifest: false, - minify: 'terser', + minify: false, terserOptions: { compress: { keep_classnames: true, diff --git a/packages/renderer/package.json b/packages/renderer/package.json index acf38ffa722..bdf6b0c83aa 100644 --- a/packages/renderer/package.json +++ b/packages/renderer/package.json @@ -21,7 +21,7 @@ "preview": "vite preview --config ./vite.config.dev.ts", "test": "jest --config jest.config.js", "vitest": "vitest", - "build:system": "farris-cli build -c ./vite.config.build.ts" + "build:system": "farris-cli build" }, "dependencies": { "@types/lodash-es": "^4.17.4", diff --git a/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts b/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts index b2f193d78c8..92dd2406adc 100644 --- a/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts +++ b/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts @@ -37,7 +37,7 @@ class FormArrayStoreConfigBuilder { * 获取表单状态配置 */ private buildStateConfig(viewModelNode: any): FormArrayStateConfig { - const vmComponentNode = this.getVmComponentNode(viewModelNode); + const vmComponentNode = this.formMetaQuery.getVmComponentByVmId(viewModelNode.id); if (!vmComponentNode) { throw new Error(`Component(viewModel=${viewModelNode.id}) not found`); } @@ -53,13 +53,13 @@ class FormArrayStoreConfigBuilder { * 构造控件配置集合 */ private buildControlConfigs(viewModelNode: any, vmComponentNode: any): FormControlConfig[] { - const wrappedControlNodes = this.collectWrappedControlNodes(vmComponentNode); - const controlConfigBuilder = new FormControlConfigBuilder(); + const columnNodes = this.collectColumnNodes(vmComponentNode); + const controlConfigBuilder = new FormControlConfigBuilder(this.formMetaQuery); const controlConfigs: FormControlConfig[] = []; - wrappedControlNodes.forEach((wrappedControlNode) => { - const controlNode = wrappedControlNode.component; - const controlConfig = controlConfigBuilder.build(viewModelNode, controlNode.editor); + columnNodes.forEach((columnNode) => { + const controlNode = columnNode; + const controlConfig = controlConfigBuilder.build(viewModelNode, controlNode); controlConfigs.push(controlConfig); }); @@ -67,7 +67,36 @@ class FormArrayStoreConfigBuilder { } /** - * 获取列表对应卡片的表单组件 + * 搜集当前VM组件下的所有输入控件 + */ + private collectColumnNodes(vmComponentNode: any): any[] { + const wrappedDataGridNode = this.getEditableDataGridNode(vmComponentNode); + if (!wrappedDataGridNode) { + return []; + } + + const columnNodes = wrappedDataGridNode.component.columns; + return columnNodes; + } + + /** + * 获取Grid组件 + */ + private getEditableDataGridNode(parentVmComponentNode: any): any { + const wrappedComponentNodes = this.formMetaQuery.getWrappedComponents(); + const wrappedDataGridNode = wrappedComponentNodes.find((wrappedComponentNode) => { + const { component, viewModelComponent } = wrappedComponentNode; + const isEditableDataGrid = component.type === 'data-grid' && component.fieldEditable === true; + const isInParentVmComponent = viewModelComponent === parentVmComponentNode; + + return isEditableDataGrid && isInParentVmComponent; + }); + + return wrappedDataGridNode; + } + + /** + * 获取列表对应卡片的组件 */ private getVmComponentNode(viewModelNode: any): any { const listVmComponentNode = this.formMetaQuery.getVmComponentByVmId(viewModelNode.id); @@ -84,26 +113,6 @@ class FormArrayStoreConfigBuilder { return cardVmComponentNode ? cardVmComponentNode : listVmComponentNode; } - - /** - * 搜集当前VM组件下的所有输入控件 - */ - private collectWrappedControlNodes(vmComponentNode: any): any[] { - const wrappedComponentNodes = this.formMetaQuery.getWrappedComponents(); - const wrappedControlNode = [] as any[]; - wrappedComponentNodes.forEach((wrappedComponentNode) => { - if (wrappedComponentNode.viewModelComponent !== vmComponentNode) { - return; - } - - const componentType = wrappedComponentNode.component.type; - if (componentType === 'form-item') { - wrappedControlNode.push(wrappedComponentNode); - } - }); - - return wrappedControlNode; - } } export { FormArrayStoreConfigBuilder }; diff --git a/packages/renderer/src/config-builders/form/form-control-config-builder.ts b/packages/renderer/src/config-builders/form/form-control-config-builder.ts index d85d8103b86..74326af1482 100644 --- a/packages/renderer/src/config-builders/form/form-control-config-builder.ts +++ b/packages/renderer/src/config-builders/form/form-control-config-builder.ts @@ -1,4 +1,5 @@ import { FormControlConfig } from '@farris/devkit-vue'; +import { FormMetadataQuery } from '../../service/form-metadata-query'; import { ValidationRuleCreator } from './validation-rule-creator'; /** @@ -6,6 +7,11 @@ import { ValidationRuleCreator } from './validation-rule-creator'; */ class FormControlConfigBuilder { + /** + * 表单元数据查询 + */ + private formMetaQuery: FormMetadataQuery; + /** * 验证规则创建器 */ @@ -14,7 +20,8 @@ class FormControlConfigBuilder { /** * 构造函数 */ - constructor() { + constructor(formMetaQuery: FormMetadataQuery) { + this.formMetaQuery = formMetaQuery; this.validationRuleCreator = new ValidationRuleCreator(); } @@ -35,27 +42,33 @@ class FormControlConfigBuilder { * 获取绑定类型 */ private getBindingType(controlNode: any): string { - const bindingType = controlNode.binding.type; - if (bindingType === 'EntityField') { + const { type } = controlNode.binding; + if (type === 'Form') { return 'EntityState'; - } else if (bindingType === 'Variable') { + } else if (type === 'Variable') { return 'UIState'; + } else { + throw new Error(`BindingType(type=${type}) unsupported`); } - - throw new Error(`BindingType(type=${bindingType}) unsupported`); } /** * 获取绑定路径 */ private getBindingPath(viewModelNode: any, controlNode: any): string { - const { bindTo } = viewModelNode; - - // Form和FormArray已经记录了实体路径,FormControl上使用相对短路径 - if (bindTo === '/') { - return controlNode.binding.path; + const { type, field, fullPath } = controlNode.binding; + if (type === 'Form') { + const { bindTo } = viewModelNode; + const wrappedFieldSchema = this.formMetaQuery.getWrappedFieldSchemaById(field); + if (bindTo === '/') { + return wrappedFieldSchema.bindingPath; + } else { + return wrappedFieldSchema.bindingPath.replace(bindTo, ''); + } + } else if (type === 'Variable') { + return `/${fullPath}`; } else { - return controlNode.binding.path.replace(bindTo, ''); + throw new Error(`BindingType(type=${type}) unsupported`); } } @@ -63,7 +76,7 @@ class FormControlConfigBuilder { * 获取绑定路径 */ private getValidationRules(controlNode: any) { - return this.validationRuleCreator.createRules(controlNode); + return this.validationRuleCreator.createRules(controlNode.editor); } } diff --git a/packages/renderer/src/config-builders/form/form-store-config-builder.ts b/packages/renderer/src/config-builders/form/form-store-config-builder.ts index cb6f53153fa..a374b27f996 100644 --- a/packages/renderer/src/config-builders/form/form-store-config-builder.ts +++ b/packages/renderer/src/config-builders/form/form-store-config-builder.ts @@ -54,13 +54,13 @@ class FormStoreConfigBuilder { * 构造控件配置集合 */ private buildControlConfigs(viewModelNode: any, vmComponentNode: any): FormControlConfig[] { - const wrappedControlNodes = this.collectWrappedControlNodes(vmComponentNode); - const controlConfigBuilder = new FormControlConfigBuilder(); + const formGroupNodes = this.collectFormGroupNodes(vmComponentNode); + const controlConfigBuilder = new FormControlConfigBuilder(this.formMetaQuery); const controlConfigs: FormControlConfig[] = []; - wrappedControlNodes.forEach((wrappedControlNode) => { - const controlNode = wrappedControlNode.component; - const controlConfig = controlConfigBuilder.build(viewModelNode, controlNode.editor); + formGroupNodes.forEach((formGroupNode) => { + const controlNode = formGroupNode; + const controlConfig = controlConfigBuilder.build(viewModelNode, controlNode); controlConfigs.push(controlConfig); }); @@ -68,23 +68,24 @@ class FormStoreConfigBuilder { } /** - * 搜集当前VM组件下的所有输入控件 + * 搜集表单控件集合 */ - private collectWrappedControlNodes(vmComponentNode: any): any[] { + public collectFormGroupNodes(parentVmComponentNode: any): any[] { const wrappedComponentNodes = this.formMetaQuery.getWrappedComponents(); - const wrappedControlNode = [] as any[]; + const formGroupNodes = [] as any[]; wrappedComponentNodes.forEach((wrappedComponentNode) => { - if (wrappedComponentNode.viewModelComponent !== vmComponentNode) { + const { component, viewModelComponent } = wrappedComponentNode; + if (viewModelComponent !== parentVmComponentNode) { return; } - - const componentType = wrappedComponentNode.component.type; - if (componentType === 'form-item') { - wrappedControlNode.push(wrappedComponentNode); + if (component.type !== 'form-group') { + return; } + + formGroupNodes.push(component); }); - return wrappedControlNode; + return formGroupNodes; } } diff --git a/packages/renderer/src/config-builders/form/validation-rule-creator.ts b/packages/renderer/src/config-builders/form/validation-rule-creator.ts index 342e9a0a595..6445eb1f669 100644 --- a/packages/renderer/src/config-builders/form/validation-rule-creator.ts +++ b/packages/renderer/src/config-builders/form/validation-rule-creator.ts @@ -72,8 +72,9 @@ class ValidationRuleCreator { if (!controlNode.maxValue) { return; } + const { maxValue } = controlNode; - return { name: 'maxValue', maxValue: controlNode.maxValue }; + return { name: 'maxValue', maxValue: maxValue }; } /** @@ -83,30 +84,33 @@ class ValidationRuleCreator { if (!controlNode.minValue) { return; } + const { minValue } = controlNode; - return { name: 'minValue', minValue: controlNode.minValue }; + return { name: 'minValue', minValue: minValue }; } /** * 最大日期 */ public maxDate(controlNode: any): MaxDateValidationRule | undefined { - if (!controlNode.maxDate) { + if (!controlNode.maxValue) { return; } + const maxDate = controlNode.maxValue; - return { name: 'maxDate', maxDate: controlNode.maxDate }; + return { name: 'maxDate', maxDate: maxDate }; } /** * 最小日期 */ public minDate(controlNode: any): MinDateValidationRule | undefined { - if (!controlNode.minDate) { + if (!controlNode.minValue) { return; } + const minDate = controlNode.minValue; - return { name: 'minDate', minDate: controlNode.minDate }; + return { name: 'minDate', minDate: minDate }; } /** @@ -116,8 +120,9 @@ class ValidationRuleCreator { if (!controlNode.formatValidation) { return; } + const { expression, message } = controlNode.formatValidation; - return { name: 'pattern', pattern: controlNode.expression }; + return { name: 'pattern', pattern: expression, message: message }; } /** diff --git a/packages/renderer/src/config-builders/module-config-builder.ts b/packages/renderer/src/config-builders/module-config-builder.ts index 35dbb6400bf..07ca309b565 100644 --- a/packages/renderer/src/config-builders/module-config-builder.ts +++ b/packages/renderer/src/config-builders/module-config-builder.ts @@ -86,6 +86,7 @@ class ModuleConfigBuilder { this.moduleConfig.id = this.formMeta.module.code; this.moduleConfig.providers = this.context.moduleProviders; + console.log(this.moduleConfig); return this.moduleConfig; } diff --git a/packages/renderer/src/store/form-metadata-store.ts b/packages/renderer/src/store/form-metadata-store.ts deleted file mode 100644 index a0a286b72b4..00000000000 --- a/packages/renderer/src/store/form-metadata-store.ts +++ /dev/null @@ -1,84 +0,0 @@ - -import { ComponentConfigResolverFactory } from "../component-config-resolver"; -import { ComponentMetadata, EntityMetadata, FormMetadata, MetadataType, ViewModelMetadata } from "../types"; - -export class FormMetadataStore { - private metadataMap: Map = new Map(); - - constructor(private metadata: FormMetadata) { - const components = this.metadata?.module?.components || []; - this.traverseComponent(components); - } - - public getModuleId(): string { - return this.metadata.module.id; - } - - public getComponents(): any[] { - return Array.from(this.metadataMap.values()).filter((item: any) => item.type === MetadataType.Component); - } - - public getMetadataById(id: string): any { - const content = this.metadataMap.get(id); - return content ? content.schema : null; - } - - public getEntity(): EntityMetadata { - return this.metadata?.module?.entity[0]?.entities[0] || {} as any; - } - - public getFrameComponent(): ComponentMetadata | null { - const { components } = this.metadata?.module || {}; - if (!components || components.length < 1) { - return null; - } - const frameComponent = components.find((component: ComponentMetadata) => component.componentType && component.componentType.toLowerCase() === 'frame'); - if (!frameComponent) { - return null; - } - return frameComponent; - } - - public getViewModels(): ViewModelMetadata[] { - const { viewmodels } = this.metadata?.module || {}; - return viewmodels; - } - - public getViewModelById(id: string) { - const { viewmodels } = this.metadata?.module || {}; - return viewmodels && viewmodels.find((viewModel) => viewModel.id === id) || null; - } - - public getMetadataByChange(change: any) { - } - - public getRelatedComponent(metadataId: string) { - let currentMetadata = this.metadataMap.get(metadataId); - while (currentMetadata.type !== 'component' && currentMetadata.parentId) { - const { parentId } = currentMetadata; - currentMetadata = this.metadataMap.get(parentId); - } - return currentMetadata.schema; - } - - // #region utility function - public traverseComponent(components: any[], parentId?: string) { - components.forEach((component) => { - if (component?.id) { - this.metadataMap.set(component.id, { - schema: component, - type: component.type, - parentId - }); - const resolver = ComponentConfigResolverFactory.getResolver(component.type); - const configs = resolver?.resolve(component); - if (configs) { - // componentConfigs.set(component.id, configs); - } - } - if (component.contents) { - this.traverseComponent(component.contents, component.id); - } - }); - } -} -- Gitee From 52d96d2aa6574b5a26d6bfce3c4a7b3315b8bbb1 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Fri, 21 Mar 2025 21:16:36 +0800 Subject: [PATCH 082/153] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=96=B0=E5=A2=9Elookup=E3=80=81search?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/cell/src/cell.component.tsx | 4 +- .../components/cell/src/cell.props.ts | 6 +- .../components/common/date/date-converter.ts | 204 ------------- .../components/common/date/use-date-format.ts | 54 ---- .../components/common/date/use-time-ago.ts | 65 ----- .../common/directive/area-response.ts | 136 --------- .../common/editor/binding-selector/style.ts | 6 - .../components/common/entity/entity-schema.ts | 274 ------------------ .../mobile-ui-vue/components/common/index.ts | 34 +-- .../common/radio-checkbox/use-check.ts | 100 ------- .../common/src/style/mixins/bem.scss | 13 +- .../components/common/src/utils/index.ts | 1 + .../utils/src}/use-appearance.ts | 0 .../common/text-box/composition/use-clear.ts | 61 ---- .../composition/use-text-box-design.ts | 96 ------ .../text-box/composition/use-text-box.ts | 181 ------------ .../components/common/utils/encrypt.ts | 246 ---------------- .../components/common/utils/resolve-field.ts | 29 -- .../components/common/utils/symbol-key.ts | 6 - .../components/common/utils/use-class.ts | 33 --- .../components/common/utils/use-guid.ts | 43 --- .../common/utils/use-request-animation.ts | 46 --- .../components/common/utils/with-install.ts | 10 - .../src/date-picker-input.props.ts | 4 +- .../src/designer-canvas.component.tsx | 2 +- packages/mobile-ui-vue/components/index.scss | 2 + packages/mobile-ui-vue/components/index.ts | 32 +- .../mobile-ui-vue/components/lookup/index.ts | 8 + .../components/content-list-nav.component.tsx | 12 + .../content-list-tree.component.tsx | 12 + .../src/components/content-list.component.tsx | 43 +++ .../components/content-search.component.tsx | 36 +++ .../components/content-selected.component.tsx | 16 + .../src/components/content.component.tsx | 58 ++++ .../src/components/footer.component.tsx | 20 ++ .../src/components/header.component.tsx | 53 ++++ .../lookup/src/composition/index.ts | 6 + .../lookup/src/composition/types.ts | 237 +++++++++++++++ .../src/composition/use-data-service.ts | 62 ++++ .../src/composition/use-load-list-data.ts | 38 +++ .../src/composition/use-load-nav-list-data.ts | 17 ++ .../src/composition/use-load-tree-data.ts | 17 ++ .../src/composition/use-lookup-panel-state.ts | 54 ++++ .../src/composition/use-lookup-state.ts | 70 +++++ .../lookup/src/composition/use-request.ts | 68 +++++ .../src/composition/use-search-service.ts | 59 ++++ .../src/composition/use-selcted-service.ts | 56 ++++ .../lookup/src/lookup-panel.component.tsx | 60 ++++ .../lookup/src/lookup.component.tsx | 48 +++ .../components/lookup/src/lookup.props.ts | 71 +++++ .../components/lookup/src/lookup.scss | 39 +++ .../picker-input/src/picker-input.props.ts | 4 +- .../components/popup/src/popup.component.tsx | 1 - .../mobile-ui-vue/components/search/index.ts | 8 + .../search/src/search.component.tsx | 75 +++++ .../src/search.props.ts} | 61 ++-- .../components/search/src/search.scss | 32 ++ packages/mobile-ui-vue/demos/lookup/basic.vue | 29 ++ packages/mobile-ui-vue/demos/lookup/http.vue | 36 +++ packages/mobile-ui-vue/demos/lookup/index.vue | 12 + packages/mobile-ui-vue/index.html | 2 +- packages/mobile-ui-vue/src/menu-data.ts | 6 + 62 files changed, 1432 insertions(+), 1682 deletions(-) delete mode 100644 packages/mobile-ui-vue/components/common/date/date-converter.ts delete mode 100644 packages/mobile-ui-vue/components/common/date/use-date-format.ts delete mode 100644 packages/mobile-ui-vue/components/common/date/use-time-ago.ts delete mode 100644 packages/mobile-ui-vue/components/common/directive/area-response.ts delete mode 100644 packages/mobile-ui-vue/components/common/editor/binding-selector/style.ts delete mode 100644 packages/mobile-ui-vue/components/common/entity/entity-schema.ts delete mode 100644 packages/mobile-ui-vue/components/common/radio-checkbox/use-check.ts rename packages/mobile-ui-vue/components/common/{utils => src/utils/src}/use-appearance.ts (100%) delete mode 100644 packages/mobile-ui-vue/components/common/text-box/composition/use-clear.ts delete mode 100644 packages/mobile-ui-vue/components/common/text-box/composition/use-text-box-design.ts delete mode 100644 packages/mobile-ui-vue/components/common/text-box/composition/use-text-box.ts delete mode 100644 packages/mobile-ui-vue/components/common/utils/encrypt.ts delete mode 100644 packages/mobile-ui-vue/components/common/utils/resolve-field.ts delete mode 100644 packages/mobile-ui-vue/components/common/utils/symbol-key.ts delete mode 100644 packages/mobile-ui-vue/components/common/utils/use-class.ts delete mode 100644 packages/mobile-ui-vue/components/common/utils/use-guid.ts delete mode 100644 packages/mobile-ui-vue/components/common/utils/use-request-animation.ts delete mode 100644 packages/mobile-ui-vue/components/common/utils/with-install.ts create mode 100644 packages/mobile-ui-vue/components/lookup/index.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/components/content-list-nav.component.tsx create mode 100644 packages/mobile-ui-vue/components/lookup/src/components/content-list-tree.component.tsx create mode 100644 packages/mobile-ui-vue/components/lookup/src/components/content-list.component.tsx create mode 100644 packages/mobile-ui-vue/components/lookup/src/components/content-search.component.tsx create mode 100644 packages/mobile-ui-vue/components/lookup/src/components/content-selected.component.tsx create mode 100644 packages/mobile-ui-vue/components/lookup/src/components/content.component.tsx create mode 100644 packages/mobile-ui-vue/components/lookup/src/components/footer.component.tsx create mode 100644 packages/mobile-ui-vue/components/lookup/src/components/header.component.tsx create mode 100644 packages/mobile-ui-vue/components/lookup/src/composition/index.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/composition/types.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/composition/use-data-service.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/composition/use-load-list-data.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/composition/use-load-nav-list-data.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/composition/use-load-tree-data.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/composition/use-lookup-panel-state.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/composition/use-lookup-state.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/composition/use-request.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/composition/use-search-service.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/composition/use-selcted-service.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/lookup-panel.component.tsx create mode 100644 packages/mobile-ui-vue/components/lookup/src/lookup.component.tsx create mode 100644 packages/mobile-ui-vue/components/lookup/src/lookup.props.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/lookup.scss create mode 100644 packages/mobile-ui-vue/components/search/index.ts create mode 100644 packages/mobile-ui-vue/components/search/src/search.component.tsx rename packages/mobile-ui-vue/components/{common/radio-checkbox/radio-checkbox.props.ts => search/src/search.props.ts} (41%) create mode 100644 packages/mobile-ui-vue/components/search/src/search.scss create mode 100644 packages/mobile-ui-vue/demos/lookup/basic.vue create mode 100644 packages/mobile-ui-vue/demos/lookup/http.vue create mode 100644 packages/mobile-ui-vue/demos/lookup/index.vue diff --git a/packages/mobile-ui-vue/components/cell/src/cell.component.tsx b/packages/mobile-ui-vue/components/cell/src/cell.component.tsx index 1921743a479..44c6c3e51a1 100644 --- a/packages/mobile-ui-vue/components/cell/src/cell.component.tsx +++ b/packages/mobile-ui-vue/components/cell/src/cell.component.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { computed, defineComponent, SetupContext } from 'vue'; +import { computed, defineComponent } from 'vue'; import { isDef, resolveAsset, useBem } from '@components/common'; import { Icon } from '@components/icon'; import { cellProps, CellProps, CELL_NAME } from './cell.props'; @@ -23,7 +23,7 @@ export default defineComponent({ name: CELL_NAME, props: cellProps, emits: ['click', 'leftIconClick', 'rightIconClick', 'extraClick'], - setup(props: CellProps, context: SetupContext) { + setup(props: CellProps, context) { const { slots, emit } = context; const getLeftIconSlot = () => resolveAsset(slots, 'leftIcon'); diff --git a/packages/mobile-ui-vue/components/cell/src/cell.props.ts b/packages/mobile-ui-vue/components/cell/src/cell.props.ts index 1b57dfa4a6f..979f6a5a86f 100644 --- a/packages/mobile-ui-vue/components/cell/src/cell.props.ts +++ b/packages/mobile-ui-vue/components/cell/src/cell.props.ts @@ -5,11 +5,11 @@ export const CELL_NAME = 'fm-cell'; export const cellProps = { type: { type: String, default: 'form' }, - title: { type: String, default: '' }, + title: { type: [String, Number], default: '' }, value: { type: [String, Number], default: '' }, - label: { type: String, default: '' }, + label: { type: [String, Number], default: '' }, valueClass: { type: String, default: '' }, @@ -37,7 +37,7 @@ export const cellProps = { rightIcon: { type: String, default: '' }, - extra: { type: String, default: '' } + extra: { type: [String, Number], default: '' } }; export type CellProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/common/date/date-converter.ts b/packages/mobile-ui-vue/components/common/date/date-converter.ts deleted file mode 100644 index d58257fe8d9..00000000000 --- a/packages/mobile-ui-vue/components/common/date/date-converter.ts +++ /dev/null @@ -1,204 +0,0 @@ - -const MONTHNAMES_LOOKUP: Record = - { jan: 1, feb: 2, mar: 3, apr: 4, may: 5, jun: 6, jul: 7, aug: 8, sep: 9, oct: 10, nov: 11, dec: 12 }; -const DAYNAMES_LOOKUP: Record = { sun: 0, mon: 1, tue: 2, wed: 3, thu: 4, fri: 5, sat: 6 }; - -export class DateConverter { - regexes: Record = { - YEAR: '[1-9]\\d{3}', - MONTH: '1[0-2]|0?[1-9]', - MONTH2: '1[0-2]|0[1-9]', - MONTHNAME: - 'jan|january|feb|february|mar|march|apr|april|may|jun|june|jul|july|aug|august|sep|september|oct|october|nov|november|dec|december', - DAYNAME: 'mon|monday|tue|tuesday|wed|wednesday|thu|thursday|fri|friday|sat|saturday|sun|sunday', - DAY: '3[01]|[12]\\d|0?[1-9]', - DAY2: '3[01]|[12]\\d|0[1-9]', - TIMEZONE: '[+-][01]\\d\\:?[0-5]\\d', - H24: '[01]\\d|2[0-3]', - MIN: '[0-5]\\d', - SEC: '[0-5]\\d', - MS: '\\d{3,}', - H12: '0?[1-9]|1[012]', - AMPM: 'am|pm', - UNIT: 'year|month|week|day|hour|minute|second|millisecond' - }; - - patterns = [ - // 2010-03-15 - ['iso_8601', this.makePattern('^(_YEAR_)-(_MONTH_)-(_DAY_)$'), '$2/$3/$1'], - - // 3-15-2010 - ['us', this.makePattern('^(_MONTH_)([\\/-])(_DAY_)\\2(_YEAR_)$'), '$1/$3/$4'], - - // 15.03.2010 - ['world', this.makePattern('^(_DAY_)([\\/\\.])(_MONTH_)\\2(_YEAR_)$'), '$3/$1/$4'], - - // 15-Mar-2010, 8 Dec 2011, "Thu, 8 Dec 2011" - ['chicago', this.makePattern('^(?:(?:_DAYNAME_),? )?(_DAY_)([ -])(_MONTHNAME_)\\2(_YEAR_)$'), '$3 $1, $4'], - - // "March 4, 2012", "Mar 4 2012", "Sun Mar 4 2012" - ['conversational', this.makePattern('^(?:(?:_DAYNAME_),? )?(_MONTHNAME_) (_DAY_),? (_YEAR_)$'), '$1 $2, $3'], - - // Tue Jun 22 17:47:27 +0000 2010 - [ - 'month_day_time_year', - this.makePattern('^(?:_DAYNAME_) (_MONTHNAME_) (_DAY_) ((?:_H24_)\\:(?:_MIN_)(?:\\:_SEC_)?) (_TIMEZONE_) (_YEAR_)$'), - (dateInfoList: Array) => { - const month = (''+this.getMonthByName(dateInfoList[1])).padStart(2, '0'); - const day = (''+dateInfoList[2]).padStart(2, '0'); - const year = dateInfoList[5]; - const time = dateInfoList[3]; - const timezone = dateInfoList[4]; - const date: any = year + '-' + month + '-' + day + 'T' + time + timezone; - if (isNaN(date)) { - return false; - } - return date; - } - ], - - // @123456789 - [ - 'unix', - /^@(-?\d+)$/, - (match: Array) => { - return this.create(parseInt(match[1], 10) * 1000); - } - ], - - // 24-hour time (This will help catch Date objects that are casted to a string) - [ - '24_hour', - this.makePattern('^(?:(.+?)(?: |T))?(_H24_)\\:(_MIN_)(?:\\:(_SEC_)(?:\\.(_MS_))?)? ?(?:GMT)?(_TIMEZONE_)?(?: \\([A-Z]+\\))?$'), - (match: Array) => { - let date: any; - const datePart = match[1]; - if (datePart) { - date = this.create(datePart); - if (isNaN(date)) { - return false; - } - } else { - date = new Date(); - date.setMilliseconds(0); - } - const hour = match[2]; - const minute = match[3]; - const second = match[4]; - const milliseconds = match[5]; - (date as Date).setHours(parseFloat(hour), parseFloat(minute), parseFloat(second || 0)); - - if (milliseconds) { - (date as Date).setMilliseconds(+String(milliseconds).slice(0, 3)); - } - - return date; - } - ], - - // 12-hour time - [ - '12_hour', - this.makePattern('^(?:(.+) )?(_H12_)(?:\\:(_MIN_)(?:\\:(_SEC_))?)? ?(_AMPM_)$'), - (match: Array) => { - let date: any; - const datePart = match[1]; - if (datePart) { - date = this.create(datePart); - if (isNaN(date)) { - return false; - } - } else { - date = new Date(); - date.setMilliseconds(0); - } - let hour = parseFloat(match[2]); - hour = match[5].toLowerCase() === 'am' ? (hour === 12 ? 0 : hour) : hour === 12 ? 12 : hour + 12; - const minute = match[3]; - const second = match[4]; - date.setHours(hour, parseFloat(minute || 0), parseFloat(second || 0)); - return date; - } - ] - ]; - - makePattern(code: string) { - code = code.replace(/_([A-Z][A-Z0-9]+)_/g, ($0, $1) => { - return this.regexes[$1]; - }); - return new RegExp(code, 'i'); - } - - getMonthByName(monthname: string) { - return MONTHNAMES_LOOKUP[String(monthname).slice(0, 3).toLowerCase()]; - } - - getWeekdayByName(dayname: string) { - return DAYNAMES_LOOKUP[String(dayname).slice(0, 3).toLowerCase()]; - } - - private parse(date: number|string) { - // If the passed value is an integer, interpret it as ms past epoch - if (!isNaN(Number(date))) { - return new Date(date); - } - - // trim the date - date = String(date).replace(/^\s*(.*)\s*$/, '$1'); - // normalize whitespace - date = date.replace(/\s{2,}/g, ' '); - if (date === '') { - return Date.now(); - } - - let i = 0; - // try each of our patterns - while(i < this.patterns.length) { - const pattern = this.patterns[i]; - let callback; - let regex: string| RegExp; - if (typeof pattern[0] == 'string') { - // pattern[0] is the name of the pattern - regex = pattern[1] as RegExp; - callback = pattern[2]; - } else { - // backwards compatibility with version 3.1 - regex = pattern[0] as RegExp; - callback = pattern[1]; - } - const match = date.match(regex); - if (!match) { - i++; - continue; - } - - if (typeof callback == 'function') { - const result = callback(match); - if (result instanceof Date) { - return result; - } - } else { - // fn is not a function but a string replace command - const milliseconds = Date.parse(date.replace(regex, callback as string)); - if (!isNaN(milliseconds)) { - return new Date(milliseconds); - } - } - i++; - } - return NaN; - } - - create(date?: Date | string | number) { - // 0 arguments or date is undefined - if (date == null) { - return Date.now(); - } - // If the passed value is already a date object, return it - if (date instanceof Date) { - return date; - } - - return this.parse(date); - } -} diff --git a/packages/mobile-ui-vue/components/common/date/use-date-format.ts b/packages/mobile-ui-vue/components/common/date/use-date-format.ts deleted file mode 100644 index 05a937d8616..00000000000 --- a/packages/mobile-ui-vue/components/common/date/use-date-format.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* eslint-disable eqeqeq */ -import { format, isValid, parseISO } from "date-fns"; - -import { UseDateFormat } from "../types"; -import { DateConverter } from "./date-converter"; - -export function useDateFormat(): UseDateFormat { - - const dateConverter = new DateConverter(); - - function formatTo(dateValue: string | Date, dateFormat: string): string { - if (!dateValue) { - return ""; - } - - if (typeof dateValue === "string" && dateValue.indexOf("0001") === 0) { - return ""; - } - - if (dateValue instanceof Date) { - return format(dateValue, dateFormat); - } - - let dateObject: any = parseISO(dateValue); - - if (dateObject == "Invalid Date") { - dateObject = dateConverter.create(dateValue) || new Date(dateValue); - } - - // const d = parseISO(value); - if (isValid(dateObject)) { - dateObject = parseISO(format(dateObject, "yyyy-MM-dd HH:mm:ss")); - return format(dateObject, dateFormat); - } - if (dateFormat.indexOf("HH") === 0 || dateFormat.indexOf("hh") === 0) { - // 仅有时间部分 - // 提取时间 - const _time = dateValue.match(/\d*/g)?.filter((n) => n !== "").join(":"); - - if (dateFormat === "HH" || dateFormat === "hh") { - dateFormat += ":mm"; - } - - const fullDateTime = parseISO("2024-06-05 " + _time); - return format(fullDateTime, dateFormat); - } - return ""; - - } - - return { - formatTo - }; -} diff --git a/packages/mobile-ui-vue/components/common/date/use-time-ago.ts b/packages/mobile-ui-vue/components/common/date/use-time-ago.ts deleted file mode 100644 index cc251eb044d..00000000000 --- a/packages/mobile-ui-vue/components/common/date/use-time-ago.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { TimeAgoDate, TimeAgoOptions, UseTimeAgoFormat } from "../types"; -import { DateConverter } from "./date-converter"; - -const TEXTZH_CN = ['秒', '分钟', '小时', '天', '周', '个月', '年']; - -const SECONDS_ARRAY = [ - 60, // 60 seconds in 1 min - 60, // 60 mins in 1 hour - 24, // 24 hours in 1 day - 7, // 7 days in 1 week - 365 / 7 / 12, // 4.345238095238096 weeks in 1 month - 12, // 12 months in 1 year -]; - -export function useTimeAgo(): UseTimeAgoFormat { - - const dateConverter = new DateConverter(); - - - function timeAgoText(second: number, index: number): [string, string] { - if (index === 0) {return ['刚刚', '片刻后'];} - const unit = TEXTZH_CN[~~(index / 2)]; - return [`${second} ${unit}前`, `${second} ${unit}后`]; - } - - function toDate(date: TimeAgoDate): Date { - if (typeof date == 'object') { - return date; - } else { - const result = dateConverter.create(date); - return typeof result == 'object' ? result : new Date(); - } - - } - function secondDifference(date: TimeAgoDate, relativeDate: TimeAgoDate | undefined): number { - const relDate = relativeDate ? toDate(relativeDate) : new Date(); - return (+relDate - +toDate(date)) / 1000; - } - - - function formatDifferent(second: number): string { - const agoIn = second < 0 ? 1 : 0; - second = Math.abs(second); - // const totalSec = diff; - let index = 0; - for (; second >= SECONDS_ARRAY[index] && index < SECONDS_ARRAY.length; index++) { - second /= SECONDS_ARRAY[index]; - } - second = Math.floor(second); - - index *= 2; - - if (second > (index === 0 ? 9 : 1)) {index += 1;} - - return timeAgoText(second, index)[agoIn].replace('%s', second.toString()); - } - function formatTo(date: TimeAgoDate, options?: TimeAgoOptions): string { - // 计算差异秒 - const second = secondDifference(date, options && options.relativeDate); - return formatDifferent(second); - }; - return { - formatTo - }; -} diff --git a/packages/mobile-ui-vue/components/common/directive/area-response.ts b/packages/mobile-ui-vue/components/common/directive/area-response.ts deleted file mode 100644 index c3cf63e64cd..00000000000 --- a/packages/mobile-ui-vue/components/common/directive/area-response.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { addClass, removeClass } from "../utils/use-class"; - -const breakPoints = [ - { size: 'sm', width: 576 }, - { size: 'md', width: 768 }, - { size: 'lg', width: 888 }, - { size: 'xl', width: 1200 }, - { size: 'el', width: 1690 } -]; - -/** - * 移除绑定 - * @param sharedObject - */ -function deleteObserver(sharedObject) { - if (sharedObject.resizeObserver) { - sharedObject.resizeObserver.disconnect(); - sharedObject.sharedObject = null; - } -} -/** - * 宽度变更后,执行事件 - * @param sharedObject - * @param bindElement - * @param newWidth - * @returns - */ -function afterWidthChange(sharedObject, bindElement, newWidth = 0) { - const result = [] as any; - if (!bindElement) { - return; - } - const areaWidth = newWidth ? newWidth : bindElement.getBoundingClientRect().width; - const width = parseFloat(areaWidth); - for (let k = 0; k < breakPoints.length; k++) { - if (breakPoints[k]['width'] <= width) { - result.push(breakPoints[k]['size']); - } - } - if (sharedObject.className.join(',') !== result.join(',')) { - // 旧的比新的多,应该移除class - const distance = sharedObject.className.length - result.length; - if (distance > 0) { - for (let m = result.length; m < sharedObject.className.length; m++) { - removeClass(bindElement, 'f-area-response--' + sharedObject.className[m]); - } - } else { - for (let m = sharedObject.className.length; m < result.length; m++) { - addClass(bindElement, 'f-area-response--' + result[m]); - } - } - sharedObject.className = [...result]; - } -} - -/** - * 绑定监听宽度变化事件 - * @param sharedObject - * @param bindElement - */ -function bindObserver(sharedObject, bindElement) { - if (sharedObject.enable && sharedObject.autoWidth) { - if (!sharedObject.resizeObserver) { - sharedObject.resizeObserver = new ResizeObserver(entries => { - if (!entries || entries.length < 1 || !entries[0].contentRect) { - return; - } - const rect = entries[0].contentRect; - if (Math.abs(parseInt(rect.width + '') - sharedObject.width) > sharedObject.threshold) { - afterWidthChange(sharedObject, bindElement, rect.width); - sharedObject.width = parseInt(rect.width + ''); - } - }); - sharedObject.resizeObserver.observe(bindElement); - } - } else { - deleteObserver(sharedObject); - } -} - -function supportResponse(sharedObject, bindElement) { - // 启用响应 - if (sharedObject.enable) { - addClass(bindElement, 'f-area-response'); - afterWidthChange(sharedObject, bindElement); - } else { - // 移除对应的样式 - removeClass(bindElement, 'f-area-response'); - for (let m = sharedObject.className.length; m > 0; m--) { - addClass(bindElement, 'f-area-response--' + sharedObject.className[m]); - } - sharedObject.className = []; - } - bindObserver(sharedObject, bindElement); -} -function updateSharedObject(sharedObject, binding) { - if (binding.value && Object.prototype.hasOwnProperty.call(binding.value, 'enable')) { - sharedObject.enable = binding.value.enable; - } - if (binding.value && Object.prototype.hasOwnProperty.call(binding.value, 'autoWidth')) { - sharedObject.autoWidth = binding.value.autoWidth; - } -} - -/** - * enable:启用 - * autoWidth:自动宽度 - */ -const areaResponseDirective = { - // 在绑定元素的父组件 - // 及他自己的所有子节点都挂载完成后调用 - mounted: (bindElement, binding, vnode) => { - vnode.sharedObject = { - className: [], - resizeObserver: null, - enable: true, - autoWidth: true, - threshold: 10, - width: 0 - }; - updateSharedObject(vnode.sharedObject, binding); - supportResponse(vnode.sharedObject, bindElement); - }, - // 在绑定元素的父组件 - // 及他自己的所有子节点都更新后调用 - updated: function (bindElement, binding, vnode, prevVnode) { - vnode.sharedObject = prevVnode.sharedObject; - updateSharedObject(vnode.sharedObject, binding); - supportResponse(vnode.sharedObject, bindElement); - }, - // 绑定元素的父组件卸载前调用 - beforeUnmount(bindElement, binding, vnode) { - deleteObserver(vnode.sharedObject); - } -}; -export default areaResponseDirective; diff --git a/packages/mobile-ui-vue/components/common/editor/binding-selector/style.ts b/packages/mobile-ui-vue/components/common/editor/binding-selector/style.ts deleted file mode 100644 index 9ca3d1dda47..00000000000 --- a/packages/mobile-ui-vue/components/common/editor/binding-selector/style.ts +++ /dev/null @@ -1,6 +0,0 @@ -import "@/components/dependent-base/style"; -import "@/components/dependent-icon/style"; -import "@/components/tree-grid/style"; -import "@/components/button-edit/style"; -import "@/components/radio/style"; -import "@/components/modal/style"; diff --git a/packages/mobile-ui-vue/components/common/entity/entity-schema.ts b/packages/mobile-ui-vue/components/common/entity/entity-schema.ts deleted file mode 100644 index 30e62037ec6..00000000000 --- a/packages/mobile-ui-vue/components/common/entity/entity-schema.ts +++ /dev/null @@ -1,274 +0,0 @@ -/* eslint-disable no-use-before-define */ -export interface FormSchema { - sourceUri: string; - id: string; - code: string; - name: string; - entities: FormSchemaEntity[]; - variables: FormSchemaEntityField[]; - eapiId: string; - extendProperties: { enableStdTimeFormat: boolean }; - eapiCode?: string; - eapiName?: string; - eapiNameSpace?: string; - voPath?: string; - voNameSpace?: string; -} - -/** - * 实体 - */ -export interface FormSchemaEntity { - id: string; - code: string; - name: string; - label: string; - type: FormSchemaEntityType; -} - -/** - * 字段类型枚举 - */ -export enum FormSchemaEntityField$Type { - /** - * 简单类型字段 - */ - SimpleField = "SimpleField", - /** - * 关联/UDT类型字段 - */ - ComplexField = "ComplexField" -} -/** - * 字段编辑器对象 - */ -export interface FormSchemaEntityFieldEditor { - $type: string; - [propName: string]: any; -} -export interface DesignViewModelField extends FormSchemaEntityField { - valueChanging: string; - valueChanged: string; - groupId: string; - groupName: string; - isSchemaRemoved?: boolean; - updateOn?: string; -} -/** - * 字段 - */ -export interface FormSchemaEntityField { - $type: FormSchemaEntityField$Type; - id: string; - originalId: string; - code: string; - label: string; - bindingField: string; - name: string; - defaultValue?: any; - require?: boolean; - readonly?: boolean; - type: FormSchemaEntityFieldType; - editor?: FormSchemaEntityFieldEditor; - path?: string; - bindingPath?: string; - multiLanguage?: boolean; - expression?: any; -} -/** - * 字段类型对象中的类型枚举 - */ -export enum FormSchemaEntityFieldType$Type { - /** - * 字符串 - */ - StringType = "StringType", - /** - * 备注 - */ - TextType = "TextType", - /** - * 数字(整数、浮点数) - */ - NumericType = "NumericType", - /** - * 布尔 - */ - BooleanType = "BooleanType", - /** - * 日期 - */ - DateType = "DateType", - /** - * 日期时间 - */ - DateTimeType = "DateTimeType", - /** - * 枚举 - */ - EnumType = "EnumType", - /** - * 实体类 - */ - EntityType = "EntityType", - /** - * 分级码 - */ - HierarchyType = "HierarchyType", - /** - * 对象 - */ - ObjectType = "ObjectType", - /** - * 数字(大数据) - */ - BigNumericType = "BigNumericType" -} -/** - * 字段类型中的名称 - */ -export enum FormSchemaEntityFieldTypeName { - /** - * 简单类型字段 - */ - String = "String", - /** - * 日期时间 - */ - DateTime = "DateTime", - /** - * 日期 - */ - Date = "Date", - /** - * 枚举 - */ - Enum = "Enum", - /** - * 布尔 - */ - Boolean = "Boolean", - /** - * 数字 - */ - Number = "Number", - /** - * 备注 - */ - Text = "Text", - /** - * 大数字 - */ - BigNumber = "BigNumber" - /** - * 人员 - */ -} -/** - * 枚举类型 - */ -export interface EnumData { - value: string; - name: string; -} -/** - * 实体 - */ -export interface FormSchemaEntity { - id: string; - code: string; - name: string; - label: string; - type: FormSchemaEntityType; -} -/** - * 实体类型对象 - */ -export interface FormSchemaEntityType { - $type: string; - name: string; - primary: string; - fields: FormSchemaEntityField[]; - entities?: FormSchemaEntity[]; - displayName?: string; -} -/** - * 字段类型对象 - */ -export interface FormSchemaEntityFieldType { - $type: FormSchemaEntityFieldType$Type; - name: FormSchemaEntityFieldTypeName | any; - length?: number; - precision?: number; - valueType?: FormSchemaEntityFieldType; - enumValues?: EnumData[]; - fields?: FormSchemaEntityField[]; - displayName?: string; - primary?: string; - entities?: FormSchemaEntity[]; - elementType?: GSPElementDataType; - extendProperty?: any; -} -/** - * 字段数据类型 - */ -export enum GSPElementDataType { - /** - * 文本 - */ - String = "String", - /** - * 备注 - */ - Text = "Text", - /** - * 整数 - */ - Integer = "Integer", - /** - * 浮点数 - */ - Decimal = "Decimal", - /** - * 布尔型 - */ - Boolean = "Boolean", - /** - * 日期型 - */ - Date = "Date", - /** - * 日期时间型 - */ - DateTime = "DateTime", - /** - * 二进制 - */ - Binary = "Binary" -} -/** - * dom Json ViewModel 节点中states实体 - */ -export interface FormVariable { - id: string; - code: string; - name: string; - value?: any; - type: string; - category: string; - fields?: any[]; - defaultValue?: any; -} -/** - * 表单变量 - */ -export interface DesignFormVariable extends FormVariable { - /** - * 分组ID - */ - groupId: string; - /** - * 分组名称 - */ - groupName: string; -} diff --git a/packages/mobile-ui-vue/components/common/index.ts b/packages/mobile-ui-vue/components/common/index.ts index 47057c50b22..c6917cafadc 100644 --- a/packages/mobile-ui-vue/components/common/index.ts +++ b/packages/mobile-ui-vue/components/common/index.ts @@ -1,36 +1,6 @@ -import { App } from 'vue'; -import areaResponseDirective from './directive/area-response'; - export * from './src/compositions'; -export * from './types'; -export * from './text-box/composition/use-text-box'; -export * from './text-box/composition/use-text-box-design'; -export * from './text-box/composition/use-clear'; -export * from './date/date-converter'; -export * from './date/use-date-format'; -export * from './date/use-time-ago'; -export * from './utils/use-request-animation'; -export * from './utils/use-appearance'; -export * from './utils/symbol-key'; -export * from './radio-checkbox/use-check'; -export * from './radio-checkbox/radio-checkbox.props'; -export * from './utils/encrypt'; -export * from './utils/resolve-field'; -export * from './utils/use-guid'; -export * from './entity/entity-schema'; export * from './src/utils'; -export const FM_UI_PROVIDER_SERVICE_TOKEN = Symbol('UIProviderService'); +export * from './types'; -export default { - install(app: App): void { - app.directive('area-response', areaResponseDirective); - }, - register(componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record): void { - componentMap['area-response'] = areaResponseDirective; - }, - registerDesigner(componentMap: Record, propsResolverMap: Record): void { - componentMap['area-response'] = areaResponseDirective; - } -}; +export const FM_UI_PROVIDER_SERVICE_TOKEN = Symbol('UIProviderService'); diff --git a/packages/mobile-ui-vue/components/common/radio-checkbox/use-check.ts b/packages/mobile-ui-vue/components/common/radio-checkbox/use-check.ts deleted file mode 100644 index 0c67b4d7e26..00000000000 --- a/packages/mobile-ui-vue/components/common/radio-checkbox/use-check.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { computed, ref, SetupContext, watch } from 'vue'; -import { isUndefined } from 'lodash-es'; -import { CheckBoxProps, CheckboxGroupProps } from '@/components/checkbox'; -import { RadioProps, RadioGroupProps } from '@/components/radio-group'; - -export function useCheck( - props: CheckBoxProps | RadioProps, - context: SetupContext, - parentProps: CheckboxGroupProps | RadioGroupProps, - parentContext: SetupContext, -) { - // name,如果相同,可以作为一组 - const name = computed(() => parentProps?.name); - // 禁用 - const disabled = computed(() => props.readonly || props.disabled || parentProps?.readonly || parentProps?.disabled); - // 展示按钮样式 - const shouldRenderButton = computed(() => parentProps?.type === 'button'); - // 展示原生单选框或者复选框 - const shouldRenderNative = computed(() => parentProps?.type === 'default' || isUndefined(parentProps?.type)); - - // 如果是group - const checked = computed(() => parentProps ? - parentProps.modelValue === props.value || parentProps.modelValue.includes(props.value) : - !!props.checked || !!props.modelValue); - - // 按钮样式 - const buttonClass = computed(() => { - return { - btn: true, - 'f-radio-button': true, - active: checked.value, - 'f-radio-button-primary': true, - }; - }); - - - const modelValue = ref(props.modelValue); - const indeterminate = ref(props.indeterminate); - watch(() => props.modelValue, (newValue: boolean) => { - modelValue.value = newValue; - }); - watch(() => props.indeterminate, (newValue: boolean) => { - indeterminate.value = newValue; - }); - - // 点击单选框事件 - const onClickRadio = (e: MouseEvent) => { - e.stopPropagation(); - if (disabled.value) { - return; - } - if (parentProps) { - // 父组件双向绑定 - if (!checked.value) { - parentContext.emit('update:modelValue', props.value); - // 值变化事件 - parentContext.emit('changeValue', props.value); - } - } else { - context.emit('update:checked', !checked.value); - } - }; - - // 点击复选框事件 - const onClickCheckBox = (e: MouseEvent) => { - e.stopPropagation(); - if (disabled.value) { - return; - } - if (parentProps) { - // 父组件双向绑定 - if (!checked.value) { - parentContext.emit('update:modelValue', [...parentProps.modelValue, props.value]); - // 值变化事件 - parentContext.emit('changeValue', [...parentProps.modelValue, props.value]); - } else { - const valuesWithoutSelf = parentProps.modelValue?.filter(value => value !== props.value); - parentContext.emit('update:modelValue', valuesWithoutSelf); - // 值变化事件 - parentContext.emit('changeValue', valuesWithoutSelf); - } - } else { - context.emit('update:checked', !checked.value); - context.emit('update:modelValue', !checked.value); - context.emit('changeValue', !checked.value); - context.emit('change', { originalEvent: e, checked: !checked.value }); - } - }; - return { - disabled, - name, - indeterminate, - shouldRenderButton, - shouldRenderNative, - buttonClass, - checked, - onClickRadio, - onClickCheckBox - }; -} diff --git a/packages/mobile-ui-vue/components/common/src/style/mixins/bem.scss b/packages/mobile-ui-vue/components/common/src/style/mixins/bem.scss index 3634e40ef02..1e7a5ced1fd 100644 --- a/packages/mobile-ui-vue/components/common/src/style/mixins/bem.scss +++ b/packages/mobile-ui-vue/components/common/src/style/mixins/bem.scss @@ -86,7 +86,7 @@ $state-prefix: 'is-'; */ @mixin b($block) { - $B: $namespace+'-' +$block !global; + $B: #{$namespace + '-' + $block} !global; .#{$B} { @content; @@ -108,13 +108,20 @@ $state-prefix: 'is-'; } */ -@mixin e($element) { +@mixin e($element, $parent: null) { $E: $element !global; $selector: &; $currentSelector: ""; + $insertSelector: ""; + + @if($parent){ + @each $unit in $parent { + $insertSelector: #{$insertSelector + $unit + $element-separator}; + } + } @each $unit in $element { - $currentSelector: #{$currentSelector + "." + $B + $element-separator + $unit + ","}; + $currentSelector: #{$currentSelector + "." + $B + $element-separator + $insertSelector + $unit + ","}; } @if hitAllSpecialNestRule($selector) { diff --git a/packages/mobile-ui-vue/components/common/src/utils/index.ts b/packages/mobile-ui-vue/components/common/src/utils/index.ts index 49433925d86..fdea8007927 100644 --- a/packages/mobile-ui-vue/components/common/src/utils/index.ts +++ b/packages/mobile-ui-vue/components/common/src/utils/index.ts @@ -9,3 +9,4 @@ export * from './src/type'; export * from './src/with-install'; export * from './src/date'; export * from './src/string'; +export * from './src/use-appearance'; diff --git a/packages/mobile-ui-vue/components/common/utils/use-appearance.ts b/packages/mobile-ui-vue/components/common/src/utils/src/use-appearance.ts similarity index 100% rename from packages/mobile-ui-vue/components/common/utils/use-appearance.ts rename to packages/mobile-ui-vue/components/common/src/utils/src/use-appearance.ts diff --git a/packages/mobile-ui-vue/components/common/text-box/composition/use-clear.ts b/packages/mobile-ui-vue/components/common/text-box/composition/use-clear.ts deleted file mode 100644 index 74957c969a7..00000000000 --- a/packages/mobile-ui-vue/components/common/text-box/composition/use-clear.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Ref, SetupContext, WatchSource, computed, ref, watch } from "vue"; -import { TextBoxProps, UseClear, UseTextBox } from "../../types"; - -export function useClear( - props: TextBoxProps, - context: SetupContext, - useTextBoxComposition: UseTextBox -): UseClear { - const hasShownClearButton = ref(false); - const shouldShowClearButton = computed(() => props.enableClear && !props.readonly && !props.disabled); - const { changeTextBoxValue, displayText, hasFocused, isEmpty } = useTextBoxComposition; - - function toggleClearIcon(isShow: boolean) { - hasShownClearButton.value = isShow; - } - - watch(displayText as WatchSource, () => { - if (hasFocused?.value) { - toggleClearIcon(!!displayText?.value); - } else { - toggleClearIcon(false); - } - }); - - const clearButtonClass = computed(() => ({ - 'input-group-text': true, - 'input-group-clear': true - })); - - const clearButtonStyle = computed(() => { - const styleObject = { - width: '24px', - display: hasShownClearButton.value ? 'flex' : 'none' - } as Record; - return styleObject; - }); - - /** 清空输入框中的值 */ - function onClearValue($event: MouseEvent) { - $event.stopPropagation(); - if (shouldShowClearButton.value) { - changeTextBoxValue('', true); - toggleClearIcon(!hasShownClearButton.value); - context.emit('clear'); - } - } - - function onMouseEnter(event: MouseEvent) { - if (shouldShowClearButton.value && !isEmpty.value) { - toggleClearIcon(true); - } - } - - function onMouseLeave(event: MouseEvent) { - if (shouldShowClearButton.value) { - toggleClearIcon(false); - } - } - - return { clearButtonClass, clearButtonStyle, hasShownClearButton, onClearValue, onMouseEnter, onMouseLeave, shouldShowClearButton }; -} diff --git a/packages/mobile-ui-vue/components/common/text-box/composition/use-text-box-design.ts b/packages/mobile-ui-vue/components/common/text-box/composition/use-text-box-design.ts deleted file mode 100644 index b4957d96db9..00000000000 --- a/packages/mobile-ui-vue/components/common/text-box/composition/use-text-box-design.ts +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { computed, ref, Ref, SetupContext, watch } from 'vue'; -import { TextBoxProps, UseTextBox } from '../../types'; - -export function useTextBoxDesign( - props: TextBoxProps, - context: SetupContext, - modelValue: Ref, - displayText: Ref -): UseTextBox { - const disabled = ref(props.disabled); - const focusStatus = ref(false); - const inputType = ref('text'); - const showBorder = ref(props.showBorder); - const textAlign = ref(props.textAlign); - - const canFocus = computed(() => props.editable || !props.readonly); - const editable = computed(() => props.editable && !props.disabled && !props.readonly); - const hasFocused = computed(() => !props.disabled && focusStatus.value); - const isEmpty = computed(() => modelValue.value === '' || modelValue.value === null || modelValue.value === undefined); - const placeholder = computed(() => (props.placeholder)); - const readonly = computed(() => props.readonly || !props.editable); - const textBoxTitle = computed(() => (props.enableTitle ? modelValue.value : '')); - - const textBoxClass = computed(() => ({ - 'form-control': true, - // 'f-utils-fill': true, - 'text-left': textAlign.value === 'left', - 'text-center': textAlign.value === 'center', - 'text-right': textAlign.value === 'right', - })); - - const inputGroupClass = computed(() => { - const classObject = { - 'f-cmp-inputgroup': true, - 'input-group': true, - 'f-state-disabled': true, - 'f-state-editable': false, - 'f-state-readonly': true, - // 'f-state-focus': hasFocused.value - }; - // const customClassArray = (props.customClass || '').split(' '); - // customClassArray.reduce>((classObject, classString) => { - // classObject[classString] = true; - // return classObject; - // }, classObject); - return classObject; - }); - - const inputGroupStyle = computed(() => { - return !showBorder.value ? 'border-width : 0 ' : ''; - }); - - function changeTextBoxValue(newValue: string, shouldEmitChangeEvent = true) { - } - - - return { - changeTextBoxValue, - disabled, - displayText, - editable, - hasFocused, - inputGroupClass, - inputType, - isEmpty, - modelValue, - readonly, - // onBlur, - // onClick, - // onFocus, - // onInput, - // onKeydown, - // onKeyup, - // onMousedown, - // onTextBoxValueChange, - placeholder, - textBoxClass, - textBoxTitle, - inputGroupStyle - }; -} diff --git a/packages/mobile-ui-vue/components/common/text-box/composition/use-text-box.ts b/packages/mobile-ui-vue/components/common/text-box/composition/use-text-box.ts deleted file mode 100644 index 572b66def91..00000000000 --- a/packages/mobile-ui-vue/components/common/text-box/composition/use-text-box.ts +++ /dev/null @@ -1,181 +0,0 @@ -/** - * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { computed, ref, Ref, SetupContext, watch } from 'vue'; -import { TextBoxProps, UseTextBox } from '../../types'; - -export function useTextBox( - props: TextBoxProps, - context: SetupContext, - modelValue: Ref, - displayText: Ref -): UseTextBox { - const disabled = ref(props.disabled); - const focusStatus = ref(false); - const inputType = ref('text'); - const showBorder = ref(props.showBorder); - const textAlign = ref(props.textAlign); - const updateOn = ref(props.updateOn); - - const canFocus = computed(() => props.editable || !props.readonly); - const editable = computed(() => props.editable && !props.disabled && !props.readonly); - const hasFocused = computed(() => !props.disabled && focusStatus.value); - const isEmpty = computed(() => modelValue.value === '' || modelValue.value === null || modelValue.value === undefined); - const placeholder = computed(() => ((props.disabled || props.readonly) && !props.forcePlaceholder ? '' : props.placeholder)); - const readonly = computed(() => props.readonly || !props.editable); - const textBoxTitle = computed(() => (props.enableTitle ? modelValue.value : '')); - - const textBoxClass = computed(() => ({ - 'form-control': true, - 'f-utils-fill': true, - 'text-left': textAlign.value === 'left', - 'text-center': textAlign.value === 'center', - 'text-right': textAlign.value === 'right', - })); - - const inputGroupClass = computed(() => { - const classObject = { - 'f-cmp-inputgroup': true, - 'input-group': true, - 'f-state-disabled': disabled.value, - 'f-state-editable': editable.value, - 'f-state-readonly': readonly.value, - 'f-state-focus': hasFocused.value - }; - const customClassArray = (props.customClass || '').split(' '); - customClassArray.reduce>((classObject, classString) => { - classObject[classString] = true; - return classObject; - }, classObject); - return classObject; - }); - - const inputGroupStyle = computed(() => { - return !showBorder.value ? 'border-width : 0 ' : ''; - }); - - function changeTextBoxValue(newValue: string, shouldEmitChangeEvent = true) { - // if (modelValue.value !== newValue) { - modelValue.value = newValue; - if (displayText.value !== newValue) { - displayText.value = newValue; - } - if (shouldEmitChangeEvent) { - context.emit('change', newValue); - } - context.emit('update:modelValue', newValue); - context.emit('update:value', newValue); - // } - } - - watch( - () => props.modelValue, - (newValue: string, oldValue: string) => { - if (newValue !== oldValue) { - modelValue.value = newValue; - displayText.value = newValue; - } - } - ); - - watch(() => props.disabled, (newValue, oldValue) => { - if (newValue !== oldValue) { - disabled.value = newValue; - } - }); - - function onBlur(payload: FocusEvent) { - focusStatus.value = false; - context.emit('blur', payload); - payload.stopPropagation(); - return false; - } - - function onClick(payload: MouseEvent) { - context.emit('click', payload); - } - - function onFocus(payload: FocusEvent) { - if (props.disabled) { - return; - } - if (showBorder.value) { - focusStatus.value = true; - } - if (canFocus.value) { - context.emit('focus', payload); - - } - } - - function onInput(payload: Event) { - context.emit('input', (payload.target as HTMLInputElement).value); - const newValue = (payload.target as HTMLInputElement).value; - displayText.value = newValue; - if (updateOn.value === 'change') { - context.emit('update:modelValue', newValue); - context.emit('update:value', newValue); - } - } - - function onKeydown(payload: KeyboardEvent) { - context.emit('keydown', payload); - } - - function onKeyup(payload: KeyboardEvent) { - context.emit('keyup', payload); - } - - function onMousedown(payload: MouseEvent) { - const target = payload.target as HTMLElement; - if (target.tagName !== 'INPUT') { - payload.preventDefault(); - } - payload.stopPropagation(); - } - - function onTextBoxValueChange(payload: Event) { - if (updateOn.value === 'blur') { - const newValue = (payload.target as HTMLInputElement).value; - payload.stopPropagation(); - changeTextBoxValue(newValue); - } - } - - return { - changeTextBoxValue, - disabled, - displayText, - editable, - hasFocused, - inputGroupClass, - inputType, - isEmpty, - modelValue, - readonly, - onBlur, - onClick, - onFocus, - onInput, - onKeydown, - onKeyup, - onMousedown, - onTextBoxValueChange, - placeholder, - textBoxClass, - textBoxTitle, - inputGroupStyle - }; -} diff --git a/packages/mobile-ui-vue/components/common/utils/encrypt.ts b/packages/mobile-ui-vue/components/common/utils/encrypt.ts deleted file mode 100644 index 8b0920d4682..00000000000 --- a/packages/mobile-ui-vue/components/common/utils/encrypt.ts +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Configurable variables. You may need to tweak these to be compatible with - * the server-side, but the defaults work in most cases. - */ -const hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ -const b64pad = ''; /* base-64 pad character. "=" for strict RFC compliance */ -const chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ - -/* - * Add integers, wrapping at 2^32. This uses 16-bit operations internally - * to work around bugs in some JS interpreters. - */ -function safeAdd(x, y) { - const lsw = (x & 0xffff) + (y & 0xffff); - const msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xffff); -} - -/* - * Bitwise rotate a 32-bit number to the left. - */ -function bitRol(num, cnt) { - return (num << cnt) | (num >>> (32 - cnt)); -} - -/* - * These functions implement the four basic operations the algorithm uses. - */ -function encryptCmn(q, a, b, x, s, t) { - return safeAdd(bitRol(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b); -} - -function encryptFf(a, b, c, d, x, s, t) { - return encryptCmn((b & c) | (~b & d), a, b, x, s, t); -} - -function encryptGg(a, b, c, d, x, s, t) { - return encryptCmn((b & d) | (c & ~d), a, b, x, s, t); -} - -function encryptHh(a, b, c, d, x, s, t) { - return encryptCmn(b ^ c ^ d, a, b, x, s, t); -} - -function encryptIi(a, b, c, d, x, s, t) { - return encryptCmn(c ^ (b | ~d), a, b, x, s, t); -} - -/* - * Convert a string to an array of little-endian words - * If chrsz is ASCII, characters >255 have their hi-byte silently ignored. - */ -function str2binl(str: string): any[] { - const bin: any = []; - const mask = (1 << chrsz) - 1; - for (let i = 0; i < str.length * chrsz; i += chrsz) { - bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << i % 32; - } - return bin; -} - -/* - * Convert an array of little-endian words to a string - */ -function binl2str(bin) { - let str = ''; - const mask = (1 << chrsz) - 1; - for (let i = 0; i < bin.length * 32; i += chrsz) { - str += String.fromCharCode((bin[i >> 5] >>> i % 32) & mask); - } - return str; -} - -/* - * Convert an array of little-endian words to a hex string. - */ -function binl2hex(binarray) { - // tslint:disable-next-line: variable-name - const hexTab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef'; - let str = ''; - for (let i = 0; i < binarray.length * 4; i++) { - str += - hexTab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xf) + - hexTab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xf); - } - return str; -} - -/* - * Convert an array of little-endian words to a base-64 string - */ -function binl2b64(binarray) { - const tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - let str = ''; - for (let i = 0; i < binarray.length * 4; i += 3) { - const triplet = - (((binarray[i >> 2] >> (8 * (i % 4))) & 0xff) << 16) | - (((binarray[(i + 1) >> 2] >> (8 * ((i + 1) % 4))) & 0xff) << 8) | - ((binarray[(i + 2) >> 2] >> (8 * ((i + 2) % 4))) & 0xff); - for (let j = 0; j < 4; j++) { - if (i * 8 + j * 6 > binarray.length * 32) { - str += b64pad; - } else { - str += tab.charAt((triplet >> (6 * (3 - j))) & 0x3f); - } - } - } - return str; -} - -/* - * Calculate the encrypt of an array of little-endian words, and a bit length - */ -function coreEncrypt(x: any, len: number) { - /* append padding */ - x[len >> 5] |= 0x80 << len % 32; - x[(((len + 64) >>> 9) << 4) + 14] = len; - - let a = 1732584193; - let b = -271733879; - let c = -1732584194; - let d = 271733878; - - for (let i = 0; i < x.length; i += 16) { - const olda = a; - const oldb = b; - const oldc = c; - const oldd = d; - - a = encryptFf(a, b, c, d, x[i + 0], 7, -680876936); - d = encryptFf(d, a, b, c, x[i + 1], 12, -389564586); - c = encryptFf(c, d, a, b, x[i + 2], 17, 606105819); - b = encryptFf(b, c, d, a, x[i + 3], 22, -1044525330); - a = encryptFf(a, b, c, d, x[i + 4], 7, -176418897); - d = encryptFf(d, a, b, c, x[i + 5], 12, 1200080426); - c = encryptFf(c, d, a, b, x[i + 6], 17, -1473231341); - b = encryptFf(b, c, d, a, x[i + 7], 22, -45705983); - a = encryptFf(a, b, c, d, x[i + 8], 7, 1770035416); - d = encryptFf(d, a, b, c, x[i + 9], 12, -1958414417); - c = encryptFf(c, d, a, b, x[i + 10], 17, -42063); - b = encryptFf(b, c, d, a, x[i + 11], 22, -1990404162); - a = encryptFf(a, b, c, d, x[i + 12], 7, 1804603682); - d = encryptFf(d, a, b, c, x[i + 13], 12, -40341101); - c = encryptFf(c, d, a, b, x[i + 14], 17, -1502002290); - b = encryptFf(b, c, d, a, x[i + 15], 22, 1236535329); - - a = encryptGg(a, b, c, d, x[i + 1], 5, -165796510); - d = encryptGg(d, a, b, c, x[i + 6], 9, -1069501632); - c = encryptGg(c, d, a, b, x[i + 11], 14, 643717713); - b = encryptGg(b, c, d, a, x[i + 0], 20, -373897302); - a = encryptGg(a, b, c, d, x[i + 5], 5, -701558691); - d = encryptGg(d, a, b, c, x[i + 10], 9, 38016083); - c = encryptGg(c, d, a, b, x[i + 15], 14, -660478335); - b = encryptGg(b, c, d, a, x[i + 4], 20, -405537848); - a = encryptGg(a, b, c, d, x[i + 9], 5, 568446438); - d = encryptGg(d, a, b, c, x[i + 14], 9, -1019803690); - c = encryptGg(c, d, a, b, x[i + 3], 14, -187363961); - b = encryptGg(b, c, d, a, x[i + 8], 20, 1163531501); - a = encryptGg(a, b, c, d, x[i + 13], 5, -1444681467); - d = encryptGg(d, a, b, c, x[i + 2], 9, -51403784); - c = encryptGg(c, d, a, b, x[i + 7], 14, 1735328473); - b = encryptGg(b, c, d, a, x[i + 12], 20, -1926607734); - - a = encryptHh(a, b, c, d, x[i + 5], 4, -378558); - d = encryptHh(d, a, b, c, x[i + 8], 11, -2022574463); - c = encryptHh(c, d, a, b, x[i + 11], 16, 1839030562); - b = encryptHh(b, c, d, a, x[i + 14], 23, -35309556); - a = encryptHh(a, b, c, d, x[i + 1], 4, -1530992060); - d = encryptHh(d, a, b, c, x[i + 4], 11, 1272893353); - c = encryptHh(c, d, a, b, x[i + 7], 16, -155497632); - b = encryptHh(b, c, d, a, x[i + 10], 23, -1094730640); - a = encryptHh(a, b, c, d, x[i + 13], 4, 681279174); - d = encryptHh(d, a, b, c, x[i + 0], 11, -358537222); - c = encryptHh(c, d, a, b, x[i + 3], 16, -722521979); - b = encryptHh(b, c, d, a, x[i + 6], 23, 76029189); - a = encryptHh(a, b, c, d, x[i + 9], 4, -640364487); - d = encryptHh(d, a, b, c, x[i + 12], 11, -421815835); - c = encryptHh(c, d, a, b, x[i + 15], 16, 530742520); - b = encryptHh(b, c, d, a, x[i + 2], 23, -995338651); - - a = encryptIi(a, b, c, d, x[i + 0], 6, -198630844); - d = encryptIi(d, a, b, c, x[i + 7], 10, 1126891415); - c = encryptIi(c, d, a, b, x[i + 14], 15, -1416354905); - b = encryptIi(b, c, d, a, x[i + 5], 21, -57434055); - a = encryptIi(a, b, c, d, x[i + 12], 6, 1700485571); - d = encryptIi(d, a, b, c, x[i + 3], 10, -1894986606); - c = encryptIi(c, d, a, b, x[i + 10], 15, -1051523); - b = encryptIi(b, c, d, a, x[i + 1], 21, -2054922799); - a = encryptIi(a, b, c, d, x[i + 8], 6, 1873313359); - d = encryptIi(d, a, b, c, x[i + 15], 10, -30611744); - c = encryptIi(c, d, a, b, x[i + 6], 15, -1560198380); - b = encryptIi(b, c, d, a, x[i + 13], 21, 1309151649); - a = encryptIi(a, b, c, d, x[i + 4], 6, -145523070); - d = encryptIi(d, a, b, c, x[i + 11], 10, -1120210379); - c = encryptIi(c, d, a, b, x[i + 2], 15, 718787259); - b = encryptIi(b, c, d, a, x[i + 9], 21, -343485551); - - a = safeAdd(a, olda); - b = safeAdd(b, oldb); - c = safeAdd(c, oldc); - d = safeAdd(d, oldd); - } - return [a, b, c, d]; -} - -/* - * Calculate the HMAC-encrypt, of a key and some data - */ -function coreHmacEncrypt(key, data) { - let bkey = str2binl(key); - if (bkey.length > 16) { - bkey = coreEncrypt(bkey, key.length * chrsz); - } - - const ipad = Array(16); - const opad = Array(16); - for (let i = 0; i < 16; i++) { - ipad[i] = bkey[i] ^ 0x36363636; - opad[i] = bkey[i] ^ 0x5c5c5c5c; - } - - const hash = coreEncrypt(ipad.concat(str2binl(data)), 512 + data.length * chrsz); - return coreEncrypt(opad.concat(hash), 512 + 128); -} - -export function encrypt(s: string, type = 'hex') { - if (type === 'hex') { - return binl2hex(coreEncrypt(str2binl(s), s.length * chrsz)); - } - - if (type === 'b64') { - return binl2b64(coreEncrypt(str2binl(s), s.length * chrsz)); - } - - return binl2str(coreEncrypt(str2binl(s), s.length * chrsz)); -} - -export function hmacEncrypt(key, data, type = 'hex') { - if (type === 'hex') { - return binl2hex(coreHmacEncrypt(key, data)); - } - if (type === 'b64') { - return binl2b64(coreHmacEncrypt(key, data)); - } - return binl2str(coreHmacEncrypt(key, data)); -} diff --git a/packages/mobile-ui-vue/components/common/utils/resolve-field.ts b/packages/mobile-ui-vue/components/common/utils/resolve-field.ts deleted file mode 100644 index 55530326bc7..00000000000 --- a/packages/mobile-ui-vue/components/common/utils/resolve-field.ts +++ /dev/null @@ -1,29 +0,0 @@ -export const resolveField = (dataItem: any, field: Array | string) => { - if (!field) { - // 空字符串或者undefined - return ''; - } - if (!dataItem) { - return ''; - } - const fieldList = typeof field === 'string' ? field.split('.') : field; - const result = fieldList.reduce((total: any, next: string) => { - return total[next]; - }, dataItem); - return result; -}; - -export const setFieldValue = (newValue: any, dataItem: any, field: Array | string) => { - let fieldList: string[] = []; - if (typeof field === 'string') { - fieldList = [...field.split('.')]; - } - if (Array.isArray(field)) { - fieldList = field; - } - let value = dataItem; - while (fieldList && fieldList.length > 1) { - value = value[fieldList.shift()!]; - } - value[fieldList.shift()!] = newValue; -}; diff --git a/packages/mobile-ui-vue/components/common/utils/symbol-key.ts b/packages/mobile-ui-vue/components/common/utils/symbol-key.ts deleted file mode 100644 index 8c3db5ff8c0..00000000000 --- a/packages/mobile-ui-vue/components/common/utils/symbol-key.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { InjectionKey } from "vue"; - -export const CHECKBOX_CONTEXT: InjectionKey<{ [key: string]: any }> = Symbol('checkboxGroupContext'); - -/** 选择控制器 */ -export const ControllerSchemaRepositorySymbol = Symbol('controller schema repository inject token'); diff --git a/packages/mobile-ui-vue/components/common/utils/use-class.ts b/packages/mobile-ui-vue/components/common/utils/use-class.ts deleted file mode 100644 index 578e29c9466..00000000000 --- a/packages/mobile-ui-vue/components/common/utils/use-class.ts +++ /dev/null @@ -1,33 +0,0 @@ -interface ElementRef { - nativeElement?: any; -} -export function getElementWithClassList(elementRef: ElementRef) { - const element = elementRef.nativeElement ? elementRef.nativeElement : elementRef; - - if (element.classList !== undefined && element.classList !== null) { - return element; - } - - return null; -} - -export function removeClass(elementRef: ElementRef | any, className: string) { - if (className === undefined) { - return; - } - const element = getElementWithClassList(elementRef); - - if (element) { - element.classList.remove(className); - } -} -export function addClass(elementRef: ElementRef | any, className: string) { - if (className === undefined) { - return; - } - const element = getElementWithClassList(elementRef); - - if (element) { - element.classList.add(className); - } -} diff --git a/packages/mobile-ui-vue/components/common/utils/use-guid.ts b/packages/mobile-ui-vue/components/common/utils/use-guid.ts deleted file mode 100644 index afc1786306f..00000000000 --- a/packages/mobile-ui-vue/components/common/utils/use-guid.ts +++ /dev/null @@ -1,43 +0,0 @@ -export function useGuid() { - function guid() { - const replaceCallback = (replaceChar: string) => { - const randomValue = (Math.random() * 16) | 0; - const result = replaceChar === 'x' ? randomValue : (randomValue & 0x3) | 0x8; - return result.toString(16); - }; - - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, replaceCallback); - } - - function uuid(uuidLength: number, radix?: number) { - const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); - const uuid: string[] = []; - let charIndex; - radix = radix || chars.length; - - if (uuidLength) { - // Compact form - for (charIndex = 0; charIndex < uuidLength; charIndex++) {uuid[charIndex] = chars[0 | (Math.random() * radix)];} - } else { - // rfc4122, version 4 form - let randomValue; - - // rfc4122 requires these characters - uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; - uuid[14] = '4'; - - // Fill in random data. At i==19 set the high bits of clock sequence as - // per rfc4122, sec. 4.1.5 - for (charIndex = 0; charIndex < 36; charIndex++) { - if (!uuid[charIndex]) { - randomValue = 0 | (Math.random() * 16); - uuid[charIndex] = chars[charIndex === 19 ? (randomValue & 0x3) | 0x8 : randomValue]; - } - } - } - - return uuid.join(''); - } - - return { guid, uuid }; -} diff --git a/packages/mobile-ui-vue/components/common/utils/use-request-animation.ts b/packages/mobile-ui-vue/components/common/utils/use-request-animation.ts deleted file mode 100644 index 67f7be8999e..00000000000 --- a/packages/mobile-ui-vue/components/common/utils/use-request-animation.ts +++ /dev/null @@ -1,46 +0,0 @@ -// tslint:disable:no-any typedef no-invalid-this -const availablePrefixes = ['moz', 'ms', 'webkit']; -function requestAnimationFramePolyfill(): typeof requestAnimationFrame { - let lastTime = 0; - return (callback: FrameRequestCallback): any => { - const currTime = new Date().getTime(); - const timeToCall = Math.max(0, 16 - (currTime - lastTime)); - const id = setTimeout(() => { - callback(currTime + timeToCall); - }, timeToCall); - lastTime = currTime + timeToCall; - return id; - }; -} - -function getRequestAnimationFrame(): typeof requestAnimationFrame { - if (typeof window === 'undefined') { - return () => 0; - } - if (window.requestAnimationFrame) { - return window.requestAnimationFrame.bind(window); - } - - const prefix = availablePrefixes.filter(key => `${key}RequestAnimationFrame` in window)[0]; - - return prefix ? (window as any)[`${prefix}RequestAnimationFrame`] : requestAnimationFramePolyfill(); -} -export function cancelRequestAnimationFrame(id: number): any { - if (typeof window === 'undefined') { - return null; - } - if (window.cancelAnimationFrame) { - return window.cancelAnimationFrame(id); - } - const prefix = availablePrefixes.filter( - key => `${key}CancelAnimationFrame` in window || `${key}CancelRequestAnimationFrame` in window - )[0]; - - return prefix - ? ((window as any)[`${prefix}CancelAnimationFrame`] || (window as any)[`${prefix}CancelRequestAnimationFrame`]) - // @ts-ignore - .call(this, id) - : clearTimeout(id); -} - -export const useReqAnimationFrame = getRequestAnimationFrame(); diff --git a/packages/mobile-ui-vue/components/common/utils/with-install.ts b/packages/mobile-ui-vue/components/common/utils/with-install.ts deleted file mode 100644 index 3bce8e707a3..00000000000 --- a/packages/mobile-ui-vue/components/common/utils/with-install.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { App, Component, Plugin } from 'vue'; - -export const withInstall = (component: T) => { - const c = component as any; - c.install = function (app: App) { - app.component(c.name, component); - }; - - return component as T & Plugin; -}; diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.props.ts b/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.props.ts index cce31ab4471..16e9a703ae5 100644 --- a/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.props.ts +++ b/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.props.ts @@ -13,8 +13,8 @@ export const datePickerInputProps = { ...datePickerProps, round: { type: Boolean, default: false } -} as Record; +}; export type DatePickerInputProps = ExtractPropTypes; -export const propsResolver = createPropsResolver(datePickerInputProps, inputSchema, schemaMapper, schemaResolver); +export const propsResolver = createPropsResolver(datePickerInputProps, inputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/designer-canvas.component.tsx b/packages/mobile-ui-vue/components/designer-canvas/src/designer-canvas.component.tsx index 5ac3463fd7a..841bb50d401 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/designer-canvas.component.tsx +++ b/packages/mobile-ui-vue/components/designer-canvas/src/designer-canvas.component.tsx @@ -10,7 +10,7 @@ import './composition/class/designer-canvas.css'; import './composition/class/control.css'; import { loadDesignerRegister } from './components/maps'; import { FM_MODAL_SERVICE_TOKEN } from '../../modal'; -import { FM_UI_PROVIDER_SERVICE_TOKEN } from '@/components'; +import { FM_UI_PROVIDER_SERVICE_TOKEN } from '@/components/common'; export default defineComponent({ name: 'FDesignerCanvas', diff --git a/packages/mobile-ui-vue/components/index.scss b/packages/mobile-ui-vue/components/index.scss index ecef13826c3..0832f1da227 100644 --- a/packages/mobile-ui-vue/components/index.scss +++ b/packages/mobile-ui-vue/components/index.scss @@ -31,6 +31,8 @@ @use './picker/src/picker.scss'; @use './picker-group/src/picker-group.scss'; @use './date-picker/src/date-picker.scss'; +@use './lookup/src/lookup.scss'; +@use './search/src/search.scss'; @use './page-container/src/page-container.scss'; @use './page-body-container/src/page-body-container.scss'; @use './page-header-container/src/page-header-container.scss'; diff --git a/packages/mobile-ui-vue/components/index.ts b/packages/mobile-ui-vue/components/index.ts index 55c3b962122..b62e0d29ca4 100644 --- a/packages/mobile-ui-vue/components/index.ts +++ b/packages/mobile-ui-vue/components/index.ts @@ -63,15 +63,15 @@ import PageFooterContainer from './page-footer-container'; import Component from './component'; import ContentContainer from './content-container'; import FloatContainer from './float-container'; -import Common from './common'; -import Modal from './modal'; -import DynamicView from './dynamic-view'; -import FDesignerCanvas from './designer-canvas'; -export * from './register'; -export * from './designer'; -export { schemaMap } from './dynamic-resolver'; -export { type DynamicViewContext, DYNAMIC_VIEW_CONTEXT, DefaultDynamicViewContext } from './dynamic-view'; +// import Modal from './modal'; +// import DynamicView from './dynamic-view'; +// import FDesignerCanvas from './designer-canvas'; + +// export * from './register'; +// export * from './designer'; +// export { schemaMap } from './dynamic-resolver'; +// export { type DynamicViewContext, DYNAMIC_VIEW_CONTEXT, DefaultDynamicViewContext } from './dynamic-view'; const components = [ Button, @@ -123,10 +123,10 @@ const components = [ ContentContainer, FloatContainer, - Common, - Modal, - DynamicView, - FDesignerCanvas + // Common, + // Modal, + // DynamicView, + // FDesignerCanvas ]; const install = (app: App): void => { @@ -184,10 +184,10 @@ export { ContentContainer, FloatContainer, Utils, - Common, - Modal, - DynamicView, - FDesignerCanvas + // Common, + // Modal, + // DynamicView, + // FDesignerCanvas }; export default { diff --git a/packages/mobile-ui-vue/components/lookup/index.ts b/packages/mobile-ui-vue/components/lookup/index.ts new file mode 100644 index 00000000000..a774c16961f --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/index.ts @@ -0,0 +1,8 @@ +import { withInstall } from '@components/common'; +import LookupInstallless from './src/lookup.component'; +import { LOOKUP_HTTP_SERVICE_TOKEN } from './src/lookup.props'; + +const Lookup = withInstall(LookupInstallless); + +export { Lookup, LOOKUP_HTTP_SERVICE_TOKEN }; +export default Lookup; diff --git a/packages/mobile-ui-vue/components/lookup/src/components/content-list-nav.component.tsx b/packages/mobile-ui-vue/components/lookup/src/components/content-list-nav.component.tsx new file mode 100644 index 00000000000..c16e439547e --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/components/content-list-nav.component.tsx @@ -0,0 +1,12 @@ +import { defineComponent } from 'vue'; + +export default defineComponent({ + setup() { + + return () => ( +
+ navlist +
+ ); + } +}); diff --git a/packages/mobile-ui-vue/components/lookup/src/components/content-list-tree.component.tsx b/packages/mobile-ui-vue/components/lookup/src/components/content-list-tree.component.tsx new file mode 100644 index 00000000000..bc7835f2975 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/components/content-list-tree.component.tsx @@ -0,0 +1,12 @@ +import { defineComponent } from 'vue'; + +export default defineComponent({ + setup() { + + return () => ( +
+ tree +
+ ); + } +}); diff --git a/packages/mobile-ui-vue/components/lookup/src/components/content-list.component.tsx b/packages/mobile-ui-vue/components/lookup/src/components/content-list.component.tsx new file mode 100644 index 00000000000..517e58fb67c --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/components/content-list.component.tsx @@ -0,0 +1,43 @@ +import { useBem } from '@/components/common'; +import { defineComponent } from 'vue'; +import { LOOKUP_PANEL_NAME } from '../lookup.props'; +import List from '@/components/list'; +import { useLookupPanelState } from '../composition'; +import Cell from '@/components/cell'; + +export default defineComponent({ + setup() { + + const { bem } = useBem(LOOKUP_PANEL_NAME); + + const { dataService, handleChange } = useLookupPanelState(); + + const { listData, loadData } = dataService; + + const handleLoad = ()=>{ + listData.pageIndex++; + loadData(); + }; + + const renderList = () => { + return ( + + {listData.dataList.map(item => ( + handleChange(item)}> + ))} + + ); + }; + + return () => ( +
+ {renderList()} +
+ ); + } +}); diff --git a/packages/mobile-ui-vue/components/lookup/src/components/content-search.component.tsx b/packages/mobile-ui-vue/components/lookup/src/components/content-search.component.tsx new file mode 100644 index 00000000000..e2d158535f5 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/components/content-search.component.tsx @@ -0,0 +1,36 @@ +import { defineComponent } from 'vue'; +import { useBem } from '@/components/common'; +import List from '@/components/list'; +import { LOOKUP_PANEL_NAME } from '../lookup.props'; +import { useLookupPanelState } from '../composition'; +import Cell from '@/components/cell'; + +export default defineComponent({ + setup() { + const { bem } = useBem(LOOKUP_PANEL_NAME); + + const { searchService, handleChange } = useLookupPanelState(); + + const { searchListData, searchData } = searchService; + + const handleLoad = ()=>{ + searchListData.pageIndex++; + searchData(); + }; + + return () => ( +
+ { + {searchListData.dataList.map(item => ( + handleChange(item)}> + ))} + } +
+ ); + } +}); diff --git a/packages/mobile-ui-vue/components/lookup/src/components/content-selected.component.tsx b/packages/mobile-ui-vue/components/lookup/src/components/content-selected.component.tsx new file mode 100644 index 00000000000..b9ffd4b7a9c --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/components/content-selected.component.tsx @@ -0,0 +1,16 @@ +import { defineComponent } from 'vue'; +import { useBem } from '@/components/common'; +import List from '@/components/list'; +import { LOOKUP_PANEL_NAME } from '../lookup.props'; + +export default defineComponent({ + setup() { + const { bem } = useBem(LOOKUP_PANEL_NAME); + + return () => ( +
+ +
+ ); + } +}); diff --git a/packages/mobile-ui-vue/components/lookup/src/components/content.component.tsx b/packages/mobile-ui-vue/components/lookup/src/components/content.component.tsx new file mode 100644 index 00000000000..a7d38a6c238 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/components/content.component.tsx @@ -0,0 +1,58 @@ +import { computed, CSSProperties, defineComponent, reactive, ref, watch } from 'vue'; +import { useBem } from '@/components/common'; +import { LookupDisplayType } from '../composition/types'; +import { LOOKUP_PANEL_NAME } from '../lookup.props'; +import { useLookupPanelState } from '../composition'; +import ListComponent from './content-list.component'; +import TreeComponent from './content-list-tree.component'; +import NavListComponent from './content-list-nav.component'; +import SearchListComponent from './content-search.component'; + + +export default defineComponent({ + setup() { + + const { bem } = useBem(LOOKUP_PANEL_NAME); + + const { panelProps, dataService, searchService, seletedService } = useLookupPanelState(); + + const listStyle = computed(()=>{ + const { showList } = dataService.listData; + return { display: showList ? 'block' : 'none' }; + }); + + const displayTypeMap = { + [LookupDisplayType.List]: ListComponent, + [LookupDisplayType.Tree]: TreeComponent, + [LookupDisplayType.NAVLIST]: NavListComponent, + }; + + const renderList = ()=>{ + const List = displayTypeMap[panelProps.displayType]; + return ; + }; + + const searchListStyle = computed(()=>{ + const { showList } = searchService.searchListData; + return { display: showList ? 'block' : 'none' }; + }); + + const renderSearchList = ()=>{ + return ( + + ); + }; + + const selectedListStyle = computed(()=>{ + const { showList } = seletedService.selectedListData; + return { display: showList ? 'block' : 'none' }; + }); + + return () => ( +
+ {renderList()} + {renderSearchList()} +
+ ); + } +}); diff --git a/packages/mobile-ui-vue/components/lookup/src/components/footer.component.tsx b/packages/mobile-ui-vue/components/lookup/src/components/footer.component.tsx new file mode 100644 index 00000000000..df69bf410dd --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/components/footer.component.tsx @@ -0,0 +1,20 @@ +import { defineComponent } from 'vue'; +import { LOOKUP_PANEL_NAME } from '../lookup.props'; +import { useBem } from '@/components/common'; + +export default defineComponent({ + setup() { + const { bem } = useBem(LOOKUP_PANEL_NAME); + + return () => ( +
+
+ left +
+
+ right +
+
+ ); + } +}); diff --git a/packages/mobile-ui-vue/components/lookup/src/components/header.component.tsx b/packages/mobile-ui-vue/components/lookup/src/components/header.component.tsx new file mode 100644 index 00000000000..1159690f06b --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/components/header.component.tsx @@ -0,0 +1,53 @@ +import { defineComponent } from 'vue'; +import { useBem } from '@/components/common'; +import Navbar from '@/components/navbar'; +import Search from '@/components/search'; +import { LOOKUP_PANEL_NAME } from '../lookup.props'; +import { useLookupPanelState } from '../composition'; + + +export default defineComponent({ + setup() { + + const { bem } = useBem(LOOKUP_PANEL_NAME); + + const { panelProps, dataService, searchService, seletedService, handleClose } = useLookupPanelState(); + const { listData } = dataService; + const { searchListData, resetListData, searchData } = searchService; + + const handleFoucs = () => { + searchListData.showList = true; + listData.showList = false; + }; + + const handleBlur = () => { + if(searchListData.searchValue) { + return; + } + searchListData.showList = false; + listData.showList = true; + }; + + const handleSearch = (value: string) => { + resetListData(); + searchListData.searchValue = value; + if(value){ + searchData(); + } + }; + + return () => ( +
+ + +
+ ); + } +}); diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/index.ts b/packages/mobile-ui-vue/components/lookup/src/composition/index.ts new file mode 100644 index 00000000000..eaa9013a2d9 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/composition/index.ts @@ -0,0 +1,6 @@ +export * from './types'; +export * from './use-lookup-state'; +export * from './use-lookup-panel-state'; +export * from './use-data-service'; +export * from './use-selcted-service'; +export * from './use-search-service'; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/types.ts b/packages/mobile-ui-vue/components/lookup/src/composition/types.ts new file mode 100644 index 00000000000..60eff115fa7 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/composition/types.ts @@ -0,0 +1,237 @@ +import { Ref, SetupContext } from "vue"; +import { LookupPanelProps } from "../lookup.props"; + +export enum LookupDisplayType { + List = 'LIST', + Tree = 'TREELIST', + NAVLIST = 'NAVLIST' +} + +export enum LoadTreeDataType { + default = 'default', + all = 'loadall', + async = 'layerload' +} + +export enum OnlySelectLeaf { + default = 'default', + yes = 'yes', + no = 'no' +} + +export enum LookupTabs { + dataList = 'datalist', + favorite = 'favorite', + recent = 'recent' +} + +export interface SearchField { + value: string; + label: string; + isDefault?: boolean; +} + +export enum Compare { + Equal = 0, + NotEqual = 1, + Greater = 2, + GreaterOrEqual = 3, + Less = 4, + LessOrEqual = 5, + Like = 6, + LikeStartWith = 7, + LikeEndWith = 8, + NotLike = 9, + NotLikeStartWith = 10, + NotLikeEndWith = 11, + Is = 12, + IsNot = 13, + In = 14, + NotIn = 15 +} +export enum FilterRelation { + Empty = 0, + And = 1, + Or = 2 +} + +export enum ExpressValueType { + Value = 0, + Expression = 1, + FrontExpress = "frontExpress" +} + +export interface FilterCondition { + filterField: string; + value: string; + lbracket?: string; + rbracket?: string; + relation?: FilterRelation; + compare?: Compare; + expresstype?: ExpressValueType; +} + +export enum LoadDataType { + all = 'all', + search = 'search', + list = 'list', + fav = 'fav', + children = 'children', + nav = 'nav' +}; + +export type BeforeLoadDataContext = { + data: any +}; + +export interface SearchParams { + category: LoadDataType; + searchField?: string; + searchValue?: string; + searchType?: string; + favoriteIds?: string[]; + sortName?: string; + sortOrder?: string; + parentLayer?: number; + parentPath?: string; +} + +export interface BuildParamsOptions { + searchParams?: { searchField: string, searchValue: string }, + context?: BeforeLoadDataContext, + pageIndex?: number, + selectedInfo?: string[], + enableFullTree?: boolean +} + +export interface LookupRequestParams { + pageIndex: number; + pageSize: number; + searchValue?: string; + selectedInfo?: string[]; + searchConditions?: Array; + /** 自定义查询数据 */ + customData?: any; + loadTreeDataType?: LoadTreeDataType; + /** 构造完整树 */ + enableFullTree?: boolean; + /** 导航帮助对应关系条件 */ + relationFilter?: Array<{ fieldName: string; fieldValue: any }>; + /** 左树右列表帮助,左树为分层分级码加载时,点击节点的分级码 */ + navPathCode?: any; +} + +export interface DisplayInfo { + valueField?: string; + idField?: string; +} + +export type ONLY_SELECT_LEAF = 'default' | 'yes' | 'no'; + +export interface TreeInfo { + /** 数据加载方式: all, async */ + loadDataType?: 'all' | 'async'; + /** 分层方式: pathcode, parentId */ + layerType?: 'pathcode' | 'parentId'; + /** 数据中带有分级信息的字段 */ + dataField?: string; + /** 父ID字段 */ + parentField?: string; + /** 分级码字段 */ + pathField?: string; + /** 级数字段 */ + layerField?: string; + /** 是否明细字段 */ + isDetailField?: string; + /** + * 只允许选择叶子节点 + * - default: 应用服务器端设置,如服务器未设置,功能同 `no` + * - `yes`: 服务器端设置失效。仅允许选择叶子节点。 + * - `no`: 服务器端设置失效。所有节点均可选择。 + */ + onlySelectLeaf?: boolean | ONLY_SELECT_LEAF; +} + +export interface LookupHttpResult { + /** 列信息 */ + columns?: any[]; + displayInfo?: DisplayInfo; + displayType?: string; + /** 数据列表 */ + items: Record[]; + navigation?: LookupHttpResult; + /** 树分级信息 */ + treeInfo?: TreeInfo; + /** 分页信息 */ + pageInfo?: { pageIndex: number; pageSize: number; pageList?: number[]; enablePager: boolean }; + /** 查询字段 */ + searchFields?: { label: string; value: string }[]; + /** 已选择数据列表 */ + selectedData?: any; + /** 总记录数 */ + total?: number; + title?: string; + idField?: string; + relations?: Array<{ groupField: string; helpField: string }>; +} + +export interface LookupHttpService { + getData(uri: string, params: Partial): Promise; + getSettings(id: string): Promise; + updateSettings(id: string, settings: any): Promise; +} + +export interface SearchInfo { + field?: string; + value?: any; + type?: 'like' | 'equal' | ''; +} + +export type BeforeLoadData = () => Promise; + +export type DataListItem = Record + +export type LookupListData = { + dataList: DataListItem[], + totalPage: number, + pageIndex: number, + loading: boolean, + finished: boolean, + showList: boolean +} + +export interface DataService { + listData: LookupListData, + loadData: (context?: BeforeLoadDataContext) => void, + resetListData: () => void, + initLoadData: () => void, +}; + +export type SearchListData = LookupListData & { + searchValue: string +} + +export interface SearchService { + searchListData: SearchListData, + searchData: () => void, + resetListData: () => void +}; + +export type SelectedListData = { dataList: DataListItem[], showList: boolean} + +export interface SeletedService { + selectedListData: SelectedListData, + toggleSelecte: (item: DataListItem) => void, + toggleSelecteAll: (items: DataListItem[]) => void, + clearSelected: () => void, + getIdValue: () => string, + getTextValue: () => string +}; + +export type LookupPanelState = { + panelProps: LookupPanelProps, + panelContext: SetupContext<['change', 'confirm', 'close', 'update:modelValue']>, + dataService: DataService, + seletedService: SeletedService, + searchService: SearchService +} diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-data-service.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-data-service.ts new file mode 100644 index 00000000000..77fbc9ecd8c --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-data-service.ts @@ -0,0 +1,62 @@ +import { reactive } from "vue"; +import { LookupPanelProps } from "../lookup.props"; +import { BeforeLoadDataContext, LookupDisplayType, LookupListData } from "./types"; +import { useLoadListData } from "./use-load-list-data"; +import { isFunction } from "@/components/common"; +import { useLoadNavListData } from "./use-load-nav-list-data"; +import { useLoadTreeData } from "./use-load-tree-data"; + +export const useDataService = (props: LookupPanelProps) => { + const listData = reactive({ + dataList: [], + totalPage: 0, + pageIndex: 1, + loading: false, + finished: false, + showList: true + }); + + const resetListData = ()=>{ + setTimeout(()=>{ + listData.dataList = []; + }, 300); + listData.totalPage = 0; + listData.pageIndex = 1; + listData.finished = false; + listData.showList = true; + }; + + const getLoadDataInstance = () => { + switch (props.displayType) { + case LookupDisplayType.List: + return useLoadListData(props, listData); + case LookupDisplayType.Tree: + return useLoadTreeData(props, listData); + case LookupDisplayType.NAVLIST: + return useLoadNavListData(props, listData); + } + }; + const { loadData } = getLoadDataInstance(); + + const beforeLoadData = () => { + const asyncTarget = isFunction(props.beforeLoadData) && props.beforeLoadData(); + if (asyncTarget instanceof Promise) { + return asyncTarget; + } else { + return Promise.resolve(undefined); + } + }; + + const initLoadData = ()=>{ + beforeLoadData().then((context?: BeforeLoadDataContext)=>{ + loadData(context); + }); + }; + + return { + listData, + loadData, + initLoadData, + resetListData + }; +}; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-load-list-data.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-load-list-data.ts new file mode 100644 index 00000000000..12206f10a33 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-load-list-data.ts @@ -0,0 +1,38 @@ +import { reactive, ref } from "vue"; +import { LookupPanelProps } from "../lookup.props"; +import { BeforeLoadDataContext, LoadDataType, LookupListData, LookupHttpResult } from "./types"; +import { useRequest } from "./use-request"; + +export const useLoadListData = (props: LookupPanelProps, listData: LookupListData) => { + const { getData, buildParams } = useRequest(props); + + const updateData = (data: LookupHttpResult)=>{ + listData.dataList = listData.dataList.concat(data.items); + const pageSize = data.pageInfo?.pageSize ?? props.pageSize; + if (data.total && pageSize) { + listData.totalPage = Math.ceil(data.total / pageSize); + } + }; + + const loadData = (context?: BeforeLoadDataContext) => { + if(listData.totalPage && (listData.pageIndex > listData.totalPage)) { + listData.finished = true; + return; + } + if(props.uri) { + const params = buildParams(LoadDataType.all, { context, pageIndex: listData.pageIndex }); + + getData(params).then(result=>{ + updateData(result); + listData.loading = false; + }); + } else { + listData.dataList = props.data; + }; + }; + + + return { + loadData + }; +}; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-load-nav-list-data.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-load-nav-list-data.ts new file mode 100644 index 00000000000..9501eb2fa15 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-load-nav-list-data.ts @@ -0,0 +1,17 @@ +import { reactive } from "vue"; +import { LookupPanelProps } from "../lookup.props"; +import { LoadDataType, LookupListData } from "./types"; +import { useRequest } from "./use-request"; + +export const useLoadNavListData = (props: LookupPanelProps, listData: LookupListData) => { + const { getData, buildParams } = useRequest(props); + + const loadData = (context?: Record) => { + const params = buildParams(LoadDataType.all, context?.data); + return getData(params); + }; + + return { + loadData + }; +}; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-load-tree-data.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-load-tree-data.ts new file mode 100644 index 00000000000..ed8f960d181 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-load-tree-data.ts @@ -0,0 +1,17 @@ +import { reactive } from "vue"; +import { LookupPanelProps } from "../lookup.props"; +import { LoadDataType, LookupListData } from "./types"; +import { useRequest } from "./use-request"; + +export const useLoadTreeData = (props: LookupPanelProps, listData: LookupListData) => { + const { getData, buildParams } = useRequest(props); + + const loadData = (context?: Record) => { + const params = buildParams(LoadDataType.all, context?.data); + return getData(params); + }; + + return { + loadData + }; +}; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-lookup-panel-state.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-lookup-panel-state.ts new file mode 100644 index 00000000000..11e8090bc0e --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-lookup-panel-state.ts @@ -0,0 +1,54 @@ +import { computed, inject, provide } from "vue"; +import { LookupPanelState } from "./types"; + +export const useLookupPanelState = (key = 'LookupPanelState') => { + + const setState = (state: LookupPanelState) => { + provide(key, state); + }; + + const getState = (): LookupPanelState => { + const state = inject(key, ({} as any)); + return state; + }; + + const { panelProps, panelContext, dataService, seletedService, searchService } = getState(); + + const resetData = ()=>{ + dataService.resetListData(); + searchService.resetListData(); + searchService.searchListData.showList = false; + }; + + const handleConfirm = () => { + resetData(); + const textValue = seletedService.getTextValue(); + panelContext.emit('confirm', textValue); + }; + + const handleChange = (item: Record) => { + seletedService.toggleSelecte(item); + panelContext.emit('change', item); + if(!panelProps.multiSelect) { + handleConfirm(); + } + }; + + const handleClose = ()=>{ + resetData(); + panelContext.emit('close'); + }; + + return { + panelProps, + panelContext, + dataService, + seletedService, + searchService, + setState, + getState, + handleChange, + handleConfirm, + handleClose + }; +}; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-lookup-state.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-lookup-state.ts new file mode 100644 index 00000000000..3f2b7389e0c --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-lookup-state.ts @@ -0,0 +1,70 @@ +import { SetupContext, computed, onMounted, shallowRef, watch } from 'vue'; +import { ButtonEditProps, useButtonEditProps } from '@/components/button-edit'; +import { ColumnItem } from '@/components/picker'; +import { lookupPanelProps } from '../lookup.props'; + +export const useLookupState = ( + props: Omit, + context: SetupContext<('change' | 'confirm' | 'update:modelValue')[]> +) => { + const { emit } = context; + + const { inputValue, showPopup, buttonEditProps } = useButtonEditProps(props); + + const componentRef = shallowRef(); + + watch(showPopup, ()=>{ + if(showPopup.value) { + componentRef.value?.initLoadData(); + } + }); + + const updateInputValue = () => { + const { getTextValue } = componentRef.value; + inputValue.value = getTextValue(); + }; + + onMounted(() => { + updateInputValue(); + }); + + const handleConfirm = (value: any[]) => { + showPopup.value = false; + updateInputValue(); + emit('confirm', value); + emit('update:modelValue', value); + }; + + const handleChange = (value: ColumnItem) => { + emit('change', value); + }; + + const handleColse = () => { + showPopup.value = false; + }; + + const lookupPanelSlotProps = computed(()=>{ + const innerProps = {}; + Object.keys(lookupPanelProps).forEach(propKey =>{ + innerProps[propKey] = props[propKey]; + }); + return { + ...innerProps, + ref: componentRef, + onClose: handleColse, + onChange: handleChange, + onConfirm: handleConfirm, + }; + }); + + return { + inputValue, + showPopup, + buttonEditProps, + lookupPanelSlotProps, + componentRef, + handleChange, + handleConfirm, + handleColse + }; +}; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-request.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-request.ts new file mode 100644 index 00000000000..94aae429254 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-request.ts @@ -0,0 +1,68 @@ +import { inject } from "vue"; +import { LOOKUP_HTTP_SERVICE_TOKEN, LookupPanelProps } from "../lookup.props"; +import { BuildParamsOptions, LoadDataType, LookupHttpService, LookupRequestParams, SearchParams } from "./types"; + +export const useRequest = (props: LookupPanelProps) => { + const httpService = inject(LOOKUP_HTTP_SERVICE_TOKEN); + + const getData = (params: LookupRequestParams) => { + if (!httpService?.getData) { + return Promise.reject('HTTP服务错误!'); + } + return httpService.getData(props.uri, params); + }; + + const buildParams = (type: LoadDataType, options: BuildParamsOptions = {}): LookupRequestParams => { + + const { context, pageIndex = 1, searchParams } = options; + + const requestParams: LookupRequestParams = { + pageIndex: pageIndex, + pageSize: props.pageSize, + }; + const searchValue: SearchParams = { + category: type + }; + + switch (type) { + case 'all': + + break; + case 'list': + + break; + case 'search': + searchValue.searchField = searchParams?.searchField; + searchValue.searchValue = searchParams?.searchValue; + break; + case 'fav': + + break; + case 'children': + + break; + case 'nav': + + break; + + default: + break; + } + + if (context?.data) { + requestParams.customData = context.data; + } + + return { + ...requestParams, + searchValue: JSON.stringify(searchValue) + }; + }; + + + return { + httpService, + getData, + buildParams + }; +}; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-search-service.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-search-service.ts new file mode 100644 index 00000000000..5470237c6b1 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-search-service.ts @@ -0,0 +1,59 @@ +import { reactive } from "vue"; +import { LookupPanelProps } from "../lookup.props"; +import { LoadDataType, LookupHttpResult, SearchListData, SearchService } from "./types"; +import { useRequest } from "./use-request"; + +export const useSearchService = (props: LookupPanelProps): SearchService => { + + const searchListData = reactive({ + dataList: [], + totalPage: 0, + pageIndex: 1, + loading: false, + finished: false, + showList: false, + searchValue: '' + }); + const resetListData = ()=>{ + searchListData.dataList = []; + searchListData.totalPage = 0; + searchListData.pageIndex = 1; + searchListData.finished = false; + searchListData.searchValue = ''; + }; + + const updateData = (data: LookupHttpResult)=>{ + searchListData.dataList = searchListData.dataList.concat(data.items); + const pageSize = data.pageInfo?.pageSize ?? props.pageSize; + if (data.total && pageSize) { + searchListData.totalPage = Math.ceil(data.total / pageSize); + } + }; + + const { getData, buildParams } = useRequest(props); + const searchData = ()=>{ + if(searchListData.totalPage && (searchListData.pageIndex > searchListData.totalPage)) { + searchListData.finished = true; + return; + } + const searchParams = { + searchField: '*', + searchValue: searchListData.searchValue + }; + + const params = buildParams(LoadDataType.search, { searchParams, pageIndex: searchListData.pageIndex }); + params.pageIndex = searchListData.pageIndex; + + getData(params).then(result=>{ + updateData(result); + searchListData.loading = false; + }); + }; + + + return { + searchListData, + searchData, + resetListData + }; +}; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-selcted-service.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-selcted-service.ts new file mode 100644 index 00000000000..c5453b0314d --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-selcted-service.ts @@ -0,0 +1,56 @@ +import { reactive } from "vue"; +import { LookupPanelProps } from "../lookup.props"; +import { DataListItem, SelectedListData, SeletedService } from "./types"; +import { getValue } from "@/components/common"; + +export const useSelectedService = (props: LookupPanelProps): SeletedService => { + const selectedListData = reactive({ + dataList: [], + showList: false + }); + + const clearSelected = () => { + selectedListData.dataList.length = 0; + }; + + const getIndex = (item: DataListItem) => { + return selectedListData.dataList.findIndex(element => getValue(props.idField, element) === getValue(props.idField, item)); + }; + + const toggleSelecte = (item: DataListItem) => { + if(!props.multiSelect) { + clearSelected(); + selectedListData.dataList.push(item); + return; + } + const itemIndex = getIndex(item); + if (itemIndex < 0) { + selectedListData.dataList.push(item); + } else { + selectedListData.dataList.splice(itemIndex, 1); + } + }; + + const toggleSelecteAll = (items: DataListItem[]) => { + items.forEach(item => { + toggleSelecte(item); + }); + }; + + const getTextValue = () => { + return selectedListData.dataList.map(item=> item[props.textField]).join(props.separator); + }; + + const getIdValue = () => { + return selectedListData.dataList.map(item=> item[props.idField]).join(props.separator); + }; + + return { + selectedListData, + toggleSelecte, + toggleSelecteAll, + clearSelected, + getTextValue, + getIdValue + }; +}; diff --git a/packages/mobile-ui-vue/components/lookup/src/lookup-panel.component.tsx b/packages/mobile-ui-vue/components/lookup/src/lookup-panel.component.tsx new file mode 100644 index 00000000000..4d8bee35bf8 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/lookup-panel.component.tsx @@ -0,0 +1,60 @@ +import { computed, defineComponent } from 'vue'; +import { useBem } from '@/components/common'; +import { LOOKUP_PANEL_NAME, lookupPanelProps } from './lookup.props'; +import { useDataService, useLookupPanelState, useSearchService, useSelectedService } from './composition'; +import HeaderComponent from './components/header.component'; +import ContentComponent from './components/content.component'; +import FooterComponent from './components/footer.component'; + +export default defineComponent({ + name: LOOKUP_PANEL_NAME, + props: lookupPanelProps, + emits: ['change', 'confirm', 'close', 'update:modelValue'], + setup(props, context) { + + const { expose } = context; + + const { bem } = useBem(LOOKUP_PANEL_NAME); + + const { setState } = useLookupPanelState(); + const dataService = useDataService(props); + const seletedService = useSelectedService(props); + const searchService = useSearchService(props); + + setState({ panelProps: props, panelContext: context, dataService, seletedService, searchService }); + + expose({ + getTextValue: seletedService.getTextValue, + initLoadData: dataService.initLoadData + }); + + const renderLookupHeader = () => { + return ( + + ); + }; + + const renderLookupContent = () => { + return ; + }; + + const showFooter = computed(() => { + return false; + }); + const renderLookupFooter = () => { + return showFooter.value && ( + + ); + }; + + return () => { + return ( +
+ {renderLookupHeader()} + {renderLookupContent()} + {renderLookupFooter()} +
+ ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/lookup/src/lookup.component.tsx b/packages/mobile-ui-vue/components/lookup/src/lookup.component.tsx new file mode 100644 index 00000000000..a59fa12dc86 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/lookup.component.tsx @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { defineComponent } from 'vue'; +import { LOOKUP_NAME, lookupProps } from './lookup.props'; +import { useBem } from '@/components/common'; +import ButtonEdit from '@/components/button-edit'; +import LookupPanel from './lookup-panel.component'; +import { useLookupState } from './composition'; + +export default defineComponent({ + name: LOOKUP_NAME, + props: lookupProps, + emits: ['change', 'confirm', 'update:modelValue'], + setup(props, context) { + const { bem } = useBem(LOOKUP_NAME); + + const { buttonEditProps, lookupPanelSlotProps, inputValue, showPopup } = useLookupState(props, context); + + return () => { + return ( + + + + ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/lookup/src/lookup.props.ts b/packages/mobile-ui-vue/components/lookup/src/lookup.props.ts new file mode 100644 index 00000000000..c135c25d1d0 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/lookup.props.ts @@ -0,0 +1,71 @@ +import { ExtractPropTypes, PropType } from 'vue'; +import { BeforeLoadData, LoadTreeDataType, LookupDisplayType, OnlySelectLeaf, SearchField } from './composition/types'; +import { buttonEditProps } from '@/components/button-edit'; + +export const LOOKUP_PANEL_NAME = 'FmLookupPanel'; +export const LOOKUP_NAME = 'FmLookup'; + +export const LOOKUP_HTTP_SERVICE_TOKEN = Symbol('fm_lookup-http-service_token'); + +export const listLookupProps = { + title: { type: String, default: '' }, + + data: { type: Array as PropType[]>, default: () => [] }, + + uri: { type: String, default: '' }, + + idField: { type: String, default: '' }, + + textField: { type: String, default: '' }, + + multiSelect: { type: Boolean, default: false }, + + mappingFields: { type: Object, default: null }, + + selectedLimit: { type: Number, default: null }, + + pageSize: { type: Number, default: 20 }, + + enableFavorite: { type: Boolean, default: false }, + + enableSearch: { type: Boolean, default: true }, + + selectedData: { type: Object, default: null }, + + searchFields: { type: Array as PropType, default: [] }, + + httpServiceToken: { type: [String, Symbol], default: () => LOOKUP_HTTP_SERVICE_TOKEN }, + + beforeLoadData: { type: Function as PropType, default: null }, + + separator: { type: String, default: ',' } +}; + +export const treeLookupProps = { + enableFullTree: { type: Boolean, default: true }, + + enableCascade: { type: Boolean, default: false }, + + onlySelectLeaf: { type: String as PropType, default: OnlySelectLeaf.default }, + + loadTreeDataType: { type: String as PropType, default: LoadTreeDataType.default }, +}; + +export const navListlookupProps = { + +}; + +export const lookupPanelProps = { + ...listLookupProps, + ...treeLookupProps, + ...navListlookupProps, + displayType: { type: String as PropType, default: LookupDisplayType.List }, +}; + +export const lookupProps = { + ...buttonEditProps, + ...lookupPanelProps +}; + +export type LookupPanelProps = ExtractPropTypes; +export type LookupProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/lookup/src/lookup.scss b/packages/mobile-ui-vue/components/lookup/src/lookup.scss new file mode 100644 index 00000000000..b0329316d93 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/lookup.scss @@ -0,0 +1,39 @@ +@use '../../common/src/style/mixins/index.scss' as *; + +:root { + --fm-lookup-panel-background: var(--fm-background); + --fm-lookup-panel-search-list-zindex: var(--fm-zindex-3); + --fm-lookup-panel-search-list-background: var(--fm-background-white); +} + +@include b(lookup-panel){ + height: 100%; + display: flex; + flex-direction: column; + overflow: hidden; + background-color: var(--fm-lookup-panel-background); + @include e(header){ + + } + @include e(content){ + flex: 1; + overflow-y: auto; + padding-top: 10px; + position: relative; + } + @include e(search-list){ + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: none; + z-index: var(--fm-lookup-panel-search-list-zindex); + background: var(--fm-lookup-panel-search-list-background); + } + + @include e(footer){ + display: flex; + } + +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/picker-input/src/picker-input.props.ts b/packages/mobile-ui-vue/components/picker-input/src/picker-input.props.ts index 20230bd4f50..7a91fbf147f 100644 --- a/packages/mobile-ui-vue/components/picker-input/src/picker-input.props.ts +++ b/packages/mobile-ui-vue/components/picker-input/src/picker-input.props.ts @@ -11,8 +11,8 @@ export const PICKER_INPUT_NAME = 'FmPickerInput'; export const pickerInputProps = { ...buttonEditProps, ...pickerProps -} as Record; +}; export type PickerInputProps = ExtractPropTypes; -export const propsResolver = createPropsResolver(pickerInputProps, inputSchema, schemaMapper, schemaResolver); +export const propsResolver = createPropsResolver(pickerInputProps, inputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/popup/src/popup.component.tsx b/packages/mobile-ui-vue/components/popup/src/popup.component.tsx index 708e2d9e299..e773289279a 100644 --- a/packages/mobile-ui-vue/components/popup/src/popup.component.tsx +++ b/packages/mobile-ui-vue/components/popup/src/popup.component.tsx @@ -21,7 +21,6 @@ export default defineComponent({ const { emit, slots, attrs } = context; const closePopup = () => { - console.log('closePopup'); props.show && emit('update:show', false); }; diff --git a/packages/mobile-ui-vue/components/search/index.ts b/packages/mobile-ui-vue/components/search/index.ts new file mode 100644 index 00000000000..0dfb4456740 --- /dev/null +++ b/packages/mobile-ui-vue/components/search/index.ts @@ -0,0 +1,8 @@ +import { withInstall } from '@components/common'; +import searchInstallless from './src/search.component'; + +const Search = withInstall(searchInstallless); + +export * from './src/search.props'; +export { Search }; +export default Search; diff --git a/packages/mobile-ui-vue/components/search/src/search.component.tsx b/packages/mobile-ui-vue/components/search/src/search.component.tsx new file mode 100644 index 00000000000..43784181ae5 --- /dev/null +++ b/packages/mobile-ui-vue/components/search/src/search.component.tsx @@ -0,0 +1,75 @@ +import { computed, CSSProperties, defineComponent, ref, watch } from "vue"; +import { useBem } from "@/components/common"; +import InputGroup from "@/components/input-group"; +import Icon from "@/components/icon"; +import { SEARCH_NAME, SearchProps, searchProps } from "./search.props"; + +export default defineComponent({ + name: SEARCH_NAME, + props: searchProps, + emits: ['focus', 'blur', 'change', 'cancel', 'search'], + setup(props: SearchProps, context) { + + const { emit } = context; + + const { bem } = useBem(SEARCH_NAME); + + const innerValue = ref(props.modelValue); + watch(() => props.modelValue, () => { + innerValue.value = props.modelValue; + }); + + const handleKeypress = (event: KeyboardEvent) => { + if (event.key === 'Enter') { + emit('search', innerValue.value); + } + }; + + const inputGroupProps = computed(() => { + return { + class: bem('input'), + showPadding: false, + placeholder: props.placeholder, + clearable: props.clearable, + inputAlign: props.inputAlign, + disabled: props.disabled, + readonly: props.readonly, + onKeypress: handleKeypress, + onFocus: (event: Event) => emit('focus', event), + onBlur: (event: Event) => emit('blur', event), + onChange: (value: string) => emit('change', value) + }; + }); + + const inputSlots = { + left: () => + }; + + const inputStyle = computed(() => { + return { + backgroundColor: props.backgroundColor + }; + }); + + const renderInput = () => ( +
+ +
+ ); + + const renderAction = () => ( + props.actionText &&
+ {props.actionText} +
+ ); + + return () => { + return ( +
+ {renderInput()} + {renderAction()} +
+ ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/common/radio-checkbox/radio-checkbox.props.ts b/packages/mobile-ui-vue/components/search/src/search.props.ts similarity index 41% rename from packages/mobile-ui-vue/components/common/radio-checkbox/radio-checkbox.props.ts rename to packages/mobile-ui-vue/components/search/src/search.props.ts index 24f1312634c..8d74a50d73e 100644 --- a/packages/mobile-ui-vue/components/common/radio-checkbox/radio-checkbox.props.ts +++ b/packages/mobile-ui-vue/components/search/src/search.props.ts @@ -1,4 +1,4 @@ - + /** * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. * @@ -14,32 +14,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { PropType } from 'vue'; -export type RadioCheckboxType = 'default' | 'button'; -export const radioCheckboxCommonProps = { - /** - * 是否被选中 - */ - checked: { type: Boolean, default: false }, - /** - * 展示方向 水平或者垂直 - */ - direction: { type: String as PropType<'vertical' | 'horizontal'>, default: 'vertical' }, - /** - * 单选组类型 - */ - // mode: { type: String as PropType<'default' | 'button' | 'tag'>, default: 'default' }, - /** - * type为button或者tag时的颜色 - */ - type: { type: String as PropType, default: 'default' }, - /** - * type为button或者tag时的尺寸 - * 应该要弃用 - */ - size: { type: String as PropType<'small' | 'middle' | 'large'>, default: 'middle' }, - /** - * 选项列表 - */ - options: { type: Object, default: []} +import { ExtractPropTypes, PropType } from 'vue'; + +export const SEARCH_NAME = 'FmSearch'; + +export enum SearchShape { + round = 'round', + square = 'square' +} + +export const searchProps = { + modelValue: { type: String, default: '' }, + + shape: { type: String as PropType, default: SearchShape.round }, + + placeholder: { type: String, default: '' }, + + clearable: { type: Boolean, default: true }, + + backgroundColor: { type: String, default: '' }, + + showAction: { type: Boolean, default: false }, + + actionText: { type: String, default: '' }, + + inputAlign: { type: String, default: 'left' }, + + disabled: { type: Boolean, default: false }, + + readonly: { type: Boolean,default: false } }; + +export type SearchProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/search/src/search.scss b/packages/mobile-ui-vue/components/search/src/search.scss new file mode 100644 index 00000000000..d5ca04efcf2 --- /dev/null +++ b/packages/mobile-ui-vue/components/search/src/search.scss @@ -0,0 +1,32 @@ +@use '../../common/src/style/mixins/index.scss' as *; + +:root { + --fm-search-radius: 17px; + --fm-search-color: var(--fm-text-color); + --fm-search-background: var(--fm-background-white); + --fm-search-input-background: var(--fm-background); +} + +@include b(search){ + display: flex; + align-items: center; + padding: 8px 12px; + color: var(--fm-search-color); + background-color: var(--fm-search-background); + + @include e(input-wrapper){ + flex: 1; + padding: 5px 8px; + border-radius: 17px; + background-color: var( --fm-search-input-background); + } + + @include e(input){ + background-color: var( --fm-search-input-background); + } + + @include e(search-icon){ + margin-right: 4px; + color: var(--fm-text-color-light); + } +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/demos/lookup/basic.vue b/packages/mobile-ui-vue/demos/lookup/basic.vue new file mode 100644 index 00000000000..ef8540ab37b --- /dev/null +++ b/packages/mobile-ui-vue/demos/lookup/basic.vue @@ -0,0 +1,29 @@ + + diff --git a/packages/mobile-ui-vue/demos/lookup/http.vue b/packages/mobile-ui-vue/demos/lookup/http.vue new file mode 100644 index 00000000000..cc65f75d747 --- /dev/null +++ b/packages/mobile-ui-vue/demos/lookup/http.vue @@ -0,0 +1,36 @@ + + diff --git a/packages/mobile-ui-vue/demos/lookup/index.vue b/packages/mobile-ui-vue/demos/lookup/index.vue new file mode 100644 index 00000000000..beb0592372b --- /dev/null +++ b/packages/mobile-ui-vue/demos/lookup/index.vue @@ -0,0 +1,12 @@ + + diff --git a/packages/mobile-ui-vue/index.html b/packages/mobile-ui-vue/index.html index 59efb9525e5..23f687958c7 100644 --- a/packages/mobile-ui-vue/index.html +++ b/packages/mobile-ui-vue/index.html @@ -4,7 +4,7 @@ - + Farris Mobile diff --git a/packages/mobile-ui-vue/src/menu-data.ts b/packages/mobile-ui-vue/src/menu-data.ts index 0dff7a7ef99..9fa102a2562 100644 --- a/packages/mobile-ui-vue/src/menu-data.ts +++ b/packages/mobile-ui-vue/src/menu-data.ts @@ -109,6 +109,12 @@ export default { name: "button-edit", url: "/demos/button-edit", component: "/button-edit", + }, + { + title: "帮助", + name: "lookup", + url: "/demos/lookup", + component: "/lookup", } ], }, -- Gitee From a5613f3e0179afc801b37997433136a40298288b Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Fri, 21 Mar 2025 22:21:25 +0800 Subject: [PATCH 083/153] =?UTF-8?q?feature:=20=E6=A0=BC=E5=BC=8F=E5=8C=96?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E9=94=99=E8=AF=AF=E4=BF=A1=E6=81=AF=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=B2=BE=E7=A1=AE=E6=98=BE=E7=A4=BA=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/validation.service.ts | 73 ++++++++++++--- .../lib/verify-detail.service.ts | 29 +----- .../form-array-store-config-manager.ts | 14 ++- .../form/configs/form-store-config-manager.ts | 12 +++ .../store/form/configs/form-store-config.ts | 50 ++++++++++ packages/devkit/lib/store/form/form-array.ts | 6 +- .../lib/store/form/form-error-formatter.ts | 92 +++++++++++++++++++ packages/devkit/lib/store/form/form-store.ts | 7 ++ packages/devkit/lib/store/form/index.ts | 1 + packages/devkit/lib/store/form/types.ts | 28 +++++- .../dynamic-demo/module/dynamic-module.ts | 26 +++--- .../module/services/validation.service.ts | 12 ++- 12 files changed, 286 insertions(+), 64 deletions(-) create mode 100644 packages/devkit/lib/store/form/form-error-formatter.ts diff --git a/packages/command-services/lib/validation.service.ts b/packages/command-services/lib/validation.service.ts index c9b6e88f090..e509f8b0fb6 100644 --- a/packages/command-services/lib/validation.service.ts +++ b/packages/command-services/lib/validation.service.ts @@ -1,20 +1,29 @@ -import { ViewModel, ViewModelState, FormError, FormArrayError } from "@farris/devkit-vue"; +import { ViewModel, ViewModelState, FormError, FormArrayError, FlattenedControlError, FormErrorFormatter } from "@farris/devkit-vue"; import { BaseDataService } from "./data-services/base-data.service"; -import { VerifyDetailService } from './verify-detail.service'; +import { VerifyDetailOptions, VerifyDetailService } from './verify-detail.service'; + export class ValidationService extends BaseDataService { + /** + * 表单错误格式化器 + */ + private formErrorFormatter: FormErrorFormatter; + /** * 错误提示服务 */ private verifyDetailService: VerifyDetailService; + /** * 构造函数 */ constructor(viewModel: ViewModel) { super(viewModel); + this.formErrorFormatter = new FormErrorFormatter(); this.verifyDetailService = this.getService(VerifyDetailService); + } /** @@ -32,53 +41,89 @@ export class ValidationService extends BaseDataService { } /** - * 验证全部 + * 验证全部表单 */ - public validateAll(){ + public validateAll(): Promise { const viewModels = this.module.getViewModels(); - let allViewModelErrors: FormArrayError = []; + let allViewModelErrors: FlattenedControlError[] = []; viewModels.forEach((viewModel) => { - const viewModelError = this.validateByViewModel(viewModel) as FormArrayError; + const viewModelError = this.validateByViewModel(viewModel) as FlattenedControlError[]; if (viewModelError && Array.isArray(viewModelError)) { allViewModelErrors = allViewModelErrors.concat(viewModelError); } }); if (allViewModelErrors.length > 0) { - this.verifyDetailService.show({}); + const verifyDetailOptions = this.buildVerifyDetailOptions(allViewModelErrors); + this.verifyDetailService.show(verifyDetailOptions); return Promise.reject(allViewModelErrors) } return Promise.resolve(null); } - public resetValidation(){ + public resetValidation() { return Promise.resolve(); } /** - * 验证指定视图模型的表单 + * 验证指定视图模型内的表单 */ - private validateByViewModel(viewModel: ViewModel): FormArrayError | null { + private validateByViewModel(viewModel: ViewModel): FlattenedControlError[] | null { const { formStore, formArrayStore } = viewModel; - let allErrors: FormArrayError = []; + let allErrors: FlattenedControlError[] = []; if (formStore) { - const formKey = formStore.getKey(); const formError = formStore.validate(); if (formError) { - allErrors.push({formKey, formError}); + const flattenFormErrors = this.formErrorFormatter.flattenFormError(formStore, formError); + allErrors = allErrors.concat(flattenFormErrors); } } if (formArrayStore) { const formArrayError = formArrayStore.validate(); if (formArrayError && Array.isArray(formArrayError)) { - allErrors = allErrors.concat(formArrayError); + const flattenFormArrayErrors = this.formErrorFormatter.flattenFormArrayError(formArrayStore, formArrayError); + allErrors = allErrors.concat(flattenFormArrayErrors); } } return allErrors && allErrors.length > 0 ? allErrors : null; } + /** + * 构造错误提示配置 + */ + public buildVerifyDetailOptions(errors: FlattenedControlError[]): VerifyDetailOptions { + const verifyTypes = [ + { id: '1', type: 'all', title: '全部' }, + { id: '2', type: 'error', title: '错填', iconCls: 'f-icon-default', iconStyle: 'color:pink;' }, + { id: '3', type: 'empty', title: '漏填', iconStyle: 'color:pink;' }, + ]; + const verifyList: any[] = []; + errors.forEach((error: FlattenedControlError, errorIndex) => { + const { formIndex, formDisplayName, controlDisplayName, name, message } = error; + const verifyItem = { + id: errorIndex, + type: name === 'required' ? 'empty' : 'error', + title: '', + msg: message, + }; + if (formIndex !== undefined) { + verifyItem.title = `${formDisplayName} 第${formIndex}行 - ${controlDisplayName}`; + } else { + verifyItem.title = `${formDisplayName} - ${controlDisplayName}`; + } + verifyList.push(verifyItem); + }); + + const options: VerifyDetailOptions = { + showList: true, + verifyType: verifyTypes, + verifyList: verifyList, + }; + + return options; + } } \ No newline at end of file diff --git a/packages/command-services/lib/verify-detail.service.ts b/packages/command-services/lib/verify-detail.service.ts index f14527839ce..d3ab6f5c597 100644 --- a/packages/command-services/lib/verify-detail.service.ts +++ b/packages/command-services/lib/verify-detail.service.ts @@ -3,7 +3,7 @@ import { FVerifyDetailService, VerifyDetailProps } from '@farris/ui-vue'; /** * 验证配置 */ -type VerifyDetailOptions = Partial; +export type VerifyDetailOptions = Partial; /** * 验证错误提示服务 @@ -14,7 +14,6 @@ export class VerifyDetailService { * 显示验证信息 */ public show(options: VerifyDetailOptions, parentElement?: HTMLElement): void { - options = this.buildOptions(); FVerifyDetailService.show(options as any, parentElement); } @@ -24,30 +23,4 @@ export class VerifyDetailService { public clear(): void { FVerifyDetailService.clear(); } - - /** - * 构造验证配置信息 - */ - public buildOptions() { - const verifyTypes = [ - { id: '1', type: 'all', title: '全部' }, - { id: '2', type: 'error', title: '错填', iconCls: 'f-icon-default', iconStyle: 'color:pink;' }, - { id: '3', type: 'empty', title: '漏填', iconStyle: 'color:pink;' }, - ]; - - const verifyList = [ - { id: '1', title: '单据信息01[销售组织]', msg: '字段值不能为空', type: 'empty' }, - { id: '2', title: '单据信息02[销售组织]', msg: '字段值不能为空', type: 'empty' }, - { id: '3', title: '单据信息03[销售组织]', msg: '字段值填写错误', type: 'error' }, - { id: '4', title: '单据信息04[销售组织]', msg: '字段值填写问题', type: 'error' }, - ]; - - const options: VerifyDetailOptions = { - showList: true, - verifyType: verifyTypes, - verifyList: verifyList, - }; - - return options; - } } diff --git a/packages/devkit/lib/store/form/configs/form-array-store-config-manager.ts b/packages/devkit/lib/store/form/configs/form-array-store-config-manager.ts index 5eabc9b850b..865e15769fe 100644 --- a/packages/devkit/lib/store/form/configs/form-array-store-config-manager.ts +++ b/packages/devkit/lib/store/form/configs/form-array-store-config-manager.ts @@ -41,7 +41,7 @@ class FormArrayStoreConfigManager { } /** - * 获取表单控件配置 + * 获取全部表单控件配置 */ public getControlConfigs(): FormControlConfig[] { const stateConfig = this.getFormStateConfig(); @@ -49,6 +49,18 @@ class FormArrayStoreConfigManager { return controlConfigs; } + + /** + * 获取表单控件配置 + */ + public getControlConfig(name: string): FormControlConfig | undefined { + const controlConfigs = this.getControlConfigs(); + const targetControlConfig = controlConfigs.find((controlConfig) => { + return controlConfig.name === name; + }); + + return targetControlConfig; + } } export { FormArrayStoreConfigManager }; diff --git a/packages/devkit/lib/store/form/configs/form-store-config-manager.ts b/packages/devkit/lib/store/form/configs/form-store-config-manager.ts index 413a38e9541..83cacbec305 100644 --- a/packages/devkit/lib/store/form/configs/form-store-config-manager.ts +++ b/packages/devkit/lib/store/form/configs/form-store-config-manager.ts @@ -49,6 +49,18 @@ class FormStoreConfigManager { return controlConfigs; } + + /** + * 获取表单控件配置 + */ + public getControlConfig(name: string): FormControlConfig | undefined { + const controlConfigs = this.getControlConfigs(); + const targetControlConfig = controlConfigs.find((controlConfig) => { + return controlConfig.name === name; + }); + + return targetControlConfig; + } } export { FormStoreConfigManager }; diff --git a/packages/devkit/lib/store/form/configs/form-store-config.ts b/packages/devkit/lib/store/form/configs/form-store-config.ts index ec370ff0710..227bdc3dd26 100644 --- a/packages/devkit/lib/store/form/configs/form-store-config.ts +++ b/packages/devkit/lib/store/form/configs/form-store-config.ts @@ -15,6 +15,11 @@ interface FormControlConfig { */ name: string; + /** + * 显示名称 + */ + displayName: string; + /** * 绑定类型 */ @@ -42,9 +47,29 @@ interface FormStateConfig { * 表单仓库配置 */ interface FormStoreConfig extends StoreConfig { + /** + * ID + */ id: string; + + /** + * 类型 + */ type?: Type>; + + /** + * 显示名称 + */ + displayName: string; + + /** + * 绑定路径 + */ bindingPath: string; + + /** + * 状态配置 + */ state: FormStateConfig; }; @@ -52,6 +77,10 @@ interface FormStoreConfig extends StoreConfig { * 表单数组状态配置 */ interface FormArrayStateConfig { + + /** + * 控件配置 + */ controls: FormControlConfig[]; } @@ -59,9 +88,30 @@ interface FormArrayStateConfig { * 表单数组仓库配置 */ interface FormArrayStoreConfig extends StoreConfig { + + /** + * ID + */ id: string; + + /** + * 类型 + */ type?: Type>; + + /** + * 显示名称 + */ + displayName: string; + + /** + * 绑定路径 + */ bindingPath: string; + + /** + * 绑定状态 + */ state: FormStateConfig; }; diff --git a/packages/devkit/lib/store/form/form-array.ts b/packages/devkit/lib/store/form/form-array.ts index cea1d4162c8..a4f2bb58d67 100644 --- a/packages/devkit/lib/store/form/form-array.ts +++ b/packages/devkit/lib/store/form/form-array.ts @@ -125,11 +125,11 @@ class FormArray { const formArrayValue: FormArrayValue = []; const formArrayError: FormArrayError = []; - this.forms.forEach((form) => { + this.forms.forEach((form, formIndex) => { const { key: formKey, value: formValue, error: formError } = form; - formArrayValue.push({ formKey, formValue }); + formArrayValue.push({ formKey, formIndex, formValue }); if (formError) { - formArrayError.push({ formKey, formError }); + formArrayError.push({ formKey, formIndex, formError }); } }); diff --git a/packages/devkit/lib/store/form/form-error-formatter.ts b/packages/devkit/lib/store/form/form-error-formatter.ts new file mode 100644 index 00000000000..49302e91b9b --- /dev/null +++ b/packages/devkit/lib/store/form/form-error-formatter.ts @@ -0,0 +1,92 @@ + +import { ValidationError } from './validation/index'; +import { FormError, FormArrayError } from './types'; +import { FormState, FormArrayState, } from './form-state'; +import { FormStore } from './form-store'; +import { FormArrayStore } from './form-array-store'; + +/** + * 补充了控件信息的验证错误 + */ +interface FlattenedControlError extends ValidationError { + formKey: string, + formIndex?: number, + formDisplayName: string, + controlDisplayName: string, +} + +/** + * 表单验证错误格式化器 + */ +class FormErrorFormatter { + + /** + * 格式化错误信息 + */ + public flattenFormError(formStore: FormStore, formError: FormError): FlattenedControlError[] { + if (!formError) { + return []; + } + + const configManager = formStore.getConfigManager(); + const storeConfig = configManager.getStoreConfig(); + const formKey = formStore.getKey(); + const formDisplayName = storeConfig.displayName; + + const errors: FlattenedControlError[] = []; + Object.keys(formError).forEach((controlName: string) => { + const controlConfig = configManager.getControlConfig(controlName); + if (!controlConfig) { + throw new Error(`FormControlConfig(name=${controlName}) not found`) + } + const controlDisplayName = controlConfig.displayName; + const controlError = formError[controlName]; + const formattedControlError = Object.assign({ + formKey, + formDisplayName, + controlDisplayName + }, controlError); + errors.push(formattedControlError); + }); + + return errors; + } + + /** + * 输出错误信息 + */ + public flattenFormArrayError(formArrayStore: FormArrayStore, formArrayError: FormArrayError): FlattenedControlError[] { + if (!formArrayError) { + return []; + } + + const configManager = formArrayStore.getConfigManager(); + const storeConfig = configManager.getStoreConfig(); + const formDisplayName = storeConfig.displayName; + + const errors: FlattenedControlError[] = []; + formArrayError.forEach((formArrayItemError) => { + const { formKey, formIndex, formError } = formArrayItemError; + Object.keys(formError).forEach((controlName: string) => { + const controlConfig = configManager.getControlConfig(controlName); + if (!controlConfig) { + throw new Error(`FormControlConfig(name=${controlName}) not found`) + } + + const controlDisplayName = controlConfig.displayName; + const controlError = formError[controlName]; + const error = Object.assign({ + formKey, + formIndex, + formDisplayName, + controlDisplayName + }, controlError); + errors.push(error); + }); + }); + + return errors; + } +} + +export { FlattenedControlError, FormErrorFormatter }; \ No newline at end of file diff --git a/packages/devkit/lib/store/form/form-store.ts b/packages/devkit/lib/store/form/form-store.ts index e8523faeeeb..3ab761efd42 100644 --- a/packages/devkit/lib/store/form/form-store.ts +++ b/packages/devkit/lib/store/form/form-store.ts @@ -141,6 +141,13 @@ class FormStore extends Store { return controlError; } + /** + * 获取配置管理器 + */ + public getConfigManager() { + return this.configManager; + } + /** * 刷新状态 */ diff --git a/packages/devkit/lib/store/form/index.ts b/packages/devkit/lib/store/form/index.ts index 61638fb06a2..51a1293d21f 100644 --- a/packages/devkit/lib/store/form/index.ts +++ b/packages/devkit/lib/store/form/index.ts @@ -5,4 +5,5 @@ export * from './form-change'; export * from './form-state'; export * from './form-store'; export * from './form-array-store'; +export * from './form-error-formatter'; diff --git a/packages/devkit/lib/store/form/types.ts b/packages/devkit/lib/store/form/types.ts index 6ceaeb56436..e3f64d6a5f9 100644 --- a/packages/devkit/lib/store/form/types.ts +++ b/packages/devkit/lib/store/form/types.ts @@ -24,16 +24,34 @@ type FormValue = { [controlName: string]: any }; /** * 表单所有控件的错误信息 */ -type FormError = { [controlName: string]: ValidationError}; +type FormError = { [controlName: string]: ValidationError }; + +/** + * 表单数组内单个表单的值 + */ +type FormArrayItemValue = { + formKey: string, + formIndex: number, + formValue: FormValue +} /** * 表单数组内所有表单的值集合 */ -type FormArrayValue = Array<{formKey: string, formValue: FormValue}>; +type FormArrayValue = Array; + +/** + * 表单数组内单个表单的错误 + */ +type FormArrayItemError = { + formKey: string, + formIndex: number, + formError: FormError +}; /** - * 表单内所有表单 + * 表单内所有表单的错误集合 */ -type FormArrayError = Array<{formKey: string, formError: FormError}>; +type FormArrayError = Array; -export { FormControlBindingType, FormValue, FormError, FormArrayValue, FormArrayError }; +export { FormControlBindingType, FormValue, FormError, FormArrayItemValue, FormArrayValue, FormArrayItemError, FormArrayError }; diff --git a/packages/devkit/src/views/dynamic-demo/module/dynamic-module.ts b/packages/devkit/src/views/dynamic-demo/module/dynamic-module.ts index 40282609331..e6680768bf8 100644 --- a/packages/devkit/src/views/dynamic-demo/module/dynamic-module.ts +++ b/packages/devkit/src/views/dynamic-demo/module/dynamic-module.ts @@ -287,17 +287,18 @@ export const dynamicModuleConfig: ModuleConfig = { formStores: [ { id: 'dynamic-form-store', + displayName: '员工基本信息', bindingPath: '/', state: { controls: [ { - name: 'code', bindingType: 'EntityState', bindingPath: '/code', + name: 'code', displayName: '编号', bindingType: 'EntityState', bindingPath: '/code', validationRules: [ { name: 'required' }, ] }, { - name: 'name', bindingType: 'EntityState', bindingPath: '/name', + name: 'name', displayName: '姓名', bindingType: 'EntityState', bindingPath: '/name', validationRules: [ { name: 'required' }, { name: 'maxLength', maxLength: 4 }, @@ -305,27 +306,27 @@ export const dynamicModuleConfig: ModuleConfig = { ] }, { - name: 'age', bindingType: 'EntityState', bindingPath: '/age', + name: 'age', displayName: '年龄', bindingType: 'EntityState', bindingPath: '/age', validationRules: [ { name: 'maxValue', maxValue: 65 }, { name: 'minValue', minValue: 20 } ] }, { - name: 'birthday', bindingType: 'EntityState', bindingPath: '/birthday', + name: 'birthday', displayName: '生日', bindingType: 'EntityState', bindingPath: '/birthday', validationRules: [ { name: 'maxDate', maxDate: '2025-01-01' }, { name: 'minDate', minDate: '1960-01-01' } ] }, { - name: 'mobile', bindingType: 'EntityState', bindingPath: '/mobile', + name: 'mobile', displayName: '手机', bindingType: 'EntityState', bindingPath: '/mobile', validationRules: [ { name: 'pattern', pattern: /^1[3-9]\d{9}$/ }, ] }, { - name: 'address', bindingType: 'EntityState', bindingPath: '/address', + name: 'address', displayName: '住址', bindingType: 'EntityState', bindingPath: '/address', validationRules: [ { name: 'customFunction', customFn: (value: any) => { return value && value.startsWith('山东'); } }, ] @@ -337,17 +338,18 @@ export const dynamicModuleConfig: ModuleConfig = { formArrayStores: [ { id: 'dynamic-form-array-store', + displayName: '员工列表', bindingPath: '/', state: { controls: [ { - name: 'code', bindingType: 'EntityState', bindingPath: '/code', + name: 'code', displayName: '编号', bindingType: 'EntityState', bindingPath: '/code', validationRules: [ { name: 'required' }, ] }, { - name: 'name', bindingType: 'EntityState', bindingPath: '/name', + name: 'name', displayName: '姓名', bindingType: 'EntityState', bindingPath: '/name', validationRules: [ { name: 'required' }, { name: 'maxLength', maxLength: 4 }, @@ -355,27 +357,27 @@ export const dynamicModuleConfig: ModuleConfig = { ] }, { - name: 'age', bindingType: 'EntityState', bindingPath: '/age', + name: 'age', displayName: '年龄', bindingType: 'EntityState', bindingPath: '/age', validationRules: [ { name: 'maxValue', maxValue: 65 }, { name: 'minValue', minValue: 20 } ] }, { - name: 'birthday', bindingType: 'EntityState', bindingPath: '/birthday', + name: 'birthday', displayName: '生日', bindingType: 'EntityState', bindingPath: '/birthday', validationRules: [ { name: 'maxDate', maxDate: '2025-01-01' }, { name: 'minDate', minDate: '1960-01-01' } ] }, { - name: 'mobile', bindingType: 'EntityState', bindingPath: '/mobile', + name: 'mobile', displayName:'手机', bindingType: 'EntityState', bindingPath: '/mobile', validationRules: [ { name: 'pattern', pattern: /^1[3-9]\d{9}$/ }, ] }, { - name: 'address', bindingType: 'EntityState', bindingPath: '/address', + name: 'address', displayName:'住址', bindingType: 'EntityState', bindingPath: '/address', validationRules: [ { name: 'customFunction', customFn: (value: any) => { return value && value.startsWith('山东'); } }, ] diff --git a/packages/devkit/src/views/dynamic-demo/module/services/validation.service.ts b/packages/devkit/src/views/dynamic-demo/module/services/validation.service.ts index 7954ff07dcb..0529bc50bbe 100644 --- a/packages/devkit/src/views/dynamic-demo/module/services/validation.service.ts +++ b/packages/devkit/src/views/dynamic-demo/module/services/validation.service.ts @@ -1,4 +1,4 @@ -import { ViewModelState, ViewModel, Entity, EntityState, EntityStore, UIState, UIStore } from '../../../../../lib/index'; +import { ViewModelState, ViewModel, FormErrorFormatter } from '../../../../../lib/index'; import { BaseDataService } from './base-data.service'; /** @@ -6,11 +6,17 @@ import { BaseDataService } from './base-data.service'; */ class ValidationService extends BaseDataService { + /** + * 验证错误格式化器 + */ + private formErrorFormatter: FormErrorFormatter; + /** * 构造函数 */ constructor(viewModel: ViewModel) { super(viewModel); + this.formErrorFormatter = new FormErrorFormatter(); } /** @@ -19,12 +25,16 @@ class ValidationService extends BaseDataService { public validate() { const { formStore, formArrayStore } = this.viewModel; const formError = formStore.validate(); + const flattenedFormErrors = this.formErrorFormatter.flattenFormError(formStore, formError); console.log('----------formError----------'); console.log(formError); + console.log(flattenedFormErrors); console.log('----------formArrayError----------'); const formArrayError = formArrayStore.validate(); + const flattenedFormArrayErrors = this.formErrorFormatter.flattenFormArrayError(formArrayStore, formArrayError); console.log(formArrayError); + console.log(flattenedFormArrayErrors); } /** -- Gitee From c87c8ea3c50b3032a8433b90ffab4b48c58fd82f Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Sat, 22 Mar 2025 09:36:05 +0800 Subject: [PATCH 084/153] =?UTF-8?q?feature:=20=E8=A1=A8=E5=8D=95=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E8=BD=AC=E6=8D=A2=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=EF=BC=8C=E4=B8=8E=E9=AA=8C=E8=AF=81=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E6=8F=90=E7=A4=BA=E5=BC=B9=E7=AA=97=E9=9B=86=E6=88=90?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/validation.service.ts | 2 +- .../form/form-array-store-config-builder.ts | 21 ++----------------- .../form/form-control-config-builder.ts | 3 ++- .../form/form-store-config-builder.ts | 7 ++++--- 4 files changed, 9 insertions(+), 24 deletions(-) diff --git a/packages/command-services/lib/validation.service.ts b/packages/command-services/lib/validation.service.ts index e509f8b0fb6..c81bd99ff33 100644 --- a/packages/command-services/lib/validation.service.ts +++ b/packages/command-services/lib/validation.service.ts @@ -111,7 +111,7 @@ export class ValidationService extends BaseDataService { msg: message, }; if (formIndex !== undefined) { - verifyItem.title = `${formDisplayName} 第${formIndex}行 - ${controlDisplayName}`; + verifyItem.title = `${formDisplayName} 第${formIndex + 1}行 - ${controlDisplayName}`; } else { verifyItem.title = `${formDisplayName} - ${controlDisplayName}`; } diff --git a/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts b/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts index 92dd2406adc..09f827480f0 100644 --- a/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts +++ b/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts @@ -23,9 +23,11 @@ class FormArrayStoreConfigBuilder { * 构造配置 */ public build(viewModelNode: any): FormArrayStoreConfig { + const vmComponentNode = this.formMetaQuery.getVmComponentByVmId(viewModelNode.id); const stateConfig = this.buildStateConfig(viewModelNode); const storeConfig: FormArrayStoreConfig = { id: viewModelNode.code + '-form-array-store', + displayName: viewModelNode.name, bindingPath: viewModelNode.bindTo, state: stateConfig }; @@ -94,25 +96,6 @@ class FormArrayStoreConfigBuilder { return wrappedDataGridNode; } - - /** - * 获取列表对应卡片的组件 - */ - private getVmComponentNode(viewModelNode: any): any { - const listVmComponentNode = this.formMetaQuery.getVmComponentByVmId(viewModelNode.id); - - // 对用对应卡片的组件模拟批量编辑场景 - const vmComponentNodes = this.formMetaQuery.getVmComponents(); - const cardVmComponentNode = vmComponentNodes.find((vmComponentNode) => { - return vmComponentNode !== listVmComponentNode && vmComponentNode.bindTo === listVmComponentNode.bindTo; - }); - - if (!listVmComponentNode && !cardVmComponentNode) { - throw new Error(`Component(viewModel=${viewModelNode.id}) not found`); - } - - return cardVmComponentNode ? cardVmComponentNode : listVmComponentNode; - } } export { FormArrayStoreConfigBuilder }; diff --git a/packages/renderer/src/config-builders/form/form-control-config-builder.ts b/packages/renderer/src/config-builders/form/form-control-config-builder.ts index 74326af1482..2b9ac336e35 100644 --- a/packages/renderer/src/config-builders/form/form-control-config-builder.ts +++ b/packages/renderer/src/config-builders/form/form-control-config-builder.ts @@ -30,10 +30,11 @@ class FormControlConfigBuilder { */ public build(viewModelNode: any, controlNode: any): FormControlConfig { const name = controlNode.id; + const displayName = controlNode.type === 'form-group' ? controlNode.label: controlNode.title; const bindingType = this.getBindingType(controlNode); const bindingPath = this.getBindingPath(viewModelNode, controlNode); const validationRules = this.getValidationRules(controlNode); - const controlConfig = { name, bindingType, bindingPath, validationRules }; + const controlConfig = { name, displayName, bindingType, bindingPath, validationRules }; return controlConfig; } diff --git a/packages/renderer/src/config-builders/form/form-store-config-builder.ts b/packages/renderer/src/config-builders/form/form-store-config-builder.ts index a374b27f996..a6da226c0b1 100644 --- a/packages/renderer/src/config-builders/form/form-store-config-builder.ts +++ b/packages/renderer/src/config-builders/form/form-store-config-builder.ts @@ -23,9 +23,11 @@ class FormStoreConfigBuilder { * 构造配置 */ public build(viewModelNode: any): FormStoreConfig { - const stateConfig = this.buildStateConfig(viewModelNode); + const vmComponentNode = this.formMetaQuery.getVmComponentByVmId(viewModelNode.id); + const stateConfig = this.buildStateConfig(viewModelNode, vmComponentNode); const storeConfig: FormStoreConfig = { id: viewModelNode.code + '-form-store', + displayName: vmComponentNode.name, bindingPath: viewModelNode.bindTo, state: stateConfig }; @@ -36,8 +38,7 @@ class FormStoreConfigBuilder { /** * 获取表单状态配置 */ - private buildStateConfig(viewModelNode: any): FormStateConfig { - const vmComponentNode = this.formMetaQuery.getVmComponentByVmId(viewModelNode.id); + private buildStateConfig(viewModelNode: any, vmComponentNode: any): FormStateConfig { if (!vmComponentNode) { throw new Error(`Component(viewModel=${viewModelNode.id}) not found`); } -- Gitee From 517879e099aa1513e2e6170e633a25a10ccc7475 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Sat, 22 Mar 2025 14:46:09 +0800 Subject: [PATCH 085/153] =?UTF-8?q?feature:=20=E4=B8=8B=E6=8B=89=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E8=AE=BE=E8=AE=A1=E5=99=A8=E5=B1=9E=E6=80=A7=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../farris-theme/theme/components/verify-detail.scss | 12 +++++------- .../property-config/combo-list.property-config.ts | 5 +++++ .../combo-list/src/schema/combo-list.schema.json | 5 +++++ .../verify-detail/src/verify-detail.component.tsx | 8 ++++---- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/farris-theme/theme/components/verify-detail.scss b/packages/farris-theme/theme/components/verify-detail.scss index 17132ad3ab6..93adf6accb7 100644 --- a/packages/farris-theme/theme/components/verify-detail.scss +++ b/packages/farris-theme/theme/components/verify-detail.scss @@ -29,10 +29,10 @@ bottom:1.75rem; width: 28.125rem; .f-verify-form-content{ - // background-color: #fff; - // box-shadow: 0 2px 8px 0 rgba(0,0,0,0.15); - border-radius: .125rem; + border-radius: 4px; width: 100%; + overflow: hidden; + box-shadow: 0 2px 8px 0 rgba(0,0,0,0.15); .f-verify-form-content-arrow{ display: block; position: absolute; @@ -43,9 +43,8 @@ background: 0 0; border-style: solid; border-width: 0.3125rem; - // box-shadow: 2px 2px 5px rgba(0,0,0,.08); + box-shadow: 2px 2px 5px rgba(0,0,0,.08); transform: translateX(-50%) rotate(45deg); - // border-color:transparent #fff #fff transparent; } .f-verify-form-content-list{ position: relative; @@ -107,12 +106,11 @@ } .list-title{ font-size: 0.875rem; - // color: rgba(0,0,0,0.75); line-height: 1.375rem; } .list-msg{ font-size: 0.75rem; - // color: rgba(0,0,0,0.45); + color: rgba(0,0,0,0.45); line-height: 1.25rem; } } diff --git a/packages/ui-vue/components/combo-list/src/property-config/combo-list.property-config.ts b/packages/ui-vue/components/combo-list/src/property-config/combo-list.property-config.ts index c78c17365bb..eb633a1d16b 100644 --- a/packages/ui-vue/components/combo-list/src/property-config/combo-list.property-config.ts +++ b/packages/ui-vue/components/combo-list/src/property-config/combo-list.property-config.ts @@ -66,6 +66,11 @@ export class ComboListProperty extends InputBaseProperty { title: "启用多选", type: "boolean" }, + maxLength: { + description: "", + title: "最大输入长度", + type: "number" + }, }, this.setEditorPropertyRelates); diff --git a/packages/ui-vue/components/combo-list/src/schema/combo-list.schema.json b/packages/ui-vue/components/combo-list/src/schema/combo-list.schema.json index eb553404d4d..750b9fd440e 100644 --- a/packages/ui-vue/components/combo-list/src/schema/combo-list.schema.json +++ b/packages/ui-vue/components/combo-list/src/schema/combo-list.schema.json @@ -129,6 +129,11 @@ "type": "boolean", "default": false }, + "maxLength": { + "description": "", + "type": "number", + "default": null + }, "visible": { "description": "", "type": "boolean", diff --git a/packages/ui-vue/components/verify-detail/src/verify-detail.component.tsx b/packages/ui-vue/components/verify-detail/src/verify-detail.component.tsx index 09be3291a1b..24a732a04c5 100644 --- a/packages/ui-vue/components/verify-detail/src/verify-detail.component.tsx +++ b/packages/ui-vue/components/verify-detail/src/verify-detail.component.tsx @@ -65,12 +65,12 @@ export default defineComponent({
  • errorClick(item)}>
    -

    +

    {item.title} -

    -

    +

    +
    {item.msg} -

    +
  • ); -- Gitee From a3a39374c74e00b40877e88cf3e488b4c431e388 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Sat, 22 Mar 2025 15:12:05 +0800 Subject: [PATCH 086/153] =?UTF-8?q?feature:=201=E3=80=81BEF=E6=94=AF?= =?UTF-8?q?=E6=8C=81VO=E5=8F=98=E9=87=8F=E7=AE=A1=E7=90=86=EF=BC=9B2?= =?UTF-8?q?=E3=80=81PC=E5=92=8CMobile=E8=A1=A8=E5=8D=95=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96VO=E5=8F=98=E9=87=8F=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/bef/lib/bef-repository-config.ts | 20 ++ packages/bef/lib/bef-repository.ts | 19 +- packages/bef/lib/bef-variable-manager.ts | 228 ++++++++++++++++++ packages/bef/lib/index.ts | 1 + .../repository-config-builder.ts | 30 ++- packages/mobile-ui-vue/components/index.ts | 29 ++- .../repository-config-builder.ts | 28 ++- 7 files changed, 330 insertions(+), 25 deletions(-) create mode 100644 packages/bef/lib/bef-repository-config.ts create mode 100644 packages/bef/lib/bef-variable-manager.ts diff --git a/packages/bef/lib/bef-repository-config.ts b/packages/bef/lib/bef-repository-config.ts new file mode 100644 index 00000000000..465c2eba3ad --- /dev/null +++ b/packages/bef/lib/bef-repository-config.ts @@ -0,0 +1,20 @@ +import { Type, RepositoryConfig } from '@farris/devkit-vue'; +import { BefProxy } from './bef-proxy'; + +/** + * Bef远程仓库变量配置 + */ +interface BefVariableConfig { + name: string; +} + +/** + * Bef远程仓库配置 + */ +interface BefRepositoryConfig extends RepositoryConfig { + baseUrl: string; + variables: BefVariableConfig[]; + apiProxyType?: Type; +} + +export { BefVariableConfig, BefRepositoryConfig }; diff --git a/packages/bef/lib/bef-repository.ts b/packages/bef/lib/bef-repository.ts index a35f69a7223..9e4c5113b6c 100644 --- a/packages/bef/lib/bef-repository.ts +++ b/packages/bef/lib/bef-repository.ts @@ -3,13 +3,16 @@ import { } from '@farris/devkit-vue'; import { FrameworkSessionService } from './framework-session.service'; import { BefSessionHandlingStrategyFactory, BefSessionService } from './session/index'; +import { BefRepositoryConfig } from './bef-repository-config'; import { BefProxy } from './bef-proxy'; import { BefProxyExtend } from './bef-proxy-extend'; +import { BefVariableManager } from './bef-variable-manager'; /** * Bef实体仓库 */ class BefRepository extends Repository { + /** * Bef代理 */ @@ -35,6 +38,11 @@ class BefRepository extends Repository { */ public paginationInfo: any = null; + /** + * 变量管理器 + */ + public variableManager: BefVariableManager; + /** * 构造函数 */ @@ -46,11 +54,12 @@ class BefRepository extends Repository { /** * 初始化 */ - public init(config: RepositoryConfig) { + public init(config: BefRepositoryConfig) { super.init(config); this.initApiProxy(config); this.initSessionService(); this.initPaginationInfo(); + this.initVariableManager(config); } /** @@ -88,6 +97,14 @@ class BefRepository extends Repository { this.entityStore.setEntityPagination(pagination); } + /** + * 初始化变量变更 + */ + private initVariableManager(config: RepositoryConfig) { + const variableConfigs = config.variables; + this.variableManager = new BefVariableManager(this.module, variableConfigs); + } + /** * 查询实体 */ diff --git a/packages/bef/lib/bef-variable-manager.ts b/packages/bef/lib/bef-variable-manager.ts new file mode 100644 index 00000000000..54fd431b342 --- /dev/null +++ b/packages/bef/lib/bef-variable-manager.ts @@ -0,0 +1,228 @@ +import { format } from 'date-fns'; +import { Module, UIStore, UIState } from '@farris/devkit-vue'; +import { BefVariableConfig } from './bef-repository-config'; +import { ChangeDetailType, ChangeDetail } from './change/types'; + +/** + * Bef变量管理器 + */ +class BefVariableManager { + + /** + * 模块 + */ + private module: Module; + + /** + * 根UI仓库 + */ + private rootUIStore: UIStore; + + /** + * 变量元数据 + */ + private varaibleConfigMap: Map; + + /** + * 设置值 + */ + private innerValueMap: Map; + + /** + * 构造函数 + */ + constructor(module: Module, variableConfigs: any) { + this.module = module; + this.rootUIStore = this.getRootUIStore(); + this.innerValueMap = new Map(); + this.initVariableConfigMap(variableConfigs); + } + + /** + * 初始化变量配置 + */ + private initVariableConfigMap(variableConfigs: BefVariableConfig[]) { + this.varaibleConfigMap = new Map(); + if (!Array.isArray(variableConfigs)) { + return; + } + + variableConfigs.forEach((variableConfig: BefVariableConfig) => { + this.varaibleConfigMap.set(variableConfig.name, variableConfig); + }); + } + + /** + * 应用后端返回的更集 + */ + public handleChangeDetail(changeDetail: ChangeDetail): void { + const changeInfo = changeDetail.ChangeInfo; + Object.keys(changeInfo).forEach((name: string) => { + const variableConfig = this.varaibleConfigMap.get(name); + if (!variableConfig) { + return; + } + + // 判断是否发生变化 + const newValue = changeInfo[name]; + const oldValue = this.getValueFromUIState(name); + if (oldValue === newValue) { + return; + } + + // 更新值 + this.setValueToUIState(name, newValue); + this.innerValueMap.set(name, newValue); + }); + } + + /** + * 构造变量变更 + */ + public buildChangeDetail(): ChangeDetail | null { + const changeDetail = this.createEmptyChange(ChangeDetailType.Modify); + + this.varaibleConfigMap.forEach((variableConfig, name: string) => { + const newValue = this.getValueFromUIState(name); + const oldValue = this.innerValueMap.get(name); + if (this.isValueEqual(newValue, oldValue) === false) { + this.appendToChangeInfo(changeDetail, name, newValue); + } + }); + + if (Object.keys(changeDetail.ChangeInfo).length === 0) { + return null; + } + + return changeDetail; + } + + /** + * 清空内部的变量值 + */ + public reset() { + this.innerValueMap.clear(); + } + + /** + * 清空所有vo变量变更集 + */ + public clearChanges() { + this.varaibleConfigMap.forEach((variableConfig, name: string) => { + const newValue = this.getValueFromUIState(name); + const oldValue = this.innerValueMap.get(name); + if (this.isValueEqual(newValue, oldValue) === false) { + this.innerValueMap.set(name, newValue); + } + }); + } + + /** + * 清空只读vo变更 + */ + public clearChangeDetail(changeDetail: ChangeDetail) { + if (!changeDetail || Object.keys(changeDetail.ChangeInfo).length === 0) { + return; + } + + Object.keys(changeDetail.ChangeInfo).forEach((key: string) => { + const variableConfig = this.varaibleConfigMap.get(key); + if (!variableConfig) { + return; + } + const newValue = this.getValueFromUIState(key); + this.innerValueMap.set(key, newValue); + }); + } + + /** + * 追加变量变更 + */ + private appendToChangeInfo(changeDetail: ChangeDetail, varName: string, varValue: any): void { + if (this.isUdtVariable(varValue) === true) { + const udtVarChangeDetail = this.createEmptyChange(ChangeDetailType.Modify); + udtVarChangeDetail.ChangeInfo = varValue; + changeDetail.ChangeInfo[varName] = udtVarChangeDetail; + } else { + changeDetail.ChangeInfo[varName] = varValue; + } + } + + /** + * 从UIState上获取变量值 + */ + private getValueFromUIState(mapping: string): any { + const uiState = this.getRootUIStore(); + + // 计算value + const mappingArray = mapping.split('.'); + const value = mappingArray.reduce((accumulator: any, currentValue: any) => { + return accumulator ? accumulator[currentValue] : null; + }, uiState); + + if (value instanceof Date) { + return format(value, 'yyyy-MM-dd HH:mm:ss'); + } + return value; + } + + /** + * 值比较 + */ + private isValueEqual(srcValue: any, dstValue: any): boolean { + return JSON.stringify(srcValue) === JSON.stringify(dstValue); + } + + /** + * 检查是否是UDT变量 + */ + private isUdtVariable(obj: any): boolean { + return obj && obj.constructor && + obj.toString() === '[object Object]' && + obj.constructor.prototype.hasOwnProperty('isPrototypeOf'); + } + + /** + * 设置值到UIState + * @todo: + * 1、服务器端不支持; + * 2、日期类型处理方案待定。 + */ + private setValueToUIState(name: string, value: any): void { + this.rootUIStore.setValue(name, value); + } + + /** + * 创建空变更 + */ + private createEmptyChange(type: ChangeDetailType, dataId?: string) { + const changeDetail: ChangeDetail = { + ChangeType: type, + ChangeInfo: {} + }; + + if (dataId) { + changeDetail.ChangeInfo['DataId'] = dataId; + } + return changeDetail; + } + + /** + * 获取根组件上的UIState + */ + private getRootUIStore(): UIStore { + const viewModels = this.module.getViewModels(); + const rootViewModel = viewModels.find((viewModel) => { + const parentViewMode = viewModel.getParent(); + return !parentViewMode; + }) + + if (!rootViewModel || !rootViewModel.uiStore) { + throw new Error('Root UIStore not found'); + } + + return rootViewModel.uiStore; + } +} + +export { BefVariableManager }; diff --git a/packages/bef/lib/index.ts b/packages/bef/lib/index.ts index 9737a5b8d81..ff237e74cf9 100644 --- a/packages/bef/lib/index.ts +++ b/packages/bef/lib/index.ts @@ -5,6 +5,7 @@ export * from './session/index'; export * from './change/index'; export * from './bef-proxy-extend'; export * from './bef-proxy'; +export * from './bef-repository-config'; export * from './bef-repository'; export * from './bef-tree-repository'; export * from './bef-parent-tree-repository'; diff --git a/packages/mobile-render/src/services/module-config/repository-config-builder.ts b/packages/mobile-render/src/services/module-config/repository-config-builder.ts index 6ea679932d9..4ebcc4b6d74 100644 --- a/packages/mobile-render/src/services/module-config/repository-config-builder.ts +++ b/packages/mobile-render/src/services/module-config/repository-config-builder.ts @@ -1,5 +1,5 @@ -import { Module, RepositoryConfig } from '@farris/devkit-vue'; -import { BefRepository } from '@farris/bef-vue'; +import { Module } from '@farris/devkit-vue'; +import { BefRepository, BefRepositoryConfig, BefVariableConfig } from '@farris/bef-vue'; /** * 远程实体仓库配置构造器 @@ -21,18 +21,38 @@ class RepositoryConfigBuilder { /** * 构造配置 */ - public build(schema: any): RepositoryConfig { - const config = { + public build(schema: any): BefRepositoryConfig { + const variableConfigs = this.buildVariableConfigs(schema.variables); + const config: BefRepositoryConfig = { id: this.formMeta.module.code + '-repository', type: BefRepository, deps: [ Module ], isDynamic: true, entityStore: this.formMeta.module.code + '-entitystore', - baseUrl: '/' + schema.sourceUri.toLowerCase() + baseUrl: '/' + schema.sourceUri.toLowerCase(), + variables: variableConfigs }; return config; } + + /** + * 构造变量配置 + */ + private buildVariableConfigs(variableNodes: any[]): BefVariableConfig[] { + if (!Array.isArray(variableNodes)) { + return []; + } + const variableConfigs = variableNodes.map((variableNode) => { + const variableConfig: BefVariableConfig = { + name: variableNode.label + }; + + return variableConfig; + }); + + return variableConfigs; + } } export { RepositoryConfigBuilder }; diff --git a/packages/mobile-ui-vue/components/index.ts b/packages/mobile-ui-vue/components/index.ts index b62e0d29ca4..1de9986d9c6 100644 --- a/packages/mobile-ui-vue/components/index.ts +++ b/packages/mobile-ui-vue/components/index.ts @@ -64,14 +64,14 @@ import Component from './component'; import ContentContainer from './content-container'; import FloatContainer from './float-container'; -// import Modal from './modal'; -// import DynamicView from './dynamic-view'; -// import FDesignerCanvas from './designer-canvas'; +import Modal from './modal'; +import DynamicView from './dynamic-view'; +import FDesignerCanvas from './designer-canvas'; -// export * from './register'; -// export * from './designer'; -// export { schemaMap } from './dynamic-resolver'; -// export { type DynamicViewContext, DYNAMIC_VIEW_CONTEXT, DefaultDynamicViewContext } from './dynamic-view'; +export * from './register'; +export * from './designer'; +export { schemaMap } from './dynamic-resolver'; +export { type DynamicViewContext, DYNAMIC_VIEW_CONTEXT, DefaultDynamicViewContext } from './dynamic-view'; const components = [ Button, @@ -123,10 +123,9 @@ const components = [ ContentContainer, FloatContainer, - // Common, - // Modal, - // DynamicView, - // FDesignerCanvas + Modal, + DynamicView, + FDesignerCanvas ]; const install = (app: App): void => { @@ -184,10 +183,10 @@ export { ContentContainer, FloatContainer, Utils, - // Common, - // Modal, - // DynamicView, - // FDesignerCanvas + + Modal, + DynamicView, + FDesignerCanvas }; export default { diff --git a/packages/renderer/src/config-builders/repository-config-builder.ts b/packages/renderer/src/config-builders/repository-config-builder.ts index 7c6ecae1d7b..f77dd8c89d8 100644 --- a/packages/renderer/src/config-builders/repository-config-builder.ts +++ b/packages/renderer/src/config-builders/repository-config-builder.ts @@ -1,5 +1,5 @@ -import { Module, RepositoryConfig } from '@farris/devkit-vue'; -import { BefRepository } from '@farris/bef-vue'; +import { Module } from '@farris/devkit-vue'; +import { BefRepository, BefRepositoryConfig, BefVariableConfig } from '@farris/bef-vue'; import { ENTITY_STORE_SUFFIX } from '../types'; /** @@ -22,18 +22,38 @@ class RepositoryConfigBuilder { /** * 构造配置 */ - public build(schema: any): RepositoryConfig { + public build(schema: any): BefRepositoryConfig { + const variableConfigs = this.buildVariableConfigs(schema.variables); const config = { id: this.formMeta.module.code + '-repository', type: BefRepository, deps: [ Module ], isDynamic: true, entityStore: this.formMeta.module.code + ENTITY_STORE_SUFFIX, - baseUrl: '/' + schema.sourceUri.toLowerCase() + baseUrl: '/' + schema.sourceUri.toLowerCase(), + variables: variableConfigs }; return config; } + + /** + * 构造变量配置 + */ + private buildVariableConfigs(variableNodes: any[]): BefVariableConfig[] { + if (!Array.isArray(variableNodes)) { + return []; + } + const variableConfigs = variableNodes.map((variableNode) => { + const variableConfig: BefVariableConfig = { + name: variableNode.label + }; + + return variableConfig; + }); + + return variableConfigs; + } } export { RepositoryConfigBuilder }; -- Gitee From 8241d3658fa4ae8c405ab64db086d14784c6337f Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Mon, 24 Mar 2025 09:05:56 +0800 Subject: [PATCH 087/153] chore: update pnpm lock --- pnpm-lock.yaml | 189 +++++++++++-------------------------------------- 1 file changed, 42 insertions(+), 147 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c5c91438d19..74d1aca1faa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -599,10 +599,10 @@ importers: version: 7.18.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.6.3) '@vitejs/plugin-vue': specifier: ^4.2.3 - version: 4.6.2(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)) + version: 4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)) '@vitejs/plugin-vue-jsx': specifier: ^3.0.1 - version: 3.1.0(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)) + version: 3.1.0(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)) '@vue/babel-plugin-jsx': specifier: ^1.1.1 version: 1.2.5(@babel/core@7.25.8) @@ -638,7 +638,7 @@ importers: version: 9.3.7 jest: specifier: ^29.0.0 - version: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) + version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) ora: specifier: ^6.1.2 version: 6.3.1 @@ -659,28 +659,28 @@ importers: version: 5.6.3 vite: specifier: ^5.3.3 - version: 5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0) + version: 5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0) vite-plugin-banner: specifier: ^0.8.0 version: 0.8.0 vite-plugin-dts: specifier: 3.9.1 - version: 3.9.1(@types/node@18.19.57)(rollup@4.24.0)(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) + version: 3.9.1(@types/node@20.5.1)(rollup@4.24.0)(typescript@5.6.3)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) vite-plugin-md: specifier: ^0.21.5 - version: 0.21.5(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) + version: 0.21.5(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) vite-svg-loader: specifier: ^5.1.0 version: 5.1.0(vue@3.5.12(typescript@5.6.3)) vitepress: specifier: ^1.0.0-alpha.8 - version: 1.0.0-alpha.10(@types/node@18.19.57)(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(terser@5.36.0)(typescript@5.6.3) + version: 1.0.0-alpha.10(@algolia/client-search@4.24.0)(@types/node@20.5.1)(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(search-insights@2.17.2)(terser@5.36.0)(typescript@5.6.3) vitepress-theme-demoblock: specifier: 1.4.2 version: 1.4.2(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(typescript@5.6.3) vitest: specifier: ^1.4.0 - version: 1.6.0(@types/node@18.19.57)(happy-dom@8.9.0)(jsdom@20.0.3)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0) + version: 1.6.0(@types/node@20.5.1)(happy-dom@8.9.0)(jsdom@20.0.3)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0) vue-tsc: specifier: ^2.0.0 version: 2.1.6(typescript@5.6.3) @@ -1785,6 +1785,9 @@ importers: lodash-es: specifier: ^4.17.20 version: 4.17.21 + rxjs: + specifier: ^7.4.0 + version: 7.8.1 vue: specifier: ^3.2.37 version: 3.5.12(typescript@4.9.5) @@ -13365,7 +13368,7 @@ snapshots: jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3))': + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -13379,7 +13382,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -13400,7 +13403,7 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5))': + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -13414,7 +13417,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) + jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -13435,7 +13438,7 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3))': + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -13449,7 +13452,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) + jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -14720,16 +14723,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue-jsx@3.1.0(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))': - dependencies: - '@babel/core': 7.25.8 - '@babel/plugin-transform-typescript': 7.25.7(@babel/core@7.25.8) - '@vue/babel-plugin-jsx': 1.2.5(@babel/core@7.25.8) - vite: 5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0) - vue: 3.5.12(typescript@5.6.3) - transitivePeerDependencies: - - supports-color - '@vitejs/plugin-vue-jsx@3.1.0(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))': dependencies: '@babel/core': 7.25.8 @@ -14784,11 +14777,6 @@ snapshots: vite: 4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0) vue: 3.5.12(typescript@4.9.5) - '@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))': - dependencies: - vite: 5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0) - vue: 3.5.12(typescript@5.6.3) - '@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3))': dependencies: vite: 5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0) @@ -15255,31 +15243,6 @@ snapshots: - terser - vite - '@yankeeinlondon/builder-api@1.4.1(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))': - dependencies: - '@types/markdown-it': 12.2.3 - '@yankeeinlondon/happy-wrapper': 2.10.1(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) - fp-ts: 2.16.9 - inferred-types: 0.37.6(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) - markdown-it: 13.0.2 - vite-plugin-md: 0.22.5(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) - transitivePeerDependencies: - - '@edge-runtime/vm' - - '@vitejs/plugin-vue' - - '@vitest/browser' - - '@vitest/ui' - - encoding - - happy-dom - - jsdom - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - - vite - '@yankeeinlondon/builder-api@1.4.1(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))': dependencies: '@types/markdown-it': 12.2.3 @@ -15312,7 +15275,7 @@ snapshots: fp-ts: 2.16.9 inferred-types: 0.37.6(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) markdown-it: 13.0.2 - vite-plugin-md: 0.22.5(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) + vite-plugin-md: 0.22.5(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) transitivePeerDependencies: - '@edge-runtime/vm' - '@vitejs/plugin-vue' @@ -16092,7 +16055,7 @@ snapshots: dependencies: bumpp: 8.2.1 callsites: 4.2.0 - inferred-types: 0.37.6(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) + inferred-types: 0.37.6(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) vitest: 0.25.8(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) transitivePeerDependencies: - '@edge-runtime/vm' @@ -19465,7 +19428,7 @@ snapshots: jest-cli@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 @@ -19522,7 +19485,7 @@ snapshots: jest-cli@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 @@ -19935,7 +19898,7 @@ snapshots: jest@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) '@jest/types': 29.6.3 import-local: 3.2.0 jest-cli: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) @@ -19971,7 +19934,7 @@ snapshots: jest@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) '@jest/types': 29.6.3 import-local: 3.2.0 jest-cli: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) @@ -23224,6 +23187,23 @@ snapshots: - rollup - supports-color + vite-plugin-dts@3.9.1(@types/node@20.5.1)(rollup@4.24.0)(typescript@5.6.3)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)): + dependencies: + '@microsoft/api-extractor': 7.43.0(@types/node@20.5.1) + '@rollup/pluginutils': 5.1.2(rollup@4.24.0) + '@vue/language-core': 1.8.27(typescript@5.6.3) + debug: 4.3.7 + kolorist: 1.8.0 + magic-string: 0.30.12 + typescript: 5.6.3 + vue-tsc: 1.8.27(typescript@5.6.3) + optionalDependencies: + vite: 5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0) + transitivePeerDependencies: + - '@types/node' + - rollup + - supports-color + vite-plugin-md@0.20.6(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0)): dependencies: '@yankeeinlondon/builder-api': 1.4.1(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0)) @@ -23272,30 +23252,6 @@ snapshots: - terser - vite - vite-plugin-md@0.21.5(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)): - dependencies: - '@yankeeinlondon/builder-api': 1.4.1(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) - '@yankeeinlondon/gray-matter': 6.2.1(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) - '@yankeeinlondon/happy-wrapper': 2.10.1(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) - markdown-it: 13.0.2 - source-map-js: 1.2.1 - vite: 5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0) - transitivePeerDependencies: - - '@edge-runtime/vm' - - '@vitejs/plugin-vue' - - '@vitest/browser' - - '@vitest/ui' - - encoding - - happy-dom - - jsdom - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - vite-plugin-md@0.21.5(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)): dependencies: '@yankeeinlondon/builder-api': 1.4.1(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) @@ -23392,34 +23348,10 @@ snapshots: - supports-color - terser - vite-plugin-md@0.22.5(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)): - dependencies: - '@vitejs/plugin-vue': 4.6.2(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)) - '@yankeeinlondon/builder-api': 1.4.1(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) - '@yankeeinlondon/gray-matter': 6.2.1(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) - '@yankeeinlondon/happy-wrapper': 2.10.1(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) - markdown-it: 13.0.2 - source-map-js: 1.2.1 - vite: 5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0) - transitivePeerDependencies: - - '@edge-runtime/vm' - - '@vitest/browser' - - '@vitest/ui' - - encoding - - happy-dom - - jsdom - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - vite-plugin-md@0.22.5(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)): dependencies: '@vitejs/plugin-vue': 4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)) - '@yankeeinlondon/builder-api': 1.4.1(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) + '@yankeeinlondon/builder-api': 1.4.1(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) '@yankeeinlondon/gray-matter': 6.2.1(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) '@yankeeinlondon/happy-wrapper': 2.10.1(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) markdown-it: 13.0.2 @@ -23440,7 +23372,7 @@ snapshots: - supports-color - terser - vite-plugin-md@0.22.5(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)): + vite-plugin-md@0.22.5(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)): dependencies: '@vitejs/plugin-vue': 5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)) '@yankeeinlondon/builder-api': 1.4.1(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) @@ -23454,7 +23386,6 @@ snapshots: - '@vitest/browser' - '@vitest/ui' - encoding - - happy-dom - jsdom - less - lightningcss @@ -23966,42 +23897,6 @@ snapshots: - supports-color - terser - vitest@1.6.0(@types/node@18.19.57)(happy-dom@8.9.0)(jsdom@20.0.3)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0): - dependencies: - '@vitest/expect': 1.6.0 - '@vitest/runner': 1.6.0 - '@vitest/snapshot': 1.6.0 - '@vitest/spy': 1.6.0 - '@vitest/utils': 1.6.0 - acorn-walk: 8.3.4 - chai: 4.5.0 - debug: 4.3.7 - execa: 8.0.1 - local-pkg: 0.5.0 - magic-string: 0.30.12 - pathe: 1.1.2 - picocolors: 1.1.1 - std-env: 3.7.0 - strip-literal: 2.1.0 - tinybench: 2.9.0 - tinypool: 0.8.4 - vite: 5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0) - vite-node: 1.6.0(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 18.19.57 - happy-dom: 8.9.0 - jsdom: 20.0.3 - transitivePeerDependencies: - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - vitest@1.6.0(@types/node@20.5.1)(happy-dom@8.9.0)(jsdom@20.0.3)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0): dependencies: '@vitest/expect': 1.6.0 -- Gitee From 314f67503243812091732e958332718da88cfc3b Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Mon, 24 Mar 2025 11:54:21 +0800 Subject: [PATCH 088/153] =?UTF-8?q?chore:=20=E7=BB=84=E4=BB=B6=E5=8F=AF?= =?UTF-8?q?=E8=A7=81=E7=AD=89=E5=B1=9E=E6=80=A7=E6=94=AF=E6=8C=81=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E3=80=81=E8=A1=A8=E8=BE=BE=E5=BC=8F=E3=80=81=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...xpression-result-change-effect-resolver.ts | 2 +- ...er-component-config-dependency-resolver.ts | 8 ++- .../data-grid-component-config-resolver.ts | 14 ++-- .../form-group-component-config-resolver.ts | 10 +-- .../page-header-component-config-resolver.ts | 11 +-- .../response-toolbar-config-resolver.ts | 4 +- .../section-component-config-resolver.ts | 4 +- .../tab-page-component-config-resolver.ts | 4 +- .../tree-grid-component-config-resolver.ts | 10 +-- .../config-builders/module-config-builder.ts | 28 ++++++-- .../standard-config-dependency-resolver.ts | 20 ++++-- .../src/config-dependency-resolver/types.ts | 6 ++ .../renderer/src/config/config-resolver.ts | 72 ++++++++++++++++--- packages/renderer/src/config/providers.ts | 5 +- pnpm-lock.yaml | 50 ++++++++++++- 15 files changed, 196 insertions(+), 52 deletions(-) diff --git a/packages/renderer/src/change-effect-resolver/expression-result-change-effect-resolver.ts b/packages/renderer/src/change-effect-resolver/expression-result-change-effect-resolver.ts index 94de38c8568..5c3299dfa41 100644 --- a/packages/renderer/src/change-effect-resolver/expression-result-change-effect-resolver.ts +++ b/packages/renderer/src/change-effect-resolver/expression-result-change-effect-resolver.ts @@ -19,7 +19,7 @@ export class ExpressionResultChangeEffectResolver extends ChangeEffectResolver { return dependency.type === DependencyKind.ExpressionResult && dependency.path === expressionResultChange.id; }); - return !!match;; + return !!match; }); if (matchedConfigs && matchedConfigs.length > 0) { result.set(id, matchedConfigs); diff --git a/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts index e1f330dd264..47371918b0c 100644 --- a/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts @@ -1,4 +1,4 @@ - import { Configuration } from "../config"; +import { Configuration } from "../config"; import { ConfigDependencyResolveService } from "../config-dependency-resolver"; import { ComponentConfigDependencyResolver } from "./component-config-dependency-resolver"; @@ -27,6 +27,12 @@ export class PageHeaderComponentConfigDependencyResolver extends ComponentConfig if (diabledConfigDeps) { configs.push({ deps: diabledConfigDeps, config: disabled, path: `/toolbar/buttons/${button.id}:disabled` }); } + if (visible !== null && visible !== undefined) { + const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); + if (visibleConfigDeps) { + configs.push({ deps: visibleConfigDeps, config: visible, path: `/toolbar/buttons/${button.id}:visible` }); + } + } }); return configs; } diff --git a/packages/renderer/src/component-config-resolver/data-grid-component-config-resolver.ts b/packages/renderer/src/component-config-resolver/data-grid-component-config-resolver.ts index c01ba3a9e41..32c073fa2ba 100644 --- a/packages/renderer/src/component-config-resolver/data-grid-component-config-resolver.ts +++ b/packages/renderer/src/component-config-resolver/data-grid-component-config-resolver.ts @@ -10,12 +10,12 @@ export class DataGridComponentConfigResolver extends ComponentConfigResolver { } public resolve(metadata: Record): Record { - const { disabled, columns, editable, pagination } = metadata; - metadata.editable = this.configResolver.resolve(editable); - metadata.disabled = this.configResolver.resolve(disabled); + const { disabled, columns, editable, pagination, id } = metadata; + metadata.editable = this.configResolver.resolve(editable, id); + metadata.disabled = this.configResolver.resolve(disabled, id); if (pagination) { const { disabled = false } = pagination; - pagination.disabled = this.configResolver.resolve(disabled); + pagination.disabled = this.configResolver.resolve(disabled, id); } if (!columns || !Array.isArray(columns) || columns.length < 1) { return metadata; @@ -42,9 +42,9 @@ export class DataGridComponentConfigResolver extends ComponentConfigResolver { return; } const { readonly, required, disabled } = editor; - editor.readonly = this.configResolver.resolve(readonly); - editor.required = this.configResolver.resolve(required); - editor.disabled = this.configResolver.resolve(disabled); + editor.readonly = this.configResolver.resolve(readonly, id); + editor.required = this.configResolver.resolve(required, id); + editor.disabled = this.configResolver.resolve(disabled, id); }); return metadata; } diff --git a/packages/renderer/src/component-config-resolver/form-group-component-config-resolver.ts b/packages/renderer/src/component-config-resolver/form-group-component-config-resolver.ts index e967c2823d5..3fcc7c693c3 100644 --- a/packages/renderer/src/component-config-resolver/form-group-component-config-resolver.ts +++ b/packages/renderer/src/component-config-resolver/form-group-component-config-resolver.ts @@ -10,15 +10,15 @@ export class FormGroupComponentConfigResolver extends ComponentConfigResolver { } public resolve(metadata: Record): Record { - const { visible, editor = null } = metadata; - metadata.visible = this.configResolver.resolve(visible); + const { visible, editor = null, id } = metadata; + metadata.visible = this.configResolver.resolve(visible, id); if (!editor) { return metadata; } const { readonly, required, disabled } = editor; - editor.readonly = this.configResolver.resolve(readonly); - editor.disabled = this.configResolver.resolve(disabled); - editor.required = this.configResolver.resolve(required); + editor.readonly = this.configResolver.resolve(readonly, id); + editor.disabled = this.configResolver.resolve(disabled, id); + editor.required = this.configResolver.resolve(required, id); return metadata; } } diff --git a/packages/renderer/src/component-config-resolver/page-header-component-config-resolver.ts b/packages/renderer/src/component-config-resolver/page-header-component-config-resolver.ts index e2d9cf7d628..56bef28175a 100644 --- a/packages/renderer/src/component-config-resolver/page-header-component-config-resolver.ts +++ b/packages/renderer/src/component-config-resolver/page-header-component-config-resolver.ts @@ -1,16 +1,16 @@ - import { FormMetadataService } from "../service"; +import { FormMetadataService } from "../service"; import { ComponentConfigResolver } from "./component-config-resolver"; import { ConfigResolver } from "../config"; export class PageHeaderComponentConfigResolver extends ComponentConfigResolver { - public type: string='page-header'; + public type: string = 'page-header'; constructor(private formMetadataService: FormMetadataService, private configResolver: ConfigResolver) { super(); } public resolve(metadata: Record): Record { - const { toolbar } = metadata; + const { toolbar, id } = metadata; if (!toolbar) { return metadata; } @@ -20,7 +20,10 @@ export class PageHeaderComponentConfigResolver extends ComponentConfigResolver { } buttons.forEach((button: Record) => { const { disabled, visible } = button; - button.disabled = this.configResolver.resolve(disabled); + button.disabled = this.configResolver.resolve(disabled, id); + if (visible !== undefined && visible !== null) { + button.visible = this.configResolver.resolve(visible, id); + } }); return metadata; } diff --git a/packages/renderer/src/component-config-resolver/response-toolbar-config-resolver.ts b/packages/renderer/src/component-config-resolver/response-toolbar-config-resolver.ts index 53b57f9d8de..89d1f360b82 100644 --- a/packages/renderer/src/component-config-resolver/response-toolbar-config-resolver.ts +++ b/packages/renderer/src/component-config-resolver/response-toolbar-config-resolver.ts @@ -9,13 +9,13 @@ export class ResponseToolbarConfigResolver extends ComponentConfigResolver { } public resolve(metadata: Record): Record { - const { buttons } = metadata; + const { buttons, id } = metadata; if (!buttons || !Array.isArray(buttons) || buttons.length < 1) { return metadata; } buttons.forEach((button: Record) => { const { disabled, visible } = button; - button.disabled = this.configResolver.resolve(disabled); + button.disabled = this.configResolver.resolve(disabled, id); }); return metadata; } diff --git a/packages/renderer/src/component-config-resolver/section-component-config-resolver.ts b/packages/renderer/src/component-config-resolver/section-component-config-resolver.ts index 66e50a83d95..9cd6e59a600 100644 --- a/packages/renderer/src/component-config-resolver/section-component-config-resolver.ts +++ b/packages/renderer/src/component-config-resolver/section-component-config-resolver.ts @@ -10,7 +10,7 @@ export class SectionComponentConfigResolver extends ComponentConfigResolver { } public resolve(metadata: Record): Record { - const { toolbar } = metadata; + const { toolbar, id } = metadata; if (!toolbar) { return metadata; } @@ -20,7 +20,7 @@ export class SectionComponentConfigResolver extends ComponentConfigResolver { } buttons.forEach((button: Record) => { const { disabled, visible } = button; - button.disabled = this.configResolver.resolve(disabled); + button.disabled = this.configResolver.resolve(disabled, id); }); return metadata; } diff --git a/packages/renderer/src/component-config-resolver/tab-page-component-config-resolver.ts b/packages/renderer/src/component-config-resolver/tab-page-component-config-resolver.ts index d27efd66051..10a561c41fe 100644 --- a/packages/renderer/src/component-config-resolver/tab-page-component-config-resolver.ts +++ b/packages/renderer/src/component-config-resolver/tab-page-component-config-resolver.ts @@ -10,7 +10,7 @@ export class TabPageComponentConfigResolver extends ComponentConfigResolver { } public resolve(metadata: Record): Record { - const { toolbar } = metadata; + const { toolbar, id } = metadata; if (!toolbar) { return metadata; } @@ -20,7 +20,7 @@ export class TabPageComponentConfigResolver extends ComponentConfigResolver { } buttons.forEach((button: Record) => { const { disabled, visible } = button; - button.disabled = this.configResolver.resolve(disabled); + button.disabled = this.configResolver.resolve(disabled, id); }); return metadata; } diff --git a/packages/renderer/src/component-config-resolver/tree-grid-component-config-resolver.ts b/packages/renderer/src/component-config-resolver/tree-grid-component-config-resolver.ts index 955f9d01875..5f9bcdb7c27 100644 --- a/packages/renderer/src/component-config-resolver/tree-grid-component-config-resolver.ts +++ b/packages/renderer/src/component-config-resolver/tree-grid-component-config-resolver.ts @@ -10,9 +10,9 @@ export class TreeGridComponentConfigResolver extends ComponentConfigResolver { } public resolve(metadata: Record): Record { - const { disabled, columns, editable } = metadata; - metadata.editable = this.configResolver.resolve(editable); - metadata.disabled = this.configResolver.resolve(disabled); + const { disabled, columns, editable, id } = metadata; + metadata.editable = this.configResolver.resolve(editable, id); + metadata.disabled = this.configResolver.resolve(disabled, id); if (!columns || !Array.isArray(columns) || columns.length < 1) { return metadata; } @@ -22,8 +22,8 @@ export class TreeGridComponentConfigResolver extends ComponentConfigResolver { return; } const { readonly, required } = editor; - editor.readonly = this.configResolver.resolve(readonly); - editor.required = this.configResolver.resolve(required); + editor.readonly = this.configResolver.resolve(readonly, id); + editor.required = this.configResolver.resolve(required, id); }); return metadata; } diff --git a/packages/renderer/src/config-builders/module-config-builder.ts b/packages/renderer/src/config-builders/module-config-builder.ts index 07ca309b565..e9c41e8a287 100644 --- a/packages/renderer/src/config-builders/module-config-builder.ts +++ b/packages/renderer/src/config-builders/module-config-builder.ts @@ -1,6 +1,7 @@ import { StaticProvider, EntityStoreConfig, UIStoreConfig, FormStoreConfig, FormArrayStoreConfig, StateMachineConfig, RepositoryConfig, ViewModelConfig, ModuleConfig, + ExpressionConfig, } from '@farris/devkit-vue'; import { FormMetadataQuery } from '../service/index'; import { RepositoryConfigBuilder } from './repository-config-builder'; @@ -9,6 +10,8 @@ import { UIStoreConfigBuilder } from './ui-store-config-builder'; import { FormStoreConfigBuilder, FormArrayStoreConfigBuilder } from './form/index'; import { StateMachineConfigBuilder } from './state-machine-config-builder'; import { ViewModelConfigBuilder } from './viewmodel-config-builder'; +import { ExpressionConfigBuilder } from './expression-config-builder'; +import { ExpressionMetadata } from '../types'; /** * 模块配置构造器 @@ -70,7 +73,8 @@ class ModuleConfigBuilder { formArrayStores: [], stateMachines: [], repositories: [], - viewModels: [] + viewModels: [], + expressions: [] }; } @@ -82,11 +86,9 @@ class ModuleConfigBuilder { this.buildEntityStoreConfigs(this.formMeta); this.buildStateMachineConfigs(this.formMeta, this.smMetas); this.buildViewModelConfigs(this.formMeta, this.webCmdMetas, this.webCmpMetas, this.context.viewModelProviders); - + this.buildExpressionConfigs(this.formMeta); this.moduleConfig.id = this.formMeta.module.code; this.moduleConfig.providers = this.context.moduleProviders; - - console.log(this.moduleConfig); return this.moduleConfig; } @@ -208,6 +210,24 @@ class ModuleConfigBuilder { return config; } + private buildExpressionConfigs(formMeta: any) { + const expressionConfigs = this.buildExpressions(formMeta); + if (!expressionConfigs) { + return; + } + this.moduleConfig.expressions = expressionConfigs; + } + private buildExpressions(formMeta: any): ExpressionConfig[] | null { + const { expressions } = formMeta.module; + if (!expressions || !Array.isArray(expressions) || expressions.length < 1) { + return null; + } + const expressionConfigBuilder = new ExpressionConfigBuilder(formMeta); + expressions.forEach((expression: ExpressionMetadata) => { + expressionConfigBuilder.build(expression); + }); + return expressions; + } } export { ModuleConfigBuilder }; diff --git a/packages/renderer/src/config-dependency-resolver/standard-config-dependency-resolver.ts b/packages/renderer/src/config-dependency-resolver/standard-config-dependency-resolver.ts index cb0152528ce..a7ce91fe3f2 100644 --- a/packages/renderer/src/config-dependency-resolver/standard-config-dependency-resolver.ts +++ b/packages/renderer/src/config-dependency-resolver/standard-config-dependency-resolver.ts @@ -1,5 +1,5 @@ import { ConfigDependency, DependencyKind } from "../config/types"; -import { ConfigDependencyResolver, ExpressionConfig, StandardPropertyConfig, VariableConfig } from "./types"; +import { ConfigDependencyResolver, ExpressionConfig, StandardPropertyConfig, StateMachineConfig, VariableConfig } from "./types"; export class StandardConfigDependencyResolver implements ConfigDependencyResolver { resolve(config: string | boolean | StandardPropertyConfig): ConfigDependency[] | null { @@ -7,38 +7,46 @@ export class StandardConfigDependencyResolver implements ConfigDependencyResolve if (typeof config === 'string' || typeof config === 'boolean') { return null; } - + // 验证是否为有效的配置对象 if (!this.isValidConfig(config)) { return null; } - + // 根据配置类型分发到对应的处理方法 switch (config.type) { case 'Expression': return this.resolveExpressionConfig(config as ExpressionConfig); case 'Variable': return this.resolveVariableConfig(config as VariableConfig); + case 'StateMachine': + return this.resolveStateMachineConfig(config as StateMachineConfig); default: return null; } } - + private isValidConfig(config: any): config is StandardPropertyConfig { return config && typeof config === 'object' && 'type' in config; } - + private resolveExpressionConfig(config: ExpressionConfig): ConfigDependency[] { return [{ type: DependencyKind.ExpressionResult, path: config.expressionId }]; } - + private resolveVariableConfig(config: VariableConfig): ConfigDependency[] { return [{ type: DependencyKind.UIState, path: config.path }]; } + private resolveStateMachineConfig(config: StateMachineConfig): ConfigDependency[] { + return [{ + type: DependencyKind.StateMachine, + path: config.field + }]; + } } diff --git a/packages/renderer/src/config-dependency-resolver/types.ts b/packages/renderer/src/config-dependency-resolver/types.ts index b6025967495..2f3a9d0c72f 100644 --- a/packages/renderer/src/config-dependency-resolver/types.ts +++ b/packages/renderer/src/config-dependency-resolver/types.ts @@ -3,6 +3,7 @@ import { ConfigDependency } from "../config"; export enum ConfigType { Expression = 'Expression', Variable = 'Variable', + StateMachine = 'StateMachine' } export interface StandardPropertyConfig { type: ConfigType; @@ -17,6 +18,11 @@ export interface VariableConfig extends StandardPropertyConfig { fullPath: string; field: string; } +export interface StateMachineConfig extends StandardPropertyConfig { + type: ConfigType.StateMachine; + field: string; + status: boolean; +} export interface ConfigDependencyResolver { resolve(config: string | boolean | StandardPropertyConfig): ConfigDependency[] | null; } diff --git a/packages/renderer/src/config/config-resolver.ts b/packages/renderer/src/config/config-resolver.ts index 7356a58c1c3..30769a8d2f3 100644 --- a/packages/renderer/src/config/config-resolver.ts +++ b/packages/renderer/src/config/config-resolver.ts @@ -1,23 +1,75 @@ - -import { Module, ViewModel, ViewModelState } from "@farris/devkit-vue"; + +import { ExpressionResult, Module, ViewModel, ViewModelState } from "@farris/devkit-vue"; +import { ConfigType, ExpressionConfig, StandardPropertyConfig, StateMachineConfig, VariableConfig } from "../config-dependency-resolver"; +import { FormMetadataService } from "../service"; export class ConfigResolver { - constructor(private module: Module, private viewModel: ViewModel) { + constructor( + private viewModel: ViewModel, + private expressionResult: ExpressionResult, + private formMetadataService: FormMetadataService + ) { } - public resolve(config: string | boolean) { + public resolve(config: string | boolean | StandardPropertyConfig, metadataId: string) { if (typeof config === 'boolean') { return config; } - // TODO: 应获取指定的viewModel - const viewModels = this.module.getViewModels(); - const currentViewModel = viewModels[0]; + if (config && typeof config === 'object' && 'type' in config) { + return this.resolveStandardConfig(config as StandardPropertyConfig, metadataId); + } + const relatedComponent = this.formMetadataService.getRelatedComponent(metadataId); + if (!relatedComponent) { + console.warn(`解析配置异常,未找到相关组件: ${metadataId}`); + return; + } + const viewModel = this.viewModel.getModule().getViewModel(relatedComponent.id); + if (!viewModel) { + return; + } const context = { - stateMachine: currentViewModel.state.stateMachine, - uiState: currentViewModel.state.uiState, - entityState: currentViewModel.state.entityState?.currentEntity + stateMachine: viewModel.state.stateMachine, + uiState: viewModel.state.uiState, + entityState: viewModel.state.entityState?.currentEntity }; return new Function('viewModel', `return ${config}`)(context); } + private resolveStandardConfig(config: StandardPropertyConfig, metadataId: string) { + if (config.type === ConfigType.Expression) { + return this.resolveExpressionConfig(config as ExpressionConfig); + } else if (config.type === ConfigType.Variable) { + return this.resolveVariableConfig(config as VariableConfig, metadataId); + } else if (config.type === ConfigType.StateMachine) { + return this.resolveStateMachineConfig(config as StateMachineConfig); + } + } + private resolveVariableConfig(config: VariableConfig, metadataId: string) { + const relatedComponent = this.formMetadataService.getRelatedComponent(metadataId); + if (!relatedComponent) { + return; + } + const { fullPath, path } = config; + let viewModelId: string = relatedComponent.id; + if (fullPath !== path) { + // 跨组件引用变量 + viewModelId = path.split('.')[0]; + } + const viewModel = this.viewModel.getModule().getViewModel(viewModelId); + if (!viewModel) { + return; + } + return viewModel.uiStore?.getValue(fullPath); + + } + private resolveExpressionConfig(config: ExpressionConfig) { + return this.expressionResult[config.expressionId]; + } + private resolveStateMachineConfig(config: StateMachineConfig) { + const { field } = config; + const { stateMachine } = this.viewModel; + const value = stateMachine?.getValue(field); + const status = typeof config.status === 'boolean' ? config.status : config.status === '!' ? false : true; + return status ? value : !value; + } } diff --git a/packages/renderer/src/config/providers.ts b/packages/renderer/src/config/providers.ts index ee8108a77ba..e8392c20e02 100644 --- a/packages/renderer/src/config/providers.ts +++ b/packages/renderer/src/config/providers.ts @@ -1,8 +1,9 @@ -import { StaticProvider, Module } from "@farris/devkit-vue"; +import { StaticProvider, ViewModel, ExpressionResult } from "@farris/devkit-vue"; import { ComponentConfigDependencyRegistry } from "./component-config-dependency-registry"; import { ConfigResolver } from './config-resolver'; +import { FormMetadataService } from "../service"; export const configProviders: StaticProvider[] = [ { provide: ComponentConfigDependencyRegistry, useClass: ComponentConfigDependencyRegistry, deps: [] }, - { provide: ConfigResolver, useClass: ConfigResolver, deps: [Module] } + { provide: ConfigResolver, useClass: ConfigResolver, deps: [ViewModel, ExpressionResult, FormMetadataService] } ]; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 74d1aca1faa..0ca4f4cf909 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -914,12 +914,21 @@ importers: packages/devkit: dependencies: + '@farris/expression-engine-vue': + specifier: workspace:^ + version: link:../expression-engine axios: specifier: ^1.7.2 version: 1.7.7 + bignumber.js: + specifier: ^9.1.1 + version: 9.1.2 date-fns: specifier: ^3.6.0 version: 3.6.0 + rxjs: + specifier: ^7.4.0 + version: 7.8.1 vue: specifier: ^3.2.37 version: 3.5.12(typescript@4.9.5) @@ -1139,6 +1148,42 @@ importers: specifier: ^0.40.4 version: 0.40.13(typescript@4.9.5) + packages/expression-engine: + devDependencies: + '@rollup/plugin-babel': + specifier: ^6.0.4 + version: 6.0.4(@babel/core@7.25.8)(@types/babel__core@7.20.5)(rollup@4.24.0) + '@rollup/plugin-commonjs': + specifier: ^28.0.1 + version: 28.0.1(rollup@4.24.0) + '@rollup/plugin-json': + specifier: ^6.1.0 + version: 6.1.0(rollup@4.24.0) + '@rollup/plugin-node-resolve': + specifier: ^15.2.3 + version: 15.3.0(rollup@4.24.0) + '@rollup/plugin-terser': + specifier: ^0.4.4 + version: 0.4.4(rollup@4.24.0) + rollup: + specifier: ^4.24.0 + version: 4.24.0 + rollup-plugin-typescript2: + specifier: ^0.36.0 + version: 0.36.0(rollup@4.24.0)(typescript@5.6.3) + rollup-plugin-visualizer: + specifier: ^5.12.0 + version: 5.12.0(rollup@4.24.0) + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@20.5.1)(typescript@5.6.3) + tslib: + specifier: ^2.7.0 + version: 2.8.0 + typescript: + specifier: ^5.5.3 + version: 5.6.3 + packages/farris-admin: dependencies: '@farris/ui-vue': @@ -1752,6 +1797,9 @@ importers: '@farris/devkit-vue': specifier: workspace:^ version: link:../devkit + '@farris/expression-engine-vue': + specifier: workspace:^ + version: link:../expression-engine '@farris/ui-binding-vue': specifier: workspace:^ version: link:../ui-binding @@ -16055,7 +16103,7 @@ snapshots: dependencies: bumpp: 8.2.1 callsites: 4.2.0 - inferred-types: 0.37.6(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) + inferred-types: 0.37.6(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) vitest: 0.25.8(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) transitivePeerDependencies: - '@edge-runtime/vm' -- Gitee From fba71b9c491a7e542751713e6c1110a6613c7838 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Mon, 24 Mar 2025 14:34:43 +0800 Subject: [PATCH 089/153] =?UTF-8?q?chore:=20=E5=8F=98=E9=87=8F=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=BB=98=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/renderer/src/composition/index.ts | 1 + .../composition/use-view-model-initializer.ts | 81 +++++++++++++++++++ packages/renderer/src/preview.vue | 3 +- packages/renderer/src/renderer.vue | 3 +- 4 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 packages/renderer/src/composition/use-view-model-initializer.ts diff --git a/packages/renderer/src/composition/index.ts b/packages/renderer/src/composition/index.ts index fdda018542f..6ed85d0add2 100644 --- a/packages/renderer/src/composition/index.ts +++ b/packages/renderer/src/composition/index.ts @@ -21,3 +21,4 @@ export * from './use-module-config'; export * from './use-model-value'; export * from './use-session'; export * from './use-callback-handler-registry'; +export * from './use-view-model-initializer'; diff --git a/packages/renderer/src/composition/use-view-model-initializer.ts b/packages/renderer/src/composition/use-view-model-initializer.ts new file mode 100644 index 00000000000..9bb83299d79 --- /dev/null +++ b/packages/renderer/src/composition/use-view-model-initializer.ts @@ -0,0 +1,81 @@ +import { Module } from "@farris/devkit-vue"; + +export function useViewModelInitializer(module: Module, metadata: Record) { + function getComponentByViewModelId(viewModelId: string) { + const { components } = metadata.value.form?.content?.module || []; + return components.find((component: Record) => { + return component.viewModel === viewModelId; + }); + } + function getViewModelById(viewModelId: string) { + const componentId = getComponentByViewModelId(viewModelId)?.id; + if (!componentId) { + return null; + } + return module.getViewModel(componentId); + } + function transformValue(value: any, type: string): any { + switch (type) { + case "String": + case "Text": { + if (typeof value === 'string') { + return value; + } + return value + ''; + } + case "Number": { + if (typeof value === 'number') { + return value; + } + const numResult = Number(value); + if (isNaN(numResult)) { + console.warn(`类型转换失败,参数${name}值为${value},无法转换为${type}类型。`); + return value; + } + return numResult; + } + case "Boolean": { + if (typeof value === 'boolean') { + return value; + } + let boolResult: boolean; + const strValue = (value + '').toLowerCase(); + if (strValue === 'true') { + boolResult = true; + } else if (strValue === 'false') { + boolResult = false; + } else { + boolResult = false; + } + return boolResult; + } + case "Date": + case "DateTime": + return new Date(value); + case "Object": + case "Array": + return JSON.parse(value); + default: + return value; + } + } + const { viewmodels } = metadata.value.form?.content?.module || []; + if (!viewmodels || viewmodels.length < 1) { + return; + } + viewmodels.forEach((viewmodel: Record) => { + const { states, id } = viewmodel; + if (!states || states.length < 1) { + return; + } + states.forEach((state: Record) => { + const { code, type, category, value } = state; + const viewModel = getViewModelById(id); + if (!viewModel) { + return; + } + const stateValue = transformValue(value, type); + viewModel.uiStore?.setValue(code, stateValue); + }); + }); +} diff --git a/packages/renderer/src/preview.vue b/packages/renderer/src/preview.vue index 4b40597d3a2..e7759006beb 100644 --- a/packages/renderer/src/preview.vue +++ b/packages/renderer/src/preview.vue @@ -2,7 +2,7 @@ diff --git a/packages/mobile-ui-vue/demos/lookup/multi-select.vue b/packages/mobile-ui-vue/demos/lookup/multi-select.vue new file mode 100644 index 00000000000..abbfbbe9c55 --- /dev/null +++ b/packages/mobile-ui-vue/demos/lookup/multi-select.vue @@ -0,0 +1,36 @@ + + -- Gitee From 5e9c3e29cb8bb11209984854ea8ce9cd45e8bddb Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 25 Mar 2025 08:51:17 +0800 Subject: [PATCH 101/153] =?UTF-8?q?chore:=20=E8=A1=A8=E6=A0=BC=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=A0=BC=E7=BC=96=E8=BE=91=E5=89=8D=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../before-edit-cell-callback-handler.ts | 52 +++++++++++++++---- .../src/callback-handler/providers.ts | 4 +- .../src/schema/callback-resolvers.ts | 2 +- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts b/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts index 003f58552ec..c4500226c42 100644 --- a/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts +++ b/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts @@ -1,57 +1,87 @@ -import { Module } from "@farris/devkit-vue"; +import { ExpressionEvaluator, Module } from "@farris/devkit-vue"; import { CallbackHandler } from "./callback-handler"; import { get } from 'lodash-es'; import { FormMetadataService } from "../service"; import { DataSourceResolver, FieldResolver } from "../resolvers"; import { ENTITY_STORE_SUFFIX } from "../types"; +import { ConfigType } from "../config-dependency-resolver"; export class BeforeEditCallCallbackHandler extends CallbackHandler { public callbackType: string | null = 'beforeEditCell'; constructor( private module: Module, - private formMetadataService: FormMetadataService + private formMetadataService: FormMetadataService, + private expressionEvaluator: ExpressionEvaluator ) { super(); } public handle(callbackType: string, args: any[]): undefined | boolean | Promise { const { column, rawData } = args[0]; + const { viewSchema } = args[1]; + // 确定单元格是否允许编辑 + const canEdit = this.canEditCell(column, rawData, viewSchema); + if (!canEdit) { + return false; + } + // 可以编辑,更新lookup的选中行主键 + this.setLookupValue(column, rawData); + return true; + } + private canEditCell(column: Record, rowData: Record, viewSchema: Record): boolean { + const { id } = column; + const { dataSource } = viewSchema; + const resolvedEntity = DataSourceResolver.resolve(this.entitySchema, dataSource); + if(!resolvedEntity){ + console.warn(`当前单元格无法编辑,表格数据源${dataSource}不存在,请检查数据源配置`); + return false; + } + const { bindingPaths = [], primaryKey = 'id' } = resolvedEntity; + const columnSchema = viewSchema.columns.find((column: Record) => column.id === id); + const readonlyConfig = columnSchema?.editor?.readonly; + if (readonlyConfig && readonlyConfig.type === ConfigType.Expression) { + const { expressionId } = readonlyConfig; + const result = this.expressionEvaluator.evaluate(expressionId, [{ bindingPath: `/${bindingPaths.join('/')}`, primaryValue: rowData[primaryKey] }]); + return !result; + } + return !column.editor.readonly; + } + private setLookupValue(column: Record, rowData: Record) { const { editor, binding } = column || {}; if (!editor || !binding) { - return true; + return; } const { type, mappingFields, dataSource } = editor; if (type !== 'lookup' || !dataSource) { - return true; + return; } const { idField } = dataSource; const mappingFieldsObject = typeof mappingFields === 'string' ? JSON.parse(mappingFields) : mappingFields; if (!mappingFieldsObject || Object.keys(mappingFieldsObject).length < 1) { - return true; + return; } const valueField = get(mappingFieldsObject, idField); const entityStoreId = this.formMetadataService.getModuleCode() + ENTITY_STORE_SUFFIX; const entityStore = this.module.getEntityStore(entityStoreId); if (!entityStore) { - return true; + return; } const { field } = binding; if (!field) { - return true; + return; } const { dataSource: entitySource } = FieldResolver.resolve(this.entitySchema, field) || {}; if (!entitySource) { - return true; + return; } const { bindingPaths = [], primaryKey = 'id' } = DataSourceResolver.resolve(this.entitySchema, entitySource) || {}; const entityListPath = `/${bindingPaths.join('/')}`; const entityList = entityStore?.getEntityListByPath(entityListPath); - const primaryValue = rawData[primaryKey]; + const primaryValue = rowData[primaryKey]; const entity = entityList?.getEntityById(primaryValue); if (!entity) { - return true; + return; } editor.idValue = get(entity, valueField); - return true; } private get entitySchema() { return this.formMetadataService.getEntity(); diff --git a/packages/renderer/src/callback-handler/providers.ts b/packages/renderer/src/callback-handler/providers.ts index 78b26cf45de..059aed437f7 100644 --- a/packages/renderer/src/callback-handler/providers.ts +++ b/packages/renderer/src/callback-handler/providers.ts @@ -1,4 +1,4 @@ -import { Injector, Module, StaticProvider } from "@farris/devkit-vue"; +import { ExpressionEvaluator, Injector, Module, StaticProvider } from "@farris/devkit-vue"; import { CALLBACK_HANDLER_TOKEN } from "../tokens"; import { BeforeEditCallCallbackHandler } from "./before-edit-cell-callback-handler"; import { CallbackHandlerRegistry } from "./callback-handler-registry"; @@ -6,6 +6,6 @@ import { FormMetadataService } from "../service"; export const callbackHandlerProviders: StaticProvider[] = [ - { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeEditCallCallbackHandler, deps: [Module, FormMetadataService], multi: true }, + { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeEditCallCallbackHandler, deps: [Module, FormMetadataService, ExpressionEvaluator], multi: true }, { provide: CallbackHandlerRegistry, useClass: CallbackHandlerRegistry, deps: [Injector] } ]; diff --git a/packages/ui-vue/components/data-grid/src/schema/callback-resolvers.ts b/packages/ui-vue/components/data-grid/src/schema/callback-resolvers.ts index 3507cb579c1..70ef9e3582c 100644 --- a/packages/ui-vue/components/data-grid/src/schema/callback-resolvers.ts +++ b/packages/ui-vue/components/data-grid/src/schema/callback-resolvers.ts @@ -5,7 +5,7 @@ export function createDataGridCallbackResolver() { function resolve(viewSchema: Record, caller: Caller) { const callbacks: Record = {}; callbacks.beforeEditCell = (context: { row: VisualData, cell: VisualDataCell, rawData: any, column: DataColumn; }): Promise => { - return caller.call('beforeEditCell', [context]); + return caller.call('beforeEditCell', [context, viewSchema]); }; return callbacks; } -- Gitee From 9e9571d33b0e647833eb460da6bc00af5b60f349 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Tue, 25 Mar 2025 09:24:06 +0800 Subject: [PATCH 102/153] =?UTF-8?q?feature:=20=E5=AE=8C=E5=96=84=E5=89=8D?= =?UTF-8?q?=E7=AB=AFVariable=E5=8F=98=E6=9B=B4=E6=8F=90=E5=8F=96=E5=92=8C?= =?UTF-8?q?=E5=90=8E=E7=AB=AFVariable=E5=8F=98=E6=9B=B4=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E8=BF=87=E7=A8=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/bef/lib/bef-proxy-extend.ts | 51 +++++++++++++++++--- packages/bef/lib/bef-variable-manager.ts | 11 ++--- packages/bef/lib/utils/request-info.util.ts | 27 +++++++++-- packages/bef/lib/utils/response-info.util.ts | 12 +++++ 4 files changed, 82 insertions(+), 19 deletions(-) diff --git a/packages/bef/lib/bef-proxy-extend.ts b/packages/bef/lib/bef-proxy-extend.ts index 9da66f4f149..6eb15a41099 100644 --- a/packages/bef/lib/bef-proxy-extend.ts +++ b/packages/bef/lib/bef-proxy-extend.ts @@ -33,7 +33,11 @@ export class BefProxyExtend implements IProxyExtend { public onResponse(response: any, hasRequestInfo: boolean): ResponseInfo { this.handleResponseHeaders(response.headers); this.handleEntityChanges(response.body); + this.handleVariableChange(response.body); + this.clearEntityChanges(hasRequestInfo); + this.clearVariableChange(hasRequestInfo); + return this.handleResponseBody(response.body); } @@ -43,13 +47,28 @@ export class BefProxyExtend implements IProxyExtend { private handleResponseHeaders(headers: any): void { this.repository.sessionService.handleResponseHeaders(headers); } - private handleEntityChanges(responseInfo: ResponseInfo) { + + /** + * 处理服务器端返回的Entity变更 + */ + private handleEntityChanges(responseInfo: ResponseInfo): void { const dataChanges = responseInfo && responseInfo.innerDataChange; if (!dataChanges || !Array.isArray(dataChanges) || dataChanges.length < 1) { return; } ResponseInfoUtil.handleEntityChanges(this.repository, dataChanges); } + + /** + * 处理后端返回的变量 + */ + private handleVariableChange(responseInfo: ResponseInfo): void { + if (!responseInfo || !responseInfo.innerVariableChange) { + return; + } + ResponseInfoUtil.handleVariableChange(this.repository, responseInfo.innerVariableChange); + } + /** * 处理服务器端返回的的body数据 */ @@ -59,13 +78,31 @@ export class BefProxyExtend implements IProxyExtend { } return responseInfo; } - private clearEntityChanges(hasRequestInfo?: boolean) { - if (hasRequestInfo) { - // 重置变更状态 - const entityStore = this.repository.entityStore; - const entityChangeHistory = entityStore.entityChangeHistory; - entityChangeHistory.stageChanges(); + + /** + * 清空Entity变更 + */ + private clearEntityChanges(hasRequestInfo?: boolean): void { + if (!hasRequestInfo) { + return; + } + + // 重置变更状态 + const entityStore = this.repository.entityStore; + const entityChangeHistory = entityStore.entityChangeHistory; + entityChangeHistory.stageChanges(); + } + + /** + * 清空Variable变更 + */ + private clearVariableChange(hasRequestInfo?: boolean): void { + if (!hasRequestInfo) { + return; } + + const variableManager = this.repository.variableManager; + variableManager.clearChanges(); } /** diff --git a/packages/bef/lib/bef-variable-manager.ts b/packages/bef/lib/bef-variable-manager.ts index 54fd431b342..adc46f780b4 100644 --- a/packages/bef/lib/bef-variable-manager.ts +++ b/packages/bef/lib/bef-variable-manager.ts @@ -151,14 +151,9 @@ class BefVariableManager { /** * 从UIState上获取变量值 */ - private getValueFromUIState(mapping: string): any { - const uiState = this.getRootUIStore(); - - // 计算value - const mappingArray = mapping.split('.'); - const value = mappingArray.reduce((accumulator: any, currentValue: any) => { - return accumulator ? accumulator[currentValue] : null; - }, uiState); + private getValueFromUIState(name: string): any { + const rootUIStore = this.getRootUIStore(); + const value = rootUIStore.getValue(name); if (value instanceof Date) { return format(value, 'yyyy-MM-dd HH:mm:ss'); diff --git a/packages/bef/lib/utils/request-info.util.ts b/packages/bef/lib/utils/request-info.util.ts index 396bfcd0775..0ce32601c72 100644 --- a/packages/bef/lib/utils/request-info.util.ts +++ b/packages/bef/lib/utils/request-info.util.ts @@ -9,15 +9,34 @@ class RequestInfoUtil { * 构造RequestInfo */ public static buildRequestInfo(repository: BefRepository): RequestInfo { - const changeDetailBuilder = new BefChangeDetailBuilder(repository); - const changeDetails = changeDetailBuilder.build(); const requestInfo: RequestInfo = { - dataChange: changeDetails, - variableChange: null + dataChange: this.buildEntityChangeDetials(repository), + variableChange: this.buildVariableChangeDetail(repository) }; return requestInfo; } + + /** + * 构造Entity变更集合 + */ + public static buildEntityChangeDetials(repository: BefRepository) { + const changeDetailBuilder = new BefChangeDetailBuilder(repository); + const changeDetails = changeDetailBuilder.build(); + + return changeDetails; + } + + /** + * 构造Variable变更 + */ + public static buildVariableChangeDetail(repository: BefRepository) { + const variableManager = repository.variableManager; + const variableChangeDetail = variableManager.buildChangeDetail(); + + return variableChangeDetail; + } + /** * 向body中添加RequestInfo */ diff --git a/packages/bef/lib/utils/response-info.util.ts b/packages/bef/lib/utils/response-info.util.ts index cb12bdd2726..78e5a9ea987 100644 --- a/packages/bef/lib/utils/response-info.util.ts +++ b/packages/bef/lib/utils/response-info.util.ts @@ -35,10 +35,22 @@ class ResponseInfoUtil { return result.returnValue; } + + /** + * 处理Entity变更 + */ public static handleEntityChanges(repository: BefRepository, changeDetails: ChangeDetail[]) { const changeDetailHandler = new BefChangeDetailHandler(repository); changeDetailHandler.handle(changeDetails); } + + /** + * 处理Variable变更 + */ + public static handleVariableChange(repository: BefRepository, changeDetail: ChangeDetail) { + const variableManager = repository.variableManager; + variableManager.handleChangeDetail(changeDetail); + } } export { ResponseInfoUtil }; -- Gitee From e597817d224747ed13d7f3972f776cddd09cb882 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Tue, 25 Mar 2025 10:36:48 +0800 Subject: [PATCH 103/153] =?UTF-8?q?feature:=20=E7=BB=84=E4=BB=B6=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E3=80=81=E8=A1=A8=E5=8D=95=E5=8F=98=E9=87=8F=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=AE=BE=E7=BD=AE=E9=BB=98=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/store/ui-store/configs/ui-config.ts | 1 + packages/devkit/lib/store/ui-store/ui-store.ts | 17 +++++++++++++---- .../config-builders/ui-store-config-builder.ts | 5 ++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/devkit/lib/store/ui-store/configs/ui-config.ts b/packages/devkit/lib/store/ui-store/configs/ui-config.ts index 35fef4d5c05..dff8fc84620 100644 --- a/packages/devkit/lib/store/ui-store/configs/ui-config.ts +++ b/packages/devkit/lib/store/ui-store/configs/ui-config.ts @@ -7,6 +7,7 @@ import { UIState, UIStore } from '../ui-store'; */ interface UIStatePropConfig { name: string; + defaultValue?: any; } /** diff --git a/packages/devkit/lib/store/ui-store/ui-store.ts b/packages/devkit/lib/store/ui-store/ui-store.ts index 7c4a9194da0..5c7731784eb 100644 --- a/packages/devkit/lib/store/ui-store/ui-store.ts +++ b/packages/devkit/lib/store/ui-store/ui-store.ts @@ -1,6 +1,6 @@ import { Module } from '../../module/index'; import { Store } from '../store/index'; -import { UIStoreConfig } from './configs/index'; +import { UIStoreConfig, UIStatePropConfig } from './configs/index'; import { UIStateChangeType, UIStateValueChange } from './uistate-change'; /** @@ -27,14 +27,23 @@ class UIStore extends Store { */ public init(config: UIStoreConfig): void { super.init(config); - this.initState(); + this.initState(config); } /** * 初始化属性 */ - private initState(): void { - this.state = {} as any; + private initState(config: UIStoreConfig): void { + const state = {} as any; + const statePropConfigs = config.state.props; + statePropConfigs.forEach((statePropConfig: UIStatePropConfig) => { + const { name, defaultValue } = statePropConfig; + if (defaultValue !== undefined) { + state[name] = defaultValue; + } + }); + + this.state = state; } /** diff --git a/packages/renderer/src/config-builders/ui-store-config-builder.ts b/packages/renderer/src/config-builders/ui-store-config-builder.ts index 9ad39b83bf1..14a24cf9f01 100644 --- a/packages/renderer/src/config-builders/ui-store-config-builder.ts +++ b/packages/renderer/src/config-builders/ui-store-config-builder.ts @@ -49,8 +49,11 @@ class UIStoreConfigBuilder { const propConfigs: UIStatePropConfig[] = []; stateNodes.forEach((stateNode) => { const propConfig: UIStatePropConfig = { - name: stateNode.code + name: stateNode.code, }; + if (stateNode.value) { + propConfig.defaultValue = stateNode.value; + } propConfigs.push(propConfig); }); -- Gitee From 42fe245db49b197c3ff0db440976046bed4de1e8 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 25 Mar 2025 10:51:08 +0800 Subject: [PATCH 104/153] =?UTF-8?q?chore:=20=E6=94=AF=E6=8C=81=E5=B8=AE?= =?UTF-8?q?=E5=8A=A9=E5=89=8D=E3=80=81=E5=8A=A0=E8=BD=BD=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=89=8D=E3=80=81=E6=95=B0=E6=8D=AE=E9=80=89=E6=8B=A9=E7=A1=AE?= =?UTF-8?q?=E8=AE=A4=E5=89=8D=E5=9B=9E=E8=B0=83=EF=BC=9B=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E6=9C=AA=E5=AE=9A=E4=B9=89=E9=BB=98=E8=AE=A4=E5=80=BC=E6=97=B6?= =?UTF-8?q?=E4=B8=8D=E5=86=8D=E6=A0=B9=E6=8D=AE=E7=B1=BB=E5=9E=8B=E8=B5=8B?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../before-load-data-callback-handler.ts | 24 ++++++++++++++++++ .../before-select-data-callback-handler.ts | 24 ++++++++++++++++++ .../dict-picking-callback-handler.ts | 25 +++++++++++++++++++ .../renderer/src/callback-handler/index.ts | 3 +++ .../src/callback-handler/providers.ts | 6 +++++ .../composition/use-view-model-initializer.ts | 17 +------------ packages/ui-vue/components/lookup/index.ts | 3 ++- .../components/lookup/src/lookup.props.ts | 3 +++ .../lookup/src/schema/callback-resolvers.ts | 24 ++++++++++++++++++ 9 files changed, 112 insertions(+), 17 deletions(-) create mode 100644 packages/renderer/src/callback-handler/before-load-data-callback-handler.ts create mode 100644 packages/renderer/src/callback-handler/before-select-data-callback-handler.ts create mode 100644 packages/renderer/src/callback-handler/dict-picking-callback-handler.ts create mode 100644 packages/ui-vue/components/lookup/src/schema/callback-resolvers.ts diff --git a/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts b/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts new file mode 100644 index 00000000000..bccbfc43337 --- /dev/null +++ b/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts @@ -0,0 +1,24 @@ +import { Module } from "@farris/devkit-vue"; +import { CallbackHandler } from "./callback-handler"; +import { FormMetadataService } from "../service"; + +export class BeforeLoadDataCallbackHandler extends CallbackHandler { + public callbackType: string | null = 'beforeLoadData'; + constructor( + private module: Module, + private formMetadataService: FormMetadataService + ) { + super(); + } + public handle(type: string, args: any[]): undefined | boolean | Promise { + const eventArgs = args[0]; + const { viewSchema } = args[1]; + const { beforeLoadData, id } = viewSchema; + if (!beforeLoadData) { + return true; + } + const relatedComponent = this.formMetadataService.getRelatedComponent(id); + const viewModel = this.module.getViewModel(relatedComponent.id); + return (viewModel as any)[beforeLoadData](eventArgs); + } +} diff --git a/packages/renderer/src/callback-handler/before-select-data-callback-handler.ts b/packages/renderer/src/callback-handler/before-select-data-callback-handler.ts new file mode 100644 index 00000000000..b88a30985fa --- /dev/null +++ b/packages/renderer/src/callback-handler/before-select-data-callback-handler.ts @@ -0,0 +1,24 @@ +import { Module } from "@farris/devkit-vue"; +import { CallbackHandler } from "./callback-handler"; +import { FormMetadataService } from "../service"; + +export class BeforeSelectDataCallbackHandler extends CallbackHandler { + public callbackType: string | null = 'beforeSelectData'; + constructor( + private module: Module, + private formMetadataService: FormMetadataService, + ) { + super(); + } + public handle(type: string, args: any[]): undefined | boolean | Promise { + const eventArgs = args[0]; + const { viewSchema } = args[1]; + const { beforeSelectData, id } = viewSchema; + if (!beforeSelectData) { + return true; + } + const relatedComponent = this.formMetadataService.getRelatedComponent(id); + const viewModel = this.module.getViewModel(relatedComponent.id); + return (viewModel as any)[beforeSelectData](eventArgs); + } +} diff --git a/packages/renderer/src/callback-handler/dict-picking-callback-handler.ts b/packages/renderer/src/callback-handler/dict-picking-callback-handler.ts new file mode 100644 index 00000000000..10a2f92fa25 --- /dev/null +++ b/packages/renderer/src/callback-handler/dict-picking-callback-handler.ts @@ -0,0 +1,25 @@ +import { ExpressionEvaluator, Module } from "@farris/devkit-vue"; +import { CallbackHandler } from "./callback-handler"; +import { FormMetadataService } from "../service"; + +export class DictPickingCallbackHandler extends CallbackHandler { + public callbackType: string | null = 'dictPicking'; + constructor( + private module: Module, + private formMetadataService: FormMetadataService, + private expressionEvaluator: ExpressionEvaluator + ) { + super(); + } + public handle(type: string, args: any[]): undefined | boolean | Promise { + const eventArgs = args[0]; + const { viewSchema } = args[1]; + const { dictPicking, id } = viewSchema; + if (!dictPicking) { + return true; + } + const relatedComponent = this.formMetadataService.getRelatedComponent(id); + const viewModel = this.module.getViewModel(relatedComponent.id); + return (viewModel as any)[dictPicking](eventArgs); + } +} diff --git a/packages/renderer/src/callback-handler/index.ts b/packages/renderer/src/callback-handler/index.ts index be56bc66d3d..d09eb80c230 100644 --- a/packages/renderer/src/callback-handler/index.ts +++ b/packages/renderer/src/callback-handler/index.ts @@ -1,4 +1,7 @@ export * from './callback-handler'; export * from './before-edit-cell-callback-handler'; +export * from './dict-picking-callback-handler'; +export * from './before-load-data-callback-handler'; +export * from './before-select-data-callback-handler'; export * from './callback-handler-registry'; export * from './providers'; diff --git a/packages/renderer/src/callback-handler/providers.ts b/packages/renderer/src/callback-handler/providers.ts index 059aed437f7..a6a3d1f6f26 100644 --- a/packages/renderer/src/callback-handler/providers.ts +++ b/packages/renderer/src/callback-handler/providers.ts @@ -3,9 +3,15 @@ import { CALLBACK_HANDLER_TOKEN } from "../tokens"; import { BeforeEditCallCallbackHandler } from "./before-edit-cell-callback-handler"; import { CallbackHandlerRegistry } from "./callback-handler-registry"; import { FormMetadataService } from "../service"; +import { DictPickingCallbackHandler } from "./dict-picking-callback-handler"; +import { BeforeLoadDataCallbackHandler } from "./before-load-data-callback-handler"; +import { BeforeSelectDataCallbackHandler } from "./before-select-data-callback-handler"; export const callbackHandlerProviders: StaticProvider[] = [ { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeEditCallCallbackHandler, deps: [Module, FormMetadataService, ExpressionEvaluator], multi: true }, + { provide: CALLBACK_HANDLER_TOKEN, useClass: DictPickingCallbackHandler, deps: [Module, FormMetadataService, ExpressionEvaluator], multi: true }, + { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeLoadDataCallbackHandler, deps: [Module, FormMetadataService], multi: true }, + { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeSelectDataCallbackHandler, deps: [Module, FormMetadataService], multi: true }, { provide: CallbackHandlerRegistry, useClass: CallbackHandlerRegistry, deps: [Injector] } ]; diff --git a/packages/renderer/src/composition/use-view-model-initializer.ts b/packages/renderer/src/composition/use-view-model-initializer.ts index 1d0dbbd4ba4..fd5e99eb722 100644 --- a/packages/renderer/src/composition/use-view-model-initializer.ts +++ b/packages/renderer/src/composition/use-view-model-initializer.ts @@ -18,18 +18,12 @@ export function useViewModelInitializer(module: Module, metadata: Record { FLookup.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { componentMap.lookup = FLookup; propsResolverMap.lookup = propsResolver; + resolverMap.lookup = { callbackResolver }; }; FLookup.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record) => { diff --git a/packages/ui-vue/components/lookup/src/lookup.props.ts b/packages/ui-vue/components/lookup/src/lookup.props.ts index c3bd8a9cd88..405dd687778 100644 --- a/packages/ui-vue/components/lookup/src/lookup.props.ts +++ b/packages/ui-vue/components/lookup/src/lookup.props.ts @@ -10,6 +10,7 @@ import { BeforeOpenDialogFunction, BeforeSubmitFunction, CallBackFunction, LoadT NavigationOptions, SearchField, TextChangedType, BeforeLoadData, CascadeOptions} from "./composition/types"; +import { createLookupCallbackResolver } from "./schema/callback-resolvers"; export const lookupProps = { id: {type: String, require: true}, @@ -91,3 +92,5 @@ export const lookupProps = { export type LookupProps = ExtractPropTypes; export const propsResolver = createPropsResolver(lookupProps, lookupSchema,schemaMapper, schemaResolver); + +export const callbackResolver = createLookupCallbackResolver(); diff --git a/packages/ui-vue/components/lookup/src/schema/callback-resolvers.ts b/packages/ui-vue/components/lookup/src/schema/callback-resolvers.ts new file mode 100644 index 00000000000..8f47c7cda07 --- /dev/null +++ b/packages/ui-vue/components/lookup/src/schema/callback-resolvers.ts @@ -0,0 +1,24 @@ +import { Caller } from "../../../dynamic-resolver"; +import { LookupHttpResult } from "../composition/types"; + +export function createLookupCallbackResolver() { + function resolve(viewSchema: Record, caller: Caller) { + const callbacks: Record = {}; + callbacks.dictPicking = (context: { customData: any, options: any; }): Promise => { + return caller.call('dictPicking', [context, viewSchema]); + }; + callbacks.beforeLoadData = (data: any): Promise => { + return caller.call('beforeLoadData', [data, viewSchema]); + }; + callbacks.beforeSelectData = (items: any): boolean | {canSelect: boolean, message?: string} => { + return caller.call('beforeSelectData', [items, viewSchema]); + }; + // callbacks.dictPicked = (items: any): void => { + // return caller.call('dictPicked', [items, viewSchema]); + // }; + return callbacks; + } + return { + resolve + }; +} -- Gitee From e4b2145ffb57372569acdd96177e2e9ac65a207d Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 25 Mar 2025 11:47:11 +0800 Subject: [PATCH 105/153] =?UTF-8?q?chore:=20=E4=BF=AE=E5=A4=8D=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E8=A7=A3=E6=9E=84=E9=94=99=E8=AF=AF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/command-services/lib/navigation-history.service.ts | 2 +- .../src/callback-handler/before-edit-cell-callback-handler.ts | 4 ++-- .../src/callback-handler/before-load-data-callback-handler.ts | 2 +- .../callback-handler/before-select-data-callback-handler.ts | 2 +- .../src/callback-handler/dict-picking-callback-handler.ts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/command-services/lib/navigation-history.service.ts b/packages/command-services/lib/navigation-history.service.ts index 224696ed16e..5b0bb02ae7d 100644 --- a/packages/command-services/lib/navigation-history.service.ts +++ b/packages/command-services/lib/navigation-history.service.ts @@ -62,7 +62,7 @@ export class NavigationHistoryService { * @param history */ private serialize(history: any) { - sessionStorage.setItem(this.COMMAND_SERVICE_NAVIGATION_HISTORY, JSON.stringify(history)); + sessionStorage?.setItem(this.COMMAND_SERVICE_NAVIGATION_HISTORY, JSON.stringify(history)); } /** * 对象化 diff --git a/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts b/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts index c4500226c42..323370908c7 100644 --- a/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts +++ b/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts @@ -17,7 +17,7 @@ export class BeforeEditCallCallbackHandler extends CallbackHandler { } public handle(callbackType: string, args: any[]): undefined | boolean | Promise { const { column, rawData } = args[0]; - const { viewSchema } = args[1]; + const viewSchema = args[1]; // 确定单元格是否允许编辑 const canEdit = this.canEditCell(column, rawData, viewSchema); if (!canEdit) { @@ -31,7 +31,7 @@ export class BeforeEditCallCallbackHandler extends CallbackHandler { const { id } = column; const { dataSource } = viewSchema; const resolvedEntity = DataSourceResolver.resolve(this.entitySchema, dataSource); - if(!resolvedEntity){ + if (!resolvedEntity) { console.warn(`当前单元格无法编辑,表格数据源${dataSource}不存在,请检查数据源配置`); return false; } diff --git a/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts b/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts index bccbfc43337..d2594438ba6 100644 --- a/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts +++ b/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts @@ -12,7 +12,7 @@ export class BeforeLoadDataCallbackHandler extends CallbackHandler { } public handle(type: string, args: any[]): undefined | boolean | Promise { const eventArgs = args[0]; - const { viewSchema } = args[1]; + const viewSchema = args[1]; const { beforeLoadData, id } = viewSchema; if (!beforeLoadData) { return true; diff --git a/packages/renderer/src/callback-handler/before-select-data-callback-handler.ts b/packages/renderer/src/callback-handler/before-select-data-callback-handler.ts index b88a30985fa..34d0ad4df23 100644 --- a/packages/renderer/src/callback-handler/before-select-data-callback-handler.ts +++ b/packages/renderer/src/callback-handler/before-select-data-callback-handler.ts @@ -12,7 +12,7 @@ export class BeforeSelectDataCallbackHandler extends CallbackHandler { } public handle(type: string, args: any[]): undefined | boolean | Promise { const eventArgs = args[0]; - const { viewSchema } = args[1]; + const viewSchema = args[1]; const { beforeSelectData, id } = viewSchema; if (!beforeSelectData) { return true; diff --git a/packages/renderer/src/callback-handler/dict-picking-callback-handler.ts b/packages/renderer/src/callback-handler/dict-picking-callback-handler.ts index 10a2f92fa25..5dd174aad81 100644 --- a/packages/renderer/src/callback-handler/dict-picking-callback-handler.ts +++ b/packages/renderer/src/callback-handler/dict-picking-callback-handler.ts @@ -13,7 +13,7 @@ export class DictPickingCallbackHandler extends CallbackHandler { } public handle(type: string, args: any[]): undefined | boolean | Promise { const eventArgs = args[0]; - const { viewSchema } = args[1]; + const viewSchema = args[1]; const { dictPicking, id } = viewSchema; if (!dictPicking) { return true; -- Gitee From 3d701b0ce492aef56a3c653a78617863885bcf54 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 25 Mar 2025 15:09:40 +0800 Subject: [PATCH 106/153] =?UTF-8?q?chore:=20=E8=A7=A3=E5=86=B3=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E6=89=A7=E8=A1=8C=E5=90=8E=E6=97=A0=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E5=80=BC=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/devkit/lib/command/dynamic-command-handler.ts | 2 +- packages/devkit/lib/command/taskflow/task-flow.ts | 3 +++ packages/devkit/lib/viewmodel/viewmodel.ts | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/devkit/lib/command/dynamic-command-handler.ts b/packages/devkit/lib/command/dynamic-command-handler.ts index 840f61c38f7..28b36ed3a4d 100644 --- a/packages/devkit/lib/command/dynamic-command-handler.ts +++ b/packages/devkit/lib/command/dynamic-command-handler.ts @@ -70,7 +70,7 @@ class DynamicCommandHandler extends CommandHandler { const serviceInstancePromise = this.getServiceInstance(taskConfig, taskFlowContext.commandContext); if (TypeUtil.isPromise(serviceInstancePromise)) { - serviceInstancePromise.then((serviceInstance) => { + return serviceInstancePromise.then((serviceInstance) => { serviceInstance['context'] = taskFlowContext.commandContext; return serviceInstance[methodName](...methodParams); }); diff --git a/packages/devkit/lib/command/taskflow/task-flow.ts b/packages/devkit/lib/command/taskflow/task-flow.ts index c25f2d21fae..b7eaf737129 100644 --- a/packages/devkit/lib/command/taskflow/task-flow.ts +++ b/packages/devkit/lib/command/taskflow/task-flow.ts @@ -31,9 +31,11 @@ class TaskFlow { public async execute() { let currentTask: TaskNode | null = this.getFistTask(); let rejectedOrHasException = false; + let lastResult: any = undefined; while (currentTask && !rejectedOrHasException) { try { const currentTaskResult = await currentTask.execute(this.context); + lastResult = currentTaskResult; this.context.setTaskResult(currentTask.name, currentTaskResult); currentTask = this.getNextTask(currentTask); } catch (error: any) { @@ -43,6 +45,7 @@ class TaskFlow { rejectedOrHasException = true; } } + return !rejectedOrHasException ? lastResult : undefined; } /** diff --git a/packages/devkit/lib/viewmodel/viewmodel.ts b/packages/devkit/lib/viewmodel/viewmodel.ts index 5842fea2b43..38dcedb4f08 100644 --- a/packages/devkit/lib/viewmodel/viewmodel.ts +++ b/packages/devkit/lib/viewmodel/viewmodel.ts @@ -130,7 +130,7 @@ class ViewModel extends ViewModelNode { if (!this.commandBus) { throw new Error('No CommandBus provided'); } - this.commandBus.dispatch(command); + return this.commandBus.dispatch(command); } } -- Gitee From de1ceacdd29896698e10516e1caab2cdaac29836 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 25 Mar 2025 15:10:24 +0800 Subject: [PATCH 107/153] =?UTF-8?q?chore:=20=E8=BE=93=E5=85=A5=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=94=AF=E6=8C=81=E5=9B=9E=E8=B0=83=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/dynamic-view.component.tsx | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/packages/ui-vue/components/dynamic-view/src/dynamic-view.component.tsx b/packages/ui-vue/components/dynamic-view/src/dynamic-view.component.tsx index 7da507e1991..75a6dcbb6f5 100644 --- a/packages/ui-vue/components/dynamic-view/src/dynamic-view.component.tsx +++ b/packages/ui-vue/components/dynamic-view/src/dynamic-view.component.tsx @@ -65,12 +65,23 @@ const FDynamicView = defineComponent({ if (!resolvers || Object.keys(resolvers).length < 1) { return {}; } - const { callbackResolver } = resolvers; + const { callbackResolver, editorResolver } = resolvers; + const callbackDeliver = createCallbackDeliver(callback.value); + if (editorResolver) { + const editor = editorResolver.resolve(viewSchema); + const componentType = editor.type; + const resolvers = resolverMap[componentType]; + const { callbackResolver } = resolvers || {}; + if (!callbackResolver) { + return {}; + } + return callbackResolver.resolve(viewSchema, callbackDeliver); + } if (!callbackResolver) { return {}; } - const callbackDeliver = createCallbackDeliver(callback.value); return callbackResolver.resolve(viewSchema, callbackDeliver); + } function resolveEvents(viewSchema: Record) { const componentKey = viewSchema.type; @@ -105,24 +116,16 @@ const FDynamicView = defineComponent({ const componentKey = viewSchema.type; const propsConverter = componentPropsConverter[componentKey]; const componentProps: Record = propsConverter ? propsConverter(viewSchema) : {}; - // const Component = componentMap[componentKey]; - // const componentPropertyProps = Object.keys(Component?.props || {}); - // const componentEventProps = (Component?.emits as string[] || []).map((eventName: string) => `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`); - // const currentComponentProps = componentPropertyProps.concat(componentEventProps); - // const componentProps = Object.keys(componentSchema).reduce((props: Record, propertyName: string) => { - // if (currentComponentProps.indexOf(propertyName) !== -1) { - // props[propertyName] = componentSchema[propertyName]; - // } - // return props; - // }, {}); const eventProps = { ...resolveEvents(viewSchema) }; + const callbackProps = { + ...resolveCallbacks(viewSchema) + }; const viewProps = { ...componentProps, ...resolveModels(viewSchema), - ...resolveExtraProps(viewSchema), - ...resolveCallbacks(viewSchema) + ...resolveExtraProps(viewSchema) }; const props = { ...viewProps, @@ -134,7 +137,7 @@ const FDynamicView = defineComponent({ } } }; - return { props, eventProps }; + return { props, eventProps, callbackProps }; } function render(viewSchema: Record) { @@ -272,12 +275,12 @@ const FDynamicView = defineComponent({ if (!Component) { return; } - const { props, eventProps } = resolveProps(viewSchema); + const { props, eventProps, callbackProps } = resolveProps(viewSchema); const resolver = resolverMap[componentKey]; const editorResolver: EditorResolver = resolver ? resolver.editorResolver : null; if (editorResolver) { const editor = editorResolver.resolve(viewSchema); - Object.assign(editor, eventProps); + Object.assign(editor, eventProps, callbackProps); } else { Object.assign(props, eventProps); } -- Gitee From 86a10f37f51931cc425b50a54e465dbbe23b16d4 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 25 Mar 2025 15:28:52 +0800 Subject: [PATCH 108/153] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0html?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=BB=84=E4=BB=B6=E6=B8=B2=E6=9F=93=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E7=BC=96=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../html-template-component-template-transformer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/renderer/src/template-transformer/html-template-component-template-transformer.ts b/packages/renderer/src/template-transformer/html-template-component-template-transformer.ts index 9ed419912f8..48de01a5497 100644 --- a/packages/renderer/src/template-transformer/html-template-component-template-transformer.ts +++ b/packages/renderer/src/template-transformer/html-template-component-template-transformer.ts @@ -16,6 +16,6 @@ export class HtmlTemplateComponentTemplateTransformer extends TemplateTransforme const render = () => { return createVNode({ render: compiledTemplate, props: ['viewModel'] }, { viewModel: templateContext }); }; - schema.html = render; + schema.renderFunction = render; } } -- Gitee From 303894c8f55ee712d44f471b99c2873518fb9a0a Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 25 Mar 2025 15:33:04 +0800 Subject: [PATCH 109/153] =?UTF-8?q?chore:=20=E6=94=AF=E6=8C=81=E5=B8=AE?= =?UTF-8?q?=E5=8A=A9=E5=90=8E=E5=9B=9E=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dict-picked-callback-handler.ts | 24 +++++++++++++++++++ .../renderer/src/callback-handler/index.ts | 1 + .../src/callback-handler/providers.ts | 2 ++ .../lookup/src/schema/callback-resolvers.ts | 6 ++--- 4 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 packages/renderer/src/callback-handler/dict-picked-callback-handler.ts diff --git a/packages/renderer/src/callback-handler/dict-picked-callback-handler.ts b/packages/renderer/src/callback-handler/dict-picked-callback-handler.ts new file mode 100644 index 00000000000..3dcb8f317b9 --- /dev/null +++ b/packages/renderer/src/callback-handler/dict-picked-callback-handler.ts @@ -0,0 +1,24 @@ +import { Module } from "@farris/devkit-vue"; +import { CallbackHandler } from "./callback-handler"; +import { FormMetadataService } from "../service"; + +export class DictPickedCallbackHandler extends CallbackHandler { + public callbackType: string | null = 'dictPicked'; + constructor( + private module: Module, + private formMetadataService: FormMetadataService, + ) { + super(); + } + public handle(type: string, args: any[]): undefined | boolean | Promise { + const eventArgs = args[0]; + const viewSchema = args[1]; + const { dictPicked, id } = viewSchema; + if (!dictPicked) { + return true; + } + const relatedComponent = this.formMetadataService.getRelatedComponent(id); + const viewModel = this.module.getViewModel(relatedComponent.id); + return (viewModel as any)[dictPicked](eventArgs); + } +} diff --git a/packages/renderer/src/callback-handler/index.ts b/packages/renderer/src/callback-handler/index.ts index d09eb80c230..eea8153ac31 100644 --- a/packages/renderer/src/callback-handler/index.ts +++ b/packages/renderer/src/callback-handler/index.ts @@ -3,5 +3,6 @@ export * from './before-edit-cell-callback-handler'; export * from './dict-picking-callback-handler'; export * from './before-load-data-callback-handler'; export * from './before-select-data-callback-handler'; +export * from './dict-picked-callback-handler'; export * from './callback-handler-registry'; export * from './providers'; diff --git a/packages/renderer/src/callback-handler/providers.ts b/packages/renderer/src/callback-handler/providers.ts index a6a3d1f6f26..aaf3bb27702 100644 --- a/packages/renderer/src/callback-handler/providers.ts +++ b/packages/renderer/src/callback-handler/providers.ts @@ -6,6 +6,7 @@ import { FormMetadataService } from "../service"; import { DictPickingCallbackHandler } from "./dict-picking-callback-handler"; import { BeforeLoadDataCallbackHandler } from "./before-load-data-callback-handler"; import { BeforeSelectDataCallbackHandler } from "./before-select-data-callback-handler"; +import { DictPickedCallbackHandler } from "./dict-picked-callback-handler"; export const callbackHandlerProviders: StaticProvider[] = [ @@ -13,5 +14,6 @@ export const callbackHandlerProviders: StaticProvider[] = [ { provide: CALLBACK_HANDLER_TOKEN, useClass: DictPickingCallbackHandler, deps: [Module, FormMetadataService, ExpressionEvaluator], multi: true }, { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeLoadDataCallbackHandler, deps: [Module, FormMetadataService], multi: true }, { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeSelectDataCallbackHandler, deps: [Module, FormMetadataService], multi: true }, + { provide: CALLBACK_HANDLER_TOKEN, useClass: DictPickedCallbackHandler, deps: [Module, FormMetadataService], multi: true }, { provide: CallbackHandlerRegistry, useClass: CallbackHandlerRegistry, deps: [Injector] } ]; diff --git a/packages/ui-vue/components/lookup/src/schema/callback-resolvers.ts b/packages/ui-vue/components/lookup/src/schema/callback-resolvers.ts index 8f47c7cda07..e935e543bd3 100644 --- a/packages/ui-vue/components/lookup/src/schema/callback-resolvers.ts +++ b/packages/ui-vue/components/lookup/src/schema/callback-resolvers.ts @@ -13,9 +13,9 @@ export function createLookupCallbackResolver() { callbacks.beforeSelectData = (items: any): boolean | {canSelect: boolean, message?: string} => { return caller.call('beforeSelectData', [items, viewSchema]); }; - // callbacks.dictPicked = (items: any): void => { - // return caller.call('dictPicked', [items, viewSchema]); - // }; + callbacks.dictPicked = (items: any): void => { + return caller.call('dictPicked', [items, viewSchema]); + }; return callbacks; } return { -- Gitee From 7b008a20b7c49fc017103eaf73fd21529f927b3d Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 25 Mar 2025 17:12:35 +0800 Subject: [PATCH 110/153] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E7=BC=96=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../callback-handler/before-load-data-callback-handler.ts | 4 ++-- .../callback-handler/before-select-data-callback-handler.ts | 4 ++-- .../src/callback-handler/dict-picked-callback-handler.ts | 6 +++--- .../src/callback-handler/dict-picking-callback-handler.ts | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts b/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts index d2594438ba6..342cf74cba9 100644 --- a/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts +++ b/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts @@ -11,7 +11,7 @@ export class BeforeLoadDataCallbackHandler extends CallbackHandler { super(); } public handle(type: string, args: any[]): undefined | boolean | Promise { - const eventArgs = args[0]; + const payload = args[0]; const viewSchema = args[1]; const { beforeLoadData, id } = viewSchema; if (!beforeLoadData) { @@ -19,6 +19,6 @@ export class BeforeLoadDataCallbackHandler extends CallbackHandler { } const relatedComponent = this.formMetadataService.getRelatedComponent(id); const viewModel = this.module.getViewModel(relatedComponent.id); - return (viewModel as any)[beforeLoadData](eventArgs); + return (viewModel as any)[beforeLoadData](payload); } } diff --git a/packages/renderer/src/callback-handler/before-select-data-callback-handler.ts b/packages/renderer/src/callback-handler/before-select-data-callback-handler.ts index 34d0ad4df23..9529628074b 100644 --- a/packages/renderer/src/callback-handler/before-select-data-callback-handler.ts +++ b/packages/renderer/src/callback-handler/before-select-data-callback-handler.ts @@ -11,7 +11,7 @@ export class BeforeSelectDataCallbackHandler extends CallbackHandler { super(); } public handle(type: string, args: any[]): undefined | boolean | Promise { - const eventArgs = args[0]; + const payload = args[0]; const viewSchema = args[1]; const { beforeSelectData, id } = viewSchema; if (!beforeSelectData) { @@ -19,6 +19,6 @@ export class BeforeSelectDataCallbackHandler extends CallbackHandler { } const relatedComponent = this.formMetadataService.getRelatedComponent(id); const viewModel = this.module.getViewModel(relatedComponent.id); - return (viewModel as any)[beforeSelectData](eventArgs); + return (viewModel as any)[beforeSelectData](payload); } } diff --git a/packages/renderer/src/callback-handler/dict-picked-callback-handler.ts b/packages/renderer/src/callback-handler/dict-picked-callback-handler.ts index 3dcb8f317b9..71b2736230a 100644 --- a/packages/renderer/src/callback-handler/dict-picked-callback-handler.ts +++ b/packages/renderer/src/callback-handler/dict-picked-callback-handler.ts @@ -11,14 +11,14 @@ export class DictPickedCallbackHandler extends CallbackHandler { super(); } public handle(type: string, args: any[]): undefined | boolean | Promise { - const eventArgs = args[0]; + const payload = args[0]; const viewSchema = args[1]; const { dictPicked, id } = viewSchema; if (!dictPicked) { - return true; + return payload.data; } const relatedComponent = this.formMetadataService.getRelatedComponent(id); const viewModel = this.module.getViewModel(relatedComponent.id); - return (viewModel as any)[dictPicked](eventArgs); + return (viewModel as any)[dictPicked](payload); } } diff --git a/packages/renderer/src/callback-handler/dict-picking-callback-handler.ts b/packages/renderer/src/callback-handler/dict-picking-callback-handler.ts index 5dd174aad81..af6c338a2de 100644 --- a/packages/renderer/src/callback-handler/dict-picking-callback-handler.ts +++ b/packages/renderer/src/callback-handler/dict-picking-callback-handler.ts @@ -12,7 +12,7 @@ export class DictPickingCallbackHandler extends CallbackHandler { super(); } public handle(type: string, args: any[]): undefined | boolean | Promise { - const eventArgs = args[0]; + const payload = args[0]; const viewSchema = args[1]; const { dictPicking, id } = viewSchema; if (!dictPicking) { @@ -20,6 +20,6 @@ export class DictPickingCallbackHandler extends CallbackHandler { } const relatedComponent = this.formMetadataService.getRelatedComponent(id); const viewModel = this.module.getViewModel(relatedComponent.id); - return (viewModel as any)[dictPicking](eventArgs); + return (viewModel as any)[dictPicking](payload); } } -- Gitee From 40d3dd397b33d2933448d41807646dc2dd4e2c80 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 25 Mar 2025 17:23:46 +0800 Subject: [PATCH 111/153] =?UTF-8?q?chore:=20=E8=A7=A3=E5=86=B3=E5=B8=AE?= =?UTF-8?q?=E5=8A=A9=E6=95=B0=E6=8D=AE=E4=B8=8D=E5=8A=A0=E8=BD=BD=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/callback-handler/before-load-data-callback-handler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts b/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts index 342cf74cba9..a3463c12e4b 100644 --- a/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts +++ b/packages/renderer/src/callback-handler/before-load-data-callback-handler.ts @@ -15,7 +15,7 @@ export class BeforeLoadDataCallbackHandler extends CallbackHandler { const viewSchema = args[1]; const { beforeLoadData, id } = viewSchema; if (!beforeLoadData) { - return true; + return payload.data; } const relatedComponent = this.formMetadataService.getRelatedComponent(id); const viewModel = this.module.getViewModel(relatedComponent.id); -- Gitee From 03bce7475e7df40cd81dbcc4dde77a01aec09483 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Tue, 25 Mar 2025 20:02:40 +0800 Subject: [PATCH 112/153] =?UTF-8?q?fix:=201=E3=80=81=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E9=94=99=E8=AF=AF=E4=BF=A1=E6=81=AF=EF=BC=9B?= =?UTF-8?q?2=E3=80=81=E6=A0=A1=E9=AA=8C=E9=80=9A=E8=BF=87=E5=90=8E?= =?UTF-8?q?=E5=85=B3=E9=97=AD=E9=94=99=E8=AF=AF=E7=AA=97=E5=8F=A3=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/command-services/lib/validation.service.ts | 2 +- .../lib/store/form/validation/validators/max-date-validator.ts | 2 +- .../store/form/validation/validators/max-length-validator.ts | 2 +- .../lib/store/form/validation/validators/max-value-validator.ts | 2 +- .../lib/store/form/validation/validators/min-date-validator.ts | 2 +- .../store/form/validation/validators/min-length-validator.ts | 2 +- .../lib/store/form/validation/validators/min-value-validator.ts | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/command-services/lib/validation.service.ts b/packages/command-services/lib/validation.service.ts index c81bd99ff33..c748ab53cb9 100644 --- a/packages/command-services/lib/validation.service.ts +++ b/packages/command-services/lib/validation.service.ts @@ -58,7 +58,7 @@ export class ValidationService extends BaseDataService { this.verifyDetailService.show(verifyDetailOptions); return Promise.reject(allViewModelErrors) } - + this.verifyDetailService.clear(); return Promise.resolve(null); } diff --git a/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts b/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts index 8bf20430869..ba9e590c3fe 100644 --- a/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts @@ -34,7 +34,7 @@ class MaxDateValidator extends BaseValidator { if (value.getTime() > maxDate.getTime()) { const formattedActualDate = DateUtil.format(value); const formattedMaxDate = DateUtil.format(maxDate); - message = message || `输入的日期不能大于${formattedMaxDate}`; + message = message || `输入的值不应晚于${formattedMaxDate}`; return { name, message, actualDate: formattedActualDate, maxDate: formattedMaxDate }; } diff --git a/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts b/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts index 5ec79465197..e8966b60936 100644 --- a/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts @@ -26,7 +26,7 @@ class MaxLengthValidator extends BaseValidator { if (actualLength > maxLength) { const name = rule.name; - const message = rule.message || `输入值的长度不能超过${maxLength}个字符`; + const message = rule.message || `输入的值不应超过${maxLength}个字符`; const error = { name, message, actualLength, maxLength }; return error; diff --git a/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts b/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts index de5b602f52d..0faf73ffb77 100644 --- a/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts @@ -32,7 +32,7 @@ class MaxValueValidator extends BaseValidator { } const { name, maxValue } = rule; - const message = rule.message || `输入的值不能大于${maxValue}`; + const message = rule.message || `输入的值不应大于${maxValue}`; const error = { name, message, maxValue, actualValue: value }; return value > maxValue ? error : null; } diff --git a/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts b/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts index d7f2e0ac923..639095dde0d 100644 --- a/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts @@ -34,7 +34,7 @@ class MinDateValidator extends BaseValidator { if (value.getTime() < minDate.getTime()) { const formattedActualDate = DateUtil.format(value); const formattedMinDate = DateUtil.format(minDate); - message = message || `输入的日期不能小于${formattedMinDate}`; + message = message || `输入的值不应早于${formattedMinDate}`; return { name, message, actualDate: formattedActualDate, minDate: formattedMinDate }; } diff --git a/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts b/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts index 5f89ce6ef76..522d0babf16 100644 --- a/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts @@ -26,7 +26,7 @@ class MinLengthValidator extends BaseValidator { if (actualLength < minLength) { const name = rule.name; - const message = rule.message || `输入值的长度不能小于${minLength}个字符`; + const message = rule.message || `输入的值不应小于${minLength}个字符`; const error = { name, message, actualLength, minLength }; return error; diff --git a/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts b/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts index 8f5df3f6fe6..9b01b77b984 100644 --- a/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts @@ -32,7 +32,7 @@ class MinValueValidator extends BaseValidator { } const { name, minValue } = rule; - const message = rule.message || `输入的值不能小于${minValue}`; + const message = rule.message || `输入的值不应小于${minValue}`; const error = { name, message, minValue, actualValue: value }; return value < minValue ? error : null; -- Gitee From cac4c2505a73a08c7aa4401b5d3d09f0fe7c6b39 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 25 Mar 2025 21:19:55 +0800 Subject: [PATCH 113/153] =?UTF-8?q?chore:=20=E8=A7=A3=E5=86=B3=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E4=BE=9D=E8=B5=96=E8=B7=AF=E5=BE=84=E4=B8=8D=E5=87=86?= =?UTF-8?q?=E7=A1=AE=EF=BC=8C=E5=AF=BC=E8=87=B4=E6=97=A0=E6=B3=95=E4=BA=A7?= =?UTF-8?q?=E7=94=9F=E6=AD=A3=E7=A1=AE=E7=9A=84=E5=89=AF=E4=BD=9C=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B=E6=98=8E=E7=A1=AEformMetad?= =?UTF-8?q?ataService=E8=81=8C=E8=B4=A3=EF=BC=8C=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E4=BE=9D=E8=B5=96=E8=A7=A3=E6=9E=90=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E7=B1=BB=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui-state-change-effect-resolver.ts | 5 ++-- ...id-component-config-dependency-resolver.ts | 14 +++++------ ...up-component-config-dependency-resolver.ts | 8 +++--- ...er-component-config-dependency-resolver.ts | 4 +-- ...on-component-config-dependency-resolver.ts | 2 +- ...ar-component-config-dependency-resolver.ts | 2 +- ...on-component-config-dependency-resolver.ts | 6 ++--- ...ge-component-config-dependency-resolver.ts | 6 ++--- ...id-component-config-dependency-resolver.ts | 10 ++++---- packages/renderer/src/composition/index.ts | 1 + ...se-component-config-dependency-resolver.ts | 25 +++++++++++++++++++ .../src/composition/use-navigation.ts | 6 ++--- .../config-dependency-resolve-service.ts | 6 ++--- .../config-dependency-resolver/providers.ts | 3 ++- .../standard-config-dependency-resolver.ts | 24 +++++++++++++++--- .../src/config-dependency-resolver/types.ts | 2 +- .../ui-state-config-dependency-resolver.ts | 3 ++- packages/renderer/src/preview.vue | 3 ++- packages/renderer/src/renderer.vue | 3 ++- .../src/resolvers/model-value-resolver.ts | 2 +- .../src/service/form-metadata-service.ts | 22 ++++------------ packages/renderer/src/service/providers.ts | 5 ++-- 22 files changed, 99 insertions(+), 63 deletions(-) create mode 100644 packages/renderer/src/composition/use-component-config-dependency-resolver.ts diff --git a/packages/renderer/src/change-effect-resolver/ui-state-change-effect-resolver.ts b/packages/renderer/src/change-effect-resolver/ui-state-change-effect-resolver.ts index b3764e3bf4d..7f98e5c5476 100644 --- a/packages/renderer/src/change-effect-resolver/ui-state-change-effect-resolver.ts +++ b/packages/renderer/src/change-effect-resolver/ui-state-change-effect-resolver.ts @@ -19,8 +19,9 @@ export class UIStateChangeEffectResolver extends ChangeEffectResolver { Array.from(registry.entries()).forEach(([id, configs]) => { const matchedConfigs = configs.filter((config: Configuration) => { const match = config.deps.find((dependency: ConfigDependency) => { - const dependencyPath = `/${dependency.path}`; - return dependency.type === DependencyKind.UIState && dependencyPath === uiStateChange.path; + const dependencyPath = dependency.path; + const changePath = `${change.viewModelId}.${uiStateChange.path.slice(1)}`; + return dependency.type === DependencyKind.UIState && dependencyPath === changePath; }); return !!match;; }); diff --git a/packages/renderer/src/component-config-dependency-resolver/data-grid-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/data-grid-component-config-dependency-resolver.ts index 9669cee6610..fce6cb2116e 100644 --- a/packages/renderer/src/component-config-dependency-resolver/data-grid-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/data-grid-component-config-dependency-resolver.ts @@ -14,22 +14,22 @@ export class DataGridComponentConfigDependencyResolver extends ComponentConfigDe } const { columns: fields, editable, disabled, pagination, visible } = schema; const configs: Configuration[] = []; - const editableConfigDeps = this.configDepencencyResolveService.resolve(editable); + const editableConfigDeps = this.configDepencencyResolveService.resolve(editable, schema); if (editableConfigDeps) { configs.push({ deps: editableConfigDeps, config: editable, path: '/editable' }); } - const disabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); + const disabledConfigDeps = this.configDepencencyResolveService.resolve(disabled, schema); if (disabledConfigDeps) { configs.push({ deps: disabledConfigDeps, config: disabled, path: '/disabled' }); } if (pagination) { const { disabled = false } = pagination; - const paginationDisabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); + const paginationDisabledConfigDeps = this.configDepencencyResolveService.resolve(disabled, schema); if (paginationDisabledConfigDeps) { configs.push({ deps: paginationDisabledConfigDeps, config: disabled, path: '/pagination/disabled' }); } } - const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); + const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible, schema); if (visibleConfigDeps) { configs.push({ deps: visibleConfigDeps, config: visible, path: '/visible' }); } @@ -39,17 +39,17 @@ export class DataGridComponentConfigDependencyResolver extends ComponentConfigDe } return fields.reduce((configs: Configuration[], field: Record) => { const { visible, editor, id } = field; - const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); + const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible, schema); if (visibleConfigDeps) { configs.push({ deps: visibleConfigDeps, config: visible, path: `/columns/${id}:visible` }); } if (editor) { - const readonlyConfigDeps = this.configDepencencyResolveService.resolve(editor?.readonly); + const readonlyConfigDeps = this.configDepencencyResolveService.resolve(editor?.readonly, schema); if (readonlyConfigDeps) { configs.push({ deps: readonlyConfigDeps, config: editor?.readonly, path: `columns/${id}:editor/readonly` }); } - const disabledConfigDeps = this.configDepencencyResolveService.resolve(editor?.disabled); + const disabledConfigDeps = this.configDepencencyResolveService.resolve(editor?.disabled, schema); if (disabledConfigDeps) { configs.push({ deps: disabledConfigDeps, config: editor?.disabled, path: `columns/${id}:editor/disabled` }); } diff --git a/packages/renderer/src/component-config-dependency-resolver/form-group-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/form-group-component-config-dependency-resolver.ts index b52633723c8..3ef83901d58 100644 --- a/packages/renderer/src/component-config-dependency-resolver/form-group-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/form-group-component-config-dependency-resolver.ts @@ -14,7 +14,7 @@ export class FormGroupComponentConfigDependencyResolver extends ComponentConfigD } const configs: Configuration[] = []; const { editor, visible } = schema; - const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); + const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible, schema); if (visibleConfigDeps) { configs.push({ deps: visibleConfigDeps, config: visible, path: '/visible' }); } @@ -22,15 +22,15 @@ export class FormGroupComponentConfigDependencyResolver extends ComponentConfigD return configs; } const { readonly, required, disabled } = editor; - const readonlyConfigDeps = this.configDepencencyResolveService.resolve(readonly); + const readonlyConfigDeps = this.configDepencencyResolveService.resolve(readonly, schema); if (readonlyConfigDeps) { configs.push({ deps: readonlyConfigDeps, config: readonly, path: '/editor/readonly' }); } - const disabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); + const disabledConfigDeps = this.configDepencencyResolveService.resolve(disabled, schema); if (disabledConfigDeps) { configs.push({ deps: disabledConfigDeps, config: disabled, path: '/editor/disabled' }); } - const requiredConfigDeps = this.configDepencencyResolveService.resolve(required); + const requiredConfigDeps = this.configDepencencyResolveService.resolve(required, schema); if (requiredConfigDeps) { configs.push({ deps: requiredConfigDeps, config: required, path: '/editor/required' }); } diff --git a/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts index b82574c9e13..3d06f8e2cda 100644 --- a/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts @@ -24,12 +24,12 @@ export class PageHeaderComponentConfigDependencyResolver extends ComponentConfig const configs: Configuration[] = []; buttons.forEach((button: Record) => { const { disabled, visible } = button; - const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); + const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled, schema); if (diabledConfigDeps) { configs.push({ deps: diabledConfigDeps, config: disabled, path: `/toolbar/buttons/${button.id}:disabled` }); } if (!isNil(visible)) { - const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); + const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible, schema); if (visibleConfigDeps) { configs.push({ deps: visibleConfigDeps, config: visible, path: `/toolbar/buttons/${button.id}:visible` }); } diff --git a/packages/renderer/src/component-config-dependency-resolver/query-solution-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/query-solution-component-config-dependency-resolver.ts index d6b79263558..9432a3e53a6 100644 --- a/packages/renderer/src/component-config-dependency-resolver/query-solution-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/query-solution-component-config-dependency-resolver.ts @@ -15,7 +15,7 @@ export class QuerySolutionComponentConfigDependencyResolver extends ComponentCon return null; } const configs: Configuration[] = []; - const defaultValuesConfigDeps = this.configDepencencyResolveService.resolve(defaultValues); + const defaultValuesConfigDeps = this.configDepencencyResolveService.resolve(defaultValues, schema); if (defaultValuesConfigDeps) { configs.push({ deps: defaultValuesConfigDeps, config: defaultValues, path: '/defaultValues' }); } diff --git a/packages/renderer/src/component-config-dependency-resolver/response-toolbar-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/response-toolbar-component-config-dependency-resolver.ts index 24877643ecd..f18093b0a7d 100644 --- a/packages/renderer/src/component-config-dependency-resolver/response-toolbar-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/response-toolbar-component-config-dependency-resolver.ts @@ -22,7 +22,7 @@ export class ResponseToolbarComponentConfigDependencyResolver extends ComponentC const configs: Configuration[] = []; buttons.forEach((button: Record) => { const { disabled, visible } = button; - const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); + const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled, schema); if (diabledConfigDeps) { configs.push({ deps: diabledConfigDeps, config: disabled, path: `/buttons/${button.id}:disabled` }); } diff --git a/packages/renderer/src/component-config-dependency-resolver/section-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/section-component-config-dependency-resolver.ts index eea7ec6e427..ed1fee8efb9 100644 --- a/packages/renderer/src/component-config-dependency-resolver/section-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/section-component-config-dependency-resolver.ts @@ -14,7 +14,7 @@ export class SectionComponentConfigDependencyResolver extends ComponentConfigDep } const configs: Configuration[] = []; const { toolbar, visible } = schema; - const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); + const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible, schema); if (visibleConfigDeps) { configs.push({ deps: visibleConfigDeps, config: visible, path: `/visible` }); } @@ -28,11 +28,11 @@ export class SectionComponentConfigDependencyResolver extends ComponentConfigDep buttons.forEach((button: Record) => { const { disabled, visible } = button; - const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); + const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled, schema); if (diabledConfigDeps) { configs.push({ deps: diabledConfigDeps, config: disabled, path: `/toolbar/buttons/${button.id}:disabled` }); } - const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); + const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible, schema); if (visibleConfigDeps) { configs.push({ deps: visibleConfigDeps, config: visible, path: `/toolbar/buttons/${button.id}:visible` }); } diff --git a/packages/renderer/src/component-config-dependency-resolver/tab-page-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/tab-page-component-config-dependency-resolver.ts index 973d7cbe6ca..ae46861ea90 100644 --- a/packages/renderer/src/component-config-dependency-resolver/tab-page-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/tab-page-component-config-dependency-resolver.ts @@ -13,7 +13,7 @@ export class TabPageComponentConfigDependencyResolver extends ComponentConfigDep } const { toolbar, visible } = schema; const configs: Configuration[] = []; - const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); + const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible, schema); if (visibleConfigDeps) { configs.push({ deps: visibleConfigDeps, config: visible, path: `/visible` }); } @@ -26,11 +26,11 @@ export class TabPageComponentConfigDependencyResolver extends ComponentConfigDep } buttons.forEach((button: Record) => { const { disabled, visible } = button; - const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); + const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled, schema); if (diabledConfigDeps) { configs.push({ deps: diabledConfigDeps, config: disabled, path: `/toolbar/buttons/${button.id}:disabled` }); } - const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); + const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible, schema); if (visibleConfigDeps) { configs.push({ deps: visibleConfigDeps, config: visible, path: `/toolbar/buttons/${button.id}:visible` }); } diff --git a/packages/renderer/src/component-config-dependency-resolver/tree-grid-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/tree-grid-component-config-dependency-resolver.ts index 76a297a9464..e228bfdc719 100644 --- a/packages/renderer/src/component-config-dependency-resolver/tree-grid-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/tree-grid-component-config-dependency-resolver.ts @@ -14,15 +14,15 @@ export class TreeGridComponentConfigDependencyResolver extends ComponentConfigDe } const { columns: fields, editable, disabled, visible } = schema; const configs: Configuration[] = []; - const editableConfigDeps = this.configDepencencyResolveService.resolve(editable); + const editableConfigDeps = this.configDepencencyResolveService.resolve(editable, schema); if (editableConfigDeps) { configs.push({ deps: editableConfigDeps, config: editable, path: '/editable' }); } - const disabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); + const disabledConfigDeps = this.configDepencencyResolveService.resolve(disabled, schema); if (disabledConfigDeps) { configs.push({ deps: disabledConfigDeps, config: disabled, path: '/disabled' }); } - const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); + const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible, schema); if (visibleConfigDeps) { configs.push({ deps: visibleConfigDeps, config: visible, path: '/visible' }); } @@ -31,12 +31,12 @@ export class TreeGridComponentConfigDependencyResolver extends ComponentConfigDe } return fields.reduce((configs: Configuration[], field: Record) => { const { visible, editor } = field; - const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); + const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible, schema); if (visibleConfigDeps) { configs.push({ deps: visibleConfigDeps, config: visible, path: `/columns/${field.id}:visible` }); } if (editor) { - const readonlyConfigDeps = this.configDepencencyResolveService.resolve(editor?.readonly); + const readonlyConfigDeps = this.configDepencencyResolveService.resolve(editor?.readonly, schema); if (readonlyConfigDeps) { configs.push({ deps: readonlyConfigDeps, config: editor?.readonly, path: `/columns/${field.id}:editor/readonly` }); } diff --git a/packages/renderer/src/composition/index.ts b/packages/renderer/src/composition/index.ts index abfb9229038..350346d22e7 100644 --- a/packages/renderer/src/composition/index.ts +++ b/packages/renderer/src/composition/index.ts @@ -23,3 +23,4 @@ export * from './use-session'; export * from './use-callback-handler-registry'; export * from './use-view-model-initializer'; export * from './use-html-template-transformer'; +export * from './use-component-config-dependency-resolver'; diff --git a/packages/renderer/src/composition/use-component-config-dependency-resolver.ts b/packages/renderer/src/composition/use-component-config-dependency-resolver.ts new file mode 100644 index 00000000000..a71ede8fa69 --- /dev/null +++ b/packages/renderer/src/composition/use-component-config-dependency-resolver.ts @@ -0,0 +1,25 @@ +import { Injector } from "@farris/devkit-vue"; +import { useFormMetadataService } from "./use-form-metadata-service"; +import { ComponentConfigDependencyResolveService } from "../component-config-dependency-resolver"; +import { ComponentConfigDependencyRegistry } from "../config"; + +export function useComponentConfigDependencyResolver(injector: Injector) { + const componentConfigDependencyResolveService = injector.get(ComponentConfigDependencyResolveService); + const componentConfigDependencyRegistry = injector.get(ComponentConfigDependencyRegistry); + function traverseComponent(components: any[], parentId?: string) { + components.forEach((component) => { + if (component?.id) { + const configs = componentConfigDependencyResolveService.resolve(component); + if (configs) { + componentConfigDependencyRegistry.setConfigs(component.id, configs); + } + } + if (component.contents) { + traverseComponent(component.contents, component.id); + } + }); + } + const formMetadataService = useFormMetadataService(injector); + const components = formMetadataService.getComponents(); + traverseComponent(components); +} diff --git a/packages/renderer/src/composition/use-navigation.ts b/packages/renderer/src/composition/use-navigation.ts index 8decae0bfd3..d3f4c99219e 100644 --- a/packages/renderer/src/composition/use-navigation.ts +++ b/packages/renderer/src/composition/use-navigation.ts @@ -11,9 +11,9 @@ export function useNavigation(injector: Injector) { navigationEventService.addEventListener(TAB_EVENT.onTabRefresh, () => { const components = formMetadata.getComponents(); components.forEach((component: any) => { - if (component.schema.onInit) { - const viewModel: any = module.getViewModel(component.schema.id); - viewModel[component.schema.onInit](); + if (component.onInit) { + const viewModel: any = module.getViewModel(component.id); + viewModel[component.onInit](); } }); }); diff --git a/packages/renderer/src/config-dependency-resolver/config-dependency-resolve-service.ts b/packages/renderer/src/config-dependency-resolver/config-dependency-resolve-service.ts index afe992070dc..a79a001de5b 100644 --- a/packages/renderer/src/config-dependency-resolver/config-dependency-resolve-service.ts +++ b/packages/renderer/src/config-dependency-resolver/config-dependency-resolve-service.ts @@ -1,17 +1,17 @@ - import { ConfigDependencyResolver } from "./types"; +import { ConfigDependencyResolver } from "./types"; import { ConfigDependency } from "../config"; import { ConfigDependencyResolverRegistry } from "./config-dependency-resolver-registry"; export class ConfigDependencyResolveService { constructor(private configDependencyResolverRegistry: ConfigDependencyResolverRegistry) { } - public resolve(config: string | boolean): ConfigDependency[] | null { + public resolve(config: string | boolean, viewSchema?: Record): ConfigDependency[] | null { const { resolvers } = this.configDependencyResolverRegistry; if (!resolvers) { return null; } return resolvers.reduce((dependencies: ConfigDependency[], resolver: ConfigDependencyResolver) => { - const configs = resolver.resolve(config); + const configs = resolver.resolve(config, viewSchema); if (configs) { dependencies.push(...configs); } diff --git a/packages/renderer/src/config-dependency-resolver/providers.ts b/packages/renderer/src/config-dependency-resolver/providers.ts index 293c5444065..cf7388bcc85 100644 --- a/packages/renderer/src/config-dependency-resolver/providers.ts +++ b/packages/renderer/src/config-dependency-resolver/providers.ts @@ -8,6 +8,7 @@ import { EmptyConfigDependencyResolver } from "./empty-config-dependency-resolve import { EntityStateConfigDependencyResolver } from "./entity-state-config-dependency-resolver"; import { ConfigDependencyResolverRegistry } from "./config-dependency-resolver-registry"; import { StandardConfigDependencyResolver } from "./standard-config-dependency-resolver"; +import { FormMetadataService } from "../service"; export const configDependencyResolverProviders: StaticProvider[] = [ { provide: CONFIG_DEPENDENCY_RESOLVER_TOKEN, useClass: StateMachineConfigDependencyResolver, deps: [], multi: true }, @@ -15,7 +16,7 @@ export const configDependencyResolverProviders: StaticProvider[] = [ { provide: CONFIG_DEPENDENCY_RESOLVER_TOKEN, useClass: StaticConfigDependencyResolver, deps: [], multi: true }, { provide: CONFIG_DEPENDENCY_RESOLVER_TOKEN, useClass: EmptyConfigDependencyResolver, deps: [], multi: true }, { provide: CONFIG_DEPENDENCY_RESOLVER_TOKEN, useClass: EntityStateConfigDependencyResolver, deps: [], multi: true }, - { provide: CONFIG_DEPENDENCY_RESOLVER_TOKEN, useClass: StandardConfigDependencyResolver, deps: [], multi: true}, + { provide: CONFIG_DEPENDENCY_RESOLVER_TOKEN, useClass: StandardConfigDependencyResolver, deps: [FormMetadataService], multi: true }, { provide: ConfigDependencyResolverRegistry, useClass: ConfigDependencyResolverRegistry, deps: [Injector] }, { provide: ConfigDependencyResolveService, useClass: ConfigDependencyResolveService, deps: [ConfigDependencyResolverRegistry] } ]; diff --git a/packages/renderer/src/config-dependency-resolver/standard-config-dependency-resolver.ts b/packages/renderer/src/config-dependency-resolver/standard-config-dependency-resolver.ts index a7ce91fe3f2..894af42cb0a 100644 --- a/packages/renderer/src/config-dependency-resolver/standard-config-dependency-resolver.ts +++ b/packages/renderer/src/config-dependency-resolver/standard-config-dependency-resolver.ts @@ -1,8 +1,10 @@ import { ConfigDependency, DependencyKind } from "../config/types"; +import { FormMetadataService } from "../service"; import { ConfigDependencyResolver, ExpressionConfig, StandardPropertyConfig, StateMachineConfig, VariableConfig } from "./types"; export class StandardConfigDependencyResolver implements ConfigDependencyResolver { - resolve(config: string | boolean | StandardPropertyConfig): ConfigDependency[] | null { + constructor(private formMetadataService: FormMetadataService) { } + resolve(config: string | boolean | StandardPropertyConfig, viewSchema?: Record): ConfigDependency[] | null { // 处理基本类型 if (typeof config === 'string' || typeof config === 'boolean') { return null; @@ -18,7 +20,7 @@ export class StandardConfigDependencyResolver implements ConfigDependencyResolve case 'Expression': return this.resolveExpressionConfig(config as ExpressionConfig); case 'Variable': - return this.resolveVariableConfig(config as VariableConfig); + return this.resolveVariableConfig(config as VariableConfig, viewSchema); case 'StateMachine': return this.resolveStateMachineConfig(config as StateMachineConfig); default: @@ -37,7 +39,23 @@ export class StandardConfigDependencyResolver implements ConfigDependencyResolve }]; } - private resolveVariableConfig(config: VariableConfig): ConfigDependency[] { + private resolveVariableConfig(config: VariableConfig, viewSchema?: Record): ConfigDependency[] { + if (config.path.indexOf('.') !== -1) { + return [{ + type: DependencyKind.UIState, + path: config.path + }]; + } + if (viewSchema) { + const schemaId = viewSchema.id; + const relatedComponent = this.formMetadataService.getRelatedComponent(schemaId); + if (relatedComponent) { + return [{ + type: DependencyKind.UIState, + path: `${relatedComponent.id}.${config.path}` + }]; + } + } return [{ type: DependencyKind.UIState, path: config.path diff --git a/packages/renderer/src/config-dependency-resolver/types.ts b/packages/renderer/src/config-dependency-resolver/types.ts index 2f3a9d0c72f..4424c68993c 100644 --- a/packages/renderer/src/config-dependency-resolver/types.ts +++ b/packages/renderer/src/config-dependency-resolver/types.ts @@ -24,5 +24,5 @@ export interface StateMachineConfig extends StandardPropertyConfig { status: boolean; } export interface ConfigDependencyResolver { - resolve(config: string | boolean | StandardPropertyConfig): ConfigDependency[] | null; + resolve(config: string | boolean | StandardPropertyConfig, viewSchema?: Record): ConfigDependency[] | null; } diff --git a/packages/renderer/src/config-dependency-resolver/ui-state-config-dependency-resolver.ts b/packages/renderer/src/config-dependency-resolver/ui-state-config-dependency-resolver.ts index a2b70437724..cda57825f12 100644 --- a/packages/renderer/src/config-dependency-resolver/ui-state-config-dependency-resolver.ts +++ b/packages/renderer/src/config-dependency-resolver/ui-state-config-dependency-resolver.ts @@ -1,8 +1,9 @@ import { ConfigDependency, DependencyKind } from "../config"; +import { FormMetadataService } from "../service"; import { ConfigDependencyResolver } from "./types"; export class UIStateConfigDependencyResolver implements ConfigDependencyResolver { - public resolve(config: string): ConfigDependency[] | null { + public resolve(config: string, viewSchema?: Record): ConfigDependency[] | null { if (typeof config !== 'string') { return null; } diff --git a/packages/renderer/src/preview.vue b/packages/renderer/src/preview.vue index a052503cbf8..a4998f6bcf9 100644 --- a/packages/renderer/src/preview.vue +++ b/packages/renderer/src/preview.vue @@ -2,7 +2,7 @@ diff --git a/packages/mobile-ui-vue/demos/lookup/tree.vue b/packages/mobile-ui-vue/demos/lookup/tree.vue new file mode 100644 index 00000000000..8ed9bed0572 --- /dev/null +++ b/packages/mobile-ui-vue/demos/lookup/tree.vue @@ -0,0 +1,18 @@ + + diff --git a/packages/mobile-ui-vue/public/assets/datas/combo-list/data.json b/packages/mobile-ui-vue/public/assets/datas/combo-list/data.json new file mode 100644 index 00000000000..5a6b1f3de9f --- /dev/null +++ b/packages/mobile-ui-vue/public/assets/datas/combo-list/data.json @@ -0,0 +1,13 @@ +[{ + "id":"001", + "name":"远程数据类型一" +},{ + "id":"002", + "name":"远程数据类型二" +},{ + "id":"003", + "name":"远程数据类型三" +},{ + "id":"004", + "name":"远程数据类型四" +}] \ No newline at end of file diff --git a/packages/mobile-ui-vue/public/assets/datas/lookup/lookup-list.json b/packages/mobile-ui-vue/public/assets/datas/lookup/lookup-list.json new file mode 100644 index 00000000000..112ac71f705 --- /dev/null +++ b/packages/mobile-ui-vue/public/assets/datas/lookup/lookup-list.json @@ -0,0 +1,990 @@ +{ + "columns": [ + { + "field": "code", + "title": "编号", + "width": 100, + "fieldPath": "Code", + "fieldType": "StringType", + "supportSearch": true, + "align": "left", + "formatter": null, + "sortable": true, + "order": null, + "precision": 0, + "hAlign": "left" + }, + { + "field": "name", + "title": "名称", + "width": 100, + "fieldPath": "Name", + "fieldType": "StringType", + "supportSearch": true, + "align": "left", + "formatter": null, + "sortable": true, + "order": null, + "precision": 0, + "hAlign": "left" + }, + { + "field": "gjmc", + "title": "国际名称", + "width": 100, + "fieldPath": "GJMC", + "fieldType": "StringType", + "supportSearch": true, + "align": "right", + "formatter": null, + "sortable": true, + "order": null, + "precision": 0, + "hAlign": "right" + }, + { + "field": "udtwb.chComTextMDS", + "title": "U文本", + "width": 100, + "fieldPath": "UDTWB.CHComTextMDS", + "fieldType": "StringType", + "supportSearch": true, + "align": "left", + "formatter": null, + "sortable": true, + "order": null, + "precision": 0, + "hAlign": "left" + } + ], + "items": [ + { + "id": "yzsj0xzq-99d5-4d3e-ab4e-a14d01690ef5", + "version": null, + "code": "820000", + "name": "澳门特别行政区", + "gjmc": "澳门特别行政区", + "udtwb": { + "chComTextMDS": "3219" + }, + "pathInfo": { + "path": "0036", + "layer": 1, + "isDetail": true + }, + "parentInfo": { + "parentElement": null, + "sequence": 36, + "layer": 1, + "isDetail": true + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3219", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-705a-46dc-919f-a7ba7d66cf52", + "version": null, + "code": "810000", + "name": "香港特别行政区", + "gjmc": "香港特别行政区", + "udtwb": { + "chComTextMDS": "3218" + }, + "pathInfo": { + "path": "0034", + "layer": 1, + "isDetail": true + }, + "parentInfo": { + "parentElement": null, + "sequence": 34, + "layer": 1, + "isDetail": true + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3218", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-7be8-4aaa-99d2-57482aae4afd", + "version": null, + "code": "710000", + "name": "台湾省", + "gjmc": "台湾省", + "udtwb": { + "chComTextMDS": "3217" + }, + "pathInfo": { + "path": "0033", + "layer": 1, + "isDetail": true + }, + "parentInfo": { + "parentElement": null, + "sequence": 33, + "layer": 1, + "isDetail": true + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3217", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-0e85-5d05-6631-95793b1dc46d", + "version": null, + "code": "659010", + "name": "胡杨河市", + "gjmc": "胡杨河市", + "udtwb": { + "chComTextMDS": "3216" + }, + "pathInfo": { + "path": "00320024", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 24, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3216", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-6c41-4ba9-93fb-2250c90f32a8", + "version": null, + "code": "659009", + "name": "昆玉市", + "gjmc": "昆玉市", + "udtwb": { + "chComTextMDS": "3215" + }, + "pathInfo": { + "path": "00320023", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 23, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3215", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-c8ab-4207-97b2-0cdd4c6c693f", + "version": null, + "code": "659008", + "name": "可克达拉市", + "gjmc": "可克达拉市", + "udtwb": { + "chComTextMDS": "3214" + }, + "pathInfo": { + "path": "00320022", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 22, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3214", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-02e4-4bba-8ce5-af5d1bd04343", + "version": null, + "code": "659007", + "name": "双河市", + "gjmc": "双河市", + "udtwb": { + "chComTextMDS": "3213" + }, + "pathInfo": { + "path": "00320021", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 21, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3213", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-13e7-4a1b-8ccd-6a3f77651b5d", + "version": null, + "code": "659006", + "name": "铁门关市", + "gjmc": "铁门关市", + "udtwb": { + "chComTextMDS": "3212" + }, + "pathInfo": { + "path": "00320020", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 20, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3212", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-f2ca-48df-8ff5-0a3182af53b6", + "version": null, + "code": "659005", + "name": "北屯市", + "gjmc": "北屯市", + "udtwb": { + "chComTextMDS": "3211" + }, + "pathInfo": { + "path": "00320019", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 19, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3211", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-f5e0-454b-a496-5a1e7f66aa86", + "version": null, + "code": "659004", + "name": "五家渠市", + "gjmc": "五家渠市", + "udtwb": { + "chComTextMDS": "3210" + }, + "pathInfo": { + "path": "00320018", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 18, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3210", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-02ad-4ae9-93a9-4ffedec8c957", + "version": null, + "code": "659003", + "name": "图木舒克市", + "gjmc": "图木舒克市", + "udtwb": { + "chComTextMDS": "3209" + }, + "pathInfo": { + "path": "00320017", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 17, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3209", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-bde4-42d3-acf3-a5c41498a6f3", + "version": null, + "code": "659002", + "name": "阿拉尔市", + "gjmc": "阿拉尔市", + "udtwb": { + "chComTextMDS": "3208" + }, + "pathInfo": { + "path": "00320016", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 16, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3208", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-435d-41c1-8bba-c3bf0ce33246", + "version": null, + "code": "659001", + "name": "石河子市", + "gjmc": "石河子市", + "udtwb": { + "chComTextMDS": "3207" + }, + "pathInfo": { + "path": "00320015", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 15, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3207", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-c72f-449d-bcc4-d753854426ba", + "version": null, + "code": "654326", + "name": "吉木乃县", + "gjmc": "吉木乃县", + "udtwb": { + "chComTextMDS": "3206" + }, + "pathInfo": { + "path": "003200140007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "navParaentId_Code": "654300", + "navParaentId_Name": "阿勒泰地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3206", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-1b6f-46eb-93f3-5cb74a657770", + "version": null, + "code": "654325", + "name": "青河县", + "gjmc": "青河县", + "udtwb": { + "chComTextMDS": "3205" + }, + "pathInfo": { + "path": "003200140006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "navParaentId_Code": "654300", + "navParaentId_Name": "阿勒泰地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3205", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-7834-4508-87d1-46298cb3c47b", + "version": null, + "code": "654324", + "name": "哈巴河县", + "gjmc": "哈巴河县", + "udtwb": { + "chComTextMDS": "3204" + }, + "pathInfo": { + "path": "003200140005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "navParaentId_Code": "654300", + "navParaentId_Name": "阿勒泰地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3204", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-b024-43c9-9616-6d3e8333e462", + "version": null, + "code": "654323", + "name": "福海县", + "gjmc": "福海县", + "udtwb": { + "chComTextMDS": "3203" + }, + "pathInfo": { + "path": "003200140004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "navParaentId_Code": "654300", + "navParaentId_Name": "阿勒泰地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3203", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-0b15-4a65-b8fc-1e660ef13b84", + "version": null, + "code": "654322", + "name": "富蕴县", + "gjmc": "富蕴县", + "udtwb": { + "chComTextMDS": "3202" + }, + "pathInfo": { + "path": "003200140003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "navParaentId_Code": "654300", + "navParaentId_Name": "阿勒泰地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3202", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-77d5-43cc-864e-5e35b03762e3", + "version": null, + "code": "654321", + "name": "布尔津县", + "gjmc": "布尔津县", + "udtwb": { + "chComTextMDS": "3201" + }, + "pathInfo": { + "path": "003200140002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "navParaentId_Code": "654300", + "navParaentId_Name": "阿勒泰地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3201", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + { + "id": "yzsj0xzq-1a8e-4587-b43c-04f7ba002c1c", + "version": null, + "code": "654301", + "name": "阿勒泰市", + "gjmc": "阿勒泰市", + "udtwb": { + "chComTextMDS": "3200" + }, + "pathInfo": { + "path": "003200140001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "navParaentId_Code": "654300", + "navParaentId_Name": "阿勒泰地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3200", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + } + ], + "favoriteData": null, + "total": 3219, + "pageInfo": { + "pageList": [ + 5, + 10, + 20, + 30, + 50, + 100, + 200, + 500, + 1000, + 10000 + ], + "pageSize": 20, + "pageIndex": 1, + "enablePager": true + }, + "treeInfo": null, + "displayType": "List", + "title": "分页列表帮助", + "navigation": null, + "displayInfo": { + "idField": "id", + "valueField": "id", + "textField": "name" + }, + "searchFields": [ + { + "label": "code", + "value": "Code" + }, + { + "label": "name", + "value": "Name" + }, + { + "label": "gjmc", + "value": "GJMC" + }, + { + "label": "udtwb.chComTextMDS", + "value": "UDTWB.CHComTextMDS" + } + ], + "sortable": false, + "selectedData": null +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/public/assets/datas/lookup/lookup-treedata.json b/packages/mobile-ui-vue/public/assets/datas/lookup/lookup-treedata.json new file mode 100644 index 00000000000..9e64a817271 --- /dev/null +++ b/packages/mobile-ui-vue/public/assets/datas/lookup/lookup-treedata.json @@ -0,0 +1,43871 @@ +{ + "columns": [ + { + "field": "code", + "title": "编号", + "width": 100, + "fieldPath": "Code", + "fieldType": "StringType", + "supportSearch": true, + "align": "left", + "formatter": null, + "sortable": true, + "order": null, + "precision": 0, + "hAlign": "left" + }, + { + "field": "name", + "title": "名称", + "width": 100, + "fieldPath": "Name", + "fieldType": "StringType", + "supportSearch": true, + "align": "left", + "formatter": null, + "sortable": true, + "order": null, + "precision": 0, + "hAlign": "left" + }, + { + "field": "gjmc", + "title": "国际名称", + "width": 100, + "fieldPath": "GJMC", + "fieldType": "StringType", + "supportSearch": true, + "align": "right", + "formatter": null, + "sortable": true, + "order": null, + "precision": 0, + "hAlign": "right" + }, + { + "field": "pathInfo.isDetail", + "title": "明细", + "width": 50, + "fieldPath": "PathInfo.IsDetail", + "fieldType": "BooleanType", + "supportSearch": false, + "align": "left", + "formatter": null, + "sortable": true, + "order": null, + "precision": 0, + "hAlign": "left" + } + ], + "items": [ + { + "data": { + "id": "yzsj0xzq-99d5-4d3e-ab4e-a14d01690ef5", + "version": null, + "code": "820000", + "name": "澳门特别行政区", + "gjmc": "澳门特别行政区", + "udtwb": { + "chComTextMDS": "3219" + }, + "pathInfo": { + "path": "0036", + "layer": 1, + "isDetail": true + }, + "parentInfo": { + "parentElement": null, + "sequence": 36, + "layer": 1, + "isDetail": true + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3219", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-99d5-4d3e-ab4e-a14d01690ef5", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-705a-46dc-919f-a7ba7d66cf52", + "version": null, + "code": "810000", + "name": "香港特别行政区", + "gjmc": "香港特别行政区", + "udtwb": { + "chComTextMDS": "3218" + }, + "pathInfo": { + "path": "0034", + "layer": 1, + "isDetail": true + }, + "parentInfo": { + "parentElement": null, + "sequence": 34, + "layer": 1, + "isDetail": true + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3218", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-705a-46dc-919f-a7ba7d66cf52", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7be8-4aaa-99d2-57482aae4afd", + "version": null, + "code": "710000", + "name": "台湾省", + "gjmc": "台湾省", + "udtwb": { + "chComTextMDS": "3217" + }, + "pathInfo": { + "path": "0033", + "layer": 1, + "isDetail": true + }, + "parentInfo": { + "parentElement": null, + "sequence": 33, + "layer": 1, + "isDetail": true + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3217", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7be8-4aaa-99d2-57482aae4afd", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "version": null, + "code": "650000", + "name": "新疆维吾尔自治区", + "gjmc": "新疆维吾尔自治区", + "udtwb": { + "chComTextMDS": "3096" + }, + "pathInfo": { + "path": "0032", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 32, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3096", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-0e85-5d05-6631-95793b1dc46d", + "version": null, + "code": "659010", + "name": "胡杨河市", + "gjmc": "胡杨河市", + "udtwb": { + "chComTextMDS": "3216" + }, + "pathInfo": { + "path": "00320024", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 24, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3216", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0e85-5d05-6631-95793b1dc46d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6c41-4ba9-93fb-2250c90f32a8", + "version": null, + "code": "659009", + "name": "昆玉市", + "gjmc": "昆玉市", + "udtwb": { + "chComTextMDS": "3215" + }, + "pathInfo": { + "path": "00320023", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 23, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3215", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6c41-4ba9-93fb-2250c90f32a8", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c8ab-4207-97b2-0cdd4c6c693f", + "version": null, + "code": "659008", + "name": "可克达拉市", + "gjmc": "可克达拉市", + "udtwb": { + "chComTextMDS": "3214" + }, + "pathInfo": { + "path": "00320022", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 22, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3214", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c8ab-4207-97b2-0cdd4c6c693f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-02e4-4bba-8ce5-af5d1bd04343", + "version": null, + "code": "659007", + "name": "双河市", + "gjmc": "双河市", + "udtwb": { + "chComTextMDS": "3213" + }, + "pathInfo": { + "path": "00320021", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 21, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3213", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-02e4-4bba-8ce5-af5d1bd04343", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-13e7-4a1b-8ccd-6a3f77651b5d", + "version": null, + "code": "659006", + "name": "铁门关市", + "gjmc": "铁门关市", + "udtwb": { + "chComTextMDS": "3212" + }, + "pathInfo": { + "path": "00320020", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 20, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3212", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-13e7-4a1b-8ccd-6a3f77651b5d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f2ca-48df-8ff5-0a3182af53b6", + "version": null, + "code": "659005", + "name": "北屯市", + "gjmc": "北屯市", + "udtwb": { + "chComTextMDS": "3211" + }, + "pathInfo": { + "path": "00320019", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 19, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3211", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f2ca-48df-8ff5-0a3182af53b6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f5e0-454b-a496-5a1e7f66aa86", + "version": null, + "code": "659004", + "name": "五家渠市", + "gjmc": "五家渠市", + "udtwb": { + "chComTextMDS": "3210" + }, + "pathInfo": { + "path": "00320018", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 18, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3210", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f5e0-454b-a496-5a1e7f66aa86", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-02ad-4ae9-93a9-4ffedec8c957", + "version": null, + "code": "659003", + "name": "图木舒克市", + "gjmc": "图木舒克市", + "udtwb": { + "chComTextMDS": "3209" + }, + "pathInfo": { + "path": "00320017", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 17, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3209", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-02ad-4ae9-93a9-4ffedec8c957", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bde4-42d3-acf3-a5c41498a6f3", + "version": null, + "code": "659002", + "name": "阿拉尔市", + "gjmc": "阿拉尔市", + "udtwb": { + "chComTextMDS": "3208" + }, + "pathInfo": { + "path": "00320016", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 16, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3208", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bde4-42d3-acf3-a5c41498a6f3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-435d-41c1-8bba-c3bf0ce33246", + "version": null, + "code": "659001", + "name": "石河子市", + "gjmc": "石河子市", + "udtwb": { + "chComTextMDS": "3207" + }, + "pathInfo": { + "path": "00320015", + "layer": 2, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 15, + "layer": 2, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3207", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": true, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-435d-41c1-8bba-c3bf0ce33246", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "version": null, + "code": "654300", + "name": "阿勒泰地区", + "gjmc": "阿勒泰地区", + "udtwb": { + "chComTextMDS": "3199" + }, + "pathInfo": { + "path": "00320014", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 14, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3199", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-c72f-449d-bcc4-d753854426ba", + "version": null, + "code": "654326", + "name": "吉木乃县", + "gjmc": "吉木乃县", + "udtwb": { + "chComTextMDS": "3206" + }, + "pathInfo": { + "path": "003200140007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "navParaentId_Code": "654300", + "navParaentId_Name": "阿勒泰地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3206", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c72f-449d-bcc4-d753854426ba", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1b6f-46eb-93f3-5cb74a657770", + "version": null, + "code": "654325", + "name": "青河县", + "gjmc": "青河县", + "udtwb": { + "chComTextMDS": "3205" + }, + "pathInfo": { + "path": "003200140006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "navParaentId_Code": "654300", + "navParaentId_Name": "阿勒泰地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3205", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1b6f-46eb-93f3-5cb74a657770", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7834-4508-87d1-46298cb3c47b", + "version": null, + "code": "654324", + "name": "哈巴河县", + "gjmc": "哈巴河县", + "udtwb": { + "chComTextMDS": "3204" + }, + "pathInfo": { + "path": "003200140005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "navParaentId_Code": "654300", + "navParaentId_Name": "阿勒泰地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3204", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7834-4508-87d1-46298cb3c47b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b024-43c9-9616-6d3e8333e462", + "version": null, + "code": "654323", + "name": "福海县", + "gjmc": "福海县", + "udtwb": { + "chComTextMDS": "3203" + }, + "pathInfo": { + "path": "003200140004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "navParaentId_Code": "654300", + "navParaentId_Name": "阿勒泰地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3203", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b024-43c9-9616-6d3e8333e462", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0b15-4a65-b8fc-1e660ef13b84", + "version": null, + "code": "654322", + "name": "富蕴县", + "gjmc": "富蕴县", + "udtwb": { + "chComTextMDS": "3202" + }, + "pathInfo": { + "path": "003200140003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "navParaentId_Code": "654300", + "navParaentId_Name": "阿勒泰地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3202", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0b15-4a65-b8fc-1e660ef13b84", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-77d5-43cc-864e-5e35b03762e3", + "version": null, + "code": "654321", + "name": "布尔津县", + "gjmc": "布尔津县", + "udtwb": { + "chComTextMDS": "3201" + }, + "pathInfo": { + "path": "003200140002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "navParaentId_Code": "654300", + "navParaentId_Name": "阿勒泰地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3201", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-77d5-43cc-864e-5e35b03762e3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1a8e-4587-b43c-04f7ba002c1c", + "version": null, + "code": "654301", + "name": "阿勒泰市", + "gjmc": "阿勒泰市", + "udtwb": { + "chComTextMDS": "3200" + }, + "pathInfo": { + "path": "003200140001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "navParaentId_Code": "654300", + "navParaentId_Name": "阿勒泰地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3200", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1a8e-4587-b43c-04f7ba002c1c", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ad2c-4b84-b747-faa51c04e0b4", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-776c-48a7-9aa4-06b8d852c631", + "version": null, + "code": "654200", + "name": "塔城地区", + "gjmc": "塔城地区", + "udtwb": { + "chComTextMDS": "3191" + }, + "pathInfo": { + "path": "00320013", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 13, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3191", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-0417-456d-a802-8320e7fe3045", + "version": null, + "code": "654226", + "name": "和布克赛尔蒙古自治县", + "gjmc": "和布克赛尔蒙古自治县", + "udtwb": { + "chComTextMDS": "3198" + }, + "pathInfo": { + "path": "003200130007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-776c-48a7-9aa4-06b8d852c631", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-776c-48a7-9aa4-06b8d852c631", + "navParaentId_Code": "654200", + "navParaentId_Name": "塔城地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3198", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0417-456d-a802-8320e7fe3045", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b6dd-454f-91a0-8b3871a0b940", + "version": null, + "code": "654225", + "name": "裕民县", + "gjmc": "裕民县", + "udtwb": { + "chComTextMDS": "3197" + }, + "pathInfo": { + "path": "003200130006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-776c-48a7-9aa4-06b8d852c631", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-776c-48a7-9aa4-06b8d852c631", + "navParaentId_Code": "654200", + "navParaentId_Name": "塔城地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3197", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b6dd-454f-91a0-8b3871a0b940", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6cc0-405d-89bc-471eb7ae6a92", + "version": null, + "code": "654224", + "name": "托里县", + "gjmc": "托里县", + "udtwb": { + "chComTextMDS": "3196" + }, + "pathInfo": { + "path": "003200130005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-776c-48a7-9aa4-06b8d852c631", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-776c-48a7-9aa4-06b8d852c631", + "navParaentId_Code": "654200", + "navParaentId_Name": "塔城地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3196", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6cc0-405d-89bc-471eb7ae6a92", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d8c6-43bf-b6d4-f55140272ab6", + "version": null, + "code": "654223", + "name": "沙湾县", + "gjmc": "沙湾县", + "udtwb": { + "chComTextMDS": "3195" + }, + "pathInfo": { + "path": "003200130004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-776c-48a7-9aa4-06b8d852c631", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-776c-48a7-9aa4-06b8d852c631", + "navParaentId_Code": "654200", + "navParaentId_Name": "塔城地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3195", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d8c6-43bf-b6d4-f55140272ab6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b329-4bbf-9f86-3f38760cb89c", + "version": null, + "code": "654221", + "name": "额敏县", + "gjmc": "额敏县", + "udtwb": { + "chComTextMDS": "3194" + }, + "pathInfo": { + "path": "003200130003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-776c-48a7-9aa4-06b8d852c631", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-776c-48a7-9aa4-06b8d852c631", + "navParaentId_Code": "654200", + "navParaentId_Name": "塔城地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3194", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b329-4bbf-9f86-3f38760cb89c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-88e6-4fe9-9af2-541c4b76f992", + "version": null, + "code": "654202", + "name": "乌苏市", + "gjmc": "乌苏市", + "udtwb": { + "chComTextMDS": "3193" + }, + "pathInfo": { + "path": "003200130002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-776c-48a7-9aa4-06b8d852c631", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-776c-48a7-9aa4-06b8d852c631", + "navParaentId_Code": "654200", + "navParaentId_Name": "塔城地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3193", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-88e6-4fe9-9af2-541c4b76f992", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-88e5-4502-8671-9c0db7f4dc20", + "version": null, + "code": "654201", + "name": "塔城市", + "gjmc": "塔城市", + "udtwb": { + "chComTextMDS": "3192" + }, + "pathInfo": { + "path": "003200130001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-776c-48a7-9aa4-06b8d852c631", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-776c-48a7-9aa4-06b8d852c631", + "navParaentId_Code": "654200", + "navParaentId_Name": "塔城地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3192", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-88e5-4502-8671-9c0db7f4dc20", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-776c-48a7-9aa4-06b8d852c631", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "version": null, + "code": "654000", + "name": "伊犁哈萨克自治州", + "gjmc": "伊犁哈萨克自治州", + "udtwb": { + "chComTextMDS": "3179" + }, + "pathInfo": { + "path": "00320012", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 12, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3179", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-951a-4c8f-8da8-f2c8822b2dc1", + "version": null, + "code": "654028", + "name": "尼勒克县", + "gjmc": "尼勒克县", + "udtwb": { + "chComTextMDS": "3190" + }, + "pathInfo": { + "path": "003200120011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "navParaentId_Code": "654000", + "navParaentId_Name": "伊犁哈萨克自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3190", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-951a-4c8f-8da8-f2c8822b2dc1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-16e8-4dc5-90fe-35cc8af80a90", + "version": null, + "code": "654027", + "name": "特克斯县", + "gjmc": "特克斯县", + "udtwb": { + "chComTextMDS": "3189" + }, + "pathInfo": { + "path": "003200120010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "navParaentId_Code": "654000", + "navParaentId_Name": "伊犁哈萨克自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3189", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-16e8-4dc5-90fe-35cc8af80a90", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6e77-4a04-83cd-85d86cc4e76c", + "version": null, + "code": "654026", + "name": "昭苏县", + "gjmc": "昭苏县", + "udtwb": { + "chComTextMDS": "3188" + }, + "pathInfo": { + "path": "003200120009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "navParaentId_Code": "654000", + "navParaentId_Name": "伊犁哈萨克自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3188", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6e77-4a04-83cd-85d86cc4e76c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-529c-492b-9572-2eb784e6451c", + "version": null, + "code": "654025", + "name": "新源县", + "gjmc": "新源县", + "udtwb": { + "chComTextMDS": "3187" + }, + "pathInfo": { + "path": "003200120008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "navParaentId_Code": "654000", + "navParaentId_Name": "伊犁哈萨克自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3187", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-529c-492b-9572-2eb784e6451c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-603e-4bc8-b9c2-1e740b6d9695", + "version": null, + "code": "654024", + "name": "巩留县", + "gjmc": "巩留县", + "udtwb": { + "chComTextMDS": "3186" + }, + "pathInfo": { + "path": "003200120007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "navParaentId_Code": "654000", + "navParaentId_Name": "伊犁哈萨克自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3186", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-603e-4bc8-b9c2-1e740b6d9695", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-afd9-4a79-8d5c-24ac2dccedd0", + "version": null, + "code": "654023", + "name": "霍城县", + "gjmc": "霍城县", + "udtwb": { + "chComTextMDS": "3185" + }, + "pathInfo": { + "path": "003200120006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "navParaentId_Code": "654000", + "navParaentId_Name": "伊犁哈萨克自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3185", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-afd9-4a79-8d5c-24ac2dccedd0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3b4d-48a4-9604-7986b670a3e0", + "version": null, + "code": "654022", + "name": "察布查尔锡伯自治县", + "gjmc": "察布查尔锡伯自治县", + "udtwb": { + "chComTextMDS": "3184" + }, + "pathInfo": { + "path": "003200120005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "navParaentId_Code": "654000", + "navParaentId_Name": "伊犁哈萨克自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3184", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3b4d-48a4-9604-7986b670a3e0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-286f-4c81-af62-40737e23aaff", + "version": null, + "code": "654021", + "name": "伊宁县", + "gjmc": "伊宁县", + "udtwb": { + "chComTextMDS": "3183" + }, + "pathInfo": { + "path": "003200120004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "navParaentId_Code": "654000", + "navParaentId_Name": "伊犁哈萨克自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3183", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-286f-4c81-af62-40737e23aaff", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2dcf-4836-a768-36889fd49043", + "version": null, + "code": "654004", + "name": "霍尔果斯市", + "gjmc": "霍尔果斯市", + "udtwb": { + "chComTextMDS": "3182" + }, + "pathInfo": { + "path": "003200120003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "navParaentId_Code": "654000", + "navParaentId_Name": "伊犁哈萨克自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3182", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2dcf-4836-a768-36889fd49043", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6c75-4b67-845d-cc0916a48551", + "version": null, + "code": "654003", + "name": "奎屯市", + "gjmc": "奎屯市", + "udtwb": { + "chComTextMDS": "3181" + }, + "pathInfo": { + "path": "003200120002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "navParaentId_Code": "654000", + "navParaentId_Name": "伊犁哈萨克自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3181", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6c75-4b67-845d-cc0916a48551", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c5b8-4019-808a-c8929b936aec", + "version": null, + "code": "654002", + "name": "伊宁市", + "gjmc": "伊宁市", + "udtwb": { + "chComTextMDS": "3180" + }, + "pathInfo": { + "path": "003200120001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "navParaentId_Code": "654000", + "navParaentId_Name": "伊犁哈萨克自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3180", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c5b8-4019-808a-c8929b936aec", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-caa9-4c8c-88c4-086fa2f16f3c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0c71-4821-9c39-d1517f326cd1", + "version": null, + "code": "653200", + "name": "和田地区", + "gjmc": "和田地区", + "udtwb": { + "chComTextMDS": "3170" + }, + "pathInfo": { + "path": "00320011", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 11, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3170", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-28ac-4d15-a035-dcef6d2c4380", + "version": null, + "code": "653227", + "name": "民丰县", + "gjmc": "民丰县", + "udtwb": { + "chComTextMDS": "3178" + }, + "pathInfo": { + "path": "003200110008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c71-4821-9c39-d1517f326cd1", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c71-4821-9c39-d1517f326cd1", + "navParaentId_Code": "653200", + "navParaentId_Name": "和田地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3178", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-28ac-4d15-a035-dcef6d2c4380", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c533-49bc-8891-7cd09f956400", + "version": null, + "code": "653226", + "name": "于田县", + "gjmc": "于田县", + "udtwb": { + "chComTextMDS": "3177" + }, + "pathInfo": { + "path": "003200110007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c71-4821-9c39-d1517f326cd1", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c71-4821-9c39-d1517f326cd1", + "navParaentId_Code": "653200", + "navParaentId_Name": "和田地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3177", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c533-49bc-8891-7cd09f956400", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e14f-4ab3-9d2c-9f56dc9c879e", + "version": null, + "code": "653225", + "name": "策勒县", + "gjmc": "策勒县", + "udtwb": { + "chComTextMDS": "3176" + }, + "pathInfo": { + "path": "003200110006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c71-4821-9c39-d1517f326cd1", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c71-4821-9c39-d1517f326cd1", + "navParaentId_Code": "653200", + "navParaentId_Name": "和田地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3176", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e14f-4ab3-9d2c-9f56dc9c879e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1fcf-402c-aabd-32ca1995f9db", + "version": null, + "code": "653224", + "name": "洛浦县", + "gjmc": "洛浦县", + "udtwb": { + "chComTextMDS": "3175" + }, + "pathInfo": { + "path": "003200110005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c71-4821-9c39-d1517f326cd1", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c71-4821-9c39-d1517f326cd1", + "navParaentId_Code": "653200", + "navParaentId_Name": "和田地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3175", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1fcf-402c-aabd-32ca1995f9db", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-829c-4099-a309-3bb3cf9d778c", + "version": null, + "code": "653223", + "name": "皮山县", + "gjmc": "皮山县", + "udtwb": { + "chComTextMDS": "3174" + }, + "pathInfo": { + "path": "003200110004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c71-4821-9c39-d1517f326cd1", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c71-4821-9c39-d1517f326cd1", + "navParaentId_Code": "653200", + "navParaentId_Name": "和田地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3174", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-829c-4099-a309-3bb3cf9d778c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-fa2a-4805-9906-c319fab713b3", + "version": null, + "code": "653222", + "name": "墨玉县", + "gjmc": "墨玉县", + "udtwb": { + "chComTextMDS": "3173" + }, + "pathInfo": { + "path": "003200110003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c71-4821-9c39-d1517f326cd1", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c71-4821-9c39-d1517f326cd1", + "navParaentId_Code": "653200", + "navParaentId_Name": "和田地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3173", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fa2a-4805-9906-c319fab713b3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6240-4366-a47f-e655683dff8a", + "version": null, + "code": "653221", + "name": "和田县", + "gjmc": "和田县", + "udtwb": { + "chComTextMDS": "3172" + }, + "pathInfo": { + "path": "003200110002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c71-4821-9c39-d1517f326cd1", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c71-4821-9c39-d1517f326cd1", + "navParaentId_Code": "653200", + "navParaentId_Name": "和田地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3172", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6240-4366-a47f-e655683dff8a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3dc4-4608-88d5-3280683f0ee2", + "version": null, + "code": "653201", + "name": "和田市", + "gjmc": "和田市", + "udtwb": { + "chComTextMDS": "3171" + }, + "pathInfo": { + "path": "003200110001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c71-4821-9c39-d1517f326cd1", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c71-4821-9c39-d1517f326cd1", + "navParaentId_Code": "653200", + "navParaentId_Name": "和田地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3171", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3dc4-4608-88d5-3280683f0ee2", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0c71-4821-9c39-d1517f326cd1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3ed7-415e-9bac-758861943357", + "version": null, + "code": "653100", + "name": "喀什地区", + "gjmc": "喀什地区", + "udtwb": { + "chComTextMDS": "3157" + }, + "pathInfo": { + "path": "00320010", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 10, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3157", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-f83f-4ebc-99e2-a9a2c91056a3", + "version": null, + "code": "653131", + "name": "塔什库尔干塔吉克自治县", + "gjmc": "塔什库尔干塔吉克自治县", + "udtwb": { + "chComTextMDS": "3169" + }, + "pathInfo": { + "path": "003200100012", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3ed7-415e-9bac-758861943357", + "sequence": 12, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3ed7-415e-9bac-758861943357", + "navParaentId_Code": "653100", + "navParaentId_Name": "喀什地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3169", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f83f-4ebc-99e2-a9a2c91056a3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8f90-4f3f-a56e-a25d2f297364", + "version": null, + "code": "653130", + "name": "巴楚县", + "gjmc": "巴楚县", + "udtwb": { + "chComTextMDS": "3168" + }, + "pathInfo": { + "path": "003200100011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3ed7-415e-9bac-758861943357", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3ed7-415e-9bac-758861943357", + "navParaentId_Code": "653100", + "navParaentId_Name": "喀什地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3168", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8f90-4f3f-a56e-a25d2f297364", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b093-4fd8-89ef-a1043f99b23e", + "version": null, + "code": "653129", + "name": "伽师县", + "gjmc": "伽师县", + "udtwb": { + "chComTextMDS": "3167" + }, + "pathInfo": { + "path": "003200100010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3ed7-415e-9bac-758861943357", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3ed7-415e-9bac-758861943357", + "navParaentId_Code": "653100", + "navParaentId_Name": "喀什地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3167", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b093-4fd8-89ef-a1043f99b23e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1049-4d2c-816d-aef6ead307a4", + "version": null, + "code": "653128", + "name": "岳普湖县", + "gjmc": "岳普湖县", + "udtwb": { + "chComTextMDS": "3166" + }, + "pathInfo": { + "path": "003200100009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3ed7-415e-9bac-758861943357", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3ed7-415e-9bac-758861943357", + "navParaentId_Code": "653100", + "navParaentId_Name": "喀什地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3166", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1049-4d2c-816d-aef6ead307a4", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-81e8-49f6-9596-aeb0ef201ce9", + "version": null, + "code": "653127", + "name": "麦盖提县", + "gjmc": "麦盖提县", + "udtwb": { + "chComTextMDS": "3165" + }, + "pathInfo": { + "path": "003200100008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3ed7-415e-9bac-758861943357", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3ed7-415e-9bac-758861943357", + "navParaentId_Code": "653100", + "navParaentId_Name": "喀什地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3165", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-81e8-49f6-9596-aeb0ef201ce9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-abe4-447e-bd44-dcbbf12a360f", + "version": null, + "code": "653126", + "name": "叶城县", + "gjmc": "叶城县", + "udtwb": { + "chComTextMDS": "3164" + }, + "pathInfo": { + "path": "003200100007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3ed7-415e-9bac-758861943357", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3ed7-415e-9bac-758861943357", + "navParaentId_Code": "653100", + "navParaentId_Name": "喀什地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3164", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-abe4-447e-bd44-dcbbf12a360f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8c0e-46e6-9ff1-13977a2a52ef", + "version": null, + "code": "653125", + "name": "莎车县", + "gjmc": "莎车县", + "udtwb": { + "chComTextMDS": "3163" + }, + "pathInfo": { + "path": "003200100006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3ed7-415e-9bac-758861943357", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3ed7-415e-9bac-758861943357", + "navParaentId_Code": "653100", + "navParaentId_Name": "喀什地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3163", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8c0e-46e6-9ff1-13977a2a52ef", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d6c1-4e7d-bc74-299aa69ac151", + "version": null, + "code": "653124", + "name": "泽普县", + "gjmc": "泽普县", + "udtwb": { + "chComTextMDS": "3162" + }, + "pathInfo": { + "path": "003200100005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3ed7-415e-9bac-758861943357", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3ed7-415e-9bac-758861943357", + "navParaentId_Code": "653100", + "navParaentId_Name": "喀什地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3162", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d6c1-4e7d-bc74-299aa69ac151", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2fc9-424c-b8b6-9b91a747dae6", + "version": null, + "code": "653123", + "name": "英吉沙县", + "gjmc": "英吉沙县", + "udtwb": { + "chComTextMDS": "3161" + }, + "pathInfo": { + "path": "003200100004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3ed7-415e-9bac-758861943357", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3ed7-415e-9bac-758861943357", + "navParaentId_Code": "653100", + "navParaentId_Name": "喀什地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3161", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2fc9-424c-b8b6-9b91a747dae6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8271-41fa-9067-c78aa1730a92", + "version": null, + "code": "653122", + "name": "疏勒县", + "gjmc": "疏勒县", + "udtwb": { + "chComTextMDS": "3160" + }, + "pathInfo": { + "path": "003200100003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3ed7-415e-9bac-758861943357", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3ed7-415e-9bac-758861943357", + "navParaentId_Code": "653100", + "navParaentId_Name": "喀什地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3160", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8271-41fa-9067-c78aa1730a92", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-34f2-4b46-b974-cb537a41998b", + "version": null, + "code": "653121", + "name": "疏附县", + "gjmc": "疏附县", + "udtwb": { + "chComTextMDS": "3159" + }, + "pathInfo": { + "path": "003200100002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3ed7-415e-9bac-758861943357", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3ed7-415e-9bac-758861943357", + "navParaentId_Code": "653100", + "navParaentId_Name": "喀什地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3159", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-34f2-4b46-b974-cb537a41998b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9372-43f3-b007-26357acf4734", + "version": null, + "code": "653101", + "name": "喀什市", + "gjmc": "喀什市", + "udtwb": { + "chComTextMDS": "3158" + }, + "pathInfo": { + "path": "003200100001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3ed7-415e-9bac-758861943357", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3ed7-415e-9bac-758861943357", + "navParaentId_Code": "653100", + "navParaentId_Name": "喀什地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3158", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9372-43f3-b007-26357acf4734", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3ed7-415e-9bac-758861943357", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-73b6-4eae-b117-d7866be24fc4", + "version": null, + "code": "653000", + "name": "克孜勒苏柯尔克孜自治州", + "gjmc": "克孜勒苏柯尔克孜自治州", + "udtwb": { + "chComTextMDS": "3152" + }, + "pathInfo": { + "path": "00320009", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 9, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3152", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-6f8f-433d-8bb1-b1a5f30344dd", + "version": null, + "code": "653024", + "name": "乌恰县", + "gjmc": "乌恰县", + "udtwb": { + "chComTextMDS": "3156" + }, + "pathInfo": { + "path": "003200090004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-73b6-4eae-b117-d7866be24fc4", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-73b6-4eae-b117-d7866be24fc4", + "navParaentId_Code": "653000", + "navParaentId_Name": "克孜勒苏柯尔克孜自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3156", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6f8f-433d-8bb1-b1a5f30344dd", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4f88-464f-8ab5-36a6ab502f40", + "version": null, + "code": "653023", + "name": "阿合奇县", + "gjmc": "阿合奇县", + "udtwb": { + "chComTextMDS": "3155" + }, + "pathInfo": { + "path": "003200090003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-73b6-4eae-b117-d7866be24fc4", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-73b6-4eae-b117-d7866be24fc4", + "navParaentId_Code": "653000", + "navParaentId_Name": "克孜勒苏柯尔克孜自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3155", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4f88-464f-8ab5-36a6ab502f40", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1cca-49f4-9103-9a3839167505", + "version": null, + "code": "653022", + "name": "阿克陶县", + "gjmc": "阿克陶县", + "udtwb": { + "chComTextMDS": "3154" + }, + "pathInfo": { + "path": "003200090002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-73b6-4eae-b117-d7866be24fc4", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-73b6-4eae-b117-d7866be24fc4", + "navParaentId_Code": "653000", + "navParaentId_Name": "克孜勒苏柯尔克孜自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3154", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1cca-49f4-9103-9a3839167505", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8d8c-4716-8262-4014549a5d52", + "version": null, + "code": "653001", + "name": "阿图什市", + "gjmc": "阿图什市", + "udtwb": { + "chComTextMDS": "3153" + }, + "pathInfo": { + "path": "003200090001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-73b6-4eae-b117-d7866be24fc4", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-73b6-4eae-b117-d7866be24fc4", + "navParaentId_Code": "653000", + "navParaentId_Name": "克孜勒苏柯尔克孜自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3153", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8d8c-4716-8262-4014549a5d52", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-73b6-4eae-b117-d7866be24fc4", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c046-4f44-b1b8-648c850a2822", + "version": null, + "code": "652900", + "name": "阿克苏地区", + "gjmc": "阿克苏地区", + "udtwb": { + "chComTextMDS": "3142" + }, + "pathInfo": { + "path": "00320008", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 8, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3142", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-9c7e-4214-b142-4270726bc9e6", + "version": null, + "code": "652929", + "name": "柯坪县", + "gjmc": "柯坪县", + "udtwb": { + "chComTextMDS": "3151" + }, + "pathInfo": { + "path": "003200080009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c046-4f44-b1b8-648c850a2822", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c046-4f44-b1b8-648c850a2822", + "navParaentId_Code": "652900", + "navParaentId_Name": "阿克苏地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3151", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9c7e-4214-b142-4270726bc9e6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d51b-4918-a39c-5d1da74b77b3", + "version": null, + "code": "652928", + "name": "阿瓦提县", + "gjmc": "阿瓦提县", + "udtwb": { + "chComTextMDS": "3150" + }, + "pathInfo": { + "path": "003200080008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c046-4f44-b1b8-648c850a2822", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c046-4f44-b1b8-648c850a2822", + "navParaentId_Code": "652900", + "navParaentId_Name": "阿克苏地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3150", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d51b-4918-a39c-5d1da74b77b3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9e2d-42f9-9130-c11290ba3baf", + "version": null, + "code": "652927", + "name": "乌什县", + "gjmc": "乌什县", + "udtwb": { + "chComTextMDS": "3149" + }, + "pathInfo": { + "path": "003200080007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c046-4f44-b1b8-648c850a2822", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c046-4f44-b1b8-648c850a2822", + "navParaentId_Code": "652900", + "navParaentId_Name": "阿克苏地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3149", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9e2d-42f9-9130-c11290ba3baf", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d1f4-488e-add4-f4e887abc30c", + "version": null, + "code": "652926", + "name": "拜城县", + "gjmc": "拜城县", + "udtwb": { + "chComTextMDS": "3148" + }, + "pathInfo": { + "path": "003200080006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c046-4f44-b1b8-648c850a2822", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c046-4f44-b1b8-648c850a2822", + "navParaentId_Code": "652900", + "navParaentId_Name": "阿克苏地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3148", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d1f4-488e-add4-f4e887abc30c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-419c-4c5a-9410-a0fd31840ba9", + "version": null, + "code": "652925", + "name": "新和县", + "gjmc": "新和县", + "udtwb": { + "chComTextMDS": "3147" + }, + "pathInfo": { + "path": "003200080005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c046-4f44-b1b8-648c850a2822", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c046-4f44-b1b8-648c850a2822", + "navParaentId_Code": "652900", + "navParaentId_Name": "阿克苏地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3147", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-419c-4c5a-9410-a0fd31840ba9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b5c5-47e8-9fd4-d7e287696fef", + "version": null, + "code": "652924", + "name": "沙雅县", + "gjmc": "沙雅县", + "udtwb": { + "chComTextMDS": "3146" + }, + "pathInfo": { + "path": "003200080004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c046-4f44-b1b8-648c850a2822", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c046-4f44-b1b8-648c850a2822", + "navParaentId_Code": "652900", + "navParaentId_Name": "阿克苏地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3146", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b5c5-47e8-9fd4-d7e287696fef", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bccd-4a25-a849-0affa4a476b1", + "version": null, + "code": "652923", + "name": "库车县", + "gjmc": "库车县", + "udtwb": { + "chComTextMDS": "3145" + }, + "pathInfo": { + "path": "003200080003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c046-4f44-b1b8-648c850a2822", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c046-4f44-b1b8-648c850a2822", + "navParaentId_Code": "652900", + "navParaentId_Name": "阿克苏地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3145", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bccd-4a25-a849-0affa4a476b1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6c2d-4116-b40c-f6233ac5edc3", + "version": null, + "code": "652922", + "name": "温宿县", + "gjmc": "温宿县", + "udtwb": { + "chComTextMDS": "3144" + }, + "pathInfo": { + "path": "003200080002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c046-4f44-b1b8-648c850a2822", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c046-4f44-b1b8-648c850a2822", + "navParaentId_Code": "652900", + "navParaentId_Name": "阿克苏地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3144", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6c2d-4116-b40c-f6233ac5edc3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5b5d-44f6-8081-a32e9c61e472", + "version": null, + "code": "652901", + "name": "阿克苏市", + "gjmc": "阿克苏市", + "udtwb": { + "chComTextMDS": "3143" + }, + "pathInfo": { + "path": "003200080001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c046-4f44-b1b8-648c850a2822", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c046-4f44-b1b8-648c850a2822", + "navParaentId_Code": "652900", + "navParaentId_Name": "阿克苏地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3143", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5b5d-44f6-8081-a32e9c61e472", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c046-4f44-b1b8-648c850a2822", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "version": null, + "code": "652800", + "name": "巴音郭楞蒙古自治州", + "gjmc": "巴音郭楞蒙古自治州", + "udtwb": { + "chComTextMDS": "3132" + }, + "pathInfo": { + "path": "00320007", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 7, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3132", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-fc8d-45e7-8e13-18c817bd672c", + "version": null, + "code": "652829", + "name": "博湖县", + "gjmc": "博湖县", + "udtwb": { + "chComTextMDS": "3141" + }, + "pathInfo": { + "path": "003200070009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "navParaentId_Code": "652800", + "navParaentId_Name": "巴音郭楞蒙古自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3141", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fc8d-45e7-8e13-18c817bd672c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-cf30-4b12-8cfe-2c93e76739f9", + "version": null, + "code": "652828", + "name": "和硕县", + "gjmc": "和硕县", + "udtwb": { + "chComTextMDS": "3140" + }, + "pathInfo": { + "path": "003200070008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "navParaentId_Code": "652800", + "navParaentId_Name": "巴音郭楞蒙古自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3140", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-cf30-4b12-8cfe-2c93e76739f9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6ac1-4b21-a182-8fee81903988", + "version": null, + "code": "652827", + "name": "和静县", + "gjmc": "和静县", + "udtwb": { + "chComTextMDS": "3139" + }, + "pathInfo": { + "path": "003200070007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "navParaentId_Code": "652800", + "navParaentId_Name": "巴音郭楞蒙古自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3139", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6ac1-4b21-a182-8fee81903988", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8634-4741-92c1-95815225ebfa", + "version": null, + "code": "652826", + "name": "焉耆回族自治县", + "gjmc": "焉耆回族自治县", + "udtwb": { + "chComTextMDS": "3138" + }, + "pathInfo": { + "path": "003200070006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "navParaentId_Code": "652800", + "navParaentId_Name": "巴音郭楞蒙古自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3138", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8634-4741-92c1-95815225ebfa", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-efaa-4b69-a588-247dc8c7fe04", + "version": null, + "code": "652825", + "name": "且末县", + "gjmc": "且末县", + "udtwb": { + "chComTextMDS": "3137" + }, + "pathInfo": { + "path": "003200070005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "navParaentId_Code": "652800", + "navParaentId_Name": "巴音郭楞蒙古自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3137", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-efaa-4b69-a588-247dc8c7fe04", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c86d-44fa-84d2-2c993b939fb2", + "version": null, + "code": "652824", + "name": "若羌县", + "gjmc": "若羌县", + "udtwb": { + "chComTextMDS": "3136" + }, + "pathInfo": { + "path": "003200070004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "navParaentId_Code": "652800", + "navParaentId_Name": "巴音郭楞蒙古自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3136", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c86d-44fa-84d2-2c993b939fb2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f6b4-4923-aa1e-22a5bdb37490", + "version": null, + "code": "652823", + "name": "尉犁县", + "gjmc": "尉犁县", + "udtwb": { + "chComTextMDS": "3135" + }, + "pathInfo": { + "path": "003200070003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "navParaentId_Code": "652800", + "navParaentId_Name": "巴音郭楞蒙古自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3135", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f6b4-4923-aa1e-22a5bdb37490", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a5a1-4c39-b11d-ce095ee9ef71", + "version": null, + "code": "652822", + "name": "轮台县", + "gjmc": "轮台县", + "udtwb": { + "chComTextMDS": "3134" + }, + "pathInfo": { + "path": "003200070002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "navParaentId_Code": "652800", + "navParaentId_Name": "巴音郭楞蒙古自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3134", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a5a1-4c39-b11d-ce095ee9ef71", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4c3a-43fb-b7e1-93b22a2867e2", + "version": null, + "code": "652801", + "name": "库尔勒市", + "gjmc": "库尔勒市", + "udtwb": { + "chComTextMDS": "3133" + }, + "pathInfo": { + "path": "003200070001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "navParaentId_Code": "652800", + "navParaentId_Name": "巴音郭楞蒙古自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3133", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4c3a-43fb-b7e1-93b22a2867e2", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-929b-40ea-a36f-2cdf1264f8dc", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-34d9-4cf7-93fb-328819fa9651", + "version": null, + "code": "652700", + "name": "博尔塔拉蒙古自治州", + "gjmc": "博尔塔拉蒙古自治州", + "udtwb": { + "chComTextMDS": "3127" + }, + "pathInfo": { + "path": "00320006", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 6, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3127", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-e34a-4c30-a95b-e19d1f231a61", + "version": null, + "code": "652723", + "name": "温泉县", + "gjmc": "温泉县", + "udtwb": { + "chComTextMDS": "3131" + }, + "pathInfo": { + "path": "003200060004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-34d9-4cf7-93fb-328819fa9651", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-34d9-4cf7-93fb-328819fa9651", + "navParaentId_Code": "652700", + "navParaentId_Name": "博尔塔拉蒙古自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3131", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e34a-4c30-a95b-e19d1f231a61", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ae0e-4171-afff-1a7ad56f9dc2", + "version": null, + "code": "652722", + "name": "精河县", + "gjmc": "精河县", + "udtwb": { + "chComTextMDS": "3130" + }, + "pathInfo": { + "path": "003200060003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-34d9-4cf7-93fb-328819fa9651", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-34d9-4cf7-93fb-328819fa9651", + "navParaentId_Code": "652700", + "navParaentId_Name": "博尔塔拉蒙古自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3130", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ae0e-4171-afff-1a7ad56f9dc2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ea9e-4cae-af37-6cd273e60e50", + "version": null, + "code": "652702", + "name": "阿拉山口市", + "gjmc": "阿拉山口市", + "udtwb": { + "chComTextMDS": "3129" + }, + "pathInfo": { + "path": "003200060002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-34d9-4cf7-93fb-328819fa9651", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-34d9-4cf7-93fb-328819fa9651", + "navParaentId_Code": "652700", + "navParaentId_Name": "博尔塔拉蒙古自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3129", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ea9e-4cae-af37-6cd273e60e50", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1175-4e61-9bbf-41c1650f3fad", + "version": null, + "code": "652701", + "name": "博乐市", + "gjmc": "博乐市", + "udtwb": { + "chComTextMDS": "3128" + }, + "pathInfo": { + "path": "003200060001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-34d9-4cf7-93fb-328819fa9651", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-34d9-4cf7-93fb-328819fa9651", + "navParaentId_Code": "652700", + "navParaentId_Name": "博尔塔拉蒙古自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3128", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1175-4e61-9bbf-41c1650f3fad", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-34d9-4cf7-93fb-328819fa9651", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "version": null, + "code": "652300", + "name": "昌吉回族自治州", + "gjmc": "昌吉回族自治州", + "udtwb": { + "chComTextMDS": "3119" + }, + "pathInfo": { + "path": "00320005", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 5, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3119", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-816d-4e4b-9b10-ca31cea8e6c6", + "version": null, + "code": "652328", + "name": "木垒哈萨克自治县", + "gjmc": "木垒哈萨克自治县", + "udtwb": { + "chComTextMDS": "3126" + }, + "pathInfo": { + "path": "003200050007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "navParaentId_Code": "652300", + "navParaentId_Name": "昌吉回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3126", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-816d-4e4b-9b10-ca31cea8e6c6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2b64-4eb0-9fad-3d78477af69e", + "version": null, + "code": "652327", + "name": "吉木萨尔县", + "gjmc": "吉木萨尔县", + "udtwb": { + "chComTextMDS": "3125" + }, + "pathInfo": { + "path": "003200050006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "navParaentId_Code": "652300", + "navParaentId_Name": "昌吉回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3125", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2b64-4eb0-9fad-3d78477af69e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-caab-4d27-bc9e-a5793bfda23d", + "version": null, + "code": "652325", + "name": "奇台县", + "gjmc": "奇台县", + "udtwb": { + "chComTextMDS": "3124" + }, + "pathInfo": { + "path": "003200050005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "navParaentId_Code": "652300", + "navParaentId_Name": "昌吉回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3124", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-caab-4d27-bc9e-a5793bfda23d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d539-4f2d-9bab-2c370574dff8", + "version": null, + "code": "652324", + "name": "玛纳斯县", + "gjmc": "玛纳斯县", + "udtwb": { + "chComTextMDS": "3123" + }, + "pathInfo": { + "path": "003200050004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "navParaentId_Code": "652300", + "navParaentId_Name": "昌吉回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3123", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d539-4f2d-9bab-2c370574dff8", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-090f-4241-b1d2-e651aeb16ecc", + "version": null, + "code": "652323", + "name": "呼图壁县", + "gjmc": "呼图壁县", + "udtwb": { + "chComTextMDS": "3122" + }, + "pathInfo": { + "path": "003200050003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "navParaentId_Code": "652300", + "navParaentId_Name": "昌吉回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3122", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-090f-4241-b1d2-e651aeb16ecc", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b2e4-44a7-b2d6-44a811e62e1a", + "version": null, + "code": "652302", + "name": "阜康市", + "gjmc": "阜康市", + "udtwb": { + "chComTextMDS": "3121" + }, + "pathInfo": { + "path": "003200050002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "navParaentId_Code": "652300", + "navParaentId_Name": "昌吉回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3121", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b2e4-44a7-b2d6-44a811e62e1a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5acb-4ebc-97bf-bf3a068a9592", + "version": null, + "code": "652301", + "name": "昌吉市", + "gjmc": "昌吉市", + "udtwb": { + "chComTextMDS": "3120" + }, + "pathInfo": { + "path": "003200050001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "navParaentId_Code": "652300", + "navParaentId_Name": "昌吉回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3120", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5acb-4ebc-97bf-bf3a068a9592", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f9f7-4583-9bd5-f57ec42f4695", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3c1f-4343-8f2d-957ed458852f", + "version": null, + "code": "650500", + "name": "哈密市", + "gjmc": "哈密市", + "udtwb": { + "chComTextMDS": "3115" + }, + "pathInfo": { + "path": "00320004", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 4, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3115", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-1d7b-471a-9546-0370b9a997bb", + "version": null, + "code": "650522", + "name": "伊吾县", + "gjmc": "伊吾县", + "udtwb": { + "chComTextMDS": "3118" + }, + "pathInfo": { + "path": "003200040003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3c1f-4343-8f2d-957ed458852f", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3c1f-4343-8f2d-957ed458852f", + "navParaentId_Code": "650500", + "navParaentId_Name": "哈密市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3118", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1d7b-471a-9546-0370b9a997bb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2448-4a8a-a96a-765c50248f98", + "version": null, + "code": "650521", + "name": "巴里坤哈萨克自治县", + "gjmc": "巴里坤哈萨克自治县", + "udtwb": { + "chComTextMDS": "3117" + }, + "pathInfo": { + "path": "003200040002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3c1f-4343-8f2d-957ed458852f", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3c1f-4343-8f2d-957ed458852f", + "navParaentId_Code": "650500", + "navParaentId_Name": "哈密市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3117", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2448-4a8a-a96a-765c50248f98", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a6de-422d-845e-7fa93882c31f", + "version": null, + "code": "650502", + "name": "伊州区", + "gjmc": "伊州区", + "udtwb": { + "chComTextMDS": "3116" + }, + "pathInfo": { + "path": "003200040001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3c1f-4343-8f2d-957ed458852f", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3c1f-4343-8f2d-957ed458852f", + "navParaentId_Code": "650500", + "navParaentId_Name": "哈密市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3116", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a6de-422d-845e-7fa93882c31f", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3c1f-4343-8f2d-957ed458852f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e570-4f01-a98d-53801d5483e1", + "version": null, + "code": "650400", + "name": "吐鲁番市", + "gjmc": "吐鲁番市", + "udtwb": { + "chComTextMDS": "3111" + }, + "pathInfo": { + "path": "00320003", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 3, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3111", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-2790-494a-8a66-bd80d2572cfd", + "version": null, + "code": "650422", + "name": "托克逊县", + "gjmc": "托克逊县", + "udtwb": { + "chComTextMDS": "3114" + }, + "pathInfo": { + "path": "003200030003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e570-4f01-a98d-53801d5483e1", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e570-4f01-a98d-53801d5483e1", + "navParaentId_Code": "650400", + "navParaentId_Name": "吐鲁番市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3114", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2790-494a-8a66-bd80d2572cfd", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b08b-4764-b202-9a7522275c14", + "version": null, + "code": "650421", + "name": "鄯善县", + "gjmc": "鄯善县", + "udtwb": { + "chComTextMDS": "3113" + }, + "pathInfo": { + "path": "003200030002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e570-4f01-a98d-53801d5483e1", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e570-4f01-a98d-53801d5483e1", + "navParaentId_Code": "650400", + "navParaentId_Name": "吐鲁番市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3113", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b08b-4764-b202-9a7522275c14", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6997-4999-b7d5-508e2609fb33", + "version": null, + "code": "650402", + "name": "高昌区", + "gjmc": "高昌区", + "udtwb": { + "chComTextMDS": "3112" + }, + "pathInfo": { + "path": "003200030001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e570-4f01-a98d-53801d5483e1", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e570-4f01-a98d-53801d5483e1", + "navParaentId_Code": "650400", + "navParaentId_Name": "吐鲁番市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3112", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6997-4999-b7d5-508e2609fb33", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e570-4f01-a98d-53801d5483e1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-fa84-4535-8be1-a14cd036d35e", + "version": null, + "code": "650200", + "name": "克拉玛依市", + "gjmc": "克拉玛依市", + "udtwb": { + "chComTextMDS": "3106" + }, + "pathInfo": { + "path": "00320002", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 2, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3106", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-01f1-4feb-8fd3-860e984420be", + "version": null, + "code": "650205", + "name": "乌尔禾区", + "gjmc": "乌尔禾区", + "udtwb": { + "chComTextMDS": "3110" + }, + "pathInfo": { + "path": "003200020004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fa84-4535-8be1-a14cd036d35e", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fa84-4535-8be1-a14cd036d35e", + "navParaentId_Code": "650200", + "navParaentId_Name": "克拉玛依市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3110", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-01f1-4feb-8fd3-860e984420be", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-61df-4346-ab0d-47a77654a173", + "version": null, + "code": "650204", + "name": "白碱滩区", + "gjmc": "白碱滩区", + "udtwb": { + "chComTextMDS": "3109" + }, + "pathInfo": { + "path": "003200020003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fa84-4535-8be1-a14cd036d35e", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fa84-4535-8be1-a14cd036d35e", + "navParaentId_Code": "650200", + "navParaentId_Name": "克拉玛依市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3109", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-61df-4346-ab0d-47a77654a173", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d1c3-49ff-9864-a758a153ec47", + "version": null, + "code": "650203", + "name": "克拉玛依区", + "gjmc": "克拉玛依区", + "udtwb": { + "chComTextMDS": "3108" + }, + "pathInfo": { + "path": "003200020002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fa84-4535-8be1-a14cd036d35e", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fa84-4535-8be1-a14cd036d35e", + "navParaentId_Code": "650200", + "navParaentId_Name": "克拉玛依市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3108", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d1c3-49ff-9864-a758a153ec47", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-fbfc-40b6-906f-3b07fabd3476", + "version": null, + "code": "650202", + "name": "独山子区", + "gjmc": "独山子区", + "udtwb": { + "chComTextMDS": "3107" + }, + "pathInfo": { + "path": "003200020001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fa84-4535-8be1-a14cd036d35e", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fa84-4535-8be1-a14cd036d35e", + "navParaentId_Code": "650200", + "navParaentId_Name": "克拉玛依市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3107", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fbfc-40b6-906f-3b07fabd3476", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fa84-4535-8be1-a14cd036d35e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "version": null, + "code": "650100", + "name": "乌鲁木齐市", + "gjmc": "乌鲁木齐市", + "udtwb": { + "chComTextMDS": "3097" + }, + "pathInfo": { + "path": "00320001", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "sequence": 1, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "navParaentId_Code": "650000", + "navParaentId_Name": "新疆维吾尔自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3097", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-c6df-430f-81d6-379ca43c164a", + "version": null, + "code": "650121", + "name": "乌鲁木齐县", + "gjmc": "乌鲁木齐县", + "udtwb": { + "chComTextMDS": "3105" + }, + "pathInfo": { + "path": "003200010008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "navParaentId_Code": "650100", + "navParaentId_Name": "乌鲁木齐市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3105", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c6df-430f-81d6-379ca43c164a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bef7-42f5-b2d6-df537fe72161", + "version": null, + "code": "650109", + "name": "米东区", + "gjmc": "米东区", + "udtwb": { + "chComTextMDS": "3104" + }, + "pathInfo": { + "path": "003200010007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "navParaentId_Code": "650100", + "navParaentId_Name": "乌鲁木齐市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3104", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bef7-42f5-b2d6-df537fe72161", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5344-453a-8298-a2e1fd4a669d", + "version": null, + "code": "650107", + "name": "达坂城区", + "gjmc": "达坂城区", + "udtwb": { + "chComTextMDS": "3103" + }, + "pathInfo": { + "path": "003200010006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "navParaentId_Code": "650100", + "navParaentId_Name": "乌鲁木齐市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3103", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5344-453a-8298-a2e1fd4a669d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3f13-4d95-9710-4308d594cc58", + "version": null, + "code": "650106", + "name": "头屯河区", + "gjmc": "头屯河区", + "udtwb": { + "chComTextMDS": "3102" + }, + "pathInfo": { + "path": "003200010005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "navParaentId_Code": "650100", + "navParaentId_Name": "乌鲁木齐市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3102", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3f13-4d95-9710-4308d594cc58", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-07ed-4f59-8f3f-f2b13ec96485", + "version": null, + "code": "650105", + "name": "水磨沟区", + "gjmc": "水磨沟区", + "udtwb": { + "chComTextMDS": "3101" + }, + "pathInfo": { + "path": "003200010004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "navParaentId_Code": "650100", + "navParaentId_Name": "乌鲁木齐市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3101", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-07ed-4f59-8f3f-f2b13ec96485", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-fe6a-406b-826f-2d8b0f323c75", + "version": null, + "code": "650104", + "name": "新市区", + "gjmc": "新市区", + "udtwb": { + "chComTextMDS": "3100" + }, + "pathInfo": { + "path": "003200010003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "navParaentId_Code": "650100", + "navParaentId_Name": "乌鲁木齐市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3100", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fe6a-406b-826f-2d8b0f323c75", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2c03-4d33-ab51-849533c6495a", + "version": null, + "code": "650103", + "name": "沙依巴克区", + "gjmc": "沙依巴克区", + "udtwb": { + "chComTextMDS": "3099" + }, + "pathInfo": { + "path": "003200010002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "navParaentId_Code": "650100", + "navParaentId_Name": "乌鲁木齐市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3099", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2c03-4d33-ab51-849533c6495a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9837-4092-a6d3-383b5f625e8f", + "version": null, + "code": "650102", + "name": "天山区", + "gjmc": "天山区", + "udtwb": { + "chComTextMDS": "3098" + }, + "pathInfo": { + "path": "003200010001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "navParaentId_Code": "650100", + "navParaentId_Name": "乌鲁木齐市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3098", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9837-4092-a6d3-383b5f625e8f", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-81c9-4cd8-bb86-136a71ad4062", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3bd7-44aa-98f6-4dbe7cb98321", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-00e4-402a-90b7-8dc26acc3e3d", + "version": null, + "code": "640000", + "name": "宁夏回族自治区", + "gjmc": "宁夏回族自治区", + "udtwb": { + "chComTextMDS": "3068" + }, + "pathInfo": { + "path": "0031", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 31, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3068", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-673f-4301-8f57-73ed11b1473b", + "version": null, + "code": "640500", + "name": "中卫市", + "gjmc": "中卫市", + "udtwb": { + "chComTextMDS": "3092" + }, + "pathInfo": { + "path": "00310005", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-00e4-402a-90b7-8dc26acc3e3d", + "sequence": 5, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-00e4-402a-90b7-8dc26acc3e3d", + "navParaentId_Code": "640000", + "navParaentId_Name": "宁夏回族自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3092", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-9ea7-48ca-a81d-3015eb5afd84", + "version": null, + "code": "640522", + "name": "海原县", + "gjmc": "海原县", + "udtwb": { + "chComTextMDS": "3095" + }, + "pathInfo": { + "path": "003100050003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-673f-4301-8f57-73ed11b1473b", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-673f-4301-8f57-73ed11b1473b", + "navParaentId_Code": "640500", + "navParaentId_Name": "中卫市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3095", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9ea7-48ca-a81d-3015eb5afd84", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0a62-467a-a7f0-ad620e033a22", + "version": null, + "code": "640521", + "name": "中宁县", + "gjmc": "中宁县", + "udtwb": { + "chComTextMDS": "3094" + }, + "pathInfo": { + "path": "003100050002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-673f-4301-8f57-73ed11b1473b", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-673f-4301-8f57-73ed11b1473b", + "navParaentId_Code": "640500", + "navParaentId_Name": "中卫市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3094", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0a62-467a-a7f0-ad620e033a22", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a957-4c44-a139-12f0c8872785", + "version": null, + "code": "640502", + "name": "沙坡头区", + "gjmc": "沙坡头区", + "udtwb": { + "chComTextMDS": "3093" + }, + "pathInfo": { + "path": "003100050001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-673f-4301-8f57-73ed11b1473b", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-673f-4301-8f57-73ed11b1473b", + "navParaentId_Code": "640500", + "navParaentId_Name": "中卫市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3093", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a957-4c44-a139-12f0c8872785", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-673f-4301-8f57-73ed11b1473b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8602-44ec-abf2-5a9aea226d27", + "version": null, + "code": "640400", + "name": "固原市", + "gjmc": "固原市", + "udtwb": { + "chComTextMDS": "3086" + }, + "pathInfo": { + "path": "00310004", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-00e4-402a-90b7-8dc26acc3e3d", + "sequence": 4, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-00e4-402a-90b7-8dc26acc3e3d", + "navParaentId_Code": "640000", + "navParaentId_Name": "宁夏回族自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3086", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-9afb-4ee2-addc-79dd6fdad2b2", + "version": null, + "code": "640425", + "name": "彭阳县", + "gjmc": "彭阳县", + "udtwb": { + "chComTextMDS": "3091" + }, + "pathInfo": { + "path": "003100040005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-8602-44ec-abf2-5a9aea226d27", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-8602-44ec-abf2-5a9aea226d27", + "navParaentId_Code": "640400", + "navParaentId_Name": "固原市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3091", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9afb-4ee2-addc-79dd6fdad2b2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-699f-4e6b-9e22-baf2ec7601a9", + "version": null, + "code": "640424", + "name": "泾源县", + "gjmc": "泾源县", + "udtwb": { + "chComTextMDS": "3090" + }, + "pathInfo": { + "path": "003100040004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-8602-44ec-abf2-5a9aea226d27", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-8602-44ec-abf2-5a9aea226d27", + "navParaentId_Code": "640400", + "navParaentId_Name": "固原市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3090", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-699f-4e6b-9e22-baf2ec7601a9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0266-4939-9eec-c9c7765aed91", + "version": null, + "code": "640423", + "name": "隆德县", + "gjmc": "隆德县", + "udtwb": { + "chComTextMDS": "3089" + }, + "pathInfo": { + "path": "003100040003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-8602-44ec-abf2-5a9aea226d27", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-8602-44ec-abf2-5a9aea226d27", + "navParaentId_Code": "640400", + "navParaentId_Name": "固原市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3089", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0266-4939-9eec-c9c7765aed91", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-dbc2-40cd-b8a8-3103cc1422b7", + "version": null, + "code": "640422", + "name": "西吉县", + "gjmc": "西吉县", + "udtwb": { + "chComTextMDS": "3088" + }, + "pathInfo": { + "path": "003100040002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-8602-44ec-abf2-5a9aea226d27", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-8602-44ec-abf2-5a9aea226d27", + "navParaentId_Code": "640400", + "navParaentId_Name": "固原市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3088", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-dbc2-40cd-b8a8-3103cc1422b7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-78a7-40dc-ada6-88d98525cdc9", + "version": null, + "code": "640402", + "name": "原州区", + "gjmc": "原州区", + "udtwb": { + "chComTextMDS": "3087" + }, + "pathInfo": { + "path": "003100040001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-8602-44ec-abf2-5a9aea226d27", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-8602-44ec-abf2-5a9aea226d27", + "navParaentId_Code": "640400", + "navParaentId_Name": "固原市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3087", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-78a7-40dc-ada6-88d98525cdc9", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8602-44ec-abf2-5a9aea226d27", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9463-4820-9884-5b0041f79855", + "version": null, + "code": "640300", + "name": "吴忠市", + "gjmc": "吴忠市", + "udtwb": { + "chComTextMDS": "3080" + }, + "pathInfo": { + "path": "00310003", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-00e4-402a-90b7-8dc26acc3e3d", + "sequence": 3, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-00e4-402a-90b7-8dc26acc3e3d", + "navParaentId_Code": "640000", + "navParaentId_Name": "宁夏回族自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3080", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-b57f-440a-85ae-d1d78c983b31", + "version": null, + "code": "640381", + "name": "青铜峡市", + "gjmc": "青铜峡市", + "udtwb": { + "chComTextMDS": "3085" + }, + "pathInfo": { + "path": "003100030005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9463-4820-9884-5b0041f79855", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9463-4820-9884-5b0041f79855", + "navParaentId_Code": "640300", + "navParaentId_Name": "吴忠市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3085", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b57f-440a-85ae-d1d78c983b31", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4e45-41d7-9f5d-0128207cc196", + "version": null, + "code": "640324", + "name": "同心县", + "gjmc": "同心县", + "udtwb": { + "chComTextMDS": "3084" + }, + "pathInfo": { + "path": "003100030004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9463-4820-9884-5b0041f79855", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9463-4820-9884-5b0041f79855", + "navParaentId_Code": "640300", + "navParaentId_Name": "吴忠市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3084", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4e45-41d7-9f5d-0128207cc196", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7250-435a-b806-b6db9c05135a", + "version": null, + "code": "640323", + "name": "盐池县", + "gjmc": "盐池县", + "udtwb": { + "chComTextMDS": "3083" + }, + "pathInfo": { + "path": "003100030003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9463-4820-9884-5b0041f79855", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9463-4820-9884-5b0041f79855", + "navParaentId_Code": "640300", + "navParaentId_Name": "吴忠市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3083", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7250-435a-b806-b6db9c05135a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b8ef-4ed6-bea3-9014b50ebb9a", + "version": null, + "code": "640303", + "name": "红寺堡区", + "gjmc": "红寺堡区", + "udtwb": { + "chComTextMDS": "3082" + }, + "pathInfo": { + "path": "003100030002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9463-4820-9884-5b0041f79855", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9463-4820-9884-5b0041f79855", + "navParaentId_Code": "640300", + "navParaentId_Name": "吴忠市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3082", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b8ef-4ed6-bea3-9014b50ebb9a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1036-4a09-a4b1-ff44c5c78002", + "version": null, + "code": "640302", + "name": "利通区", + "gjmc": "利通区", + "udtwb": { + "chComTextMDS": "3081" + }, + "pathInfo": { + "path": "003100030001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9463-4820-9884-5b0041f79855", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9463-4820-9884-5b0041f79855", + "navParaentId_Code": "640300", + "navParaentId_Name": "吴忠市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3081", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1036-4a09-a4b1-ff44c5c78002", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9463-4820-9884-5b0041f79855", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a839-4e0b-b6f8-47744ad18d34", + "version": null, + "code": "640200", + "name": "石嘴山市", + "gjmc": "石嘴山市", + "udtwb": { + "chComTextMDS": "3076" + }, + "pathInfo": { + "path": "00310002", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-00e4-402a-90b7-8dc26acc3e3d", + "sequence": 2, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-00e4-402a-90b7-8dc26acc3e3d", + "navParaentId_Code": "640000", + "navParaentId_Name": "宁夏回族自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3076", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-6f0a-4d71-9da4-e08b94c404ae", + "version": null, + "code": "640221", + "name": "平罗县", + "gjmc": "平罗县", + "udtwb": { + "chComTextMDS": "3079" + }, + "pathInfo": { + "path": "003100020003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-a839-4e0b-b6f8-47744ad18d34", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-a839-4e0b-b6f8-47744ad18d34", + "navParaentId_Code": "640200", + "navParaentId_Name": "石嘴山市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3079", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6f0a-4d71-9da4-e08b94c404ae", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2fb3-498b-95f4-77d9d71c429a", + "version": null, + "code": "640205", + "name": "惠农区", + "gjmc": "惠农区", + "udtwb": { + "chComTextMDS": "3078" + }, + "pathInfo": { + "path": "003100020002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-a839-4e0b-b6f8-47744ad18d34", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-a839-4e0b-b6f8-47744ad18d34", + "navParaentId_Code": "640200", + "navParaentId_Name": "石嘴山市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3078", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2fb3-498b-95f4-77d9d71c429a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d701-4cdf-a30a-263fc9263bca", + "version": null, + "code": "640202", + "name": "大武口区", + "gjmc": "大武口区", + "udtwb": { + "chComTextMDS": "3077" + }, + "pathInfo": { + "path": "003100020001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-a839-4e0b-b6f8-47744ad18d34", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-a839-4e0b-b6f8-47744ad18d34", + "navParaentId_Code": "640200", + "navParaentId_Name": "石嘴山市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3077", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d701-4cdf-a30a-263fc9263bca", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a839-4e0b-b6f8-47744ad18d34", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c6b7-4d20-be99-fed516839b9f", + "version": null, + "code": "640100", + "name": "银川市", + "gjmc": "银川市", + "udtwb": { + "chComTextMDS": "3069" + }, + "pathInfo": { + "path": "00310001", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-00e4-402a-90b7-8dc26acc3e3d", + "sequence": 1, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-00e4-402a-90b7-8dc26acc3e3d", + "navParaentId_Code": "640000", + "navParaentId_Name": "宁夏回族自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3069", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-5751-4bf0-82ea-0c02381eaa97", + "version": null, + "code": "640181", + "name": "灵武市", + "gjmc": "灵武市", + "udtwb": { + "chComTextMDS": "3075" + }, + "pathInfo": { + "path": "003100010006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c6b7-4d20-be99-fed516839b9f", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c6b7-4d20-be99-fed516839b9f", + "navParaentId_Code": "640100", + "navParaentId_Name": "银川市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3075", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5751-4bf0-82ea-0c02381eaa97", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-26b4-450a-832a-2b0daebf2d9f", + "version": null, + "code": "640122", + "name": "贺兰县", + "gjmc": "贺兰县", + "udtwb": { + "chComTextMDS": "3074" + }, + "pathInfo": { + "path": "003100010005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c6b7-4d20-be99-fed516839b9f", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c6b7-4d20-be99-fed516839b9f", + "navParaentId_Code": "640100", + "navParaentId_Name": "银川市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3074", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-26b4-450a-832a-2b0daebf2d9f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4fc9-4a3f-87b4-e2b8bfa3f138", + "version": null, + "code": "640121", + "name": "永宁县", + "gjmc": "永宁县", + "udtwb": { + "chComTextMDS": "3073" + }, + "pathInfo": { + "path": "003100010004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c6b7-4d20-be99-fed516839b9f", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c6b7-4d20-be99-fed516839b9f", + "navParaentId_Code": "640100", + "navParaentId_Name": "银川市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3073", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4fc9-4a3f-87b4-e2b8bfa3f138", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5392-4cf0-8bb8-b7fb354ef4db", + "version": null, + "code": "640106", + "name": "金凤区", + "gjmc": "金凤区", + "udtwb": { + "chComTextMDS": "3072" + }, + "pathInfo": { + "path": "003100010003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c6b7-4d20-be99-fed516839b9f", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c6b7-4d20-be99-fed516839b9f", + "navParaentId_Code": "640100", + "navParaentId_Name": "银川市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3072", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5392-4cf0-8bb8-b7fb354ef4db", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c8c7-458f-b07f-bb9f483fe507", + "version": null, + "code": "640105", + "name": "西夏区", + "gjmc": "西夏区", + "udtwb": { + "chComTextMDS": "3071" + }, + "pathInfo": { + "path": "003100010002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c6b7-4d20-be99-fed516839b9f", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c6b7-4d20-be99-fed516839b9f", + "navParaentId_Code": "640100", + "navParaentId_Name": "银川市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3071", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c8c7-458f-b07f-bb9f483fe507", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a179-4a95-9a7a-7b221e1b1c33", + "version": null, + "code": "640104", + "name": "兴庆区", + "gjmc": "兴庆区", + "udtwb": { + "chComTextMDS": "3070" + }, + "pathInfo": { + "path": "003100010001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c6b7-4d20-be99-fed516839b9f", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c6b7-4d20-be99-fed516839b9f", + "navParaentId_Code": "640100", + "navParaentId_Name": "银川市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3070", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a179-4a95-9a7a-7b221e1b1c33", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c6b7-4d20-be99-fed516839b9f", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-00e4-402a-90b7-8dc26acc3e3d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ea88-417e-9a7b-880433eb6941", + "version": null, + "code": "630000", + "name": "青海省", + "gjmc": "青海省", + "udtwb": { + "chComTextMDS": "3016" + }, + "pathInfo": { + "path": "0030", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 30, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3016", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-d50f-45c5-8685-52fe4e8dc39b", + "version": null, + "code": "632800", + "name": "海西蒙古族藏族自治州", + "gjmc": "海西蒙古族藏族自治州", + "udtwb": { + "chComTextMDS": "3062" + }, + "pathInfo": { + "path": "00300008", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ea88-417e-9a7b-880433eb6941", + "sequence": 8, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ea88-417e-9a7b-880433eb6941", + "navParaentId_Code": "630000", + "navParaentId_Name": "青海省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3062", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-8511-4a55-9f0f-43cf86f73f68", + "version": null, + "code": "632823", + "name": "天峻县", + "gjmc": "天峻县", + "udtwb": { + "chComTextMDS": "3067" + }, + "pathInfo": { + "path": "003000080005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d50f-45c5-8685-52fe4e8dc39b", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d50f-45c5-8685-52fe4e8dc39b", + "navParaentId_Code": "632800", + "navParaentId_Name": "海西蒙古族藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3067", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8511-4a55-9f0f-43cf86f73f68", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a606-4073-b84d-ca035e6041fa", + "version": null, + "code": "632822", + "name": "都兰县", + "gjmc": "都兰县", + "udtwb": { + "chComTextMDS": "3066" + }, + "pathInfo": { + "path": "003000080004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d50f-45c5-8685-52fe4e8dc39b", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d50f-45c5-8685-52fe4e8dc39b", + "navParaentId_Code": "632800", + "navParaentId_Name": "海西蒙古族藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3066", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a606-4073-b84d-ca035e6041fa", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-be19-46d9-9dfa-857c9c6606cb", + "version": null, + "code": "632821", + "name": "乌兰县", + "gjmc": "乌兰县", + "udtwb": { + "chComTextMDS": "3065" + }, + "pathInfo": { + "path": "003000080003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d50f-45c5-8685-52fe4e8dc39b", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d50f-45c5-8685-52fe4e8dc39b", + "navParaentId_Code": "632800", + "navParaentId_Name": "海西蒙古族藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3065", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-be19-46d9-9dfa-857c9c6606cb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6049-4ee5-9c0d-0c119266712c", + "version": null, + "code": "632802", + "name": "德令哈市", + "gjmc": "德令哈市", + "udtwb": { + "chComTextMDS": "3064" + }, + "pathInfo": { + "path": "003000080002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d50f-45c5-8685-52fe4e8dc39b", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d50f-45c5-8685-52fe4e8dc39b", + "navParaentId_Code": "632800", + "navParaentId_Name": "海西蒙古族藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3064", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6049-4ee5-9c0d-0c119266712c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2645-44fd-a345-f574b4347596", + "version": null, + "code": "632801", + "name": "格尔木市", + "gjmc": "格尔木市", + "udtwb": { + "chComTextMDS": "3063" + }, + "pathInfo": { + "path": "003000080001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d50f-45c5-8685-52fe4e8dc39b", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d50f-45c5-8685-52fe4e8dc39b", + "navParaentId_Code": "632800", + "navParaentId_Name": "海西蒙古族藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3063", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2645-44fd-a345-f574b4347596", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d50f-45c5-8685-52fe4e8dc39b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-edba-4a3b-b091-b09f3511fd77", + "version": null, + "code": "632700", + "name": "玉树藏族自治州", + "gjmc": "玉树藏族自治州", + "udtwb": { + "chComTextMDS": "3055" + }, + "pathInfo": { + "path": "00300007", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ea88-417e-9a7b-880433eb6941", + "sequence": 7, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ea88-417e-9a7b-880433eb6941", + "navParaentId_Code": "630000", + "navParaentId_Name": "青海省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3055", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-51db-4769-a6b6-270285348e09", + "version": null, + "code": "632726", + "name": "曲麻莱县", + "gjmc": "曲麻莱县", + "udtwb": { + "chComTextMDS": "3061" + }, + "pathInfo": { + "path": "003000070006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-edba-4a3b-b091-b09f3511fd77", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-edba-4a3b-b091-b09f3511fd77", + "navParaentId_Code": "632700", + "navParaentId_Name": "玉树藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3061", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-51db-4769-a6b6-270285348e09", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c5d9-4064-901a-0766efb8aca2", + "version": null, + "code": "632725", + "name": "囊谦县", + "gjmc": "囊谦县", + "udtwb": { + "chComTextMDS": "3060" + }, + "pathInfo": { + "path": "003000070005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-edba-4a3b-b091-b09f3511fd77", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-edba-4a3b-b091-b09f3511fd77", + "navParaentId_Code": "632700", + "navParaentId_Name": "玉树藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3060", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c5d9-4064-901a-0766efb8aca2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4677-4cd7-8491-505afc8c74c7", + "version": null, + "code": "632724", + "name": "治多县", + "gjmc": "治多县", + "udtwb": { + "chComTextMDS": "3059" + }, + "pathInfo": { + "path": "003000070004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-edba-4a3b-b091-b09f3511fd77", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-edba-4a3b-b091-b09f3511fd77", + "navParaentId_Code": "632700", + "navParaentId_Name": "玉树藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3059", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4677-4cd7-8491-505afc8c74c7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d3ca-4a4b-8e32-5d2d8c0ff204", + "version": null, + "code": "632723", + "name": "称多县", + "gjmc": "称多县", + "udtwb": { + "chComTextMDS": "3058" + }, + "pathInfo": { + "path": "003000070003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-edba-4a3b-b091-b09f3511fd77", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-edba-4a3b-b091-b09f3511fd77", + "navParaentId_Code": "632700", + "navParaentId_Name": "玉树藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3058", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d3ca-4a4b-8e32-5d2d8c0ff204", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1626-4f2c-9fae-e440f2e8d21f", + "version": null, + "code": "632722", + "name": "杂多县", + "gjmc": "杂多县", + "udtwb": { + "chComTextMDS": "3057" + }, + "pathInfo": { + "path": "003000070002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-edba-4a3b-b091-b09f3511fd77", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-edba-4a3b-b091-b09f3511fd77", + "navParaentId_Code": "632700", + "navParaentId_Name": "玉树藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3057", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1626-4f2c-9fae-e440f2e8d21f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ef6b-4911-b8a0-deed7bd78970", + "version": null, + "code": "632701", + "name": "玉树市", + "gjmc": "玉树市", + "udtwb": { + "chComTextMDS": "3056" + }, + "pathInfo": { + "path": "003000070001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-edba-4a3b-b091-b09f3511fd77", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-edba-4a3b-b091-b09f3511fd77", + "navParaentId_Code": "632700", + "navParaentId_Name": "玉树藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3056", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ef6b-4911-b8a0-deed7bd78970", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-edba-4a3b-b091-b09f3511fd77", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7b81-4eec-b991-b9309e840bc3", + "version": null, + "code": "632600", + "name": "果洛藏族自治州", + "gjmc": "果洛藏族自治州", + "udtwb": { + "chComTextMDS": "3048" + }, + "pathInfo": { + "path": "00300006", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ea88-417e-9a7b-880433eb6941", + "sequence": 6, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ea88-417e-9a7b-880433eb6941", + "navParaentId_Code": "630000", + "navParaentId_Name": "青海省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3048", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-5315-49cb-8177-23df11ff6ccc", + "version": null, + "code": "632626", + "name": "玛多县", + "gjmc": "玛多县", + "udtwb": { + "chComTextMDS": "3054" + }, + "pathInfo": { + "path": "003000060006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7b81-4eec-b991-b9309e840bc3", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7b81-4eec-b991-b9309e840bc3", + "navParaentId_Code": "632600", + "navParaentId_Name": "果洛藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3054", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5315-49cb-8177-23df11ff6ccc", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-83cd-40e3-966c-3571c69e6fa0", + "version": null, + "code": "632625", + "name": "久治县", + "gjmc": "久治县", + "udtwb": { + "chComTextMDS": "3053" + }, + "pathInfo": { + "path": "003000060005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7b81-4eec-b991-b9309e840bc3", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7b81-4eec-b991-b9309e840bc3", + "navParaentId_Code": "632600", + "navParaentId_Name": "果洛藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3053", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-83cd-40e3-966c-3571c69e6fa0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3388-4e42-b090-e153463b89da", + "version": null, + "code": "632624", + "name": "达日县", + "gjmc": "达日县", + "udtwb": { + "chComTextMDS": "3052" + }, + "pathInfo": { + "path": "003000060004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7b81-4eec-b991-b9309e840bc3", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7b81-4eec-b991-b9309e840bc3", + "navParaentId_Code": "632600", + "navParaentId_Name": "果洛藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3052", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3388-4e42-b090-e153463b89da", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ab06-433c-8d8d-7d06c7abaa44", + "version": null, + "code": "632623", + "name": "甘德县", + "gjmc": "甘德县", + "udtwb": { + "chComTextMDS": "3051" + }, + "pathInfo": { + "path": "003000060003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7b81-4eec-b991-b9309e840bc3", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7b81-4eec-b991-b9309e840bc3", + "navParaentId_Code": "632600", + "navParaentId_Name": "果洛藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3051", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ab06-433c-8d8d-7d06c7abaa44", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4bdf-4949-90d5-43d21bbf3052", + "version": null, + "code": "632622", + "name": "班玛县", + "gjmc": "班玛县", + "udtwb": { + "chComTextMDS": "3050" + }, + "pathInfo": { + "path": "003000060002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7b81-4eec-b991-b9309e840bc3", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7b81-4eec-b991-b9309e840bc3", + "navParaentId_Code": "632600", + "navParaentId_Name": "果洛藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3050", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4bdf-4949-90d5-43d21bbf3052", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b4f4-4484-8022-40334e71a35e", + "version": null, + "code": "632621", + "name": "玛沁县", + "gjmc": "玛沁县", + "udtwb": { + "chComTextMDS": "3049" + }, + "pathInfo": { + "path": "003000060001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7b81-4eec-b991-b9309e840bc3", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7b81-4eec-b991-b9309e840bc3", + "navParaentId_Code": "632600", + "navParaentId_Name": "果洛藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3049", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b4f4-4484-8022-40334e71a35e", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7b81-4eec-b991-b9309e840bc3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3729-49be-bbd3-05d5489fd226", + "version": null, + "code": "632500", + "name": "海南藏族自治州", + "gjmc": "海南藏族自治州", + "udtwb": { + "chComTextMDS": "3042" + }, + "pathInfo": { + "path": "00300005", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ea88-417e-9a7b-880433eb6941", + "sequence": 5, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ea88-417e-9a7b-880433eb6941", + "navParaentId_Code": "630000", + "navParaentId_Name": "青海省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3042", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-179c-4b39-ac49-190e4f800bdd", + "version": null, + "code": "632525", + "name": "贵南县", + "gjmc": "贵南县", + "udtwb": { + "chComTextMDS": "3047" + }, + "pathInfo": { + "path": "003000050005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3729-49be-bbd3-05d5489fd226", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3729-49be-bbd3-05d5489fd226", + "navParaentId_Code": "632500", + "navParaentId_Name": "海南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3047", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-179c-4b39-ac49-190e4f800bdd", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-88fc-4512-848a-47b4894b5af9", + "version": null, + "code": "632524", + "name": "兴海县", + "gjmc": "兴海县", + "udtwb": { + "chComTextMDS": "3046" + }, + "pathInfo": { + "path": "003000050004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3729-49be-bbd3-05d5489fd226", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3729-49be-bbd3-05d5489fd226", + "navParaentId_Code": "632500", + "navParaentId_Name": "海南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3046", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-88fc-4512-848a-47b4894b5af9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f31f-406b-9ff6-a25f6f37e574", + "version": null, + "code": "632523", + "name": "贵德县", + "gjmc": "贵德县", + "udtwb": { + "chComTextMDS": "3045" + }, + "pathInfo": { + "path": "003000050003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3729-49be-bbd3-05d5489fd226", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3729-49be-bbd3-05d5489fd226", + "navParaentId_Code": "632500", + "navParaentId_Name": "海南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3045", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f31f-406b-9ff6-a25f6f37e574", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f048-4c23-af9c-c71d5ae85748", + "version": null, + "code": "632522", + "name": "同德县", + "gjmc": "同德县", + "udtwb": { + "chComTextMDS": "3044" + }, + "pathInfo": { + "path": "003000050002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3729-49be-bbd3-05d5489fd226", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3729-49be-bbd3-05d5489fd226", + "navParaentId_Code": "632500", + "navParaentId_Name": "海南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3044", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f048-4c23-af9c-c71d5ae85748", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4305-487e-a603-8460bbcc1017", + "version": null, + "code": "632521", + "name": "共和县", + "gjmc": "共和县", + "udtwb": { + "chComTextMDS": "3043" + }, + "pathInfo": { + "path": "003000050001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-3729-49be-bbd3-05d5489fd226", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-3729-49be-bbd3-05d5489fd226", + "navParaentId_Code": "632500", + "navParaentId_Name": "海南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3043", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4305-487e-a603-8460bbcc1017", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3729-49be-bbd3-05d5489fd226", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-054b-4606-b703-d19a5ec4de90", + "version": null, + "code": "632300", + "name": "黄南藏族自治州", + "gjmc": "黄南藏族自治州", + "udtwb": { + "chComTextMDS": "3037" + }, + "pathInfo": { + "path": "00300004", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ea88-417e-9a7b-880433eb6941", + "sequence": 4, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ea88-417e-9a7b-880433eb6941", + "navParaentId_Code": "630000", + "navParaentId_Name": "青海省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3037", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-ed21-43e7-8eb2-cc2fe48d4239", + "version": null, + "code": "632324", + "name": "河南蒙古族自治县", + "gjmc": "河南蒙古族自治县", + "udtwb": { + "chComTextMDS": "3041" + }, + "pathInfo": { + "path": "003000040004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-054b-4606-b703-d19a5ec4de90", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-054b-4606-b703-d19a5ec4de90", + "navParaentId_Code": "632300", + "navParaentId_Name": "黄南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3041", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ed21-43e7-8eb2-cc2fe48d4239", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2017-4865-ab5e-c650674337be", + "version": null, + "code": "632323", + "name": "泽库县", + "gjmc": "泽库县", + "udtwb": { + "chComTextMDS": "3040" + }, + "pathInfo": { + "path": "003000040003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-054b-4606-b703-d19a5ec4de90", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-054b-4606-b703-d19a5ec4de90", + "navParaentId_Code": "632300", + "navParaentId_Name": "黄南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3040", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2017-4865-ab5e-c650674337be", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-49a8-4089-bdfd-a146401ca546", + "version": null, + "code": "632322", + "name": "尖扎县", + "gjmc": "尖扎县", + "udtwb": { + "chComTextMDS": "3039" + }, + "pathInfo": { + "path": "003000040002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-054b-4606-b703-d19a5ec4de90", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-054b-4606-b703-d19a5ec4de90", + "navParaentId_Code": "632300", + "navParaentId_Name": "黄南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3039", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-49a8-4089-bdfd-a146401ca546", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-fce1-4b07-ac04-afd17381ff6b", + "version": null, + "code": "632321", + "name": "同仁县", + "gjmc": "同仁县", + "udtwb": { + "chComTextMDS": "3038" + }, + "pathInfo": { + "path": "003000040001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-054b-4606-b703-d19a5ec4de90", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-054b-4606-b703-d19a5ec4de90", + "navParaentId_Code": "632300", + "navParaentId_Name": "黄南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3038", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fce1-4b07-ac04-afd17381ff6b", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-054b-4606-b703-d19a5ec4de90", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8241-453b-aacd-adfec496f6c4", + "version": null, + "code": "632200", + "name": "海北藏族自治州", + "gjmc": "海北藏族自治州", + "udtwb": { + "chComTextMDS": "3032" + }, + "pathInfo": { + "path": "00300003", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ea88-417e-9a7b-880433eb6941", + "sequence": 3, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ea88-417e-9a7b-880433eb6941", + "navParaentId_Code": "630000", + "navParaentId_Name": "青海省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3032", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-387d-433b-80b5-00ca48cad482", + "version": null, + "code": "632224", + "name": "刚察县", + "gjmc": "刚察县", + "udtwb": { + "chComTextMDS": "3036" + }, + "pathInfo": { + "path": "003000030004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-8241-453b-aacd-adfec496f6c4", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-8241-453b-aacd-adfec496f6c4", + "navParaentId_Code": "632200", + "navParaentId_Name": "海北藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3036", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-387d-433b-80b5-00ca48cad482", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-93c6-4e51-adc9-5a490d6b1a31", + "version": null, + "code": "632223", + "name": "海晏县", + "gjmc": "海晏县", + "udtwb": { + "chComTextMDS": "3035" + }, + "pathInfo": { + "path": "003000030003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-8241-453b-aacd-adfec496f6c4", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-8241-453b-aacd-adfec496f6c4", + "navParaentId_Code": "632200", + "navParaentId_Name": "海北藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3035", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-93c6-4e51-adc9-5a490d6b1a31", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-11de-4e53-8dd9-237be766c7ba", + "version": null, + "code": "632222", + "name": "祁连县", + "gjmc": "祁连县", + "udtwb": { + "chComTextMDS": "3034" + }, + "pathInfo": { + "path": "003000030002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-8241-453b-aacd-adfec496f6c4", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-8241-453b-aacd-adfec496f6c4", + "navParaentId_Code": "632200", + "navParaentId_Name": "海北藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3034", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-11de-4e53-8dd9-237be766c7ba", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2983-4f11-95ac-a11cccdcca08", + "version": null, + "code": "632221", + "name": "门源回族自治县", + "gjmc": "门源回族自治县", + "udtwb": { + "chComTextMDS": "3033" + }, + "pathInfo": { + "path": "003000030001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-8241-453b-aacd-adfec496f6c4", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-8241-453b-aacd-adfec496f6c4", + "navParaentId_Code": "632200", + "navParaentId_Name": "海北藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3033", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2983-4f11-95ac-a11cccdcca08", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8241-453b-aacd-adfec496f6c4", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b6e1-4d4b-ae55-e1c0c0728626", + "version": null, + "code": "630200", + "name": "海东市", + "gjmc": "海东市", + "udtwb": { + "chComTextMDS": "3025" + }, + "pathInfo": { + "path": "00300002", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ea88-417e-9a7b-880433eb6941", + "sequence": 2, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ea88-417e-9a7b-880433eb6941", + "navParaentId_Code": "630000", + "navParaentId_Name": "青海省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3025", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-d477-4746-bf3c-985fb787e11c", + "version": null, + "code": "630225", + "name": "循化撒拉族自治县", + "gjmc": "循化撒拉族自治县", + "udtwb": { + "chComTextMDS": "3031" + }, + "pathInfo": { + "path": "003000020006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b6e1-4d4b-ae55-e1c0c0728626", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b6e1-4d4b-ae55-e1c0c0728626", + "navParaentId_Code": "630200", + "navParaentId_Name": "海东市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3031", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d477-4746-bf3c-985fb787e11c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8d86-4ba0-9036-4095a5ad807f", + "version": null, + "code": "630224", + "name": "化隆回族自治县", + "gjmc": "化隆回族自治县", + "udtwb": { + "chComTextMDS": "3030" + }, + "pathInfo": { + "path": "003000020005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b6e1-4d4b-ae55-e1c0c0728626", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b6e1-4d4b-ae55-e1c0c0728626", + "navParaentId_Code": "630200", + "navParaentId_Name": "海东市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3030", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8d86-4ba0-9036-4095a5ad807f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-95b0-4d7d-bfab-53afecf0cf6f", + "version": null, + "code": "630223", + "name": "互助土族自治县", + "gjmc": "互助土族自治县", + "udtwb": { + "chComTextMDS": "3029" + }, + "pathInfo": { + "path": "003000020004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b6e1-4d4b-ae55-e1c0c0728626", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b6e1-4d4b-ae55-e1c0c0728626", + "navParaentId_Code": "630200", + "navParaentId_Name": "海东市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3029", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-95b0-4d7d-bfab-53afecf0cf6f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-76f9-47c8-862f-a448e634e78a", + "version": null, + "code": "630222", + "name": "民和回族土族自治县", + "gjmc": "民和回族土族自治县", + "udtwb": { + "chComTextMDS": "3028" + }, + "pathInfo": { + "path": "003000020003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b6e1-4d4b-ae55-e1c0c0728626", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b6e1-4d4b-ae55-e1c0c0728626", + "navParaentId_Code": "630200", + "navParaentId_Name": "海东市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3028", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-76f9-47c8-862f-a448e634e78a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b6c0-4d0f-9321-c40f8fa840b5", + "version": null, + "code": "630203", + "name": "平安区", + "gjmc": "平安区", + "udtwb": { + "chComTextMDS": "3027" + }, + "pathInfo": { + "path": "003000020002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b6e1-4d4b-ae55-e1c0c0728626", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b6e1-4d4b-ae55-e1c0c0728626", + "navParaentId_Code": "630200", + "navParaentId_Name": "海东市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3027", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b6c0-4d0f-9321-c40f8fa840b5", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b0dd-48cc-a2ce-9f77729eefb0", + "version": null, + "code": "630202", + "name": "乐都区", + "gjmc": "乐都区", + "udtwb": { + "chComTextMDS": "3026" + }, + "pathInfo": { + "path": "003000020001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b6e1-4d4b-ae55-e1c0c0728626", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b6e1-4d4b-ae55-e1c0c0728626", + "navParaentId_Code": "630200", + "navParaentId_Name": "海东市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3026", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b0dd-48cc-a2ce-9f77729eefb0", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b6e1-4d4b-ae55-e1c0c0728626", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-23d3-4d47-9537-08e4aa177da0", + "version": null, + "code": "630100", + "name": "西宁市", + "gjmc": "西宁市", + "udtwb": { + "chComTextMDS": "3017" + }, + "pathInfo": { + "path": "00300001", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ea88-417e-9a7b-880433eb6941", + "sequence": 1, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ea88-417e-9a7b-880433eb6941", + "navParaentId_Code": "630000", + "navParaentId_Name": "青海省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3017", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-50b2-4e19-81ad-7e27237790d9", + "version": null, + "code": "630123", + "name": "湟源县", + "gjmc": "湟源县", + "udtwb": { + "chComTextMDS": "3024" + }, + "pathInfo": { + "path": "003000010007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-23d3-4d47-9537-08e4aa177da0", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-23d3-4d47-9537-08e4aa177da0", + "navParaentId_Code": "630100", + "navParaentId_Name": "西宁市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3024", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-50b2-4e19-81ad-7e27237790d9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6838-4c56-a014-d6410c12394f", + "version": null, + "code": "630122", + "name": "湟中县", + "gjmc": "湟中县", + "udtwb": { + "chComTextMDS": "3023" + }, + "pathInfo": { + "path": "003000010006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-23d3-4d47-9537-08e4aa177da0", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-23d3-4d47-9537-08e4aa177da0", + "navParaentId_Code": "630100", + "navParaentId_Name": "西宁市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3023", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6838-4c56-a014-d6410c12394f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-dd3e-4425-a9b9-8432d3c488bb", + "version": null, + "code": "630121", + "name": "大通回族土族自治县", + "gjmc": "大通回族土族自治县", + "udtwb": { + "chComTextMDS": "3022" + }, + "pathInfo": { + "path": "003000010005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-23d3-4d47-9537-08e4aa177da0", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-23d3-4d47-9537-08e4aa177da0", + "navParaentId_Code": "630100", + "navParaentId_Name": "西宁市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3022", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-dd3e-4425-a9b9-8432d3c488bb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e8e5-4d2a-b1ac-e17801785053", + "version": null, + "code": "630105", + "name": "城北区", + "gjmc": "城北区", + "udtwb": { + "chComTextMDS": "3021" + }, + "pathInfo": { + "path": "003000010004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-23d3-4d47-9537-08e4aa177da0", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-23d3-4d47-9537-08e4aa177da0", + "navParaentId_Code": "630100", + "navParaentId_Name": "西宁市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3021", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e8e5-4d2a-b1ac-e17801785053", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c655-4f15-8e88-22953460dc8d", + "version": null, + "code": "630104", + "name": "城西区", + "gjmc": "城西区", + "udtwb": { + "chComTextMDS": "3020" + }, + "pathInfo": { + "path": "003000010003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-23d3-4d47-9537-08e4aa177da0", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-23d3-4d47-9537-08e4aa177da0", + "navParaentId_Code": "630100", + "navParaentId_Name": "西宁市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3020", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c655-4f15-8e88-22953460dc8d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c134-4b7b-a2f2-777327324115", + "version": null, + "code": "630103", + "name": "城中区", + "gjmc": "城中区", + "udtwb": { + "chComTextMDS": "3019" + }, + "pathInfo": { + "path": "003000010002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-23d3-4d47-9537-08e4aa177da0", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-23d3-4d47-9537-08e4aa177da0", + "navParaentId_Code": "630100", + "navParaentId_Name": "西宁市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3019", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c134-4b7b-a2f2-777327324115", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4425-4e40-8ff4-4f58900801ab", + "version": null, + "code": "630102", + "name": "城东区", + "gjmc": "城东区", + "udtwb": { + "chComTextMDS": "3018" + }, + "pathInfo": { + "path": "003000010001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-23d3-4d47-9537-08e4aa177da0", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-23d3-4d47-9537-08e4aa177da0", + "navParaentId_Code": "630100", + "navParaentId_Name": "西宁市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3018", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4425-4e40-8ff4-4f58900801ab", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-23d3-4d47-9537-08e4aa177da0", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ea88-417e-9a7b-880433eb6941", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "version": null, + "code": "620000", + "name": "甘肃省", + "gjmc": "甘肃省", + "udtwb": { + "chComTextMDS": "2915" + }, + "pathInfo": { + "path": "0029", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 29, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2915", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "version": null, + "code": "623000", + "name": "甘南藏族自治州", + "gjmc": "甘南藏族自治州", + "udtwb": { + "chComTextMDS": "3007" + }, + "pathInfo": { + "path": "00290014", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "sequence": 14, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-919f-4921-80c3-49db632fc7c5", + "navParaentId_Code": "620000", + "navParaentId_Name": "甘肃省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3007", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-2d4f-4698-99dc-a5c05c2b3e21", + "version": null, + "code": "623027", + "name": "夏河县", + "gjmc": "夏河县", + "udtwb": { + "chComTextMDS": "3015" + }, + "pathInfo": { + "path": "002900140008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "navParaentId_Code": "623000", + "navParaentId_Name": "甘南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3015", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2d4f-4698-99dc-a5c05c2b3e21", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8d1e-49ce-a3b0-f5e686eccbc8", + "version": null, + "code": "623026", + "name": "碌曲县", + "gjmc": "碌曲县", + "udtwb": { + "chComTextMDS": "3014" + }, + "pathInfo": { + "path": "002900140007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "navParaentId_Code": "623000", + "navParaentId_Name": "甘南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3014", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8d1e-49ce-a3b0-f5e686eccbc8", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6c8b-4314-9f24-334aeb948879", + "version": null, + "code": "623025", + "name": "玛曲县", + "gjmc": "玛曲县", + "udtwb": { + "chComTextMDS": "3013" + }, + "pathInfo": { + "path": "002900140006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "navParaentId_Code": "623000", + "navParaentId_Name": "甘南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3013", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6c8b-4314-9f24-334aeb948879", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7d1a-4e72-a934-b33fbb295dfb", + "version": null, + "code": "623024", + "name": "迭部县", + "gjmc": "迭部县", + "udtwb": { + "chComTextMDS": "3012" + }, + "pathInfo": { + "path": "002900140005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "navParaentId_Code": "623000", + "navParaentId_Name": "甘南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3012", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7d1a-4e72-a934-b33fbb295dfb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-fd00-4589-a7ae-9d250b420f41", + "version": null, + "code": "623023", + "name": "舟曲县", + "gjmc": "舟曲县", + "udtwb": { + "chComTextMDS": "3011" + }, + "pathInfo": { + "path": "002900140004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "navParaentId_Code": "623000", + "navParaentId_Name": "甘南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3011", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fd00-4589-a7ae-9d250b420f41", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c38b-497a-a4bd-2e6d200dabd0", + "version": null, + "code": "623022", + "name": "卓尼县", + "gjmc": "卓尼县", + "udtwb": { + "chComTextMDS": "3010" + }, + "pathInfo": { + "path": "002900140003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "navParaentId_Code": "623000", + "navParaentId_Name": "甘南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3010", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c38b-497a-a4bd-2e6d200dabd0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bc85-49ce-b362-71b7533e6b46", + "version": null, + "code": "623021", + "name": "临潭县", + "gjmc": "临潭县", + "udtwb": { + "chComTextMDS": "3009" + }, + "pathInfo": { + "path": "002900140002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "navParaentId_Code": "623000", + "navParaentId_Name": "甘南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3009", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bc85-49ce-b362-71b7533e6b46", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-005d-4a9c-a234-e95d10329101", + "version": null, + "code": "623001", + "name": "合作市", + "gjmc": "合作市", + "udtwb": { + "chComTextMDS": "3008" + }, + "pathInfo": { + "path": "002900140001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "navParaentId_Code": "623000", + "navParaentId_Name": "甘南藏族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3008", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-005d-4a9c-a234-e95d10329101", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d863-4fe4-99ad-b1f13f64b0ff", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9a37-4058-9c51-378e261cf9dd", + "version": null, + "code": "622900", + "name": "临夏回族自治州", + "gjmc": "临夏回族自治州", + "udtwb": { + "chComTextMDS": "2998" + }, + "pathInfo": { + "path": "00290013", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "sequence": 13, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-919f-4921-80c3-49db632fc7c5", + "navParaentId_Code": "620000", + "navParaentId_Name": "甘肃省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2998", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-cb2a-4af0-b50c-721910246ba3", + "version": null, + "code": "622927", + "name": "积石山保安族东乡族撒拉族自治县", + "gjmc": "积石山保安族东乡族撒拉族自治县", + "udtwb": { + "chComTextMDS": "3006" + }, + "pathInfo": { + "path": "002900130008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9a37-4058-9c51-378e261cf9dd", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9a37-4058-9c51-378e261cf9dd", + "navParaentId_Code": "622900", + "navParaentId_Name": "临夏回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3006", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-cb2a-4af0-b50c-721910246ba3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b1ab-47ec-8216-d01f06311c1b", + "version": null, + "code": "622926", + "name": "东乡族自治县", + "gjmc": "东乡族自治县", + "udtwb": { + "chComTextMDS": "3005" + }, + "pathInfo": { + "path": "002900130007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9a37-4058-9c51-378e261cf9dd", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9a37-4058-9c51-378e261cf9dd", + "navParaentId_Code": "622900", + "navParaentId_Name": "临夏回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3005", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b1ab-47ec-8216-d01f06311c1b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7681-4b69-bcc5-2045db1535d5", + "version": null, + "code": "622925", + "name": "和政县", + "gjmc": "和政县", + "udtwb": { + "chComTextMDS": "3004" + }, + "pathInfo": { + "path": "002900130006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9a37-4058-9c51-378e261cf9dd", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9a37-4058-9c51-378e261cf9dd", + "navParaentId_Code": "622900", + "navParaentId_Name": "临夏回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3004", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7681-4b69-bcc5-2045db1535d5", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8ce9-42e3-8565-495c821aa225", + "version": null, + "code": "622924", + "name": "广河县", + "gjmc": "广河县", + "udtwb": { + "chComTextMDS": "3003" + }, + "pathInfo": { + "path": "002900130005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9a37-4058-9c51-378e261cf9dd", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9a37-4058-9c51-378e261cf9dd", + "navParaentId_Code": "622900", + "navParaentId_Name": "临夏回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3003", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8ce9-42e3-8565-495c821aa225", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-12c9-4bfc-ac60-e3a863f1d5df", + "version": null, + "code": "622923", + "name": "永靖县", + "gjmc": "永靖县", + "udtwb": { + "chComTextMDS": "3002" + }, + "pathInfo": { + "path": "002900130004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9a37-4058-9c51-378e261cf9dd", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9a37-4058-9c51-378e261cf9dd", + "navParaentId_Code": "622900", + "navParaentId_Name": "临夏回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3002", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-12c9-4bfc-ac60-e3a863f1d5df", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-77f1-4634-bfe5-7e8642947abb", + "version": null, + "code": "622922", + "name": "康乐县", + "gjmc": "康乐县", + "udtwb": { + "chComTextMDS": "3001" + }, + "pathInfo": { + "path": "002900130003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9a37-4058-9c51-378e261cf9dd", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9a37-4058-9c51-378e261cf9dd", + "navParaentId_Code": "622900", + "navParaentId_Name": "临夏回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3001", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-77f1-4634-bfe5-7e8642947abb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f671-472a-a437-8ab56ba5db92", + "version": null, + "code": "622921", + "name": "临夏县", + "gjmc": "临夏县", + "udtwb": { + "chComTextMDS": "3000" + }, + "pathInfo": { + "path": "002900130002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9a37-4058-9c51-378e261cf9dd", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9a37-4058-9c51-378e261cf9dd", + "navParaentId_Code": "622900", + "navParaentId_Name": "临夏回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "3000", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f671-472a-a437-8ab56ba5db92", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f5d4-46d2-a1ea-257ff4dc33c6", + "version": null, + "code": "622901", + "name": "临夏市", + "gjmc": "临夏市", + "udtwb": { + "chComTextMDS": "2999" + }, + "pathInfo": { + "path": "002900130001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9a37-4058-9c51-378e261cf9dd", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9a37-4058-9c51-378e261cf9dd", + "navParaentId_Code": "622900", + "navParaentId_Name": "临夏回族自治州" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2999", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f5d4-46d2-a1ea-257ff4dc33c6", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9a37-4058-9c51-378e261cf9dd", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b1e5-42e7-a122-feedab37d20c", + "version": null, + "code": "621200", + "name": "陇南市", + "gjmc": "陇南市", + "udtwb": { + "chComTextMDS": "2988" + }, + "pathInfo": { + "path": "00290012", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "sequence": 12, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-919f-4921-80c3-49db632fc7c5", + "navParaentId_Code": "620000", + "navParaentId_Name": "甘肃省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2988", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-538c-4064-9e88-ae04b8a6a9cb", + "version": null, + "code": "621228", + "name": "两当县", + "gjmc": "两当县", + "udtwb": { + "chComTextMDS": "2997" + }, + "pathInfo": { + "path": "002900120009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b1e5-42e7-a122-feedab37d20c", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b1e5-42e7-a122-feedab37d20c", + "navParaentId_Code": "621200", + "navParaentId_Name": "陇南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2997", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-538c-4064-9e88-ae04b8a6a9cb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3d03-42b2-83d2-ddaeab774394", + "version": null, + "code": "621227", + "name": "徽县", + "gjmc": "徽县", + "udtwb": { + "chComTextMDS": "2996" + }, + "pathInfo": { + "path": "002900120008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b1e5-42e7-a122-feedab37d20c", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b1e5-42e7-a122-feedab37d20c", + "navParaentId_Code": "621200", + "navParaentId_Name": "陇南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2996", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3d03-42b2-83d2-ddaeab774394", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0884-4325-bef3-535abc0d284c", + "version": null, + "code": "621226", + "name": "礼县", + "gjmc": "礼县", + "udtwb": { + "chComTextMDS": "2995" + }, + "pathInfo": { + "path": "002900120007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b1e5-42e7-a122-feedab37d20c", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b1e5-42e7-a122-feedab37d20c", + "navParaentId_Code": "621200", + "navParaentId_Name": "陇南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2995", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0884-4325-bef3-535abc0d284c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c889-4fd0-9a92-6b193d3f19eb", + "version": null, + "code": "621225", + "name": "西和县", + "gjmc": "西和县", + "udtwb": { + "chComTextMDS": "2994" + }, + "pathInfo": { + "path": "002900120006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b1e5-42e7-a122-feedab37d20c", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b1e5-42e7-a122-feedab37d20c", + "navParaentId_Code": "621200", + "navParaentId_Name": "陇南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2994", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c889-4fd0-9a92-6b193d3f19eb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e6e3-4006-84b9-ce5fd15486e3", + "version": null, + "code": "621224", + "name": "康县", + "gjmc": "康县", + "udtwb": { + "chComTextMDS": "2993" + }, + "pathInfo": { + "path": "002900120005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b1e5-42e7-a122-feedab37d20c", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b1e5-42e7-a122-feedab37d20c", + "navParaentId_Code": "621200", + "navParaentId_Name": "陇南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2993", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e6e3-4006-84b9-ce5fd15486e3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f382-454e-bfe3-bc9a19857613", + "version": null, + "code": "621223", + "name": "宕昌县", + "gjmc": "宕昌县", + "udtwb": { + "chComTextMDS": "2992" + }, + "pathInfo": { + "path": "002900120004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b1e5-42e7-a122-feedab37d20c", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b1e5-42e7-a122-feedab37d20c", + "navParaentId_Code": "621200", + "navParaentId_Name": "陇南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2992", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f382-454e-bfe3-bc9a19857613", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-496f-437e-be6b-4c62a207dc39", + "version": null, + "code": "621222", + "name": "文县", + "gjmc": "文县", + "udtwb": { + "chComTextMDS": "2991" + }, + "pathInfo": { + "path": "002900120003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b1e5-42e7-a122-feedab37d20c", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b1e5-42e7-a122-feedab37d20c", + "navParaentId_Code": "621200", + "navParaentId_Name": "陇南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2991", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-496f-437e-be6b-4c62a207dc39", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0834-4aea-87eb-3ae0060280a4", + "version": null, + "code": "621221", + "name": "成县", + "gjmc": "成县", + "udtwb": { + "chComTextMDS": "2990" + }, + "pathInfo": { + "path": "002900120002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b1e5-42e7-a122-feedab37d20c", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b1e5-42e7-a122-feedab37d20c", + "navParaentId_Code": "621200", + "navParaentId_Name": "陇南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2990", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0834-4aea-87eb-3ae0060280a4", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-dfcc-46c8-b007-4ca7f8a618d7", + "version": null, + "code": "621202", + "name": "武都区", + "gjmc": "武都区", + "udtwb": { + "chComTextMDS": "2989" + }, + "pathInfo": { + "path": "002900120001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b1e5-42e7-a122-feedab37d20c", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b1e5-42e7-a122-feedab37d20c", + "navParaentId_Code": "621200", + "navParaentId_Name": "陇南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2989", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-dfcc-46c8-b007-4ca7f8a618d7", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b1e5-42e7-a122-feedab37d20c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "version": null, + "code": "621100", + "name": "定西市", + "gjmc": "定西市", + "udtwb": { + "chComTextMDS": "2980" + }, + "pathInfo": { + "path": "00290011", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "sequence": 11, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-919f-4921-80c3-49db632fc7c5", + "navParaentId_Code": "620000", + "navParaentId_Name": "甘肃省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2980", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-9574-45ce-8f4d-882e8203b53b", + "version": null, + "code": "621126", + "name": "岷县", + "gjmc": "岷县", + "udtwb": { + "chComTextMDS": "2987" + }, + "pathInfo": { + "path": "002900110007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "navParaentId_Code": "621100", + "navParaentId_Name": "定西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2987", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9574-45ce-8f4d-882e8203b53b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bdc5-45e5-880b-4f799774744f", + "version": null, + "code": "621125", + "name": "漳县", + "gjmc": "漳县", + "udtwb": { + "chComTextMDS": "2986" + }, + "pathInfo": { + "path": "002900110006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "navParaentId_Code": "621100", + "navParaentId_Name": "定西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2986", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bdc5-45e5-880b-4f799774744f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-54a7-46b6-8b93-556a1b7d976b", + "version": null, + "code": "621124", + "name": "临洮县", + "gjmc": "临洮县", + "udtwb": { + "chComTextMDS": "2985" + }, + "pathInfo": { + "path": "002900110005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "navParaentId_Code": "621100", + "navParaentId_Name": "定西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2985", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-54a7-46b6-8b93-556a1b7d976b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-48e1-4afc-980a-220bc1cbaa7b", + "version": null, + "code": "621123", + "name": "渭源县", + "gjmc": "渭源县", + "udtwb": { + "chComTextMDS": "2984" + }, + "pathInfo": { + "path": "002900110004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "navParaentId_Code": "621100", + "navParaentId_Name": "定西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2984", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-48e1-4afc-980a-220bc1cbaa7b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-57f9-453a-809c-bb19b3efeae4", + "version": null, + "code": "621122", + "name": "陇西县", + "gjmc": "陇西县", + "udtwb": { + "chComTextMDS": "2983" + }, + "pathInfo": { + "path": "002900110003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "navParaentId_Code": "621100", + "navParaentId_Name": "定西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2983", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-57f9-453a-809c-bb19b3efeae4", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-17d7-4be7-9689-3adfb61d809b", + "version": null, + "code": "621121", + "name": "通渭县", + "gjmc": "通渭县", + "udtwb": { + "chComTextMDS": "2982" + }, + "pathInfo": { + "path": "002900110002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "navParaentId_Code": "621100", + "navParaentId_Name": "定西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2982", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-17d7-4be7-9689-3adfb61d809b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1042-4b82-9041-7fe6faf473ea", + "version": null, + "code": "621102", + "name": "安定区", + "gjmc": "安定区", + "udtwb": { + "chComTextMDS": "2981" + }, + "pathInfo": { + "path": "002900110001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "navParaentId_Code": "621100", + "navParaentId_Name": "定西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2981", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1042-4b82-9041-7fe6faf473ea", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7c48-42fa-90ae-eaebac4b186c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-df8f-4045-ac98-485b7f543ff3", + "version": null, + "code": "621000", + "name": "庆阳市", + "gjmc": "庆阳市", + "udtwb": { + "chComTextMDS": "2971" + }, + "pathInfo": { + "path": "00290010", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "sequence": 10, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-919f-4921-80c3-49db632fc7c5", + "navParaentId_Code": "620000", + "navParaentId_Name": "甘肃省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2971", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-394b-44af-8004-487beca79206", + "version": null, + "code": "621027", + "name": "镇原县", + "gjmc": "镇原县", + "udtwb": { + "chComTextMDS": "2979" + }, + "pathInfo": { + "path": "002900100008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-df8f-4045-ac98-485b7f543ff3", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-df8f-4045-ac98-485b7f543ff3", + "navParaentId_Code": "621000", + "navParaentId_Name": "庆阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2979", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-394b-44af-8004-487beca79206", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-053a-44ce-946b-1b250e710e60", + "version": null, + "code": "621026", + "name": "宁县", + "gjmc": "宁县", + "udtwb": { + "chComTextMDS": "2978" + }, + "pathInfo": { + "path": "002900100007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-df8f-4045-ac98-485b7f543ff3", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-df8f-4045-ac98-485b7f543ff3", + "navParaentId_Code": "621000", + "navParaentId_Name": "庆阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2978", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-053a-44ce-946b-1b250e710e60", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3de8-481f-9f6c-d81e73c96111", + "version": null, + "code": "621025", + "name": "正宁县", + "gjmc": "正宁县", + "udtwb": { + "chComTextMDS": "2977" + }, + "pathInfo": { + "path": "002900100006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-df8f-4045-ac98-485b7f543ff3", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-df8f-4045-ac98-485b7f543ff3", + "navParaentId_Code": "621000", + "navParaentId_Name": "庆阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2977", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3de8-481f-9f6c-d81e73c96111", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-085e-4216-8e97-a6aa4eda6ef5", + "version": null, + "code": "621024", + "name": "合水县", + "gjmc": "合水县", + "udtwb": { + "chComTextMDS": "2976" + }, + "pathInfo": { + "path": "002900100005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-df8f-4045-ac98-485b7f543ff3", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-df8f-4045-ac98-485b7f543ff3", + "navParaentId_Code": "621000", + "navParaentId_Name": "庆阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2976", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-085e-4216-8e97-a6aa4eda6ef5", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5dc8-4c23-9756-4b6d98bea1a9", + "version": null, + "code": "621023", + "name": "华池县", + "gjmc": "华池县", + "udtwb": { + "chComTextMDS": "2975" + }, + "pathInfo": { + "path": "002900100004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-df8f-4045-ac98-485b7f543ff3", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-df8f-4045-ac98-485b7f543ff3", + "navParaentId_Code": "621000", + "navParaentId_Name": "庆阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2975", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5dc8-4c23-9756-4b6d98bea1a9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8f47-4863-a1f1-b4d4d5ecd389", + "version": null, + "code": "621022", + "name": "环县", + "gjmc": "环县", + "udtwb": { + "chComTextMDS": "2974" + }, + "pathInfo": { + "path": "002900100003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-df8f-4045-ac98-485b7f543ff3", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-df8f-4045-ac98-485b7f543ff3", + "navParaentId_Code": "621000", + "navParaentId_Name": "庆阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2974", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8f47-4863-a1f1-b4d4d5ecd389", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1082-4057-bbfa-a4b37a1cf1e4", + "version": null, + "code": "621021", + "name": "庆城县", + "gjmc": "庆城县", + "udtwb": { + "chComTextMDS": "2973" + }, + "pathInfo": { + "path": "002900100002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-df8f-4045-ac98-485b7f543ff3", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-df8f-4045-ac98-485b7f543ff3", + "navParaentId_Code": "621000", + "navParaentId_Name": "庆阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2973", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1082-4057-bbfa-a4b37a1cf1e4", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0ce6-4744-8d33-fed4973baa60", + "version": null, + "code": "621002", + "name": "西峰区", + "gjmc": "西峰区", + "udtwb": { + "chComTextMDS": "2972" + }, + "pathInfo": { + "path": "002900100001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-df8f-4045-ac98-485b7f543ff3", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-df8f-4045-ac98-485b7f543ff3", + "navParaentId_Code": "621000", + "navParaentId_Name": "庆阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2972", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0ce6-4744-8d33-fed4973baa60", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-df8f-4045-ac98-485b7f543ff3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "version": null, + "code": "620900", + "name": "酒泉市", + "gjmc": "酒泉市", + "udtwb": { + "chComTextMDS": "2963" + }, + "pathInfo": { + "path": "00290009", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "sequence": 9, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-919f-4921-80c3-49db632fc7c5", + "navParaentId_Code": "620000", + "navParaentId_Name": "甘肃省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2963", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-0a92-4f79-b2ef-3675441ec596", + "version": null, + "code": "620982", + "name": "敦煌市", + "gjmc": "敦煌市", + "udtwb": { + "chComTextMDS": "2970" + }, + "pathInfo": { + "path": "002900090007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "navParaentId_Code": "620900", + "navParaentId_Name": "酒泉市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2970", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0a92-4f79-b2ef-3675441ec596", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-096b-40bd-9ddf-2d298e2dec60", + "version": null, + "code": "620981", + "name": "玉门市", + "gjmc": "玉门市", + "udtwb": { + "chComTextMDS": "2969" + }, + "pathInfo": { + "path": "002900090006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "navParaentId_Code": "620900", + "navParaentId_Name": "酒泉市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2969", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-096b-40bd-9ddf-2d298e2dec60", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d834-4927-9885-1038a2313b7e", + "version": null, + "code": "620924", + "name": "阿克塞哈萨克族自治县", + "gjmc": "阿克塞哈萨克族自治县", + "udtwb": { + "chComTextMDS": "2968" + }, + "pathInfo": { + "path": "002900090005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "navParaentId_Code": "620900", + "navParaentId_Name": "酒泉市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2968", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d834-4927-9885-1038a2313b7e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b841-4846-990a-6c2098a62f36", + "version": null, + "code": "620923", + "name": "肃北蒙古族自治县", + "gjmc": "肃北蒙古族自治县", + "udtwb": { + "chComTextMDS": "2967" + }, + "pathInfo": { + "path": "002900090004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "navParaentId_Code": "620900", + "navParaentId_Name": "酒泉市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2967", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b841-4846-990a-6c2098a62f36", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c432-4835-a57e-05f47acc6999", + "version": null, + "code": "620922", + "name": "瓜州县", + "gjmc": "瓜州县", + "udtwb": { + "chComTextMDS": "2966" + }, + "pathInfo": { + "path": "002900090003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "navParaentId_Code": "620900", + "navParaentId_Name": "酒泉市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2966", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c432-4835-a57e-05f47acc6999", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9856-4823-aaae-7cba277a92ba", + "version": null, + "code": "620921", + "name": "金塔县", + "gjmc": "金塔县", + "udtwb": { + "chComTextMDS": "2965" + }, + "pathInfo": { + "path": "002900090002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "navParaentId_Code": "620900", + "navParaentId_Name": "酒泉市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2965", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9856-4823-aaae-7cba277a92ba", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-cfdc-4d6c-aa58-5fd319340f22", + "version": null, + "code": "620902", + "name": "肃州区", + "gjmc": "肃州区", + "udtwb": { + "chComTextMDS": "2964" + }, + "pathInfo": { + "path": "002900090001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "navParaentId_Code": "620900", + "navParaentId_Name": "酒泉市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2964", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-cfdc-4d6c-aa58-5fd319340f22", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bad5-4c46-9f5f-52fd7ce17755", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "version": null, + "code": "620800", + "name": "平凉市", + "gjmc": "平凉市", + "udtwb": { + "chComTextMDS": "2955" + }, + "pathInfo": { + "path": "00290008", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "sequence": 8, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-919f-4921-80c3-49db632fc7c5", + "navParaentId_Code": "620000", + "navParaentId_Name": "甘肃省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2955", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-2ecf-42f1-8c65-beb3de168d7d", + "version": null, + "code": "620826", + "name": "静宁县", + "gjmc": "静宁县", + "udtwb": { + "chComTextMDS": "2962" + }, + "pathInfo": { + "path": "002900080007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "navParaentId_Code": "620800", + "navParaentId_Name": "平凉市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2962", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2ecf-42f1-8c65-beb3de168d7d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-64da-4854-9157-00b41e1755c1", + "version": null, + "code": "620825", + "name": "庄浪县", + "gjmc": "庄浪县", + "udtwb": { + "chComTextMDS": "2961" + }, + "pathInfo": { + "path": "002900080006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "navParaentId_Code": "620800", + "navParaentId_Name": "平凉市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2961", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-64da-4854-9157-00b41e1755c1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4e49-4ee7-a6a2-02c0f6032194", + "version": null, + "code": "620824", + "name": "华亭县", + "gjmc": "华亭县", + "udtwb": { + "chComTextMDS": "2960" + }, + "pathInfo": { + "path": "002900080005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "navParaentId_Code": "620800", + "navParaentId_Name": "平凉市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2960", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4e49-4ee7-a6a2-02c0f6032194", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bf56-417e-a37f-4d4b3065233d", + "version": null, + "code": "620823", + "name": "崇信县", + "gjmc": "崇信县", + "udtwb": { + "chComTextMDS": "2959" + }, + "pathInfo": { + "path": "002900080004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "navParaentId_Code": "620800", + "navParaentId_Name": "平凉市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2959", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bf56-417e-a37f-4d4b3065233d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ab35-48bd-b39f-3014990b00b5", + "version": null, + "code": "620822", + "name": "灵台县", + "gjmc": "灵台县", + "udtwb": { + "chComTextMDS": "2958" + }, + "pathInfo": { + "path": "002900080003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "navParaentId_Code": "620800", + "navParaentId_Name": "平凉市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2958", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ab35-48bd-b39f-3014990b00b5", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-435d-4c37-8575-1969376d7864", + "version": null, + "code": "620821", + "name": "泾川县", + "gjmc": "泾川县", + "udtwb": { + "chComTextMDS": "2957" + }, + "pathInfo": { + "path": "002900080002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "navParaentId_Code": "620800", + "navParaentId_Name": "平凉市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2957", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-435d-4c37-8575-1969376d7864", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c340-411c-a3f4-69e3b9c0661a", + "version": null, + "code": "620802", + "name": "崆峒区", + "gjmc": "崆峒区", + "udtwb": { + "chComTextMDS": "2956" + }, + "pathInfo": { + "path": "002900080001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "navParaentId_Code": "620800", + "navParaentId_Name": "平凉市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2956", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c340-411c-a3f4-69e3b9c0661a", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-341d-4e37-9f8f-eea537c0b71c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-65dc-4080-a065-e4dbc5cfb724", + "version": null, + "code": "620700", + "name": "张掖市", + "gjmc": "张掖市", + "udtwb": { + "chComTextMDS": "2948" + }, + "pathInfo": { + "path": "00290007", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "sequence": 7, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-919f-4921-80c3-49db632fc7c5", + "navParaentId_Code": "620000", + "navParaentId_Name": "甘肃省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2948", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-4c4a-4d5a-8e96-5917aeac06d6", + "version": null, + "code": "620725", + "name": "山丹县", + "gjmc": "山丹县", + "udtwb": { + "chComTextMDS": "2954" + }, + "pathInfo": { + "path": "002900070006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-65dc-4080-a065-e4dbc5cfb724", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-65dc-4080-a065-e4dbc5cfb724", + "navParaentId_Code": "620700", + "navParaentId_Name": "张掖市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2954", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4c4a-4d5a-8e96-5917aeac06d6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2f94-420d-8ed7-39244a5fbaa0", + "version": null, + "code": "620724", + "name": "高台县", + "gjmc": "高台县", + "udtwb": { + "chComTextMDS": "2953" + }, + "pathInfo": { + "path": "002900070005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-65dc-4080-a065-e4dbc5cfb724", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-65dc-4080-a065-e4dbc5cfb724", + "navParaentId_Code": "620700", + "navParaentId_Name": "张掖市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2953", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2f94-420d-8ed7-39244a5fbaa0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c7dc-4c60-8009-e8a768504509", + "version": null, + "code": "620723", + "name": "临泽县", + "gjmc": "临泽县", + "udtwb": { + "chComTextMDS": "2952" + }, + "pathInfo": { + "path": "002900070004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-65dc-4080-a065-e4dbc5cfb724", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-65dc-4080-a065-e4dbc5cfb724", + "navParaentId_Code": "620700", + "navParaentId_Name": "张掖市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2952", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c7dc-4c60-8009-e8a768504509", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e0c8-4653-a285-57e65442edda", + "version": null, + "code": "620722", + "name": "民乐县", + "gjmc": "民乐县", + "udtwb": { + "chComTextMDS": "2951" + }, + "pathInfo": { + "path": "002900070003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-65dc-4080-a065-e4dbc5cfb724", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-65dc-4080-a065-e4dbc5cfb724", + "navParaentId_Code": "620700", + "navParaentId_Name": "张掖市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2951", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e0c8-4653-a285-57e65442edda", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-75f9-44d9-ab79-a70753b60250", + "version": null, + "code": "620721", + "name": "肃南裕固族自治县", + "gjmc": "肃南裕固族自治县", + "udtwb": { + "chComTextMDS": "2950" + }, + "pathInfo": { + "path": "002900070002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-65dc-4080-a065-e4dbc5cfb724", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-65dc-4080-a065-e4dbc5cfb724", + "navParaentId_Code": "620700", + "navParaentId_Name": "张掖市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2950", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-75f9-44d9-ab79-a70753b60250", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2b2f-4fb9-a71b-7ba083d67670", + "version": null, + "code": "620702", + "name": "甘州区", + "gjmc": "甘州区", + "udtwb": { + "chComTextMDS": "2949" + }, + "pathInfo": { + "path": "002900070001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-65dc-4080-a065-e4dbc5cfb724", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-65dc-4080-a065-e4dbc5cfb724", + "navParaentId_Code": "620700", + "navParaentId_Name": "张掖市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2949", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2b2f-4fb9-a71b-7ba083d67670", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-65dc-4080-a065-e4dbc5cfb724", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-01f6-4405-88d4-1a078312cc12", + "version": null, + "code": "620600", + "name": "武威市", + "gjmc": "武威市", + "udtwb": { + "chComTextMDS": "2943" + }, + "pathInfo": { + "path": "00290006", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "sequence": 6, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-919f-4921-80c3-49db632fc7c5", + "navParaentId_Code": "620000", + "navParaentId_Name": "甘肃省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2943", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-d590-4492-942e-a500057b9fb1", + "version": null, + "code": "620623", + "name": "天祝藏族自治县", + "gjmc": "天祝藏族自治县", + "udtwb": { + "chComTextMDS": "2947" + }, + "pathInfo": { + "path": "002900060004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-01f6-4405-88d4-1a078312cc12", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-01f6-4405-88d4-1a078312cc12", + "navParaentId_Code": "620600", + "navParaentId_Name": "武威市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2947", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d590-4492-942e-a500057b9fb1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ec1d-46be-93dc-6657b9e36d61", + "version": null, + "code": "620622", + "name": "古浪县", + "gjmc": "古浪县", + "udtwb": { + "chComTextMDS": "2946" + }, + "pathInfo": { + "path": "002900060003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-01f6-4405-88d4-1a078312cc12", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-01f6-4405-88d4-1a078312cc12", + "navParaentId_Code": "620600", + "navParaentId_Name": "武威市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2946", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ec1d-46be-93dc-6657b9e36d61", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-51ec-4e32-b8f5-5a98b736f3fb", + "version": null, + "code": "620621", + "name": "民勤县", + "gjmc": "民勤县", + "udtwb": { + "chComTextMDS": "2945" + }, + "pathInfo": { + "path": "002900060002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-01f6-4405-88d4-1a078312cc12", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-01f6-4405-88d4-1a078312cc12", + "navParaentId_Code": "620600", + "navParaentId_Name": "武威市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2945", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-51ec-4e32-b8f5-5a98b736f3fb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5d23-45f0-85f0-64a1842e74f5", + "version": null, + "code": "620602", + "name": "凉州区", + "gjmc": "凉州区", + "udtwb": { + "chComTextMDS": "2944" + }, + "pathInfo": { + "path": "002900060001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-01f6-4405-88d4-1a078312cc12", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-01f6-4405-88d4-1a078312cc12", + "navParaentId_Code": "620600", + "navParaentId_Name": "武威市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2944", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5d23-45f0-85f0-64a1842e74f5", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-01f6-4405-88d4-1a078312cc12", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-03f9-4bac-a920-6defaaa5145c", + "version": null, + "code": "620500", + "name": "天水市", + "gjmc": "天水市", + "udtwb": { + "chComTextMDS": "2935" + }, + "pathInfo": { + "path": "00290005", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "sequence": 5, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-919f-4921-80c3-49db632fc7c5", + "navParaentId_Code": "620000", + "navParaentId_Name": "甘肃省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2935", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-2614-4c08-b899-c07c38e9b1b7", + "version": null, + "code": "620525", + "name": "张家川回族自治县", + "gjmc": "张家川回族自治县", + "udtwb": { + "chComTextMDS": "2942" + }, + "pathInfo": { + "path": "002900050007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-03f9-4bac-a920-6defaaa5145c", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-03f9-4bac-a920-6defaaa5145c", + "navParaentId_Code": "620500", + "navParaentId_Name": "天水市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2942", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2614-4c08-b899-c07c38e9b1b7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7fc4-4d46-ba51-e97840011dce", + "version": null, + "code": "620524", + "name": "武山县", + "gjmc": "武山县", + "udtwb": { + "chComTextMDS": "2941" + }, + "pathInfo": { + "path": "002900050006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-03f9-4bac-a920-6defaaa5145c", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-03f9-4bac-a920-6defaaa5145c", + "navParaentId_Code": "620500", + "navParaentId_Name": "天水市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2941", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7fc4-4d46-ba51-e97840011dce", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a5a3-4691-b7e0-b00c3020354e", + "version": null, + "code": "620523", + "name": "甘谷县", + "gjmc": "甘谷县", + "udtwb": { + "chComTextMDS": "2940" + }, + "pathInfo": { + "path": "002900050005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-03f9-4bac-a920-6defaaa5145c", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-03f9-4bac-a920-6defaaa5145c", + "navParaentId_Code": "620500", + "navParaentId_Name": "天水市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2940", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a5a3-4691-b7e0-b00c3020354e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9013-4916-81d5-db8d4833bda2", + "version": null, + "code": "620522", + "name": "秦安县", + "gjmc": "秦安县", + "udtwb": { + "chComTextMDS": "2939" + }, + "pathInfo": { + "path": "002900050004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-03f9-4bac-a920-6defaaa5145c", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-03f9-4bac-a920-6defaaa5145c", + "navParaentId_Code": "620500", + "navParaentId_Name": "天水市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2939", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9013-4916-81d5-db8d4833bda2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3f4c-4438-b138-2d0f227795cb", + "version": null, + "code": "620521", + "name": "清水县", + "gjmc": "清水县", + "udtwb": { + "chComTextMDS": "2938" + }, + "pathInfo": { + "path": "002900050003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-03f9-4bac-a920-6defaaa5145c", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-03f9-4bac-a920-6defaaa5145c", + "navParaentId_Code": "620500", + "navParaentId_Name": "天水市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2938", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3f4c-4438-b138-2d0f227795cb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f68b-4de9-baa4-4c0c70ca2a65", + "version": null, + "code": "620503", + "name": "麦积区", + "gjmc": "麦积区", + "udtwb": { + "chComTextMDS": "2937" + }, + "pathInfo": { + "path": "002900050002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-03f9-4bac-a920-6defaaa5145c", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-03f9-4bac-a920-6defaaa5145c", + "navParaentId_Code": "620500", + "navParaentId_Name": "天水市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2937", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f68b-4de9-baa4-4c0c70ca2a65", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4d3b-4aa3-a4d4-83e5c38f9a05", + "version": null, + "code": "620502", + "name": "秦州区", + "gjmc": "秦州区", + "udtwb": { + "chComTextMDS": "2936" + }, + "pathInfo": { + "path": "002900050001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-03f9-4bac-a920-6defaaa5145c", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-03f9-4bac-a920-6defaaa5145c", + "navParaentId_Code": "620500", + "navParaentId_Name": "天水市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2936", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4d3b-4aa3-a4d4-83e5c38f9a05", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-03f9-4bac-a920-6defaaa5145c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f32c-475c-b279-9a18218aad89", + "version": null, + "code": "620400", + "name": "白银市", + "gjmc": "白银市", + "udtwb": { + "chComTextMDS": "2929" + }, + "pathInfo": { + "path": "00290004", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "sequence": 4, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-919f-4921-80c3-49db632fc7c5", + "navParaentId_Code": "620000", + "navParaentId_Name": "甘肃省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2929", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-a1f2-4190-b2fb-0e98a0ebaa38", + "version": null, + "code": "620423", + "name": "景泰县", + "gjmc": "景泰县", + "udtwb": { + "chComTextMDS": "2934" + }, + "pathInfo": { + "path": "002900040005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f32c-475c-b279-9a18218aad89", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f32c-475c-b279-9a18218aad89", + "navParaentId_Code": "620400", + "navParaentId_Name": "白银市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2934", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a1f2-4190-b2fb-0e98a0ebaa38", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-68f0-497e-9fb0-77eae996d9fb", + "version": null, + "code": "620422", + "name": "会宁县", + "gjmc": "会宁县", + "udtwb": { + "chComTextMDS": "2933" + }, + "pathInfo": { + "path": "002900040004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f32c-475c-b279-9a18218aad89", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f32c-475c-b279-9a18218aad89", + "navParaentId_Code": "620400", + "navParaentId_Name": "白银市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2933", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-68f0-497e-9fb0-77eae996d9fb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7fad-496d-a47c-00c50ffcc948", + "version": null, + "code": "620421", + "name": "靖远县", + "gjmc": "靖远县", + "udtwb": { + "chComTextMDS": "2932" + }, + "pathInfo": { + "path": "002900040003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f32c-475c-b279-9a18218aad89", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f32c-475c-b279-9a18218aad89", + "navParaentId_Code": "620400", + "navParaentId_Name": "白银市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2932", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7fad-496d-a47c-00c50ffcc948", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-cdb9-47bf-9c42-efbd4682f82c", + "version": null, + "code": "620403", + "name": "平川区", + "gjmc": "平川区", + "udtwb": { + "chComTextMDS": "2931" + }, + "pathInfo": { + "path": "002900040002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f32c-475c-b279-9a18218aad89", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f32c-475c-b279-9a18218aad89", + "navParaentId_Code": "620400", + "navParaentId_Name": "白银市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2931", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-cdb9-47bf-9c42-efbd4682f82c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7e02-4f47-91c9-e3b1ac76027b", + "version": null, + "code": "620402", + "name": "白银区", + "gjmc": "白银区", + "udtwb": { + "chComTextMDS": "2930" + }, + "pathInfo": { + "path": "002900040001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f32c-475c-b279-9a18218aad89", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f32c-475c-b279-9a18218aad89", + "navParaentId_Code": "620400", + "navParaentId_Name": "白银市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2930", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7e02-4f47-91c9-e3b1ac76027b", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f32c-475c-b279-9a18218aad89", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-95e6-4199-96b7-ec6aeef23b3a", + "version": null, + "code": "620300", + "name": "金昌市", + "gjmc": "金昌市", + "udtwb": { + "chComTextMDS": "2926" + }, + "pathInfo": { + "path": "00290003", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "sequence": 3, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-919f-4921-80c3-49db632fc7c5", + "navParaentId_Code": "620000", + "navParaentId_Name": "甘肃省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2926", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-de4e-4fc9-b4dc-d900a9442a84", + "version": null, + "code": "620321", + "name": "永昌县", + "gjmc": "永昌县", + "udtwb": { + "chComTextMDS": "2928" + }, + "pathInfo": { + "path": "002900030002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-95e6-4199-96b7-ec6aeef23b3a", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-95e6-4199-96b7-ec6aeef23b3a", + "navParaentId_Code": "620300", + "navParaentId_Name": "金昌市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2928", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-de4e-4fc9-b4dc-d900a9442a84", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-eb7c-4512-b128-5d6fe372a101", + "version": null, + "code": "620302", + "name": "金川区", + "gjmc": "金川区", + "udtwb": { + "chComTextMDS": "2927" + }, + "pathInfo": { + "path": "002900030001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-95e6-4199-96b7-ec6aeef23b3a", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-95e6-4199-96b7-ec6aeef23b3a", + "navParaentId_Code": "620300", + "navParaentId_Name": "金昌市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2927", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-eb7c-4512-b128-5d6fe372a101", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-95e6-4199-96b7-ec6aeef23b3a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d73d-46b0-9725-2181a01bf3f6", + "version": null, + "code": "620200", + "name": "嘉峪关市", + "gjmc": "嘉峪关市", + "udtwb": { + "chComTextMDS": "2925" + }, + "pathInfo": { + "path": "00290002", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "sequence": 2, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-919f-4921-80c3-49db632fc7c5", + "navParaentId_Code": "620000", + "navParaentId_Name": "甘肃省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2925", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d73d-46b0-9725-2181a01bf3f6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-08b3-44f6-bd24-304a046443e7", + "version": null, + "code": "620100", + "name": "兰州市", + "gjmc": "兰州市", + "udtwb": { + "chComTextMDS": "2916" + }, + "pathInfo": { + "path": "00290001", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "sequence": 1, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-919f-4921-80c3-49db632fc7c5", + "navParaentId_Code": "620000", + "navParaentId_Name": "甘肃省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2916", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-3bab-4aa1-8d13-a04c53102b2a", + "version": null, + "code": "620123", + "name": "榆中县", + "gjmc": "榆中县", + "udtwb": { + "chComTextMDS": "2924" + }, + "pathInfo": { + "path": "002900010008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-08b3-44f6-bd24-304a046443e7", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-08b3-44f6-bd24-304a046443e7", + "navParaentId_Code": "620100", + "navParaentId_Name": "兰州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2924", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3bab-4aa1-8d13-a04c53102b2a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0ab4-471f-9dae-ee8ee7034dc0", + "version": null, + "code": "620122", + "name": "皋兰县", + "gjmc": "皋兰县", + "udtwb": { + "chComTextMDS": "2923" + }, + "pathInfo": { + "path": "002900010007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-08b3-44f6-bd24-304a046443e7", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-08b3-44f6-bd24-304a046443e7", + "navParaentId_Code": "620100", + "navParaentId_Name": "兰州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2923", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0ab4-471f-9dae-ee8ee7034dc0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f77f-41e8-897d-ddce3b6c787e", + "version": null, + "code": "620121", + "name": "永登县", + "gjmc": "永登县", + "udtwb": { + "chComTextMDS": "2922" + }, + "pathInfo": { + "path": "002900010006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-08b3-44f6-bd24-304a046443e7", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-08b3-44f6-bd24-304a046443e7", + "navParaentId_Code": "620100", + "navParaentId_Name": "兰州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2922", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f77f-41e8-897d-ddce3b6c787e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4678-4217-a8df-df7a40ad47d9", + "version": null, + "code": "620111", + "name": "红古区", + "gjmc": "红古区", + "udtwb": { + "chComTextMDS": "2921" + }, + "pathInfo": { + "path": "002900010005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-08b3-44f6-bd24-304a046443e7", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-08b3-44f6-bd24-304a046443e7", + "navParaentId_Code": "620100", + "navParaentId_Name": "兰州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2921", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4678-4217-a8df-df7a40ad47d9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9e71-4fcb-8aa9-e1479ded78cb", + "version": null, + "code": "620105", + "name": "安宁区", + "gjmc": "安宁区", + "udtwb": { + "chComTextMDS": "2920" + }, + "pathInfo": { + "path": "002900010004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-08b3-44f6-bd24-304a046443e7", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-08b3-44f6-bd24-304a046443e7", + "navParaentId_Code": "620100", + "navParaentId_Name": "兰州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2920", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9e71-4fcb-8aa9-e1479ded78cb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-52dc-443c-904b-c6d5c97fc4ab", + "version": null, + "code": "620104", + "name": "西固区", + "gjmc": "西固区", + "udtwb": { + "chComTextMDS": "2919" + }, + "pathInfo": { + "path": "002900010003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-08b3-44f6-bd24-304a046443e7", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-08b3-44f6-bd24-304a046443e7", + "navParaentId_Code": "620100", + "navParaentId_Name": "兰州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2919", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-52dc-443c-904b-c6d5c97fc4ab", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e54a-4a93-8a82-bafba0c78036", + "version": null, + "code": "620103", + "name": "七里河区", + "gjmc": "七里河区", + "udtwb": { + "chComTextMDS": "2918" + }, + "pathInfo": { + "path": "002900010002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-08b3-44f6-bd24-304a046443e7", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-08b3-44f6-bd24-304a046443e7", + "navParaentId_Code": "620100", + "navParaentId_Name": "兰州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2918", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e54a-4a93-8a82-bafba0c78036", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bd69-44fd-b793-a9b7784ae877", + "version": null, + "code": "620102", + "name": "城关区", + "gjmc": "城关区", + "udtwb": { + "chComTextMDS": "2917" + }, + "pathInfo": { + "path": "002900010001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-08b3-44f6-bd24-304a046443e7", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-08b3-44f6-bd24-304a046443e7", + "navParaentId_Code": "620100", + "navParaentId_Name": "兰州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2917", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bd69-44fd-b793-a9b7784ae877", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-08b3-44f6-bd24-304a046443e7", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-919f-4921-80c3-49db632fc7c5", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "version": null, + "code": "610000", + "name": "陕西省", + "gjmc": "陕西省", + "udtwb": { + "chComTextMDS": "2797" + }, + "pathInfo": { + "path": "0028", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 28, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2797", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "version": null, + "code": "611000", + "name": "商洛市", + "gjmc": "商洛市", + "udtwb": { + "chComTextMDS": "2907" + }, + "pathInfo": { + "path": "00280010", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "sequence": 10, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "navParaentId_Code": "610000", + "navParaentId_Name": "陕西省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2907", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-24ce-4f04-abd6-73c048a5d577", + "version": null, + "code": "611026", + "name": "柞水县", + "gjmc": "柞水县", + "udtwb": { + "chComTextMDS": "2914" + }, + "pathInfo": { + "path": "002800100007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "navParaentId_Code": "611000", + "navParaentId_Name": "商洛市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2914", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-24ce-4f04-abd6-73c048a5d577", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d6d0-4dfd-8641-f78d43841280", + "version": null, + "code": "611025", + "name": "镇安县", + "gjmc": "镇安县", + "udtwb": { + "chComTextMDS": "2913" + }, + "pathInfo": { + "path": "002800100006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "navParaentId_Code": "611000", + "navParaentId_Name": "商洛市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2913", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d6d0-4dfd-8641-f78d43841280", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-474f-4640-b9ad-2e76647bc880", + "version": null, + "code": "611024", + "name": "山阳县", + "gjmc": "山阳县", + "udtwb": { + "chComTextMDS": "2912" + }, + "pathInfo": { + "path": "002800100005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "navParaentId_Code": "611000", + "navParaentId_Name": "商洛市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2912", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-474f-4640-b9ad-2e76647bc880", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3ec1-4d30-99c1-ce0682221da1", + "version": null, + "code": "611023", + "name": "商南县", + "gjmc": "商南县", + "udtwb": { + "chComTextMDS": "2911" + }, + "pathInfo": { + "path": "002800100004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "navParaentId_Code": "611000", + "navParaentId_Name": "商洛市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2911", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3ec1-4d30-99c1-ce0682221da1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-534d-4746-9f69-9561edd3c8ca", + "version": null, + "code": "611022", + "name": "丹凤县", + "gjmc": "丹凤县", + "udtwb": { + "chComTextMDS": "2910" + }, + "pathInfo": { + "path": "002800100003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "navParaentId_Code": "611000", + "navParaentId_Name": "商洛市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2910", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-534d-4746-9f69-9561edd3c8ca", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-09c2-4400-8c35-ec7cded6e80e", + "version": null, + "code": "611021", + "name": "洛南县", + "gjmc": "洛南县", + "udtwb": { + "chComTextMDS": "2909" + }, + "pathInfo": { + "path": "002800100002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "navParaentId_Code": "611000", + "navParaentId_Name": "商洛市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2909", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-09c2-4400-8c35-ec7cded6e80e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-da23-4f77-a78e-60b17652129c", + "version": null, + "code": "611002", + "name": "商州区", + "gjmc": "商州区", + "udtwb": { + "chComTextMDS": "2908" + }, + "pathInfo": { + "path": "002800100001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "navParaentId_Code": "611000", + "navParaentId_Name": "商洛市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2908", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-da23-4f77-a78e-60b17652129c", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0bf0-46c9-a8bf-187a73bbef0a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "version": null, + "code": "610900", + "name": "安康市", + "gjmc": "安康市", + "udtwb": { + "chComTextMDS": "2896" + }, + "pathInfo": { + "path": "00280009", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "sequence": 9, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "navParaentId_Code": "610000", + "navParaentId_Name": "陕西省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2896", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-de03-45b0-b37e-3aa4bbb93f52", + "version": null, + "code": "610929", + "name": "白河县", + "gjmc": "白河县", + "udtwb": { + "chComTextMDS": "2906" + }, + "pathInfo": { + "path": "002800090010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "navParaentId_Code": "610900", + "navParaentId_Name": "安康市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2906", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-de03-45b0-b37e-3aa4bbb93f52", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4b33-418f-9420-63cefbbbf569", + "version": null, + "code": "610928", + "name": "旬阳县", + "gjmc": "旬阳县", + "udtwb": { + "chComTextMDS": "2905" + }, + "pathInfo": { + "path": "002800090009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "navParaentId_Code": "610900", + "navParaentId_Name": "安康市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2905", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4b33-418f-9420-63cefbbbf569", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d8f9-42d6-9f93-17f822813d3e", + "version": null, + "code": "610927", + "name": "镇坪县", + "gjmc": "镇坪县", + "udtwb": { + "chComTextMDS": "2904" + }, + "pathInfo": { + "path": "002800090008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "navParaentId_Code": "610900", + "navParaentId_Name": "安康市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2904", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d8f9-42d6-9f93-17f822813d3e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6a83-4239-a7b6-7b4a6daf5553", + "version": null, + "code": "610926", + "name": "平利县", + "gjmc": "平利县", + "udtwb": { + "chComTextMDS": "2903" + }, + "pathInfo": { + "path": "002800090007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "navParaentId_Code": "610900", + "navParaentId_Name": "安康市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2903", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6a83-4239-a7b6-7b4a6daf5553", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7105-4c35-8b58-ad10296e37a4", + "version": null, + "code": "610925", + "name": "岚皋县", + "gjmc": "岚皋县", + "udtwb": { + "chComTextMDS": "2902" + }, + "pathInfo": { + "path": "002800090006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "navParaentId_Code": "610900", + "navParaentId_Name": "安康市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2902", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7105-4c35-8b58-ad10296e37a4", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-16f5-4ed6-a366-035f09919780", + "version": null, + "code": "610924", + "name": "紫阳县", + "gjmc": "紫阳县", + "udtwb": { + "chComTextMDS": "2901" + }, + "pathInfo": { + "path": "002800090005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "navParaentId_Code": "610900", + "navParaentId_Name": "安康市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2901", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-16f5-4ed6-a366-035f09919780", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0a3e-4bc5-bd6f-13b3c833dcaa", + "version": null, + "code": "610923", + "name": "宁陕县", + "gjmc": "宁陕县", + "udtwb": { + "chComTextMDS": "2900" + }, + "pathInfo": { + "path": "002800090004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "navParaentId_Code": "610900", + "navParaentId_Name": "安康市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2900", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0a3e-4bc5-bd6f-13b3c833dcaa", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-67ac-4252-b292-ac3961d48872", + "version": null, + "code": "610922", + "name": "石泉县", + "gjmc": "石泉县", + "udtwb": { + "chComTextMDS": "2899" + }, + "pathInfo": { + "path": "002800090003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "navParaentId_Code": "610900", + "navParaentId_Name": "安康市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2899", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-67ac-4252-b292-ac3961d48872", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-85e9-476a-96b0-41080fffcb78", + "version": null, + "code": "610921", + "name": "汉阴县", + "gjmc": "汉阴县", + "udtwb": { + "chComTextMDS": "2898" + }, + "pathInfo": { + "path": "002800090002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "navParaentId_Code": "610900", + "navParaentId_Name": "安康市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2898", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-85e9-476a-96b0-41080fffcb78", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d26d-4296-bdd8-cfa433a7da62", + "version": null, + "code": "610902", + "name": "汉滨区", + "gjmc": "汉滨区", + "udtwb": { + "chComTextMDS": "2897" + }, + "pathInfo": { + "path": "002800090001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "navParaentId_Code": "610900", + "navParaentId_Name": "安康市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2897", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d26d-4296-bdd8-cfa433a7da62", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7d1a-4887-96b5-1be01a7aa234", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "version": null, + "code": "610800", + "name": "榆林市", + "gjmc": "榆林市", + "udtwb": { + "chComTextMDS": "2883" + }, + "pathInfo": { + "path": "00280008", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "sequence": 8, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "navParaentId_Code": "610000", + "navParaentId_Name": "陕西省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2883", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-f201-496d-b695-c491ac51d536", + "version": null, + "code": "610881", + "name": "神木市", + "gjmc": "神木市", + "udtwb": { + "chComTextMDS": "2895" + }, + "pathInfo": { + "path": "002800080012", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "sequence": 12, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "navParaentId_Code": "610800", + "navParaentId_Name": "榆林市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2895", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f201-496d-b695-c491ac51d536", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-edea-47b8-948e-4e6292c52f73", + "version": null, + "code": "610831", + "name": "子洲县", + "gjmc": "子洲县", + "udtwb": { + "chComTextMDS": "2894" + }, + "pathInfo": { + "path": "002800080011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "navParaentId_Code": "610800", + "navParaentId_Name": "榆林市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2894", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-edea-47b8-948e-4e6292c52f73", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1f55-43df-a825-107d23240878", + "version": null, + "code": "610830", + "name": "清涧县", + "gjmc": "清涧县", + "udtwb": { + "chComTextMDS": "2893" + }, + "pathInfo": { + "path": "002800080010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "navParaentId_Code": "610800", + "navParaentId_Name": "榆林市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2893", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1f55-43df-a825-107d23240878", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2658-4a3e-a32c-e386bb46c023", + "version": null, + "code": "610829", + "name": "吴堡县", + "gjmc": "吴堡县", + "udtwb": { + "chComTextMDS": "2892" + }, + "pathInfo": { + "path": "002800080009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "navParaentId_Code": "610800", + "navParaentId_Name": "榆林市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2892", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2658-4a3e-a32c-e386bb46c023", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-fa1f-4ea5-8412-da1bc175495e", + "version": null, + "code": "610828", + "name": "佳县", + "gjmc": "佳县", + "udtwb": { + "chComTextMDS": "2891" + }, + "pathInfo": { + "path": "002800080008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "navParaentId_Code": "610800", + "navParaentId_Name": "榆林市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2891", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fa1f-4ea5-8412-da1bc175495e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5bb4-4ac4-91e9-58bbcad1df75", + "version": null, + "code": "610827", + "name": "米脂县", + "gjmc": "米脂县", + "udtwb": { + "chComTextMDS": "2890" + }, + "pathInfo": { + "path": "002800080007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "navParaentId_Code": "610800", + "navParaentId_Name": "榆林市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2890", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5bb4-4ac4-91e9-58bbcad1df75", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-389e-4a59-adb3-493e73aeab06", + "version": null, + "code": "610826", + "name": "绥德县", + "gjmc": "绥德县", + "udtwb": { + "chComTextMDS": "2889" + }, + "pathInfo": { + "path": "002800080006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "navParaentId_Code": "610800", + "navParaentId_Name": "榆林市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2889", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-389e-4a59-adb3-493e73aeab06", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b98b-4811-b7b3-4044350045bd", + "version": null, + "code": "610825", + "name": "定边县", + "gjmc": "定边县", + "udtwb": { + "chComTextMDS": "2888" + }, + "pathInfo": { + "path": "002800080005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "navParaentId_Code": "610800", + "navParaentId_Name": "榆林市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2888", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b98b-4811-b7b3-4044350045bd", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d07b-437d-850a-07a9d940c2fa", + "version": null, + "code": "610824", + "name": "靖边县", + "gjmc": "靖边县", + "udtwb": { + "chComTextMDS": "2887" + }, + "pathInfo": { + "path": "002800080004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "navParaentId_Code": "610800", + "navParaentId_Name": "榆林市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2887", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d07b-437d-850a-07a9d940c2fa", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f0a9-499e-a3a3-115c7519111e", + "version": null, + "code": "610822", + "name": "府谷县", + "gjmc": "府谷县", + "udtwb": { + "chComTextMDS": "2886" + }, + "pathInfo": { + "path": "002800080003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "navParaentId_Code": "610800", + "navParaentId_Name": "榆林市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2886", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f0a9-499e-a3a3-115c7519111e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-24af-45cd-b7c8-de09a7ba4b6c", + "version": null, + "code": "610803", + "name": "横山区", + "gjmc": "横山区", + "udtwb": { + "chComTextMDS": "2885" + }, + "pathInfo": { + "path": "002800080002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "navParaentId_Code": "610800", + "navParaentId_Name": "榆林市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2885", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-24af-45cd-b7c8-de09a7ba4b6c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-80b4-4f5f-9b82-e71a113f9570", + "version": null, + "code": "610802", + "name": "榆阳区", + "gjmc": "榆阳区", + "udtwb": { + "chComTextMDS": "2884" + }, + "pathInfo": { + "path": "002800080001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "navParaentId_Code": "610800", + "navParaentId_Name": "榆林市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2884", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-80b4-4f5f-9b82-e71a113f9570", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2d9e-4c2a-8992-6824d484ba99", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-eb63-4aee-89f3-393b766b36dd", + "version": null, + "code": "610700", + "name": "汉中市", + "gjmc": "汉中市", + "udtwb": { + "chComTextMDS": "2871" + }, + "pathInfo": { + "path": "00280007", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "sequence": 7, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "navParaentId_Code": "610000", + "navParaentId_Name": "陕西省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2871", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-ff7a-42f3-8330-855826635d3a", + "version": null, + "code": "610730", + "name": "佛坪县", + "gjmc": "佛坪县", + "udtwb": { + "chComTextMDS": "2882" + }, + "pathInfo": { + "path": "002800070011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb63-4aee-89f3-393b766b36dd", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb63-4aee-89f3-393b766b36dd", + "navParaentId_Code": "610700", + "navParaentId_Name": "汉中市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2882", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ff7a-42f3-8330-855826635d3a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-08d7-45f4-aaa6-e2e1787a4ee6", + "version": null, + "code": "610729", + "name": "留坝县", + "gjmc": "留坝县", + "udtwb": { + "chComTextMDS": "2881" + }, + "pathInfo": { + "path": "002800070010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb63-4aee-89f3-393b766b36dd", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb63-4aee-89f3-393b766b36dd", + "navParaentId_Code": "610700", + "navParaentId_Name": "汉中市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2881", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-08d7-45f4-aaa6-e2e1787a4ee6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-be90-4bfc-b39a-3939f4a7fd95", + "version": null, + "code": "610728", + "name": "镇巴县", + "gjmc": "镇巴县", + "udtwb": { + "chComTextMDS": "2880" + }, + "pathInfo": { + "path": "002800070009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb63-4aee-89f3-393b766b36dd", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb63-4aee-89f3-393b766b36dd", + "navParaentId_Code": "610700", + "navParaentId_Name": "汉中市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2880", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-be90-4bfc-b39a-3939f4a7fd95", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-19f9-4940-9dbd-51b84632cff0", + "version": null, + "code": "610727", + "name": "略阳县", + "gjmc": "略阳县", + "udtwb": { + "chComTextMDS": "2879" + }, + "pathInfo": { + "path": "002800070008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb63-4aee-89f3-393b766b36dd", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb63-4aee-89f3-393b766b36dd", + "navParaentId_Code": "610700", + "navParaentId_Name": "汉中市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2879", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-19f9-4940-9dbd-51b84632cff0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e6e7-4e85-a9f4-1a3790b23c4e", + "version": null, + "code": "610726", + "name": "宁强县", + "gjmc": "宁强县", + "udtwb": { + "chComTextMDS": "2878" + }, + "pathInfo": { + "path": "002800070007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb63-4aee-89f3-393b766b36dd", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb63-4aee-89f3-393b766b36dd", + "navParaentId_Code": "610700", + "navParaentId_Name": "汉中市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2878", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e6e7-4e85-a9f4-1a3790b23c4e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9c41-40da-8082-4512189140f6", + "version": null, + "code": "610725", + "name": "勉县", + "gjmc": "勉县", + "udtwb": { + "chComTextMDS": "2877" + }, + "pathInfo": { + "path": "002800070006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb63-4aee-89f3-393b766b36dd", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb63-4aee-89f3-393b766b36dd", + "navParaentId_Code": "610700", + "navParaentId_Name": "汉中市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2877", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9c41-40da-8082-4512189140f6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-333c-4454-aae5-f41afa1feb4c", + "version": null, + "code": "610724", + "name": "西乡县", + "gjmc": "西乡县", + "udtwb": { + "chComTextMDS": "2876" + }, + "pathInfo": { + "path": "002800070005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb63-4aee-89f3-393b766b36dd", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb63-4aee-89f3-393b766b36dd", + "navParaentId_Code": "610700", + "navParaentId_Name": "汉中市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2876", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-333c-4454-aae5-f41afa1feb4c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-848d-45c3-9122-bfd6db561c05", + "version": null, + "code": "610723", + "name": "洋县", + "gjmc": "洋县", + "udtwb": { + "chComTextMDS": "2875" + }, + "pathInfo": { + "path": "002800070004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb63-4aee-89f3-393b766b36dd", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb63-4aee-89f3-393b766b36dd", + "navParaentId_Code": "610700", + "navParaentId_Name": "汉中市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2875", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-848d-45c3-9122-bfd6db561c05", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-99b4-4486-9f79-b20ccb9fe528", + "version": null, + "code": "610722", + "name": "城固县", + "gjmc": "城固县", + "udtwb": { + "chComTextMDS": "2874" + }, + "pathInfo": { + "path": "002800070003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb63-4aee-89f3-393b766b36dd", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb63-4aee-89f3-393b766b36dd", + "navParaentId_Code": "610700", + "navParaentId_Name": "汉中市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2874", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-99b4-4486-9f79-b20ccb9fe528", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b1ec-45ff-b53b-892cac444fb8", + "version": null, + "code": "610703", + "name": "南郑区", + "gjmc": "南郑区", + "udtwb": { + "chComTextMDS": "2873" + }, + "pathInfo": { + "path": "002800070002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb63-4aee-89f3-393b766b36dd", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb63-4aee-89f3-393b766b36dd", + "navParaentId_Code": "610700", + "navParaentId_Name": "汉中市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2873", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b1ec-45ff-b53b-892cac444fb8", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-55ac-46a5-8159-8bfcfb1850f7", + "version": null, + "code": "610702", + "name": "汉台区", + "gjmc": "汉台区", + "udtwb": { + "chComTextMDS": "2872" + }, + "pathInfo": { + "path": "002800070001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb63-4aee-89f3-393b766b36dd", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb63-4aee-89f3-393b766b36dd", + "navParaentId_Code": "610700", + "navParaentId_Name": "汉中市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2872", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-55ac-46a5-8159-8bfcfb1850f7", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-eb63-4aee-89f3-393b766b36dd", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "version": null, + "code": "610600", + "name": "延安市", + "gjmc": "延安市", + "udtwb": { + "chComTextMDS": "2857" + }, + "pathInfo": { + "path": "00280006", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "sequence": 6, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "navParaentId_Code": "610000", + "navParaentId_Name": "陕西省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2857", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-d528-45d2-9bfc-1e52a83b069a", + "version": null, + "code": "610632", + "name": "黄陵县", + "gjmc": "黄陵县", + "udtwb": { + "chComTextMDS": "2870" + }, + "pathInfo": { + "path": "002800060013", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "sequence": 13, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "navParaentId_Code": "610600", + "navParaentId_Name": "延安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2870", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d528-45d2-9bfc-1e52a83b069a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f7bd-4432-b591-a950ff46f150", + "version": null, + "code": "610631", + "name": "黄龙县", + "gjmc": "黄龙县", + "udtwb": { + "chComTextMDS": "2869" + }, + "pathInfo": { + "path": "002800060012", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "sequence": 12, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "navParaentId_Code": "610600", + "navParaentId_Name": "延安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2869", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f7bd-4432-b591-a950ff46f150", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0ca1-4fc9-a564-1dfab39ef11a", + "version": null, + "code": "610630", + "name": "宜川县", + "gjmc": "宜川县", + "udtwb": { + "chComTextMDS": "2868" + }, + "pathInfo": { + "path": "002800060011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "navParaentId_Code": "610600", + "navParaentId_Name": "延安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2868", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0ca1-4fc9-a564-1dfab39ef11a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8a12-434f-831f-2b18f1645bdb", + "version": null, + "code": "610629", + "name": "洛川县", + "gjmc": "洛川县", + "udtwb": { + "chComTextMDS": "2867" + }, + "pathInfo": { + "path": "002800060010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "navParaentId_Code": "610600", + "navParaentId_Name": "延安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2867", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8a12-434f-831f-2b18f1645bdb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-241e-4baf-ac54-083d9d8eb4c7", + "version": null, + "code": "610628", + "name": "富县", + "gjmc": "富县", + "udtwb": { + "chComTextMDS": "2866" + }, + "pathInfo": { + "path": "002800060009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "navParaentId_Code": "610600", + "navParaentId_Name": "延安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2866", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-241e-4baf-ac54-083d9d8eb4c7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4f39-4f10-828b-9cc46ae65405", + "version": null, + "code": "610627", + "name": "甘泉县", + "gjmc": "甘泉县", + "udtwb": { + "chComTextMDS": "2865" + }, + "pathInfo": { + "path": "002800060008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "navParaentId_Code": "610600", + "navParaentId_Name": "延安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2865", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4f39-4f10-828b-9cc46ae65405", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7d8d-4532-b16c-7f4615d30215", + "version": null, + "code": "610626", + "name": "吴起县", + "gjmc": "吴起县", + "udtwb": { + "chComTextMDS": "2864" + }, + "pathInfo": { + "path": "002800060007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "navParaentId_Code": "610600", + "navParaentId_Name": "延安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2864", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7d8d-4532-b16c-7f4615d30215", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b34e-49a8-9211-8656c0d59a77", + "version": null, + "code": "610625", + "name": "志丹县", + "gjmc": "志丹县", + "udtwb": { + "chComTextMDS": "2863" + }, + "pathInfo": { + "path": "002800060006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "navParaentId_Code": "610600", + "navParaentId_Name": "延安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2863", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b34e-49a8-9211-8656c0d59a77", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5b32-4191-a7de-6dba95aac008", + "version": null, + "code": "610623", + "name": "子长县", + "gjmc": "子长县", + "udtwb": { + "chComTextMDS": "2862" + }, + "pathInfo": { + "path": "002800060005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "navParaentId_Code": "610600", + "navParaentId_Name": "延安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2862", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5b32-4191-a7de-6dba95aac008", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b4b5-4124-9bfb-992d62b1bf00", + "version": null, + "code": "610622", + "name": "延川县", + "gjmc": "延川县", + "udtwb": { + "chComTextMDS": "2861" + }, + "pathInfo": { + "path": "002800060004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "navParaentId_Code": "610600", + "navParaentId_Name": "延安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2861", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b4b5-4124-9bfb-992d62b1bf00", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5cb4-4fbd-b4fd-630bc1b96ce7", + "version": null, + "code": "610621", + "name": "延长县", + "gjmc": "延长县", + "udtwb": { + "chComTextMDS": "2860" + }, + "pathInfo": { + "path": "002800060003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "navParaentId_Code": "610600", + "navParaentId_Name": "延安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2860", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5cb4-4fbd-b4fd-630bc1b96ce7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a7d3-4b0b-8aa6-de10a0e9b2b6", + "version": null, + "code": "610603", + "name": "安塞区", + "gjmc": "安塞区", + "udtwb": { + "chComTextMDS": "2859" + }, + "pathInfo": { + "path": "002800060002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "navParaentId_Code": "610600", + "navParaentId_Name": "延安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2859", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a7d3-4b0b-8aa6-de10a0e9b2b6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e822-409e-a017-51a8afb753f2", + "version": null, + "code": "610602", + "name": "宝塔区", + "gjmc": "宝塔区", + "udtwb": { + "chComTextMDS": "2858" + }, + "pathInfo": { + "path": "002800060001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "navParaentId_Code": "610600", + "navParaentId_Name": "延安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2858", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e822-409e-a017-51a8afb753f2", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c400-45d5-9b5b-ecc2fda3e642", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c4a8-454e-a874-624aeaced3da", + "version": null, + "code": "610500", + "name": "渭南市", + "gjmc": "渭南市", + "udtwb": { + "chComTextMDS": "2845" + }, + "pathInfo": { + "path": "00280005", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "sequence": 5, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "navParaentId_Code": "610000", + "navParaentId_Name": "陕西省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2845", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-92ab-41ae-841c-bba10fc8c5be", + "version": null, + "code": "610582", + "name": "华阴市", + "gjmc": "华阴市", + "udtwb": { + "chComTextMDS": "2856" + }, + "pathInfo": { + "path": "002800050011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c4a8-454e-a874-624aeaced3da", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c4a8-454e-a874-624aeaced3da", + "navParaentId_Code": "610500", + "navParaentId_Name": "渭南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2856", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-92ab-41ae-841c-bba10fc8c5be", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-42df-40c4-8c69-415e17950acb", + "version": null, + "code": "610581", + "name": "韩城市", + "gjmc": "韩城市", + "udtwb": { + "chComTextMDS": "2855" + }, + "pathInfo": { + "path": "002800050010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c4a8-454e-a874-624aeaced3da", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c4a8-454e-a874-624aeaced3da", + "navParaentId_Code": "610500", + "navParaentId_Name": "渭南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2855", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-42df-40c4-8c69-415e17950acb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8476-4138-8b9f-c92c81bdaccb", + "version": null, + "code": "610528", + "name": "富平县", + "gjmc": "富平县", + "udtwb": { + "chComTextMDS": "2854" + }, + "pathInfo": { + "path": "002800050009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c4a8-454e-a874-624aeaced3da", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c4a8-454e-a874-624aeaced3da", + "navParaentId_Code": "610500", + "navParaentId_Name": "渭南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2854", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8476-4138-8b9f-c92c81bdaccb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2771-40dc-bd67-8c7576d0ff99", + "version": null, + "code": "610527", + "name": "白水县", + "gjmc": "白水县", + "udtwb": { + "chComTextMDS": "2853" + }, + "pathInfo": { + "path": "002800050008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c4a8-454e-a874-624aeaced3da", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c4a8-454e-a874-624aeaced3da", + "navParaentId_Code": "610500", + "navParaentId_Name": "渭南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2853", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2771-40dc-bd67-8c7576d0ff99", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7bbb-4ccf-a504-bb4658671f91", + "version": null, + "code": "610526", + "name": "蒲城县", + "gjmc": "蒲城县", + "udtwb": { + "chComTextMDS": "2852" + }, + "pathInfo": { + "path": "002800050007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c4a8-454e-a874-624aeaced3da", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c4a8-454e-a874-624aeaced3da", + "navParaentId_Code": "610500", + "navParaentId_Name": "渭南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2852", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7bbb-4ccf-a504-bb4658671f91", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a988-45f2-b13e-0a0055d2a008", + "version": null, + "code": "610525", + "name": "澄城县", + "gjmc": "澄城县", + "udtwb": { + "chComTextMDS": "2851" + }, + "pathInfo": { + "path": "002800050006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c4a8-454e-a874-624aeaced3da", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c4a8-454e-a874-624aeaced3da", + "navParaentId_Code": "610500", + "navParaentId_Name": "渭南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2851", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a988-45f2-b13e-0a0055d2a008", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a564-4305-8f4b-708264f8ab4b", + "version": null, + "code": "610524", + "name": "合阳县", + "gjmc": "合阳县", + "udtwb": { + "chComTextMDS": "2850" + }, + "pathInfo": { + "path": "002800050005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c4a8-454e-a874-624aeaced3da", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c4a8-454e-a874-624aeaced3da", + "navParaentId_Code": "610500", + "navParaentId_Name": "渭南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2850", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a564-4305-8f4b-708264f8ab4b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f142-4409-b219-981dea5ce0a9", + "version": null, + "code": "610523", + "name": "大荔县", + "gjmc": "大荔县", + "udtwb": { + "chComTextMDS": "2849" + }, + "pathInfo": { + "path": "002800050004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c4a8-454e-a874-624aeaced3da", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c4a8-454e-a874-624aeaced3da", + "navParaentId_Code": "610500", + "navParaentId_Name": "渭南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2849", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f142-4409-b219-981dea5ce0a9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e6e1-42a6-86b7-cdc876e8d358", + "version": null, + "code": "610522", + "name": "潼关县", + "gjmc": "潼关县", + "udtwb": { + "chComTextMDS": "2848" + }, + "pathInfo": { + "path": "002800050003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c4a8-454e-a874-624aeaced3da", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c4a8-454e-a874-624aeaced3da", + "navParaentId_Code": "610500", + "navParaentId_Name": "渭南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2848", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e6e1-42a6-86b7-cdc876e8d358", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-35b5-48a6-b40e-f38a432806d0", + "version": null, + "code": "610503", + "name": "华州区", + "gjmc": "华州区", + "udtwb": { + "chComTextMDS": "2847" + }, + "pathInfo": { + "path": "002800050002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c4a8-454e-a874-624aeaced3da", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c4a8-454e-a874-624aeaced3da", + "navParaentId_Code": "610500", + "navParaentId_Name": "渭南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2847", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-35b5-48a6-b40e-f38a432806d0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4dae-42cc-8b26-7765eeef16bb", + "version": null, + "code": "610502", + "name": "临渭区", + "gjmc": "临渭区", + "udtwb": { + "chComTextMDS": "2846" + }, + "pathInfo": { + "path": "002800050001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c4a8-454e-a874-624aeaced3da", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c4a8-454e-a874-624aeaced3da", + "navParaentId_Code": "610500", + "navParaentId_Name": "渭南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2846", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4dae-42cc-8b26-7765eeef16bb", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c4a8-454e-a874-624aeaced3da", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "version": null, + "code": "610400", + "name": "咸阳市", + "gjmc": "咸阳市", + "udtwb": { + "chComTextMDS": "2830" + }, + "pathInfo": { + "path": "00280004", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "sequence": 4, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "navParaentId_Code": "610000", + "navParaentId_Name": "陕西省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2830", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-c029-41ad-a363-070dcf1f5849", + "version": null, + "code": "610482", + "name": "彬州市", + "gjmc": "彬州市", + "udtwb": { + "chComTextMDS": "2844" + }, + "pathInfo": { + "path": "002800040014", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "sequence": 14, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "navParaentId_Code": "610400", + "navParaentId_Name": "咸阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2844", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c029-41ad-a363-070dcf1f5849", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f366-4bdb-8a98-000ee1b7c2bc", + "version": null, + "code": "610481", + "name": "兴平市", + "gjmc": "兴平市", + "udtwb": { + "chComTextMDS": "2843" + }, + "pathInfo": { + "path": "002800040013", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "sequence": 13, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "navParaentId_Code": "610400", + "navParaentId_Name": "咸阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2843", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f366-4bdb-8a98-000ee1b7c2bc", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5465-4528-9077-8f876d0430b1", + "version": null, + "code": "610431", + "name": "武功县", + "gjmc": "武功县", + "udtwb": { + "chComTextMDS": "2842" + }, + "pathInfo": { + "path": "002800040012", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "sequence": 12, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "navParaentId_Code": "610400", + "navParaentId_Name": "咸阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2842", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5465-4528-9077-8f876d0430b1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c9c6-4302-b7f4-354b4c841d6b", + "version": null, + "code": "610430", + "name": "淳化县", + "gjmc": "淳化县", + "udtwb": { + "chComTextMDS": "2841" + }, + "pathInfo": { + "path": "002800040011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "navParaentId_Code": "610400", + "navParaentId_Name": "咸阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2841", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c9c6-4302-b7f4-354b4c841d6b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c9c1-410b-a9d2-5ed83244b316", + "version": null, + "code": "610429", + "name": "旬邑县", + "gjmc": "旬邑县", + "udtwb": { + "chComTextMDS": "2840" + }, + "pathInfo": { + "path": "002800040010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "navParaentId_Code": "610400", + "navParaentId_Name": "咸阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2840", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c9c1-410b-a9d2-5ed83244b316", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-92e0-4d87-8228-e033083562b4", + "version": null, + "code": "610428", + "name": "长武县", + "gjmc": "长武县", + "udtwb": { + "chComTextMDS": "2839" + }, + "pathInfo": { + "path": "002800040009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "navParaentId_Code": "610400", + "navParaentId_Name": "咸阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2839", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-92e0-4d87-8228-e033083562b4", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5c26-4939-abb3-4a96760c8472", + "version": null, + "code": "610426", + "name": "永寿县", + "gjmc": "永寿县", + "udtwb": { + "chComTextMDS": "2838" + }, + "pathInfo": { + "path": "002800040008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "navParaentId_Code": "610400", + "navParaentId_Name": "咸阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2838", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5c26-4939-abb3-4a96760c8472", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1351-49a7-b66a-1ef2df7084c8", + "version": null, + "code": "610425", + "name": "礼泉县", + "gjmc": "礼泉县", + "udtwb": { + "chComTextMDS": "2837" + }, + "pathInfo": { + "path": "002800040007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "navParaentId_Code": "610400", + "navParaentId_Name": "咸阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2837", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1351-49a7-b66a-1ef2df7084c8", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f518-44bf-8c93-228c32c5680f", + "version": null, + "code": "610424", + "name": "乾县", + "gjmc": "乾县", + "udtwb": { + "chComTextMDS": "2836" + }, + "pathInfo": { + "path": "002800040006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "navParaentId_Code": "610400", + "navParaentId_Name": "咸阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2836", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f518-44bf-8c93-228c32c5680f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1852-4f45-a275-7bbad7e2c5cc", + "version": null, + "code": "610423", + "name": "泾阳县", + "gjmc": "泾阳县", + "udtwb": { + "chComTextMDS": "2835" + }, + "pathInfo": { + "path": "002800040005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "navParaentId_Code": "610400", + "navParaentId_Name": "咸阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2835", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1852-4f45-a275-7bbad7e2c5cc", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-67cc-4cca-96a9-e686c648579c", + "version": null, + "code": "610422", + "name": "三原县", + "gjmc": "三原县", + "udtwb": { + "chComTextMDS": "2834" + }, + "pathInfo": { + "path": "002800040004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "navParaentId_Code": "610400", + "navParaentId_Name": "咸阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2834", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-67cc-4cca-96a9-e686c648579c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8dce-4232-a0ca-26055aca08e7", + "version": null, + "code": "610404", + "name": "渭城区", + "gjmc": "渭城区", + "udtwb": { + "chComTextMDS": "2833" + }, + "pathInfo": { + "path": "002800040003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "navParaentId_Code": "610400", + "navParaentId_Name": "咸阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2833", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8dce-4232-a0ca-26055aca08e7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-478f-47dc-9ba6-3e25a840da92", + "version": null, + "code": "610403", + "name": "杨陵区", + "gjmc": "杨陵区", + "udtwb": { + "chComTextMDS": "2832" + }, + "pathInfo": { + "path": "002800040002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "navParaentId_Code": "610400", + "navParaentId_Name": "咸阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2832", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-478f-47dc-9ba6-3e25a840da92", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-466f-4fcc-8b57-662b4a724438", + "version": null, + "code": "610402", + "name": "秦都区", + "gjmc": "秦都区", + "udtwb": { + "chComTextMDS": "2831" + }, + "pathInfo": { + "path": "002800040001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "navParaentId_Code": "610400", + "navParaentId_Name": "咸阳市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2831", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-466f-4fcc-8b57-662b4a724438", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5c8e-4824-9586-f7fd11c390a5", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "version": null, + "code": "610300", + "name": "宝鸡市", + "gjmc": "宝鸡市", + "udtwb": { + "chComTextMDS": "2817" + }, + "pathInfo": { + "path": "00280003", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "sequence": 3, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "navParaentId_Code": "610000", + "navParaentId_Name": "陕西省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2817", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-fbd2-4f35-9521-b03685e1d33e", + "version": null, + "code": "610331", + "name": "太白县", + "gjmc": "太白县", + "udtwb": { + "chComTextMDS": "2829" + }, + "pathInfo": { + "path": "002800030012", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "sequence": 12, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "navParaentId_Code": "610300", + "navParaentId_Name": "宝鸡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2829", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fbd2-4f35-9521-b03685e1d33e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-affe-48c1-ac9b-9a3e7c3b8cc3", + "version": null, + "code": "610330", + "name": "凤县", + "gjmc": "凤县", + "udtwb": { + "chComTextMDS": "2828" + }, + "pathInfo": { + "path": "002800030011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "navParaentId_Code": "610300", + "navParaentId_Name": "宝鸡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2828", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-affe-48c1-ac9b-9a3e7c3b8cc3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0355-45b9-8890-0d3c5e8ddc87", + "version": null, + "code": "610329", + "name": "麟游县", + "gjmc": "麟游县", + "udtwb": { + "chComTextMDS": "2827" + }, + "pathInfo": { + "path": "002800030010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "navParaentId_Code": "610300", + "navParaentId_Name": "宝鸡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2827", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0355-45b9-8890-0d3c5e8ddc87", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ab8a-4f6b-a254-6ae2567d9f73", + "version": null, + "code": "610328", + "name": "千阳县", + "gjmc": "千阳县", + "udtwb": { + "chComTextMDS": "2826" + }, + "pathInfo": { + "path": "002800030009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "navParaentId_Code": "610300", + "navParaentId_Name": "宝鸡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2826", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ab8a-4f6b-a254-6ae2567d9f73", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2d52-4357-ae48-f0349490fc8a", + "version": null, + "code": "610327", + "name": "陇县", + "gjmc": "陇县", + "udtwb": { + "chComTextMDS": "2825" + }, + "pathInfo": { + "path": "002800030008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "navParaentId_Code": "610300", + "navParaentId_Name": "宝鸡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2825", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2d52-4357-ae48-f0349490fc8a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8d04-4982-a52d-78afc363755e", + "version": null, + "code": "610326", + "name": "眉县", + "gjmc": "眉县", + "udtwb": { + "chComTextMDS": "2824" + }, + "pathInfo": { + "path": "002800030007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "navParaentId_Code": "610300", + "navParaentId_Name": "宝鸡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2824", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8d04-4982-a52d-78afc363755e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2051-4aa2-b30e-dfe31ab77144", + "version": null, + "code": "610324", + "name": "扶风县", + "gjmc": "扶风县", + "udtwb": { + "chComTextMDS": "2823" + }, + "pathInfo": { + "path": "002800030006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "navParaentId_Code": "610300", + "navParaentId_Name": "宝鸡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2823", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2051-4aa2-b30e-dfe31ab77144", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bb6e-40b6-a2fc-a6558780f598", + "version": null, + "code": "610323", + "name": "岐山县", + "gjmc": "岐山县", + "udtwb": { + "chComTextMDS": "2822" + }, + "pathInfo": { + "path": "002800030005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "navParaentId_Code": "610300", + "navParaentId_Name": "宝鸡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2822", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bb6e-40b6-a2fc-a6558780f598", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7e0b-4d6b-b702-ba142e07657e", + "version": null, + "code": "610322", + "name": "凤翔县", + "gjmc": "凤翔县", + "udtwb": { + "chComTextMDS": "2821" + }, + "pathInfo": { + "path": "002800030004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "navParaentId_Code": "610300", + "navParaentId_Name": "宝鸡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2821", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7e0b-4d6b-b702-ba142e07657e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f511-46b4-b36b-089c2e7b9466", + "version": null, + "code": "610304", + "name": "陈仓区", + "gjmc": "陈仓区", + "udtwb": { + "chComTextMDS": "2820" + }, + "pathInfo": { + "path": "002800030003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "navParaentId_Code": "610300", + "navParaentId_Name": "宝鸡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2820", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f511-46b4-b36b-089c2e7b9466", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0c2e-460e-b2ca-4de56ea49d15", + "version": null, + "code": "610303", + "name": "金台区", + "gjmc": "金台区", + "udtwb": { + "chComTextMDS": "2819" + }, + "pathInfo": { + "path": "002800030002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "navParaentId_Code": "610300", + "navParaentId_Name": "宝鸡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2819", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0c2e-460e-b2ca-4de56ea49d15", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8d9d-43b1-af17-7aef1c494b60", + "version": null, + "code": "610302", + "name": "渭滨区", + "gjmc": "渭滨区", + "udtwb": { + "chComTextMDS": "2818" + }, + "pathInfo": { + "path": "002800030001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "navParaentId_Code": "610300", + "navParaentId_Name": "宝鸡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2818", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8d9d-43b1-af17-7aef1c494b60", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fb14-4612-a7c3-8bb3b32b1068", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2b1b-4dfe-b87d-5db34e1865fb", + "version": null, + "code": "610200", + "name": "铜川市", + "gjmc": "铜川市", + "udtwb": { + "chComTextMDS": "2812" + }, + "pathInfo": { + "path": "00280002", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "sequence": 2, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "navParaentId_Code": "610000", + "navParaentId_Name": "陕西省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2812", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-fe21-4f9b-a541-f19ae5fa18aa", + "version": null, + "code": "610222", + "name": "宜君县", + "gjmc": "宜君县", + "udtwb": { + "chComTextMDS": "2816" + }, + "pathInfo": { + "path": "002800020004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2b1b-4dfe-b87d-5db34e1865fb", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2b1b-4dfe-b87d-5db34e1865fb", + "navParaentId_Code": "610200", + "navParaentId_Name": "铜川市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2816", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fe21-4f9b-a541-f19ae5fa18aa", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5dce-4d77-9983-41ec50d27aae", + "version": null, + "code": "610204", + "name": "耀州区", + "gjmc": "耀州区", + "udtwb": { + "chComTextMDS": "2815" + }, + "pathInfo": { + "path": "002800020003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2b1b-4dfe-b87d-5db34e1865fb", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2b1b-4dfe-b87d-5db34e1865fb", + "navParaentId_Code": "610200", + "navParaentId_Name": "铜川市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2815", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5dce-4d77-9983-41ec50d27aae", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5d89-42a6-a3cb-b2d966598d8b", + "version": null, + "code": "610203", + "name": "印台区", + "gjmc": "印台区", + "udtwb": { + "chComTextMDS": "2814" + }, + "pathInfo": { + "path": "002800020002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2b1b-4dfe-b87d-5db34e1865fb", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2b1b-4dfe-b87d-5db34e1865fb", + "navParaentId_Code": "610200", + "navParaentId_Name": "铜川市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2814", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5d89-42a6-a3cb-b2d966598d8b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6361-4482-9207-cfd506a0d39e", + "version": null, + "code": "610202", + "name": "王益区", + "gjmc": "王益区", + "udtwb": { + "chComTextMDS": "2813" + }, + "pathInfo": { + "path": "002800020001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-2b1b-4dfe-b87d-5db34e1865fb", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-2b1b-4dfe-b87d-5db34e1865fb", + "navParaentId_Code": "610200", + "navParaentId_Name": "铜川市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2813", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6361-4482-9207-cfd506a0d39e", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2b1b-4dfe-b87d-5db34e1865fb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "version": null, + "code": "610100", + "name": "西安市", + "gjmc": "西安市", + "udtwb": { + "chComTextMDS": "2798" + }, + "pathInfo": { + "path": "00280001", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "sequence": 1, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "navParaentId_Code": "610000", + "navParaentId_Name": "陕西省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2798", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-ef57-45c3-ad2b-9c2a9c77de49", + "version": null, + "code": "610124", + "name": "周至县", + "gjmc": "周至县", + "udtwb": { + "chComTextMDS": "2811" + }, + "pathInfo": { + "path": "002800010013", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "sequence": 13, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4894-48b1-9136-17929eee9759", + "navParaentId_Code": "610100", + "navParaentId_Name": "西安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2811", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ef57-45c3-ad2b-9c2a9c77de49", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6e9d-4ab6-b029-537e5e828696", + "version": null, + "code": "610122", + "name": "蓝田县", + "gjmc": "蓝田县", + "udtwb": { + "chComTextMDS": "2810" + }, + "pathInfo": { + "path": "002800010012", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "sequence": 12, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4894-48b1-9136-17929eee9759", + "navParaentId_Code": "610100", + "navParaentId_Name": "西安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2810", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6e9d-4ab6-b029-537e5e828696", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-aab0-4d31-b6fd-fbea404e2aed", + "version": null, + "code": "610118", + "name": "鄠邑区", + "gjmc": "鄠邑区", + "udtwb": { + "chComTextMDS": "2809" + }, + "pathInfo": { + "path": "002800010011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4894-48b1-9136-17929eee9759", + "navParaentId_Code": "610100", + "navParaentId_Name": "西安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2809", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-aab0-4d31-b6fd-fbea404e2aed", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2562-459c-b7aa-37a380eb6bb8", + "version": null, + "code": "610117", + "name": "高陵区", + "gjmc": "高陵区", + "udtwb": { + "chComTextMDS": "2808" + }, + "pathInfo": { + "path": "002800010010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4894-48b1-9136-17929eee9759", + "navParaentId_Code": "610100", + "navParaentId_Name": "西安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2808", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2562-459c-b7aa-37a380eb6bb8", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4bd6-46e9-9e6f-eeff9a5a4d76", + "version": null, + "code": "610116", + "name": "长安区", + "gjmc": "长安区", + "udtwb": { + "chComTextMDS": "2807" + }, + "pathInfo": { + "path": "002800010009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4894-48b1-9136-17929eee9759", + "navParaentId_Code": "610100", + "navParaentId_Name": "西安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2807", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4bd6-46e9-9e6f-eeff9a5a4d76", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4b8b-4878-8b93-f6461fb165c2", + "version": null, + "code": "610115", + "name": "临潼区", + "gjmc": "临潼区", + "udtwb": { + "chComTextMDS": "2806" + }, + "pathInfo": { + "path": "002800010008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4894-48b1-9136-17929eee9759", + "navParaentId_Code": "610100", + "navParaentId_Name": "西安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2806", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4b8b-4878-8b93-f6461fb165c2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7771-446f-b1aa-2900b56444b1", + "version": null, + "code": "610114", + "name": "阎良区", + "gjmc": "阎良区", + "udtwb": { + "chComTextMDS": "2805" + }, + "pathInfo": { + "path": "002800010007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4894-48b1-9136-17929eee9759", + "navParaentId_Code": "610100", + "navParaentId_Name": "西安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2805", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7771-446f-b1aa-2900b56444b1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9367-4494-8043-a47865a46397", + "version": null, + "code": "610113", + "name": "雁塔区", + "gjmc": "雁塔区", + "udtwb": { + "chComTextMDS": "2804" + }, + "pathInfo": { + "path": "002800010006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4894-48b1-9136-17929eee9759", + "navParaentId_Code": "610100", + "navParaentId_Name": "西安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2804", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9367-4494-8043-a47865a46397", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f229-439f-905b-097549eacde9", + "version": null, + "code": "610112", + "name": "未央区", + "gjmc": "未央区", + "udtwb": { + "chComTextMDS": "2803" + }, + "pathInfo": { + "path": "002800010005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4894-48b1-9136-17929eee9759", + "navParaentId_Code": "610100", + "navParaentId_Name": "西安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2803", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f229-439f-905b-097549eacde9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-94a4-4521-8451-251323319e8a", + "version": null, + "code": "610111", + "name": "灞桥区", + "gjmc": "灞桥区", + "udtwb": { + "chComTextMDS": "2802" + }, + "pathInfo": { + "path": "002800010004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4894-48b1-9136-17929eee9759", + "navParaentId_Code": "610100", + "navParaentId_Name": "西安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2802", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-94a4-4521-8451-251323319e8a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3921-4087-a435-5beea547cde8", + "version": null, + "code": "610104", + "name": "莲湖区", + "gjmc": "莲湖区", + "udtwb": { + "chComTextMDS": "2801" + }, + "pathInfo": { + "path": "002800010003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4894-48b1-9136-17929eee9759", + "navParaentId_Code": "610100", + "navParaentId_Name": "西安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2801", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3921-4087-a435-5beea547cde8", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bce7-4f41-b5e9-61d1c256e7fd", + "version": null, + "code": "610103", + "name": "碑林区", + "gjmc": "碑林区", + "udtwb": { + "chComTextMDS": "2800" + }, + "pathInfo": { + "path": "002800010002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4894-48b1-9136-17929eee9759", + "navParaentId_Code": "610100", + "navParaentId_Name": "西安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2800", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bce7-4f41-b5e9-61d1c256e7fd", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-77da-4501-bb7e-fe4b6debd227", + "version": null, + "code": "610102", + "name": "新城区", + "gjmc": "新城区", + "udtwb": { + "chComTextMDS": "2799" + }, + "pathInfo": { + "path": "002800010001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4894-48b1-9136-17929eee9759", + "navParaentId_Code": "610100", + "navParaentId_Name": "西安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2799", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-77da-4501-bb7e-fe4b6debd227", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4894-48b1-9136-17929eee9759", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-109f-43d3-a70e-dffbb7fe3b3a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "version": null, + "code": "540000", + "name": "西藏自治区", + "gjmc": "西藏自治区", + "udtwb": { + "chComTextMDS": "2715" + }, + "pathInfo": { + "path": "0027", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 27, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2715", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "version": null, + "code": "542500", + "name": "阿里地区", + "gjmc": "阿里地区", + "udtwb": { + "chComTextMDS": "2789" + }, + "pathInfo": { + "path": "00270007", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "sequence": 7, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "navParaentId_Code": "540000", + "navParaentId_Name": "西藏自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2789", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-0076-4812-ada4-a52b2718bb7c", + "version": null, + "code": "542527", + "name": "措勤县", + "gjmc": "措勤县", + "udtwb": { + "chComTextMDS": "2796" + }, + "pathInfo": { + "path": "002700070007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "navParaentId_Code": "542500", + "navParaentId_Name": "阿里地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2796", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0076-4812-ada4-a52b2718bb7c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-79ae-46dd-b6e3-31ef92a737c1", + "version": null, + "code": "542526", + "name": "改则县", + "gjmc": "改则县", + "udtwb": { + "chComTextMDS": "2795" + }, + "pathInfo": { + "path": "002700070006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "navParaentId_Code": "542500", + "navParaentId_Name": "阿里地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2795", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-79ae-46dd-b6e3-31ef92a737c1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ac61-4c9e-b411-d89bc49182f2", + "version": null, + "code": "542525", + "name": "革吉县", + "gjmc": "革吉县", + "udtwb": { + "chComTextMDS": "2794" + }, + "pathInfo": { + "path": "002700070005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "navParaentId_Code": "542500", + "navParaentId_Name": "阿里地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2794", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ac61-4c9e-b411-d89bc49182f2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-75c3-4524-a7b5-72ddb55eaf2a", + "version": null, + "code": "542524", + "name": "日土县", + "gjmc": "日土县", + "udtwb": { + "chComTextMDS": "2793" + }, + "pathInfo": { + "path": "002700070004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "navParaentId_Code": "542500", + "navParaentId_Name": "阿里地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2793", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-75c3-4524-a7b5-72ddb55eaf2a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bf1c-4d86-b7e9-8071f6b08239", + "version": null, + "code": "542523", + "name": "噶尔县", + "gjmc": "噶尔县", + "udtwb": { + "chComTextMDS": "2792" + }, + "pathInfo": { + "path": "002700070003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "navParaentId_Code": "542500", + "navParaentId_Name": "阿里地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2792", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bf1c-4d86-b7e9-8071f6b08239", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8f9e-41f8-bcc1-503a7d908812", + "version": null, + "code": "542522", + "name": "札达县", + "gjmc": "札达县", + "udtwb": { + "chComTextMDS": "2791" + }, + "pathInfo": { + "path": "002700070002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "navParaentId_Code": "542500", + "navParaentId_Name": "阿里地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2791", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8f9e-41f8-bcc1-503a7d908812", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3b35-44f3-af6a-79786eb15f61", + "version": null, + "code": "542521", + "name": "普兰县", + "gjmc": "普兰县", + "udtwb": { + "chComTextMDS": "2790" + }, + "pathInfo": { + "path": "002700070001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "navParaentId_Code": "542500", + "navParaentId_Name": "阿里地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2790", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3b35-44f3-af6a-79786eb15f61", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-668f-4c02-a3a3-cd029e3cbcfc", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "version": null, + "code": "540600", + "name": "那曲市", + "gjmc": "那曲市", + "udtwb": { + "chComTextMDS": "2777" + }, + "pathInfo": { + "path": "00270006", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "sequence": 6, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "navParaentId_Code": "540000", + "navParaentId_Name": "西藏自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2777", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-e749-449e-b1f8-bf7d43193d75", + "version": null, + "code": "540630", + "name": "双湖县", + "gjmc": "双湖县", + "udtwb": { + "chComTextMDS": "2788" + }, + "pathInfo": { + "path": "002700060011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "navParaentId_Code": "540600", + "navParaentId_Name": "那曲市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2788", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e749-449e-b1f8-bf7d43193d75", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4327-4ad6-baaa-407eda4baf86", + "version": null, + "code": "540629", + "name": "尼玛县", + "gjmc": "尼玛县", + "udtwb": { + "chComTextMDS": "2787" + }, + "pathInfo": { + "path": "002700060010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "navParaentId_Code": "540600", + "navParaentId_Name": "那曲市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2787", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4327-4ad6-baaa-407eda4baf86", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-06ae-4070-8097-a6e7c394c4c1", + "version": null, + "code": "540628", + "name": "巴青县", + "gjmc": "巴青县", + "udtwb": { + "chComTextMDS": "2786" + }, + "pathInfo": { + "path": "002700060009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "navParaentId_Code": "540600", + "navParaentId_Name": "那曲市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2786", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-06ae-4070-8097-a6e7c394c4c1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4f35-4f18-80e6-112bc2738239", + "version": null, + "code": "540627", + "name": "班戈县", + "gjmc": "班戈县", + "udtwb": { + "chComTextMDS": "2785" + }, + "pathInfo": { + "path": "002700060008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "navParaentId_Code": "540600", + "navParaentId_Name": "那曲市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2785", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4f35-4f18-80e6-112bc2738239", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bfb7-4b27-8698-88177f06793d", + "version": null, + "code": "540626", + "name": "索县", + "gjmc": "索县", + "udtwb": { + "chComTextMDS": "2784" + }, + "pathInfo": { + "path": "002700060007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "navParaentId_Code": "540600", + "navParaentId_Name": "那曲市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2784", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bfb7-4b27-8698-88177f06793d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2925-4a91-9df0-45a15c4b6455", + "version": null, + "code": "540625", + "name": "申扎县", + "gjmc": "申扎县", + "udtwb": { + "chComTextMDS": "2783" + }, + "pathInfo": { + "path": "002700060006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "navParaentId_Code": "540600", + "navParaentId_Name": "那曲市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2783", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2925-4a91-9df0-45a15c4b6455", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-139b-4c2c-95e0-ce6f922ff313", + "version": null, + "code": "540624", + "name": "安多县", + "gjmc": "安多县", + "udtwb": { + "chComTextMDS": "2782" + }, + "pathInfo": { + "path": "002700060005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "navParaentId_Code": "540600", + "navParaentId_Name": "那曲市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2782", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-139b-4c2c-95e0-ce6f922ff313", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b5ee-4e18-9a45-153c912a5fd9", + "version": null, + "code": "540623", + "name": "聂荣县", + "gjmc": "聂荣县", + "udtwb": { + "chComTextMDS": "2781" + }, + "pathInfo": { + "path": "002700060004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "navParaentId_Code": "540600", + "navParaentId_Name": "那曲市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2781", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b5ee-4e18-9a45-153c912a5fd9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a8fe-4be5-84e1-25115afbdddf", + "version": null, + "code": "540622", + "name": "比如县", + "gjmc": "比如县", + "udtwb": { + "chComTextMDS": "2780" + }, + "pathInfo": { + "path": "002700060003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "navParaentId_Code": "540600", + "navParaentId_Name": "那曲市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2780", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a8fe-4be5-84e1-25115afbdddf", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f0d1-40e4-95ed-0d02f4b3c661", + "version": null, + "code": "540621", + "name": "嘉黎县", + "gjmc": "嘉黎县", + "udtwb": { + "chComTextMDS": "2779" + }, + "pathInfo": { + "path": "002700060002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "navParaentId_Code": "540600", + "navParaentId_Name": "那曲市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2779", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f0d1-40e4-95ed-0d02f4b3c661", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c1b6-4fec-bf6e-7600303e9667", + "version": null, + "code": "540602", + "name": "色尼区", + "gjmc": "色尼区", + "udtwb": { + "chComTextMDS": "2778" + }, + "pathInfo": { + "path": "002700060001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "navParaentId_Code": "540600", + "navParaentId_Name": "那曲市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2778", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c1b6-4fec-bf6e-7600303e9667", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fdc7-4e0e-b4df-8c32756d7e01", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "version": null, + "code": "540500", + "name": "山南市", + "gjmc": "山南市", + "udtwb": { + "chComTextMDS": "2764" + }, + "pathInfo": { + "path": "00270005", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "sequence": 5, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "navParaentId_Code": "540000", + "navParaentId_Name": "西藏自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2764", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-66cd-45d3-849b-5b295f45bcce", + "version": null, + "code": "540531", + "name": "浪卡子县", + "gjmc": "浪卡子县", + "udtwb": { + "chComTextMDS": "2776" + }, + "pathInfo": { + "path": "002700050012", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "sequence": 12, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "navParaentId_Code": "540500", + "navParaentId_Name": "山南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2776", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-66cd-45d3-849b-5b295f45bcce", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-eddd-4770-967a-1a1c8358164f", + "version": null, + "code": "540530", + "name": "错那县", + "gjmc": "错那县", + "udtwb": { + "chComTextMDS": "2775" + }, + "pathInfo": { + "path": "002700050011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "navParaentId_Code": "540500", + "navParaentId_Name": "山南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2775", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-eddd-4770-967a-1a1c8358164f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3098-4864-bb85-0da6e54189c0", + "version": null, + "code": "540529", + "name": "隆子县", + "gjmc": "隆子县", + "udtwb": { + "chComTextMDS": "2774" + }, + "pathInfo": { + "path": "002700050010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "navParaentId_Code": "540500", + "navParaentId_Name": "山南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2774", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3098-4864-bb85-0da6e54189c0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6a94-4ba2-b077-6a906b571f90", + "version": null, + "code": "540528", + "name": "加查县", + "gjmc": "加查县", + "udtwb": { + "chComTextMDS": "2773" + }, + "pathInfo": { + "path": "002700050009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "navParaentId_Code": "540500", + "navParaentId_Name": "山南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2773", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6a94-4ba2-b077-6a906b571f90", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f08c-40b9-8733-9ef6240603e3", + "version": null, + "code": "540527", + "name": "洛扎县", + "gjmc": "洛扎县", + "udtwb": { + "chComTextMDS": "2772" + }, + "pathInfo": { + "path": "002700050008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "navParaentId_Code": "540500", + "navParaentId_Name": "山南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2772", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f08c-40b9-8733-9ef6240603e3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-aab8-404e-aa95-a811615cc8aa", + "version": null, + "code": "540526", + "name": "措美县", + "gjmc": "措美县", + "udtwb": { + "chComTextMDS": "2771" + }, + "pathInfo": { + "path": "002700050007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "navParaentId_Code": "540500", + "navParaentId_Name": "山南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2771", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-aab8-404e-aa95-a811615cc8aa", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1b96-49e7-b172-f22f0cf9e47f", + "version": null, + "code": "540525", + "name": "曲松县", + "gjmc": "曲松县", + "udtwb": { + "chComTextMDS": "2770" + }, + "pathInfo": { + "path": "002700050006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "navParaentId_Code": "540500", + "navParaentId_Name": "山南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2770", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1b96-49e7-b172-f22f0cf9e47f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d23f-4df8-bb0e-263e80e2f5f2", + "version": null, + "code": "540524", + "name": "琼结县", + "gjmc": "琼结县", + "udtwb": { + "chComTextMDS": "2769" + }, + "pathInfo": { + "path": "002700050005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "navParaentId_Code": "540500", + "navParaentId_Name": "山南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2769", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d23f-4df8-bb0e-263e80e2f5f2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3fe1-4f46-a9aa-896348d91f05", + "version": null, + "code": "540523", + "name": "桑日县", + "gjmc": "桑日县", + "udtwb": { + "chComTextMDS": "2768" + }, + "pathInfo": { + "path": "002700050004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "navParaentId_Code": "540500", + "navParaentId_Name": "山南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2768", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3fe1-4f46-a9aa-896348d91f05", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0331-4f0c-bb33-47c7ae0ddb75", + "version": null, + "code": "540522", + "name": "贡嘎县", + "gjmc": "贡嘎县", + "udtwb": { + "chComTextMDS": "2767" + }, + "pathInfo": { + "path": "002700050003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "navParaentId_Code": "540500", + "navParaentId_Name": "山南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2767", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0331-4f0c-bb33-47c7ae0ddb75", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b993-4023-ab23-eb1df3e9e3a1", + "version": null, + "code": "540521", + "name": "扎囊县", + "gjmc": "扎囊县", + "udtwb": { + "chComTextMDS": "2766" + }, + "pathInfo": { + "path": "002700050002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "navParaentId_Code": "540500", + "navParaentId_Name": "山南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2766", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b993-4023-ab23-eb1df3e9e3a1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-dd8c-40af-9077-99c1f665c03a", + "version": null, + "code": "540502", + "name": "乃东区", + "gjmc": "乃东区", + "udtwb": { + "chComTextMDS": "2765" + }, + "pathInfo": { + "path": "002700050001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "navParaentId_Code": "540500", + "navParaentId_Name": "山南市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2765", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-dd8c-40af-9077-99c1f665c03a", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-41f2-4e4c-94b3-5fbcc28d4909", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-030f-439c-a744-129c80935bbb", + "version": null, + "code": "540400", + "name": "林芝市", + "gjmc": "林芝市", + "udtwb": { + "chComTextMDS": "2756" + }, + "pathInfo": { + "path": "00270004", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "sequence": 4, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "navParaentId_Code": "540000", + "navParaentId_Name": "西藏自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2756", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-c6ee-46a8-a6b1-081e45ea0239", + "version": null, + "code": "540426", + "name": "朗县", + "gjmc": "朗县", + "udtwb": { + "chComTextMDS": "2763" + }, + "pathInfo": { + "path": "002700040007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-030f-439c-a744-129c80935bbb", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-030f-439c-a744-129c80935bbb", + "navParaentId_Code": "540400", + "navParaentId_Name": "林芝市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2763", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c6ee-46a8-a6b1-081e45ea0239", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b7f1-48c9-9312-aa31980c5d0d", + "version": null, + "code": "540425", + "name": "察隅县", + "gjmc": "察隅县", + "udtwb": { + "chComTextMDS": "2762" + }, + "pathInfo": { + "path": "002700040006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-030f-439c-a744-129c80935bbb", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-030f-439c-a744-129c80935bbb", + "navParaentId_Code": "540400", + "navParaentId_Name": "林芝市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2762", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b7f1-48c9-9312-aa31980c5d0d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5b59-4552-919f-7928c08394bf", + "version": null, + "code": "540424", + "name": "波密县", + "gjmc": "波密县", + "udtwb": { + "chComTextMDS": "2761" + }, + "pathInfo": { + "path": "002700040005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-030f-439c-a744-129c80935bbb", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-030f-439c-a744-129c80935bbb", + "navParaentId_Code": "540400", + "navParaentId_Name": "林芝市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2761", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5b59-4552-919f-7928c08394bf", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3bfe-4da8-858e-0102c30ac334", + "version": null, + "code": "540423", + "name": "墨脱县", + "gjmc": "墨脱县", + "udtwb": { + "chComTextMDS": "2760" + }, + "pathInfo": { + "path": "002700040004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-030f-439c-a744-129c80935bbb", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-030f-439c-a744-129c80935bbb", + "navParaentId_Code": "540400", + "navParaentId_Name": "林芝市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2760", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3bfe-4da8-858e-0102c30ac334", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1ee2-41b4-bf10-e14b9b287260", + "version": null, + "code": "540422", + "name": "米林县", + "gjmc": "米林县", + "udtwb": { + "chComTextMDS": "2759" + }, + "pathInfo": { + "path": "002700040003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-030f-439c-a744-129c80935bbb", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-030f-439c-a744-129c80935bbb", + "navParaentId_Code": "540400", + "navParaentId_Name": "林芝市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2759", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1ee2-41b4-bf10-e14b9b287260", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-201d-45ba-92be-0121502ba911", + "version": null, + "code": "540421", + "name": "工布江达县", + "gjmc": "工布江达县", + "udtwb": { + "chComTextMDS": "2758" + }, + "pathInfo": { + "path": "002700040002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-030f-439c-a744-129c80935bbb", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-030f-439c-a744-129c80935bbb", + "navParaentId_Code": "540400", + "navParaentId_Name": "林芝市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2758", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-201d-45ba-92be-0121502ba911", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-024c-4e52-b5ae-3cfd351a92d5", + "version": null, + "code": "540402", + "name": "巴宜区", + "gjmc": "巴宜区", + "udtwb": { + "chComTextMDS": "2757" + }, + "pathInfo": { + "path": "002700040001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-030f-439c-a744-129c80935bbb", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-030f-439c-a744-129c80935bbb", + "navParaentId_Code": "540400", + "navParaentId_Name": "林芝市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2757", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-024c-4e52-b5ae-3cfd351a92d5", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-030f-439c-a744-129c80935bbb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "version": null, + "code": "540300", + "name": "昌都市", + "gjmc": "昌都市", + "udtwb": { + "chComTextMDS": "2744" + }, + "pathInfo": { + "path": "00270003", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "sequence": 3, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "navParaentId_Code": "540000", + "navParaentId_Name": "西藏自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2744", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-b0d5-4a1f-a1e8-91c6f79e44d3", + "version": null, + "code": "540330", + "name": "边坝县", + "gjmc": "边坝县", + "udtwb": { + "chComTextMDS": "2755" + }, + "pathInfo": { + "path": "002700030011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "navParaentId_Code": "540300", + "navParaentId_Name": "昌都市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2755", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b0d5-4a1f-a1e8-91c6f79e44d3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d5b1-4ffa-9c9d-58cd76c26031", + "version": null, + "code": "540329", + "name": "洛隆县", + "gjmc": "洛隆县", + "udtwb": { + "chComTextMDS": "2754" + }, + "pathInfo": { + "path": "002700030010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "navParaentId_Code": "540300", + "navParaentId_Name": "昌都市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2754", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d5b1-4ffa-9c9d-58cd76c26031", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c9d3-4a3b-a092-03086de4e328", + "version": null, + "code": "540328", + "name": "芒康县", + "gjmc": "芒康县", + "udtwb": { + "chComTextMDS": "2753" + }, + "pathInfo": { + "path": "002700030009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "navParaentId_Code": "540300", + "navParaentId_Name": "昌都市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2753", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c9d3-4a3b-a092-03086de4e328", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a9f7-438a-97f2-5169bc8e490a", + "version": null, + "code": "540327", + "name": "左贡县", + "gjmc": "左贡县", + "udtwb": { + "chComTextMDS": "2752" + }, + "pathInfo": { + "path": "002700030008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "navParaentId_Code": "540300", + "navParaentId_Name": "昌都市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2752", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a9f7-438a-97f2-5169bc8e490a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-dd43-4884-b712-bb899927198b", + "version": null, + "code": "540326", + "name": "八宿县", + "gjmc": "八宿县", + "udtwb": { + "chComTextMDS": "2751" + }, + "pathInfo": { + "path": "002700030007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "navParaentId_Code": "540300", + "navParaentId_Name": "昌都市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2751", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-dd43-4884-b712-bb899927198b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-cc4b-4993-b872-d0e34dc9490b", + "version": null, + "code": "540325", + "name": "察雅县", + "gjmc": "察雅县", + "udtwb": { + "chComTextMDS": "2750" + }, + "pathInfo": { + "path": "002700030006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "navParaentId_Code": "540300", + "navParaentId_Name": "昌都市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2750", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-cc4b-4993-b872-d0e34dc9490b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-347a-4f94-87b8-94eaa743430e", + "version": null, + "code": "540324", + "name": "丁青县", + "gjmc": "丁青县", + "udtwb": { + "chComTextMDS": "2749" + }, + "pathInfo": { + "path": "002700030005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "navParaentId_Code": "540300", + "navParaentId_Name": "昌都市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2749", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-347a-4f94-87b8-94eaa743430e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-be42-44a5-b922-31ae4f59f132", + "version": null, + "code": "540323", + "name": "类乌齐县", + "gjmc": "类乌齐县", + "udtwb": { + "chComTextMDS": "2748" + }, + "pathInfo": { + "path": "002700030004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "navParaentId_Code": "540300", + "navParaentId_Name": "昌都市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2748", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-be42-44a5-b922-31ae4f59f132", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-62c5-4703-a100-6a718cb25087", + "version": null, + "code": "540322", + "name": "贡觉县", + "gjmc": "贡觉县", + "udtwb": { + "chComTextMDS": "2747" + }, + "pathInfo": { + "path": "002700030003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "navParaentId_Code": "540300", + "navParaentId_Name": "昌都市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2747", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-62c5-4703-a100-6a718cb25087", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5570-4716-a78e-13ea48cb2629", + "version": null, + "code": "540321", + "name": "江达县", + "gjmc": "江达县", + "udtwb": { + "chComTextMDS": "2746" + }, + "pathInfo": { + "path": "002700030002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "navParaentId_Code": "540300", + "navParaentId_Name": "昌都市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2746", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5570-4716-a78e-13ea48cb2629", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1d2f-4cf6-beba-bea9bc4e32db", + "version": null, + "code": "540302", + "name": "卡若区", + "gjmc": "卡若区", + "udtwb": { + "chComTextMDS": "2745" + }, + "pathInfo": { + "path": "002700030001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "navParaentId_Code": "540300", + "navParaentId_Name": "昌都市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2745", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1d2f-4cf6-beba-bea9bc4e32db", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-eb5e-40a5-97ec-5860aa56e5fa", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "version": null, + "code": "540200", + "name": "日喀则市", + "gjmc": "日喀则市", + "udtwb": { + "chComTextMDS": "2725" + }, + "pathInfo": { + "path": "00270002", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "sequence": 2, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "navParaentId_Code": "540000", + "navParaentId_Name": "西藏自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2725", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-f06d-4b12-87a3-9ebdb4e5e3a9", + "version": null, + "code": "540237", + "name": "岗巴县", + "gjmc": "岗巴县", + "udtwb": { + "chComTextMDS": "2743" + }, + "pathInfo": { + "path": "002700020018", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 18, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2743", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f06d-4b12-87a3-9ebdb4e5e3a9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-70f6-4d0b-a1a8-da1cfee9b13b", + "version": null, + "code": "540236", + "name": "萨嘎县", + "gjmc": "萨嘎县", + "udtwb": { + "chComTextMDS": "2742" + }, + "pathInfo": { + "path": "002700020017", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 17, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2742", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-70f6-4d0b-a1a8-da1cfee9b13b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2be3-4624-8e01-ca215c77d397", + "version": null, + "code": "540235", + "name": "聂拉木县", + "gjmc": "聂拉木县", + "udtwb": { + "chComTextMDS": "2741" + }, + "pathInfo": { + "path": "002700020016", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 16, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2741", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2be3-4624-8e01-ca215c77d397", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a275-4542-9bcd-ab718ffa0adf", + "version": null, + "code": "540234", + "name": "吉隆县", + "gjmc": "吉隆县", + "udtwb": { + "chComTextMDS": "2740" + }, + "pathInfo": { + "path": "002700020015", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 15, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2740", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a275-4542-9bcd-ab718ffa0adf", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-37c2-4196-86f8-4ef7157c5b76", + "version": null, + "code": "540233", + "name": "亚东县", + "gjmc": "亚东县", + "udtwb": { + "chComTextMDS": "2739" + }, + "pathInfo": { + "path": "002700020014", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 14, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2739", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-37c2-4196-86f8-4ef7157c5b76", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-61ba-4089-bece-ee54a4b57cc3", + "version": null, + "code": "540232", + "name": "仲巴县", + "gjmc": "仲巴县", + "udtwb": { + "chComTextMDS": "2738" + }, + "pathInfo": { + "path": "002700020013", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 13, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2738", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-61ba-4089-bece-ee54a4b57cc3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9193-4018-abb1-ae730045a646", + "version": null, + "code": "540231", + "name": "定结县", + "gjmc": "定结县", + "udtwb": { + "chComTextMDS": "2737" + }, + "pathInfo": { + "path": "002700020012", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 12, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2737", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9193-4018-abb1-ae730045a646", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e4d3-43a3-8b1e-bdef34151f06", + "version": null, + "code": "540230", + "name": "康马县", + "gjmc": "康马县", + "udtwb": { + "chComTextMDS": "2736" + }, + "pathInfo": { + "path": "002700020011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2736", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e4d3-43a3-8b1e-bdef34151f06", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8b7f-4dfc-9c55-863e20e84345", + "version": null, + "code": "540229", + "name": "仁布县", + "gjmc": "仁布县", + "udtwb": { + "chComTextMDS": "2735" + }, + "pathInfo": { + "path": "002700020010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2735", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8b7f-4dfc-9c55-863e20e84345", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1f65-4734-86ad-7681926ddf41", + "version": null, + "code": "540228", + "name": "白朗县", + "gjmc": "白朗县", + "udtwb": { + "chComTextMDS": "2734" + }, + "pathInfo": { + "path": "002700020009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2734", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1f65-4734-86ad-7681926ddf41", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f0e7-465d-acdc-6fee66626f91", + "version": null, + "code": "540227", + "name": "谢通门县", + "gjmc": "谢通门县", + "udtwb": { + "chComTextMDS": "2733" + }, + "pathInfo": { + "path": "002700020008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2733", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f0e7-465d-acdc-6fee66626f91", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-071f-49dc-aacf-5133d126df0b", + "version": null, + "code": "540226", + "name": "昂仁县", + "gjmc": "昂仁县", + "udtwb": { + "chComTextMDS": "2732" + }, + "pathInfo": { + "path": "002700020007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2732", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-071f-49dc-aacf-5133d126df0b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-cb7f-456a-9bae-00974be4b706", + "version": null, + "code": "540225", + "name": "拉孜县", + "gjmc": "拉孜县", + "udtwb": { + "chComTextMDS": "2731" + }, + "pathInfo": { + "path": "002700020006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2731", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-cb7f-456a-9bae-00974be4b706", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-66d0-4fd3-8202-13c1811482b6", + "version": null, + "code": "540224", + "name": "萨迦县", + "gjmc": "萨迦县", + "udtwb": { + "chComTextMDS": "2730" + }, + "pathInfo": { + "path": "002700020005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2730", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-66d0-4fd3-8202-13c1811482b6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d3d8-40e9-95f8-ffb2bcdeeb0e", + "version": null, + "code": "540223", + "name": "定日县", + "gjmc": "定日县", + "udtwb": { + "chComTextMDS": "2729" + }, + "pathInfo": { + "path": "002700020004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2729", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d3d8-40e9-95f8-ffb2bcdeeb0e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-50f3-449a-93f6-aa614b22e274", + "version": null, + "code": "540222", + "name": "江孜县", + "gjmc": "江孜县", + "udtwb": { + "chComTextMDS": "2728" + }, + "pathInfo": { + "path": "002700020003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2728", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-50f3-449a-93f6-aa614b22e274", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f0a1-4dab-82da-f453902f5414", + "version": null, + "code": "540221", + "name": "南木林县", + "gjmc": "南木林县", + "udtwb": { + "chComTextMDS": "2727" + }, + "pathInfo": { + "path": "002700020002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2727", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f0a1-4dab-82da-f453902f5414", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d57b-403c-be43-66d88821a1fb", + "version": null, + "code": "540202", + "name": "桑珠孜区", + "gjmc": "桑珠孜区", + "udtwb": { + "chComTextMDS": "2726" + }, + "pathInfo": { + "path": "002700020001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9010-4a56-be55-d4cd927f4d74", + "navParaentId_Code": "540200", + "navParaentId_Name": "日喀则市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2726", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d57b-403c-be43-66d88821a1fb", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9010-4a56-be55-d4cd927f4d74", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "version": null, + "code": "540100", + "name": "拉萨市", + "gjmc": "拉萨市", + "udtwb": { + "chComTextMDS": "2716" + }, + "pathInfo": { + "path": "00270001", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "sequence": 1, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "navParaentId_Code": "540000", + "navParaentId_Name": "西藏自治区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2716", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-cdf0-467b-ae9f-cf8216bf690c", + "version": null, + "code": "540127", + "name": "墨竹工卡县", + "gjmc": "墨竹工卡县", + "udtwb": { + "chComTextMDS": "2724" + }, + "pathInfo": { + "path": "002700010008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "navParaentId_Code": "540100", + "navParaentId_Name": "拉萨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2724", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-cdf0-467b-ae9f-cf8216bf690c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0d88-4dad-a857-1b40f00984be", + "version": null, + "code": "540124", + "name": "曲水县", + "gjmc": "曲水县", + "udtwb": { + "chComTextMDS": "2723" + }, + "pathInfo": { + "path": "002700010007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "navParaentId_Code": "540100", + "navParaentId_Name": "拉萨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2723", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0d88-4dad-a857-1b40f00984be", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5cb8-4a02-9e68-3274efa436b3", + "version": null, + "code": "540123", + "name": "尼木县", + "gjmc": "尼木县", + "udtwb": { + "chComTextMDS": "2722" + }, + "pathInfo": { + "path": "002700010006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "navParaentId_Code": "540100", + "navParaentId_Name": "拉萨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2722", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5cb8-4a02-9e68-3274efa436b3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3f3e-48d0-afc4-608ddf145a02", + "version": null, + "code": "540122", + "name": "当雄县", + "gjmc": "当雄县", + "udtwb": { + "chComTextMDS": "2721" + }, + "pathInfo": { + "path": "002700010005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "navParaentId_Code": "540100", + "navParaentId_Name": "拉萨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2721", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3f3e-48d0-afc4-608ddf145a02", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e3ef-41b8-9934-5850db1b1d2a", + "version": null, + "code": "540121", + "name": "林周县", + "gjmc": "林周县", + "udtwb": { + "chComTextMDS": "2720" + }, + "pathInfo": { + "path": "002700010004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "navParaentId_Code": "540100", + "navParaentId_Name": "拉萨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2720", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e3ef-41b8-9934-5850db1b1d2a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-55b6-4ebd-bebc-5ec621c2f27e", + "version": null, + "code": "540104", + "name": "达孜区", + "gjmc": "达孜区", + "udtwb": { + "chComTextMDS": "2719" + }, + "pathInfo": { + "path": "002700010003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "navParaentId_Code": "540100", + "navParaentId_Name": "拉萨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2719", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-55b6-4ebd-bebc-5ec621c2f27e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-198d-4b5d-ba03-ac771a696c00", + "version": null, + "code": "540103", + "name": "堆龙德庆区", + "gjmc": "堆龙德庆区", + "udtwb": { + "chComTextMDS": "2718" + }, + "pathInfo": { + "path": "002700010002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "navParaentId_Code": "540100", + "navParaentId_Name": "拉萨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2718", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-198d-4b5d-ba03-ac771a696c00", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1183-469f-94f4-1c1ee3d9f719", + "version": null, + "code": "540102", + "name": "城关区", + "gjmc": "城关区", + "udtwb": { + "chComTextMDS": "2717" + }, + "pathInfo": { + "path": "002700010001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "navParaentId_Code": "540100", + "navParaentId_Name": "拉萨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2717", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1183-469f-94f4-1c1ee3d9f719", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ff10-4c1b-b528-f17b450e4b30", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bc3b-49d4-97e3-fea19a043c0d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-19de-4ec2-8928-36655d6ae7ec", + "version": null, + "code": "530000", + "name": "云南省", + "gjmc": "云南省", + "udtwb": { + "chComTextMDS": "2569" + }, + "pathInfo": { + "path": "0026", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 26, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2569", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-19de-4ec2-8928-36655d6ae7ec", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a271-4971-8475-77de459ed4a7", + "version": null, + "code": "520000", + "name": "贵州省", + "gjmc": "贵州省", + "udtwb": { + "chComTextMDS": "2471" + }, + "pathInfo": { + "path": "0025", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 25, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2471", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children":[], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a271-4971-8475-77de459ed4a7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-14d2-495d-9404-b35d230656a5", + "version": null, + "code": "510000", + "name": "四川省", + "gjmc": "四川省", + "udtwb": { + "chComTextMDS": "2266" + }, + "pathInfo": { + "path": "0024", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 24, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2266", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-14d2-495d-9404-b35d230656a5", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2802-4e6d-8d9d-4b18cc83a515", + "version": null, + "code": "500000", + "name": "重庆市", + "gjmc": "重庆市", + "udtwb": { + "chComTextMDS": "2227" + }, + "pathInfo": { + "path": "0023", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 23, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2227", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2802-4e6d-8d9d-4b18cc83a515", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6659-4ef7-b652-828d2b1f9f7f", + "version": null, + "code": "460000", + "name": "海南省", + "gjmc": "海南省", + "udtwb": { + "chComTextMDS": "2199" + }, + "pathInfo": { + "path": "0022", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 22, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2199", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6659-4ef7-b652-828d2b1f9f7f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7027-453d-a145-fecf15b09b05", + "version": null, + "code": "450000", + "name": "广西壮族自治区", + "gjmc": "广西壮族自治区", + "udtwb": { + "chComTextMDS": "2073" + }, + "pathInfo": { + "path": "0021", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 21, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "2073", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7027-453d-a145-fecf15b09b05", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1ddc-4a41-9698-fe7e2630419b", + "version": null, + "code": "440000", + "name": "广东省", + "gjmc": "广东省", + "udtwb": { + "chComTextMDS": "1930" + }, + "pathInfo": { + "path": "0020", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 20, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "1930", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1ddc-4a41-9698-fe7e2630419b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2513-4ff9-a992-ee0f045d7abf", + "version": null, + "code": "430000", + "name": "湖南省", + "gjmc": "湖南省", + "udtwb": { + "chComTextMDS": "1793" + }, + "pathInfo": { + "path": "0019", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 19, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "1793", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2513-4ff9-a992-ee0f045d7abf", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-db34-46e3-b481-9b5778cb858b", + "version": null, + "code": "420000", + "name": "湖北省", + "gjmc": "湖北省", + "udtwb": { + "chComTextMDS": "1676" + }, + "pathInfo": { + "path": "0018", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 18, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "1676", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children":[], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-db34-46e3-b481-9b5778cb858b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b2af-4205-a193-465022c379bd", + "version": null, + "code": "410000", + "name": "河南省", + "gjmc": "河南省", + "udtwb": { + "chComTextMDS": "1500" + }, + "pathInfo": { + "path": "0017", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 17, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "1500", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b2af-4205-a193-465022c379bd", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b64d-4880-a9c1-6acbe22b747b", + "version": "2023-04-12T17:29:19.381Z", + "code": "370000", + "name": "山东省", + "gjmc": "山东省", + "udtwb": { + "chComTextMDS": "1345" + }, + "pathInfo": { + "path": "0016", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 16, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "1345", + "mc": null, + "zs": 999, + "fds": 22, + "rq": "2023-04-13", + "rqsj": "2023-04-21T17:29:06.000Z", + "buer": true, + "bz": null, + "mj": "green" + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b64d-4880-a9c1-6acbe22b747b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bf2e-4a60-98dd-094e77d39f14", + "version": null, + "code": "360000", + "name": "江西省", + "gjmc": "江西省", + "udtwb": { + "chComTextMDS": "1233" + }, + "pathInfo": { + "path": "0015", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 15, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "1233", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bf2e-4a60-98dd-094e77d39f14", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7f47-463a-9aec-1d538d96c655", + "version": null, + "code": "350000", + "name": "福建省", + "gjmc": "福建省", + "udtwb": { + "chComTextMDS": "1138" + }, + "pathInfo": { + "path": "0014", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 14, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "1138", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7f47-463a-9aec-1d538d96c655", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d2d8-4fd3-a52c-5beb222ee930", + "version": null, + "code": "340000", + "name": "安徽省", + "gjmc": "安徽省", + "udtwb": { + "chComTextMDS": "1016" + }, + "pathInfo": { + "path": "0013", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 13, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "1016", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d2d8-4fd3-a52c-5beb222ee930", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-22c6-49b4-981e-9ce90ae62595", + "version": null, + "code": "330000", + "name": "浙江省", + "gjmc": "浙江省", + "udtwb": { + "chComTextMDS": "0915" + }, + "pathInfo": { + "path": "0012", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 12, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0915", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-22c6-49b4-981e-9ce90ae62595", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "version": null, + "code": "320000", + "name": "江苏省", + "gjmc": "江苏省", + "udtwb": { + "chComTextMDS": "0805" + }, + "pathInfo": { + "path": "0011", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 11, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0805", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-366d-4685-9d24-99b021a13d1f", + "version": null, + "code": "321300", + "name": "宿迁市", + "gjmc": "宿迁市", + "udtwb": { + "chComTextMDS": "0909" + }, + "pathInfo": { + "path": "00110013", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "sequence": 13, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4109-446c-8882-2e35a877166a", + "navParaentId_Code": "320000", + "navParaentId_Name": "江苏省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0909", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-348b-458f-9d9e-1ff551093bcd", + "version": null, + "code": "321324", + "name": "泗洪县", + "gjmc": "泗洪县", + "udtwb": { + "chComTextMDS": "0914" + }, + "pathInfo": { + "path": "001100130005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-366d-4685-9d24-99b021a13d1f", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-366d-4685-9d24-99b021a13d1f", + "navParaentId_Code": "321300", + "navParaentId_Name": "宿迁市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0914", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-348b-458f-9d9e-1ff551093bcd", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d42b-4109-afe4-4946254e8472", + "version": null, + "code": "321323", + "name": "泗阳县", + "gjmc": "泗阳县", + "udtwb": { + "chComTextMDS": "0913" + }, + "pathInfo": { + "path": "001100130004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-366d-4685-9d24-99b021a13d1f", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-366d-4685-9d24-99b021a13d1f", + "navParaentId_Code": "321300", + "navParaentId_Name": "宿迁市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0913", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d42b-4109-afe4-4946254e8472", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e0bd-4edd-aa9f-12327e6648b6", + "version": null, + "code": "321322", + "name": "沭阳县", + "gjmc": "沭阳县", + "udtwb": { + "chComTextMDS": "0912" + }, + "pathInfo": { + "path": "001100130003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-366d-4685-9d24-99b021a13d1f", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-366d-4685-9d24-99b021a13d1f", + "navParaentId_Code": "321300", + "navParaentId_Name": "宿迁市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0912", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e0bd-4edd-aa9f-12327e6648b6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f9a1-46fc-97d5-d0f279e6f471", + "version": null, + "code": "321311", + "name": "宿豫区", + "gjmc": "宿豫区", + "udtwb": { + "chComTextMDS": "0911" + }, + "pathInfo": { + "path": "001100130002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-366d-4685-9d24-99b021a13d1f", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-366d-4685-9d24-99b021a13d1f", + "navParaentId_Code": "321300", + "navParaentId_Name": "宿迁市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0911", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f9a1-46fc-97d5-d0f279e6f471", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9462-4d03-a8d5-266e1e592617", + "version": null, + "code": "321302", + "name": "宿城区", + "gjmc": "宿城区", + "udtwb": { + "chComTextMDS": "0910" + }, + "pathInfo": { + "path": "001100130001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-366d-4685-9d24-99b021a13d1f", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-366d-4685-9d24-99b021a13d1f", + "navParaentId_Code": "321300", + "navParaentId_Name": "宿迁市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0910", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9462-4d03-a8d5-266e1e592617", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-366d-4685-9d24-99b021a13d1f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-aabd-436d-b865-dcfc89c8055c", + "version": null, + "code": "321200", + "name": "泰州市", + "gjmc": "泰州市", + "udtwb": { + "chComTextMDS": "0902" + }, + "pathInfo": { + "path": "00110012", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "sequence": 12, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4109-446c-8882-2e35a877166a", + "navParaentId_Code": "320000", + "navParaentId_Name": "江苏省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0902", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-85e2-43ef-821d-7aef9e275ad1", + "version": null, + "code": "321283", + "name": "泰兴市", + "gjmc": "泰兴市", + "udtwb": { + "chComTextMDS": "0908" + }, + "pathInfo": { + "path": "001100120006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-aabd-436d-b865-dcfc89c8055c", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-aabd-436d-b865-dcfc89c8055c", + "navParaentId_Code": "321200", + "navParaentId_Name": "泰州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0908", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-85e2-43ef-821d-7aef9e275ad1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7e20-45ec-a2c4-e00aaf45ef44", + "version": null, + "code": "321282", + "name": "靖江市", + "gjmc": "靖江市", + "udtwb": { + "chComTextMDS": "0907" + }, + "pathInfo": { + "path": "001100120005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-aabd-436d-b865-dcfc89c8055c", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-aabd-436d-b865-dcfc89c8055c", + "navParaentId_Code": "321200", + "navParaentId_Name": "泰州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0907", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7e20-45ec-a2c4-e00aaf45ef44", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-cb72-41b9-8621-2c4123368b69", + "version": null, + "code": "321281", + "name": "兴化市", + "gjmc": "兴化市", + "udtwb": { + "chComTextMDS": "0906" + }, + "pathInfo": { + "path": "001100120004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-aabd-436d-b865-dcfc89c8055c", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-aabd-436d-b865-dcfc89c8055c", + "navParaentId_Code": "321200", + "navParaentId_Name": "泰州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0906", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-cb72-41b9-8621-2c4123368b69", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-043c-4c33-aa61-2d136aa6b2bc", + "version": null, + "code": "321204", + "name": "姜堰区", + "gjmc": "姜堰区", + "udtwb": { + "chComTextMDS": "0905" + }, + "pathInfo": { + "path": "001100120003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-aabd-436d-b865-dcfc89c8055c", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-aabd-436d-b865-dcfc89c8055c", + "navParaentId_Code": "321200", + "navParaentId_Name": "泰州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0905", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-043c-4c33-aa61-2d136aa6b2bc", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1930-41f5-ae8b-32af59b15879", + "version": null, + "code": "321203", + "name": "高港区", + "gjmc": "高港区", + "udtwb": { + "chComTextMDS": "0904" + }, + "pathInfo": { + "path": "001100120002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-aabd-436d-b865-dcfc89c8055c", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-aabd-436d-b865-dcfc89c8055c", + "navParaentId_Code": "321200", + "navParaentId_Name": "泰州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0904", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1930-41f5-ae8b-32af59b15879", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ff90-41d5-a01c-34f188262c4f", + "version": null, + "code": "321202", + "name": "海陵区", + "gjmc": "海陵区", + "udtwb": { + "chComTextMDS": "0903" + }, + "pathInfo": { + "path": "001100120001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-aabd-436d-b865-dcfc89c8055c", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-aabd-436d-b865-dcfc89c8055c", + "navParaentId_Code": "321200", + "navParaentId_Name": "泰州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0903", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ff90-41d5-a01c-34f188262c4f", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-aabd-436d-b865-dcfc89c8055c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c7fa-4d70-a7de-b77ce19c191e", + "version": null, + "code": "321100", + "name": "镇江市", + "gjmc": "镇江市", + "udtwb": { + "chComTextMDS": "0895" + }, + "pathInfo": { + "path": "00110011", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "sequence": 11, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4109-446c-8882-2e35a877166a", + "navParaentId_Code": "320000", + "navParaentId_Name": "江苏省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0895", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-d443-491d-bd3e-6365d045cd10", + "version": null, + "code": "321183", + "name": "句容市", + "gjmc": "句容市", + "udtwb": { + "chComTextMDS": "0901" + }, + "pathInfo": { + "path": "001100110006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c7fa-4d70-a7de-b77ce19c191e", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c7fa-4d70-a7de-b77ce19c191e", + "navParaentId_Code": "321100", + "navParaentId_Name": "镇江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0901", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d443-491d-bd3e-6365d045cd10", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e125-460d-8bf5-2bbaa3b857c3", + "version": null, + "code": "321182", + "name": "扬中市", + "gjmc": "扬中市", + "udtwb": { + "chComTextMDS": "0900" + }, + "pathInfo": { + "path": "001100110005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c7fa-4d70-a7de-b77ce19c191e", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c7fa-4d70-a7de-b77ce19c191e", + "navParaentId_Code": "321100", + "navParaentId_Name": "镇江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0900", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e125-460d-8bf5-2bbaa3b857c3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2fca-4995-814f-c2f6e777c0fc", + "version": null, + "code": "321181", + "name": "丹阳市", + "gjmc": "丹阳市", + "udtwb": { + "chComTextMDS": "0899" + }, + "pathInfo": { + "path": "001100110004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c7fa-4d70-a7de-b77ce19c191e", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c7fa-4d70-a7de-b77ce19c191e", + "navParaentId_Code": "321100", + "navParaentId_Name": "镇江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0899", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2fca-4995-814f-c2f6e777c0fc", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-70d3-4e64-9618-49baa31e94c0", + "version": null, + "code": "321112", + "name": "丹徒区", + "gjmc": "丹徒区", + "udtwb": { + "chComTextMDS": "0898" + }, + "pathInfo": { + "path": "001100110003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c7fa-4d70-a7de-b77ce19c191e", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c7fa-4d70-a7de-b77ce19c191e", + "navParaentId_Code": "321100", + "navParaentId_Name": "镇江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0898", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-70d3-4e64-9618-49baa31e94c0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e90c-4a31-aea9-20dba0fd29da", + "version": null, + "code": "321111", + "name": "润州区", + "gjmc": "润州区", + "udtwb": { + "chComTextMDS": "0897" + }, + "pathInfo": { + "path": "001100110002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c7fa-4d70-a7de-b77ce19c191e", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c7fa-4d70-a7de-b77ce19c191e", + "navParaentId_Code": "321100", + "navParaentId_Name": "镇江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0897", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e90c-4a31-aea9-20dba0fd29da", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4aaa-4397-9863-2ffc3b0a7ea5", + "version": null, + "code": "321102", + "name": "京口区", + "gjmc": "京口区", + "udtwb": { + "chComTextMDS": "0896" + }, + "pathInfo": { + "path": "001100110001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c7fa-4d70-a7de-b77ce19c191e", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c7fa-4d70-a7de-b77ce19c191e", + "navParaentId_Code": "321100", + "navParaentId_Name": "镇江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0896", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4aaa-4397-9863-2ffc3b0a7ea5", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c7fa-4d70-a7de-b77ce19c191e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e5d2-4380-a8e5-3ef6c77faf2c", + "version": null, + "code": "321000", + "name": "扬州市", + "gjmc": "扬州市", + "udtwb": { + "chComTextMDS": "0888" + }, + "pathInfo": { + "path": "00110010", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "sequence": 10, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4109-446c-8882-2e35a877166a", + "navParaentId_Code": "320000", + "navParaentId_Name": "江苏省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0888", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-1885-411a-ac93-51444751e79a", + "version": null, + "code": "321084", + "name": "高邮市", + "gjmc": "高邮市", + "udtwb": { + "chComTextMDS": "0894" + }, + "pathInfo": { + "path": "001100100006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e5d2-4380-a8e5-3ef6c77faf2c", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e5d2-4380-a8e5-3ef6c77faf2c", + "navParaentId_Code": "321000", + "navParaentId_Name": "扬州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0894", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1885-411a-ac93-51444751e79a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ce9a-4435-9bb8-9906b9202d22", + "version": null, + "code": "321081", + "name": "仪征市", + "gjmc": "仪征市", + "udtwb": { + "chComTextMDS": "0893" + }, + "pathInfo": { + "path": "001100100005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e5d2-4380-a8e5-3ef6c77faf2c", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e5d2-4380-a8e5-3ef6c77faf2c", + "navParaentId_Code": "321000", + "navParaentId_Name": "扬州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0893", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ce9a-4435-9bb8-9906b9202d22", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bf91-4980-8a05-1975605a2b12", + "version": null, + "code": "321023", + "name": "宝应县", + "gjmc": "宝应县", + "udtwb": { + "chComTextMDS": "0892" + }, + "pathInfo": { + "path": "001100100004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e5d2-4380-a8e5-3ef6c77faf2c", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e5d2-4380-a8e5-3ef6c77faf2c", + "navParaentId_Code": "321000", + "navParaentId_Name": "扬州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0892", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bf91-4980-8a05-1975605a2b12", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f988-460b-8f79-172d0a4927c2", + "version": null, + "code": "321012", + "name": "江都区", + "gjmc": "江都区", + "udtwb": { + "chComTextMDS": "0891" + }, + "pathInfo": { + "path": "001100100003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e5d2-4380-a8e5-3ef6c77faf2c", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e5d2-4380-a8e5-3ef6c77faf2c", + "navParaentId_Code": "321000", + "navParaentId_Name": "扬州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0891", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f988-460b-8f79-172d0a4927c2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d484-4ee6-80ee-cb21d2a97b80", + "version": null, + "code": "321003", + "name": "邗江区", + "gjmc": "邗江区", + "udtwb": { + "chComTextMDS": "0890" + }, + "pathInfo": { + "path": "001100100002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e5d2-4380-a8e5-3ef6c77faf2c", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e5d2-4380-a8e5-3ef6c77faf2c", + "navParaentId_Code": "321000", + "navParaentId_Name": "扬州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0890", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d484-4ee6-80ee-cb21d2a97b80", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c8f6-44c2-a047-ef8f40cc4ba5", + "version": null, + "code": "321002", + "name": "广陵区", + "gjmc": "广陵区", + "udtwb": { + "chComTextMDS": "0889" + }, + "pathInfo": { + "path": "001100100001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e5d2-4380-a8e5-3ef6c77faf2c", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e5d2-4380-a8e5-3ef6c77faf2c", + "navParaentId_Code": "321000", + "navParaentId_Name": "扬州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0889", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c8f6-44c2-a047-ef8f40cc4ba5", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e5d2-4380-a8e5-3ef6c77faf2c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5b54-4027-8f23-73a708250df6", + "version": null, + "code": "320900", + "name": "盐城市", + "gjmc": "盐城市", + "udtwb": { + "chComTextMDS": "0878" + }, + "pathInfo": { + "path": "00110009", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "sequence": 9, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4109-446c-8882-2e35a877166a", + "navParaentId_Code": "320000", + "navParaentId_Name": "江苏省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0878", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-707e-4dbc-9679-7b772eacd5d8", + "version": null, + "code": "320981", + "name": "东台市", + "gjmc": "东台市", + "udtwb": { + "chComTextMDS": "0887" + }, + "pathInfo": { + "path": "001100090009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5b54-4027-8f23-73a708250df6", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5b54-4027-8f23-73a708250df6", + "navParaentId_Code": "320900", + "navParaentId_Name": "盐城市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0887", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-707e-4dbc-9679-7b772eacd5d8", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3e4a-4926-8dad-b593baba478a", + "version": null, + "code": "320925", + "name": "建湖县", + "gjmc": "建湖县", + "udtwb": { + "chComTextMDS": "0886" + }, + "pathInfo": { + "path": "001100090008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5b54-4027-8f23-73a708250df6", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5b54-4027-8f23-73a708250df6", + "navParaentId_Code": "320900", + "navParaentId_Name": "盐城市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0886", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3e4a-4926-8dad-b593baba478a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e3b4-4695-be1b-bf29bf799baa", + "version": null, + "code": "320924", + "name": "射阳县", + "gjmc": "射阳县", + "udtwb": { + "chComTextMDS": "0885" + }, + "pathInfo": { + "path": "001100090007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5b54-4027-8f23-73a708250df6", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5b54-4027-8f23-73a708250df6", + "navParaentId_Code": "320900", + "navParaentId_Name": "盐城市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0885", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e3b4-4695-be1b-bf29bf799baa", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-935a-4b5d-9df4-867ddb6c82fc", + "version": null, + "code": "320923", + "name": "阜宁县", + "gjmc": "阜宁县", + "udtwb": { + "chComTextMDS": "0884" + }, + "pathInfo": { + "path": "001100090006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5b54-4027-8f23-73a708250df6", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5b54-4027-8f23-73a708250df6", + "navParaentId_Code": "320900", + "navParaentId_Name": "盐城市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0884", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-935a-4b5d-9df4-867ddb6c82fc", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6997-4059-9de0-8862532881b0", + "version": null, + "code": "320922", + "name": "滨海县", + "gjmc": "滨海县", + "udtwb": { + "chComTextMDS": "0883" + }, + "pathInfo": { + "path": "001100090005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5b54-4027-8f23-73a708250df6", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5b54-4027-8f23-73a708250df6", + "navParaentId_Code": "320900", + "navParaentId_Name": "盐城市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0883", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6997-4059-9de0-8862532881b0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f609-4a3e-8c68-172c9efdbeff", + "version": null, + "code": "320921", + "name": "响水县", + "gjmc": "响水县", + "udtwb": { + "chComTextMDS": "0882" + }, + "pathInfo": { + "path": "001100090004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5b54-4027-8f23-73a708250df6", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5b54-4027-8f23-73a708250df6", + "navParaentId_Code": "320900", + "navParaentId_Name": "盐城市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0882", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f609-4a3e-8c68-172c9efdbeff", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6704-4805-bd45-50e14050c198", + "version": null, + "code": "320904", + "name": "大丰区", + "gjmc": "大丰区", + "udtwb": { + "chComTextMDS": "0881" + }, + "pathInfo": { + "path": "001100090003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5b54-4027-8f23-73a708250df6", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5b54-4027-8f23-73a708250df6", + "navParaentId_Code": "320900", + "navParaentId_Name": "盐城市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0881", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6704-4805-bd45-50e14050c198", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8d2d-4481-b274-db1a98fba4c0", + "version": null, + "code": "320903", + "name": "盐都区", + "gjmc": "盐都区", + "udtwb": { + "chComTextMDS": "0880" + }, + "pathInfo": { + "path": "001100090002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5b54-4027-8f23-73a708250df6", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5b54-4027-8f23-73a708250df6", + "navParaentId_Code": "320900", + "navParaentId_Name": "盐城市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0880", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8d2d-4481-b274-db1a98fba4c0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c254-4952-8061-47657479a1d4", + "version": null, + "code": "320902", + "name": "亭湖区", + "gjmc": "亭湖区", + "udtwb": { + "chComTextMDS": "0879" + }, + "pathInfo": { + "path": "001100090001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-5b54-4027-8f23-73a708250df6", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-5b54-4027-8f23-73a708250df6", + "navParaentId_Code": "320900", + "navParaentId_Name": "盐城市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0879", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c254-4952-8061-47657479a1d4", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5b54-4027-8f23-73a708250df6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d235-40ba-b500-b54da35dd4dd", + "version": null, + "code": "320800", + "name": "淮安市", + "gjmc": "淮安市", + "udtwb": { + "chComTextMDS": "0870" + }, + "pathInfo": { + "path": "00110008", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "sequence": 8, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4109-446c-8882-2e35a877166a", + "navParaentId_Code": "320000", + "navParaentId_Name": "江苏省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0870", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-4643-4ba2-bf24-2ec811aba8cc", + "version": null, + "code": "320831", + "name": "金湖县", + "gjmc": "金湖县", + "udtwb": { + "chComTextMDS": "0877" + }, + "pathInfo": { + "path": "001100080007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d235-40ba-b500-b54da35dd4dd", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d235-40ba-b500-b54da35dd4dd", + "navParaentId_Code": "320800", + "navParaentId_Name": "淮安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0877", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4643-4ba2-bf24-2ec811aba8cc", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c95e-4842-9448-73cee2eada7d", + "version": null, + "code": "320830", + "name": "盱眙县", + "gjmc": "盱眙县", + "udtwb": { + "chComTextMDS": "0876" + }, + "pathInfo": { + "path": "001100080006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d235-40ba-b500-b54da35dd4dd", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d235-40ba-b500-b54da35dd4dd", + "navParaentId_Code": "320800", + "navParaentId_Name": "淮安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0876", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c95e-4842-9448-73cee2eada7d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-578d-4929-891e-73b6b07da3bc", + "version": null, + "code": "320826", + "name": "涟水县", + "gjmc": "涟水县", + "udtwb": { + "chComTextMDS": "0875" + }, + "pathInfo": { + "path": "001100080005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d235-40ba-b500-b54da35dd4dd", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d235-40ba-b500-b54da35dd4dd", + "navParaentId_Code": "320800", + "navParaentId_Name": "淮安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0875", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-578d-4929-891e-73b6b07da3bc", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6846-45cf-b09d-b02ad3975739", + "version": null, + "code": "320813", + "name": "洪泽区", + "gjmc": "洪泽区", + "udtwb": { + "chComTextMDS": "0874" + }, + "pathInfo": { + "path": "001100080004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d235-40ba-b500-b54da35dd4dd", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d235-40ba-b500-b54da35dd4dd", + "navParaentId_Code": "320800", + "navParaentId_Name": "淮安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0874", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6846-45cf-b09d-b02ad3975739", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a706-4a47-aed2-67c5a1dc02be", + "version": null, + "code": "320812", + "name": "清江浦区", + "gjmc": "清江浦区", + "udtwb": { + "chComTextMDS": "0873" + }, + "pathInfo": { + "path": "001100080003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d235-40ba-b500-b54da35dd4dd", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d235-40ba-b500-b54da35dd4dd", + "navParaentId_Code": "320800", + "navParaentId_Name": "淮安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0873", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a706-4a47-aed2-67c5a1dc02be", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8a7e-4687-83fc-278914f77b49", + "version": null, + "code": "320804", + "name": "淮阴区", + "gjmc": "淮阴区", + "udtwb": { + "chComTextMDS": "0872" + }, + "pathInfo": { + "path": "001100080002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d235-40ba-b500-b54da35dd4dd", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d235-40ba-b500-b54da35dd4dd", + "navParaentId_Code": "320800", + "navParaentId_Name": "淮安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0872", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8a7e-4687-83fc-278914f77b49", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0ea0-49f5-9a50-2518c8025f0c", + "version": null, + "code": "320803", + "name": "淮安区", + "gjmc": "淮安区", + "udtwb": { + "chComTextMDS": "0871" + }, + "pathInfo": { + "path": "001100080001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-d235-40ba-b500-b54da35dd4dd", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-d235-40ba-b500-b54da35dd4dd", + "navParaentId_Code": "320800", + "navParaentId_Name": "淮安市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0871", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0ea0-49f5-9a50-2518c8025f0c", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d235-40ba-b500-b54da35dd4dd", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9a12-4bbd-bb43-35e0689c7f74", + "version": null, + "code": "320700", + "name": "连云港市", + "gjmc": "连云港市", + "udtwb": { + "chComTextMDS": "0863" + }, + "pathInfo": { + "path": "00110007", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "sequence": 7, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4109-446c-8882-2e35a877166a", + "navParaentId_Code": "320000", + "navParaentId_Name": "江苏省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0863", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-7c66-4677-89be-0a80200917a0", + "version": null, + "code": "320724", + "name": "灌南县", + "gjmc": "灌南县", + "udtwb": { + "chComTextMDS": "0869" + }, + "pathInfo": { + "path": "001100070006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9a12-4bbd-bb43-35e0689c7f74", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9a12-4bbd-bb43-35e0689c7f74", + "navParaentId_Code": "320700", + "navParaentId_Name": "连云港市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0869", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7c66-4677-89be-0a80200917a0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6232-46c8-89ef-b295d1d25440", + "version": null, + "code": "320723", + "name": "灌云县", + "gjmc": "灌云县", + "udtwb": { + "chComTextMDS": "0868" + }, + "pathInfo": { + "path": "001100070005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9a12-4bbd-bb43-35e0689c7f74", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9a12-4bbd-bb43-35e0689c7f74", + "navParaentId_Code": "320700", + "navParaentId_Name": "连云港市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0868", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6232-46c8-89ef-b295d1d25440", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b9b4-4bee-b337-6a79ad5a543b", + "version": null, + "code": "320722", + "name": "东海县", + "gjmc": "东海县", + "udtwb": { + "chComTextMDS": "0867" + }, + "pathInfo": { + "path": "001100070004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9a12-4bbd-bb43-35e0689c7f74", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9a12-4bbd-bb43-35e0689c7f74", + "navParaentId_Code": "320700", + "navParaentId_Name": "连云港市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0867", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b9b4-4bee-b337-6a79ad5a543b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b504-4d16-90c7-4da38edd46ab", + "version": null, + "code": "320707", + "name": "赣榆区", + "gjmc": "赣榆区", + "udtwb": { + "chComTextMDS": "0866" + }, + "pathInfo": { + "path": "001100070003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9a12-4bbd-bb43-35e0689c7f74", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9a12-4bbd-bb43-35e0689c7f74", + "navParaentId_Code": "320700", + "navParaentId_Name": "连云港市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0866", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b504-4d16-90c7-4da38edd46ab", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ff52-4696-bb58-169fd1921ac3", + "version": null, + "code": "320706", + "name": "海州区", + "gjmc": "海州区", + "udtwb": { + "chComTextMDS": "0865" + }, + "pathInfo": { + "path": "001100070002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9a12-4bbd-bb43-35e0689c7f74", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9a12-4bbd-bb43-35e0689c7f74", + "navParaentId_Code": "320700", + "navParaentId_Name": "连云港市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0865", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ff52-4696-bb58-169fd1921ac3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ca42-4c77-ac2a-719c0a4b2b1a", + "version": null, + "code": "320703", + "name": "连云区", + "gjmc": "连云区", + "udtwb": { + "chComTextMDS": "0864" + }, + "pathInfo": { + "path": "001100070001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9a12-4bbd-bb43-35e0689c7f74", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9a12-4bbd-bb43-35e0689c7f74", + "navParaentId_Code": "320700", + "navParaentId_Name": "连云港市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0864", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ca42-4c77-ac2a-719c0a4b2b1a", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9a12-4bbd-bb43-35e0689c7f74", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4205-47a9-8f75-03fc40be1f39", + "version": null, + "code": "320600", + "name": "南通市", + "gjmc": "南通市", + "udtwb": { + "chComTextMDS": "0854" + }, + "pathInfo": { + "path": "00110006", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "sequence": 6, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4109-446c-8882-2e35a877166a", + "navParaentId_Code": "320000", + "navParaentId_Name": "江苏省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0854", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-5c21-49d9-ad45-76e682361dd2", + "version": null, + "code": "320685", + "name": "海安市", + "gjmc": "海安市", + "udtwb": { + "chComTextMDS": "0862" + }, + "pathInfo": { + "path": "001100060008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4205-47a9-8f75-03fc40be1f39", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4205-47a9-8f75-03fc40be1f39", + "navParaentId_Code": "320600", + "navParaentId_Name": "南通市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0862", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5c21-49d9-ad45-76e682361dd2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-fda2-4426-b02d-60f3b111a22b", + "version": null, + "code": "320684", + "name": "海门市", + "gjmc": "海门市", + "udtwb": { + "chComTextMDS": "0861" + }, + "pathInfo": { + "path": "001100060007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4205-47a9-8f75-03fc40be1f39", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4205-47a9-8f75-03fc40be1f39", + "navParaentId_Code": "320600", + "navParaentId_Name": "南通市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0861", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fda2-4426-b02d-60f3b111a22b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1902-486d-97d1-1e5f984ae691", + "version": null, + "code": "320682", + "name": "如皋市", + "gjmc": "如皋市", + "udtwb": { + "chComTextMDS": "0860" + }, + "pathInfo": { + "path": "001100060006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4205-47a9-8f75-03fc40be1f39", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4205-47a9-8f75-03fc40be1f39", + "navParaentId_Code": "320600", + "navParaentId_Name": "南通市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0860", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1902-486d-97d1-1e5f984ae691", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7bd5-45db-b921-fe9f2ef58533", + "version": null, + "code": "320681", + "name": "启东市", + "gjmc": "启东市", + "udtwb": { + "chComTextMDS": "0859" + }, + "pathInfo": { + "path": "001100060005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4205-47a9-8f75-03fc40be1f39", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4205-47a9-8f75-03fc40be1f39", + "navParaentId_Code": "320600", + "navParaentId_Name": "南通市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0859", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7bd5-45db-b921-fe9f2ef58533", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-aaae-4666-844e-a03b5a404362", + "version": null, + "code": "320623", + "name": "如东县", + "gjmc": "如东县", + "udtwb": { + "chComTextMDS": "0858" + }, + "pathInfo": { + "path": "001100060004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4205-47a9-8f75-03fc40be1f39", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4205-47a9-8f75-03fc40be1f39", + "navParaentId_Code": "320600", + "navParaentId_Name": "南通市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0858", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-aaae-4666-844e-a03b5a404362", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8890-4176-8a3c-c94b53c13ac9", + "version": null, + "code": "320612", + "name": "通州区", + "gjmc": "通州区", + "udtwb": { + "chComTextMDS": "0857" + }, + "pathInfo": { + "path": "001100060003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4205-47a9-8f75-03fc40be1f39", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4205-47a9-8f75-03fc40be1f39", + "navParaentId_Code": "320600", + "navParaentId_Name": "南通市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0857", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8890-4176-8a3c-c94b53c13ac9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c28f-461a-82ce-32c7d79d8df1", + "version": null, + "code": "320611", + "name": "港闸区", + "gjmc": "港闸区", + "udtwb": { + "chComTextMDS": "0856" + }, + "pathInfo": { + "path": "001100060002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4205-47a9-8f75-03fc40be1f39", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4205-47a9-8f75-03fc40be1f39", + "navParaentId_Code": "320600", + "navParaentId_Name": "南通市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0856", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c28f-461a-82ce-32c7d79d8df1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1f56-42e4-8fe0-0c39ecff786b", + "version": null, + "code": "320602", + "name": "崇川区", + "gjmc": "崇川区", + "udtwb": { + "chComTextMDS": "0855" + }, + "pathInfo": { + "path": "001100060001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4205-47a9-8f75-03fc40be1f39", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4205-47a9-8f75-03fc40be1f39", + "navParaentId_Code": "320600", + "navParaentId_Name": "南通市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0855", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1f56-42e4-8fe0-0c39ecff786b", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4205-47a9-8f75-03fc40be1f39", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1e56-477f-9831-698d8c1884ed", + "version": null, + "code": "320500", + "name": "苏州市", + "gjmc": "苏州市", + "udtwb": { + "chComTextMDS": "0844" + }, + "pathInfo": { + "path": "00110005", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "sequence": 5, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4109-446c-8882-2e35a877166a", + "navParaentId_Code": "320000", + "navParaentId_Name": "江苏省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0844", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-d6d6-487a-8f81-46bb6281ddf5", + "version": null, + "code": "320585", + "name": "太仓市", + "gjmc": "太仓市", + "udtwb": { + "chComTextMDS": "0853" + }, + "pathInfo": { + "path": "001100050009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1e56-477f-9831-698d8c1884ed", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1e56-477f-9831-698d8c1884ed", + "navParaentId_Code": "320500", + "navParaentId_Name": "苏州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0853", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d6d6-487a-8f81-46bb6281ddf5", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6120-4b29-ae6b-a12698454c3b", + "version": null, + "code": "320583", + "name": "昆山市", + "gjmc": "昆山市", + "udtwb": { + "chComTextMDS": "0852" + }, + "pathInfo": { + "path": "001100050008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1e56-477f-9831-698d8c1884ed", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1e56-477f-9831-698d8c1884ed", + "navParaentId_Code": "320500", + "navParaentId_Name": "苏州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0852", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6120-4b29-ae6b-a12698454c3b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d829-4e7f-9083-e3aa309daca8", + "version": null, + "code": "320582", + "name": "张家港市", + "gjmc": "张家港市", + "udtwb": { + "chComTextMDS": "0851" + }, + "pathInfo": { + "path": "001100050007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1e56-477f-9831-698d8c1884ed", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1e56-477f-9831-698d8c1884ed", + "navParaentId_Code": "320500", + "navParaentId_Name": "苏州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0851", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d829-4e7f-9083-e3aa309daca8", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7799-4229-b762-72e6361df4f7", + "version": null, + "code": "320581", + "name": "常熟市", + "gjmc": "常熟市", + "udtwb": { + "chComTextMDS": "0850" + }, + "pathInfo": { + "path": "001100050006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1e56-477f-9831-698d8c1884ed", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1e56-477f-9831-698d8c1884ed", + "navParaentId_Code": "320500", + "navParaentId_Name": "苏州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0850", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7799-4229-b762-72e6361df4f7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1e14-49c3-a04a-a118fa4e1bb3", + "version": null, + "code": "320509", + "name": "吴江区", + "gjmc": "吴江区", + "udtwb": { + "chComTextMDS": "0849" + }, + "pathInfo": { + "path": "001100050005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1e56-477f-9831-698d8c1884ed", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1e56-477f-9831-698d8c1884ed", + "navParaentId_Code": "320500", + "navParaentId_Name": "苏州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0849", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1e14-49c3-a04a-a118fa4e1bb3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-92fa-4633-ac2c-237a2cd7d9c0", + "version": null, + "code": "320508", + "name": "姑苏区", + "gjmc": "姑苏区", + "udtwb": { + "chComTextMDS": "0848" + }, + "pathInfo": { + "path": "001100050004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1e56-477f-9831-698d8c1884ed", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1e56-477f-9831-698d8c1884ed", + "navParaentId_Code": "320500", + "navParaentId_Name": "苏州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0848", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-92fa-4633-ac2c-237a2cd7d9c0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-58eb-4450-bdfa-60259d1c95cd", + "version": null, + "code": "320507", + "name": "相城区", + "gjmc": "相城区", + "udtwb": { + "chComTextMDS": "0847" + }, + "pathInfo": { + "path": "001100050003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1e56-477f-9831-698d8c1884ed", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1e56-477f-9831-698d8c1884ed", + "navParaentId_Code": "320500", + "navParaentId_Name": "苏州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0847", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-58eb-4450-bdfa-60259d1c95cd", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b620-4123-b3e2-aac20ba7df77", + "version": null, + "code": "320506", + "name": "吴中区", + "gjmc": "吴中区", + "udtwb": { + "chComTextMDS": "0846" + }, + "pathInfo": { + "path": "001100050002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1e56-477f-9831-698d8c1884ed", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1e56-477f-9831-698d8c1884ed", + "navParaentId_Code": "320500", + "navParaentId_Name": "苏州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0846", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b620-4123-b3e2-aac20ba7df77", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6950-4f38-905a-1ae21368b247", + "version": null, + "code": "320505", + "name": "虎丘区", + "gjmc": "虎丘区", + "udtwb": { + "chComTextMDS": "0845" + }, + "pathInfo": { + "path": "001100050001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1e56-477f-9831-698d8c1884ed", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1e56-477f-9831-698d8c1884ed", + "navParaentId_Code": "320500", + "navParaentId_Name": "苏州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0845", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6950-4f38-905a-1ae21368b247", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1e56-477f-9831-698d8c1884ed", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c05f-4def-a4d7-80466a8c0232", + "version": null, + "code": "320400", + "name": "常州市", + "gjmc": "常州市", + "udtwb": { + "chComTextMDS": "0837" + }, + "pathInfo": { + "path": "00110004", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "sequence": 4, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4109-446c-8882-2e35a877166a", + "navParaentId_Code": "320000", + "navParaentId_Name": "江苏省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0837", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-d198-4769-b230-2a99919817a2", + "version": null, + "code": "320481", + "name": "溧阳市", + "gjmc": "溧阳市", + "udtwb": { + "chComTextMDS": "0843" + }, + "pathInfo": { + "path": "001100040006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c05f-4def-a4d7-80466a8c0232", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c05f-4def-a4d7-80466a8c0232", + "navParaentId_Code": "320400", + "navParaentId_Name": "常州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0843", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d198-4769-b230-2a99919817a2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a3db-4b1e-9665-88297c2bad25", + "version": null, + "code": "320413", + "name": "金坛区", + "gjmc": "金坛区", + "udtwb": { + "chComTextMDS": "0842" + }, + "pathInfo": { + "path": "001100040005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c05f-4def-a4d7-80466a8c0232", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c05f-4def-a4d7-80466a8c0232", + "navParaentId_Code": "320400", + "navParaentId_Name": "常州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0842", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a3db-4b1e-9665-88297c2bad25", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-65ea-47f7-862c-fb4dbc0dc43f", + "version": null, + "code": "320412", + "name": "武进区", + "gjmc": "武进区", + "udtwb": { + "chComTextMDS": "0841" + }, + "pathInfo": { + "path": "001100040004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c05f-4def-a4d7-80466a8c0232", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c05f-4def-a4d7-80466a8c0232", + "navParaentId_Code": "320400", + "navParaentId_Name": "常州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0841", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-65ea-47f7-862c-fb4dbc0dc43f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2238-48f1-9221-3bd7bfe7a42b", + "version": null, + "code": "320411", + "name": "新北区", + "gjmc": "新北区", + "udtwb": { + "chComTextMDS": "0840" + }, + "pathInfo": { + "path": "001100040003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c05f-4def-a4d7-80466a8c0232", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c05f-4def-a4d7-80466a8c0232", + "navParaentId_Code": "320400", + "navParaentId_Name": "常州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0840", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2238-48f1-9221-3bd7bfe7a42b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1e5c-4798-815b-0148d903acce", + "version": null, + "code": "320404", + "name": "钟楼区", + "gjmc": "钟楼区", + "udtwb": { + "chComTextMDS": "0839" + }, + "pathInfo": { + "path": "001100040002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c05f-4def-a4d7-80466a8c0232", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c05f-4def-a4d7-80466a8c0232", + "navParaentId_Code": "320400", + "navParaentId_Name": "常州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0839", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1e5c-4798-815b-0148d903acce", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6576-4dd9-b0ee-9cd4bfc08cfe", + "version": null, + "code": "320402", + "name": "天宁区", + "gjmc": "天宁区", + "udtwb": { + "chComTextMDS": "0838" + }, + "pathInfo": { + "path": "001100040001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-c05f-4def-a4d7-80466a8c0232", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-c05f-4def-a4d7-80466a8c0232", + "navParaentId_Code": "320400", + "navParaentId_Name": "常州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0838", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6576-4dd9-b0ee-9cd4bfc08cfe", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c05f-4def-a4d7-80466a8c0232", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "version": null, + "code": "320300", + "name": "徐州市", + "gjmc": "徐州市", + "udtwb": { + "chComTextMDS": "0826" + }, + "pathInfo": { + "path": "00110003", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "sequence": 3, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4109-446c-8882-2e35a877166a", + "navParaentId_Code": "320000", + "navParaentId_Name": "江苏省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0826", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-245c-4faa-a1b4-62f77c355df7", + "version": null, + "code": "320382", + "name": "邳州市", + "gjmc": "邳州市", + "udtwb": { + "chComTextMDS": "0836" + }, + "pathInfo": { + "path": "001100030010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "navParaentId_Code": "320300", + "navParaentId_Name": "徐州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0836", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-245c-4faa-a1b4-62f77c355df7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d887-4b5a-8c5e-732cdaa2d518", + "version": null, + "code": "320381", + "name": "新沂市", + "gjmc": "新沂市", + "udtwb": { + "chComTextMDS": "0835" + }, + "pathInfo": { + "path": "001100030009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "navParaentId_Code": "320300", + "navParaentId_Name": "徐州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0835", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d887-4b5a-8c5e-732cdaa2d518", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2045-4189-86f2-6ea63763b97c", + "version": null, + "code": "320324", + "name": "睢宁县", + "gjmc": "睢宁县", + "udtwb": { + "chComTextMDS": "0834" + }, + "pathInfo": { + "path": "001100030008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "navParaentId_Code": "320300", + "navParaentId_Name": "徐州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0834", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2045-4189-86f2-6ea63763b97c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2582-4d53-b745-14d856916faa", + "version": null, + "code": "320322", + "name": "沛县", + "gjmc": "沛县", + "udtwb": { + "chComTextMDS": "0833" + }, + "pathInfo": { + "path": "001100030007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "navParaentId_Code": "320300", + "navParaentId_Name": "徐州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0833", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2582-4d53-b745-14d856916faa", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f28f-4871-accb-13e6826c545a", + "version": null, + "code": "320321", + "name": "丰县", + "gjmc": "丰县", + "udtwb": { + "chComTextMDS": "0832" + }, + "pathInfo": { + "path": "001100030006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "navParaentId_Code": "320300", + "navParaentId_Name": "徐州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0832", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f28f-4871-accb-13e6826c545a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6b10-4acc-81e1-b0bd678fabff", + "version": null, + "code": "320312", + "name": "铜山区", + "gjmc": "铜山区", + "udtwb": { + "chComTextMDS": "0831" + }, + "pathInfo": { + "path": "001100030005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "navParaentId_Code": "320300", + "navParaentId_Name": "徐州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0831", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6b10-4acc-81e1-b0bd678fabff", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4c59-4742-b853-8dbd0610a3bb", + "version": null, + "code": "320311", + "name": "泉山区", + "gjmc": "泉山区", + "udtwb": { + "chComTextMDS": "0830" + }, + "pathInfo": { + "path": "001100030004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "navParaentId_Code": "320300", + "navParaentId_Name": "徐州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0830", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4c59-4742-b853-8dbd0610a3bb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c4e3-4220-99f0-0daf5806a689", + "version": null, + "code": "320305", + "name": "贾汪区", + "gjmc": "贾汪区", + "udtwb": { + "chComTextMDS": "0829" + }, + "pathInfo": { + "path": "001100030003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "navParaentId_Code": "320300", + "navParaentId_Name": "徐州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0829", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c4e3-4220-99f0-0daf5806a689", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-40f7-4436-9a90-594a9302acc5", + "version": null, + "code": "320303", + "name": "云龙区", + "gjmc": "云龙区", + "udtwb": { + "chComTextMDS": "0828" + }, + "pathInfo": { + "path": "001100030002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "navParaentId_Code": "320300", + "navParaentId_Name": "徐州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0828", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-40f7-4436-9a90-594a9302acc5", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e60b-4156-8aa0-ea68a6d1bcb8", + "version": null, + "code": "320302", + "name": "鼓楼区", + "gjmc": "鼓楼区", + "udtwb": { + "chComTextMDS": "0827" + }, + "pathInfo": { + "path": "001100030001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "navParaentId_Code": "320300", + "navParaentId_Name": "徐州市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0827", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e60b-4156-8aa0-ea68a6d1bcb8", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b2db-4f1c-a04b-b8db6177523d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "version": null, + "code": "320200", + "name": "无锡市", + "gjmc": "无锡市", + "udtwb": { + "chComTextMDS": "0818" + }, + "pathInfo": { + "path": "00110002", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "sequence": 2, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4109-446c-8882-2e35a877166a", + "navParaentId_Code": "320000", + "navParaentId_Name": "江苏省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0818", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-0d47-4f96-91d3-7f6c4efc33b7", + "version": null, + "code": "320282", + "name": "宜兴市", + "gjmc": "宜兴市", + "udtwb": { + "chComTextMDS": "0825" + }, + "pathInfo": { + "path": "001100020007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "navParaentId_Code": "320200", + "navParaentId_Name": "无锡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0825", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0d47-4f96-91d3-7f6c4efc33b7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d978-4752-b99c-3fdcb66622b2", + "version": null, + "code": "320281", + "name": "江阴市", + "gjmc": "江阴市", + "udtwb": { + "chComTextMDS": "0824" + }, + "pathInfo": { + "path": "001100020006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "navParaentId_Code": "320200", + "navParaentId_Name": "无锡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0824", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d978-4752-b99c-3fdcb66622b2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0ba4-4856-a46f-eb5473393226", + "version": null, + "code": "320214", + "name": "新吴区", + "gjmc": "新吴区", + "udtwb": { + "chComTextMDS": "0823" + }, + "pathInfo": { + "path": "001100020005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "navParaentId_Code": "320200", + "navParaentId_Name": "无锡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0823", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0ba4-4856-a46f-eb5473393226", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-fa08-4f36-8011-0ec9d728d301", + "version": null, + "code": "320213", + "name": "梁溪区", + "gjmc": "梁溪区", + "udtwb": { + "chComTextMDS": "0822" + }, + "pathInfo": { + "path": "001100020004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "navParaentId_Code": "320200", + "navParaentId_Name": "无锡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0822", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fa08-4f36-8011-0ec9d728d301", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e27d-4d0e-b0de-db2abad432c9", + "version": null, + "code": "320211", + "name": "滨湖区", + "gjmc": "滨湖区", + "udtwb": { + "chComTextMDS": "0821" + }, + "pathInfo": { + "path": "001100020003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "navParaentId_Code": "320200", + "navParaentId_Name": "无锡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0821", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e27d-4d0e-b0de-db2abad432c9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0fc6-4b0d-8d20-6f0a9928e096", + "version": null, + "code": "320206", + "name": "惠山区", + "gjmc": "惠山区", + "udtwb": { + "chComTextMDS": "0820" + }, + "pathInfo": { + "path": "001100020002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "navParaentId_Code": "320200", + "navParaentId_Name": "无锡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0820", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0fc6-4b0d-8d20-6f0a9928e096", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7871-4467-ad07-bc4bc39c963d", + "version": null, + "code": "320205", + "name": "锡山区", + "gjmc": "锡山区", + "udtwb": { + "chComTextMDS": "0819" + }, + "pathInfo": { + "path": "001100020001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "navParaentId_Code": "320200", + "navParaentId_Name": "无锡市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0819", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7871-4467-ad07-bc4bc39c963d", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a4f3-4992-8c88-4d4689f75be9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "version": null, + "code": "320100", + "name": "南京市", + "gjmc": "南京市", + "udtwb": { + "chComTextMDS": "0806" + }, + "pathInfo": { + "path": "00110001", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "sequence": 1, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-4109-446c-8882-2e35a877166a", + "navParaentId_Code": "320000", + "navParaentId_Name": "江苏省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0806", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-15ff-42b6-8950-5d3131709a46", + "version": null, + "code": "320118", + "name": "高淳区", + "gjmc": "高淳区", + "udtwb": { + "chComTextMDS": "0817" + }, + "pathInfo": { + "path": "001100010011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "navParaentId_Code": "320100", + "navParaentId_Name": "南京市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0817", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-15ff-42b6-8950-5d3131709a46", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-067c-45a0-84a1-aa47231ccd77", + "version": null, + "code": "320117", + "name": "溧水区", + "gjmc": "溧水区", + "udtwb": { + "chComTextMDS": "0816" + }, + "pathInfo": { + "path": "001100010010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "navParaentId_Code": "320100", + "navParaentId_Name": "南京市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0816", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-067c-45a0-84a1-aa47231ccd77", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-dfcf-46cc-bd5a-ecebba5b962f", + "version": null, + "code": "320116", + "name": "六合区", + "gjmc": "六合区", + "udtwb": { + "chComTextMDS": "0815" + }, + "pathInfo": { + "path": "001100010009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "navParaentId_Code": "320100", + "navParaentId_Name": "南京市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0815", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-dfcf-46cc-bd5a-ecebba5b962f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a509-46c4-b1b0-585cd692cd7f", + "version": null, + "code": "320115", + "name": "江宁区", + "gjmc": "江宁区", + "udtwb": { + "chComTextMDS": "0814" + }, + "pathInfo": { + "path": "001100010008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "navParaentId_Code": "320100", + "navParaentId_Name": "南京市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0814", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a509-46c4-b1b0-585cd692cd7f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e11e-4e6f-830a-823d5ed666bb", + "version": null, + "code": "320114", + "name": "雨花台区", + "gjmc": "雨花台区", + "udtwb": { + "chComTextMDS": "0813" + }, + "pathInfo": { + "path": "001100010007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "navParaentId_Code": "320100", + "navParaentId_Name": "南京市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0813", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e11e-4e6f-830a-823d5ed666bb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d865-411c-a704-3bcbd6bc4608", + "version": null, + "code": "320113", + "name": "栖霞区", + "gjmc": "栖霞区", + "udtwb": { + "chComTextMDS": "0812" + }, + "pathInfo": { + "path": "001100010006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "navParaentId_Code": "320100", + "navParaentId_Name": "南京市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0812", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d865-411c-a704-3bcbd6bc4608", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8013-488e-95e4-458b6fff9634", + "version": null, + "code": "320111", + "name": "浦口区", + "gjmc": "浦口区", + "udtwb": { + "chComTextMDS": "0811" + }, + "pathInfo": { + "path": "001100010005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "navParaentId_Code": "320100", + "navParaentId_Name": "南京市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0811", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8013-488e-95e4-458b6fff9634", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-471e-409f-8c15-a86dfebc9810", + "version": null, + "code": "320106", + "name": "鼓楼区", + "gjmc": "鼓楼区", + "udtwb": { + "chComTextMDS": "0810" + }, + "pathInfo": { + "path": "001100010004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "navParaentId_Code": "320100", + "navParaentId_Name": "南京市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0810", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-471e-409f-8c15-a86dfebc9810", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a22f-46ff-9738-dbcbe3fa2b31", + "version": null, + "code": "320105", + "name": "建邺区", + "gjmc": "建邺区", + "udtwb": { + "chComTextMDS": "0809" + }, + "pathInfo": { + "path": "001100010003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "navParaentId_Code": "320100", + "navParaentId_Name": "南京市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0809", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a22f-46ff-9738-dbcbe3fa2b31", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2f8c-48c7-bdee-d0a699581ac9", + "version": null, + "code": "320104", + "name": "秦淮区", + "gjmc": "秦淮区", + "udtwb": { + "chComTextMDS": "0808" + }, + "pathInfo": { + "path": "001100010002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "navParaentId_Code": "320100", + "navParaentId_Name": "南京市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0808", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2f8c-48c7-bdee-d0a699581ac9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0210-4bfe-8912-2d091bfaa239", + "version": null, + "code": "320102", + "name": "玄武区", + "gjmc": "玄武区", + "udtwb": { + "chComTextMDS": "0807" + }, + "pathInfo": { + "path": "001100010001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "navParaentId_Code": "320100", + "navParaentId_Name": "南京市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0807", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0210-4bfe-8912-2d091bfaa239", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e2c6-44c8-b47e-dcc01a59aec7", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4109-446c-8882-2e35a877166a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c56a-4929-8ffa-fb5841ef6db0", + "version": null, + "code": "310000", + "name": "上海市", + "gjmc": "上海市", + "udtwb": { + "chComTextMDS": "0788" + }, + "pathInfo": { + "path": "0010", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 10, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0788", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c56a-4929-8ffa-fb5841ef6db0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "version": null, + "code": "230000", + "name": "黑龙江省", + "gjmc": "黑龙江省", + "udtwb": { + "chComTextMDS": "0646" + }, + "pathInfo": { + "path": "0009", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 9, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0646", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-0bbb-4c6f-bdca-487ee5baabad", + "version": null, + "code": "232700", + "name": "大兴安岭地区", + "gjmc": "大兴安岭地区", + "udtwb": { + "chComTextMDS": "0784" + }, + "pathInfo": { + "path": "00090013", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "sequence": 13, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b8ad-4190-816f-fd987704296c", + "navParaentId_Code": "230000", + "navParaentId_Name": "黑龙江省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0784", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-47c7-4cef-8a46-8c44d942124c", + "version": null, + "code": "232723", + "name": "漠河县", + "gjmc": "漠河县", + "udtwb": { + "chComTextMDS": "0787" + }, + "pathInfo": { + "path": "000900130003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0bbb-4c6f-bdca-487ee5baabad", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0bbb-4c6f-bdca-487ee5baabad", + "navParaentId_Code": "232700", + "navParaentId_Name": "大兴安岭地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0787", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-47c7-4cef-8a46-8c44d942124c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ff89-42de-b622-0e673bea4a9e", + "version": null, + "code": "232722", + "name": "塔河县", + "gjmc": "塔河县", + "udtwb": { + "chComTextMDS": "0786" + }, + "pathInfo": { + "path": "000900130002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0bbb-4c6f-bdca-487ee5baabad", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0bbb-4c6f-bdca-487ee5baabad", + "navParaentId_Code": "232700", + "navParaentId_Name": "大兴安岭地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0786", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ff89-42de-b622-0e673bea4a9e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-438a-4151-bf97-f0fa7e9cad53", + "version": null, + "code": "232721", + "name": "呼玛县", + "gjmc": "呼玛县", + "udtwb": { + "chComTextMDS": "0785" + }, + "pathInfo": { + "path": "000900130001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0bbb-4c6f-bdca-487ee5baabad", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0bbb-4c6f-bdca-487ee5baabad", + "navParaentId_Code": "232700", + "navParaentId_Name": "大兴安岭地区" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0785", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-438a-4151-bf97-f0fa7e9cad53", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0bbb-4c6f-bdca-487ee5baabad", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "version": null, + "code": "231200", + "name": "绥化市", + "gjmc": "绥化市", + "udtwb": { + "chComTextMDS": "0773" + }, + "pathInfo": { + "path": "00090012", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "sequence": 12, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b8ad-4190-816f-fd987704296c", + "navParaentId_Code": "230000", + "navParaentId_Name": "黑龙江省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0773", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-08a0-4371-8897-f8d53716a622", + "version": null, + "code": "231283", + "name": "海伦市", + "gjmc": "海伦市", + "udtwb": { + "chComTextMDS": "0783" + }, + "pathInfo": { + "path": "000900120010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "navParaentId_Code": "231200", + "navParaentId_Name": "绥化市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0783", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-08a0-4371-8897-f8d53716a622", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9692-4501-8310-88fdd7de0c9c", + "version": null, + "code": "231282", + "name": "肇东市", + "gjmc": "肇东市", + "udtwb": { + "chComTextMDS": "0782" + }, + "pathInfo": { + "path": "000900120009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "navParaentId_Code": "231200", + "navParaentId_Name": "绥化市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0782", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9692-4501-8310-88fdd7de0c9c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-32bc-4bc6-af6b-1cb5c684ea2d", + "version": null, + "code": "231281", + "name": "安达市", + "gjmc": "安达市", + "udtwb": { + "chComTextMDS": "0781" + }, + "pathInfo": { + "path": "000900120008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "navParaentId_Code": "231200", + "navParaentId_Name": "绥化市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0781", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-32bc-4bc6-af6b-1cb5c684ea2d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-de71-4282-a8ca-248be5e62de7", + "version": null, + "code": "231226", + "name": "绥棱县", + "gjmc": "绥棱县", + "udtwb": { + "chComTextMDS": "0780" + }, + "pathInfo": { + "path": "000900120007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "navParaentId_Code": "231200", + "navParaentId_Name": "绥化市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0780", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-de71-4282-a8ca-248be5e62de7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4445-4cb1-bb40-80699fd66eb2", + "version": null, + "code": "231225", + "name": "明水县", + "gjmc": "明水县", + "udtwb": { + "chComTextMDS": "0779" + }, + "pathInfo": { + "path": "000900120006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "navParaentId_Code": "231200", + "navParaentId_Name": "绥化市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0779", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4445-4cb1-bb40-80699fd66eb2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-38d3-4e45-b5df-a20499ee5958", + "version": null, + "code": "231224", + "name": "庆安县", + "gjmc": "庆安县", + "udtwb": { + "chComTextMDS": "0778" + }, + "pathInfo": { + "path": "000900120005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "navParaentId_Code": "231200", + "navParaentId_Name": "绥化市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0778", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-38d3-4e45-b5df-a20499ee5958", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a390-46ea-9a5a-224367e0cfc9", + "version": null, + "code": "231223", + "name": "青冈县", + "gjmc": "青冈县", + "udtwb": { + "chComTextMDS": "0777" + }, + "pathInfo": { + "path": "000900120004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "navParaentId_Code": "231200", + "navParaentId_Name": "绥化市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0777", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a390-46ea-9a5a-224367e0cfc9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-015c-462e-8384-da404f062aa2", + "version": null, + "code": "231222", + "name": "兰西县", + "gjmc": "兰西县", + "udtwb": { + "chComTextMDS": "0776" + }, + "pathInfo": { + "path": "000900120003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "navParaentId_Code": "231200", + "navParaentId_Name": "绥化市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0776", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-015c-462e-8384-da404f062aa2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-71b4-460c-8deb-27854325341a", + "version": null, + "code": "231221", + "name": "望奎县", + "gjmc": "望奎县", + "udtwb": { + "chComTextMDS": "0775" + }, + "pathInfo": { + "path": "000900120002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "navParaentId_Code": "231200", + "navParaentId_Name": "绥化市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0775", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-71b4-460c-8deb-27854325341a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d82d-48d6-b0b0-cc796fa874c7", + "version": null, + "code": "231202", + "name": "北林区", + "gjmc": "北林区", + "udtwb": { + "chComTextMDS": "0774" + }, + "pathInfo": { + "path": "000900120001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "navParaentId_Code": "231200", + "navParaentId_Name": "绥化市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0774", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d82d-48d6-b0b0-cc796fa874c7", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1624-4d55-abf5-2918a1e43b6a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-840e-4662-9833-134b74f81216", + "version": null, + "code": "231100", + "name": "黑河市", + "gjmc": "黑河市", + "udtwb": { + "chComTextMDS": "0766" + }, + "pathInfo": { + "path": "00090011", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "sequence": 11, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b8ad-4190-816f-fd987704296c", + "navParaentId_Code": "230000", + "navParaentId_Name": "黑龙江省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0766", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-62e6-4647-8423-db9eba87aa16", + "version": null, + "code": "231182", + "name": "五大连池市", + "gjmc": "五大连池市", + "udtwb": { + "chComTextMDS": "0772" + }, + "pathInfo": { + "path": "000900110006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-840e-4662-9833-134b74f81216", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-840e-4662-9833-134b74f81216", + "navParaentId_Code": "231100", + "navParaentId_Name": "黑河市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0772", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-62e6-4647-8423-db9eba87aa16", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-468a-4621-bd1f-e9aff930fe35", + "version": null, + "code": "231181", + "name": "北安市", + "gjmc": "北安市", + "udtwb": { + "chComTextMDS": "0771" + }, + "pathInfo": { + "path": "000900110005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-840e-4662-9833-134b74f81216", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-840e-4662-9833-134b74f81216", + "navParaentId_Code": "231100", + "navParaentId_Name": "黑河市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0771", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-468a-4621-bd1f-e9aff930fe35", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6517-40b1-8316-1d7a286f5ed0", + "version": null, + "code": "231124", + "name": "孙吴县", + "gjmc": "孙吴县", + "udtwb": { + "chComTextMDS": "0770" + }, + "pathInfo": { + "path": "000900110004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-840e-4662-9833-134b74f81216", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-840e-4662-9833-134b74f81216", + "navParaentId_Code": "231100", + "navParaentId_Name": "黑河市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0770", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6517-40b1-8316-1d7a286f5ed0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6ee5-472f-a925-4f764944a747", + "version": null, + "code": "231123", + "name": "逊克县", + "gjmc": "逊克县", + "udtwb": { + "chComTextMDS": "0769" + }, + "pathInfo": { + "path": "000900110003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-840e-4662-9833-134b74f81216", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-840e-4662-9833-134b74f81216", + "navParaentId_Code": "231100", + "navParaentId_Name": "黑河市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0769", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6ee5-472f-a925-4f764944a747", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6564-472d-946a-2a84399ba4ae", + "version": null, + "code": "231121", + "name": "嫩江县", + "gjmc": "嫩江县", + "udtwb": { + "chComTextMDS": "0768" + }, + "pathInfo": { + "path": "000900110002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-840e-4662-9833-134b74f81216", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-840e-4662-9833-134b74f81216", + "navParaentId_Code": "231100", + "navParaentId_Name": "黑河市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0768", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6564-472d-946a-2a84399ba4ae", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-186c-42a9-a9e7-7fcb9b8f9aec", + "version": null, + "code": "231102", + "name": "爱辉区", + "gjmc": "爱辉区", + "udtwb": { + "chComTextMDS": "0767" + }, + "pathInfo": { + "path": "000900110001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-840e-4662-9833-134b74f81216", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-840e-4662-9833-134b74f81216", + "navParaentId_Code": "231100", + "navParaentId_Name": "黑河市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0767", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-186c-42a9-a9e7-7fcb9b8f9aec", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-840e-4662-9833-134b74f81216", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-af24-4864-ba27-338ad735b7be", + "version": null, + "code": "231000", + "name": "牡丹江市", + "gjmc": "牡丹江市", + "udtwb": { + "chComTextMDS": "0755" + }, + "pathInfo": { + "path": "00090010", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "sequence": 10, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b8ad-4190-816f-fd987704296c", + "navParaentId_Code": "230000", + "navParaentId_Name": "黑龙江省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0755", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-5b38-4b00-b673-4db08958d0f7", + "version": null, + "code": "231086", + "name": "东宁市", + "gjmc": "东宁市", + "udtwb": { + "chComTextMDS": "0765" + }, + "pathInfo": { + "path": "000900100010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-af24-4864-ba27-338ad735b7be", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-af24-4864-ba27-338ad735b7be", + "navParaentId_Code": "231000", + "navParaentId_Name": "牡丹江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0765", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5b38-4b00-b673-4db08958d0f7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6318-4f36-98ed-5a4abddc0bbb", + "version": null, + "code": "231085", + "name": "穆棱市", + "gjmc": "穆棱市", + "udtwb": { + "chComTextMDS": "0764" + }, + "pathInfo": { + "path": "000900100009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-af24-4864-ba27-338ad735b7be", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-af24-4864-ba27-338ad735b7be", + "navParaentId_Code": "231000", + "navParaentId_Name": "牡丹江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0764", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6318-4f36-98ed-5a4abddc0bbb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-71b4-4294-8ddd-27313e43698c", + "version": null, + "code": "231084", + "name": "宁安市", + "gjmc": "宁安市", + "udtwb": { + "chComTextMDS": "0763" + }, + "pathInfo": { + "path": "000900100008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-af24-4864-ba27-338ad735b7be", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-af24-4864-ba27-338ad735b7be", + "navParaentId_Code": "231000", + "navParaentId_Name": "牡丹江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0763", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-71b4-4294-8ddd-27313e43698c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4d73-4477-be29-cf91dbbf877b", + "version": null, + "code": "231083", + "name": "海林市", + "gjmc": "海林市", + "udtwb": { + "chComTextMDS": "0762" + }, + "pathInfo": { + "path": "000900100007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-af24-4864-ba27-338ad735b7be", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-af24-4864-ba27-338ad735b7be", + "navParaentId_Code": "231000", + "navParaentId_Name": "牡丹江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0762", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4d73-4477-be29-cf91dbbf877b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a368-479f-b108-923ee554f44a", + "version": null, + "code": "231081", + "name": "绥芬河市", + "gjmc": "绥芬河市", + "udtwb": { + "chComTextMDS": "0761" + }, + "pathInfo": { + "path": "000900100006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-af24-4864-ba27-338ad735b7be", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-af24-4864-ba27-338ad735b7be", + "navParaentId_Code": "231000", + "navParaentId_Name": "牡丹江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0761", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a368-479f-b108-923ee554f44a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b5b1-4154-98a1-3c4099fe2bc5", + "version": null, + "code": "231025", + "name": "林口县", + "gjmc": "林口县", + "udtwb": { + "chComTextMDS": "0760" + }, + "pathInfo": { + "path": "000900100005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-af24-4864-ba27-338ad735b7be", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-af24-4864-ba27-338ad735b7be", + "navParaentId_Code": "231000", + "navParaentId_Name": "牡丹江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0760", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b5b1-4154-98a1-3c4099fe2bc5", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f6ad-4a3d-9051-4537d3efc8f8", + "version": null, + "code": "231005", + "name": "西安区", + "gjmc": "西安区", + "udtwb": { + "chComTextMDS": "0759" + }, + "pathInfo": { + "path": "000900100004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-af24-4864-ba27-338ad735b7be", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-af24-4864-ba27-338ad735b7be", + "navParaentId_Code": "231000", + "navParaentId_Name": "牡丹江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0759", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f6ad-4a3d-9051-4537d3efc8f8", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d168-4322-9346-1750d543f902", + "version": null, + "code": "231004", + "name": "爱民区", + "gjmc": "爱民区", + "udtwb": { + "chComTextMDS": "0758" + }, + "pathInfo": { + "path": "000900100003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-af24-4864-ba27-338ad735b7be", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-af24-4864-ba27-338ad735b7be", + "navParaentId_Code": "231000", + "navParaentId_Name": "牡丹江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0758", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d168-4322-9346-1750d543f902", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ec44-4f5d-83c9-93a38554fc03", + "version": null, + "code": "231003", + "name": "阳明区", + "gjmc": "阳明区", + "udtwb": { + "chComTextMDS": "0757" + }, + "pathInfo": { + "path": "000900100002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-af24-4864-ba27-338ad735b7be", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-af24-4864-ba27-338ad735b7be", + "navParaentId_Code": "231000", + "navParaentId_Name": "牡丹江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0757", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ec44-4f5d-83c9-93a38554fc03", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-95ae-428b-91d0-a5eca7b8ca1d", + "version": null, + "code": "231002", + "name": "东安区", + "gjmc": "东安区", + "udtwb": { + "chComTextMDS": "0756" + }, + "pathInfo": { + "path": "000900100001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-af24-4864-ba27-338ad735b7be", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-af24-4864-ba27-338ad735b7be", + "navParaentId_Code": "231000", + "navParaentId_Name": "牡丹江市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0756", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-95ae-428b-91d0-a5eca7b8ca1d", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-af24-4864-ba27-338ad735b7be", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a7e4-4d5a-848e-b9a7ac703b14", + "version": null, + "code": "230900", + "name": "七台河市", + "gjmc": "七台河市", + "udtwb": { + "chComTextMDS": "0750" + }, + "pathInfo": { + "path": "00090009", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "sequence": 9, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b8ad-4190-816f-fd987704296c", + "navParaentId_Code": "230000", + "navParaentId_Name": "黑龙江省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0750", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-35e1-45d8-b7cb-18a678eaab57", + "version": null, + "code": "230921", + "name": "勃利县", + "gjmc": "勃利县", + "udtwb": { + "chComTextMDS": "0754" + }, + "pathInfo": { + "path": "000900090004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-a7e4-4d5a-848e-b9a7ac703b14", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-a7e4-4d5a-848e-b9a7ac703b14", + "navParaentId_Code": "230900", + "navParaentId_Name": "七台河市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0754", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-35e1-45d8-b7cb-18a678eaab57", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-fce5-4bb0-8e08-a386b95dcc81", + "version": null, + "code": "230904", + "name": "茄子河区", + "gjmc": "茄子河区", + "udtwb": { + "chComTextMDS": "0753" + }, + "pathInfo": { + "path": "000900090003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-a7e4-4d5a-848e-b9a7ac703b14", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-a7e4-4d5a-848e-b9a7ac703b14", + "navParaentId_Code": "230900", + "navParaentId_Name": "七台河市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0753", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fce5-4bb0-8e08-a386b95dcc81", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2b45-4eee-8f85-1a86115b0f6f", + "version": null, + "code": "230903", + "name": "桃山区", + "gjmc": "桃山区", + "udtwb": { + "chComTextMDS": "0752" + }, + "pathInfo": { + "path": "000900090002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-a7e4-4d5a-848e-b9a7ac703b14", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-a7e4-4d5a-848e-b9a7ac703b14", + "navParaentId_Code": "230900", + "navParaentId_Name": "七台河市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0752", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2b45-4eee-8f85-1a86115b0f6f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ef9b-4601-9a25-f6e2543f29b0", + "version": null, + "code": "230902", + "name": "新兴区", + "gjmc": "新兴区", + "udtwb": { + "chComTextMDS": "0751" + }, + "pathInfo": { + "path": "000900090001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-a7e4-4d5a-848e-b9a7ac703b14", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-a7e4-4d5a-848e-b9a7ac703b14", + "navParaentId_Code": "230900", + "navParaentId_Name": "七台河市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0751", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ef9b-4601-9a25-f6e2543f29b0", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a7e4-4d5a-848e-b9a7ac703b14", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "version": null, + "code": "230800", + "name": "佳木斯市", + "gjmc": "佳木斯市", + "udtwb": { + "chComTextMDS": "0739" + }, + "pathInfo": { + "path": "00090008", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "sequence": 8, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b8ad-4190-816f-fd987704296c", + "navParaentId_Code": "230000", + "navParaentId_Name": "黑龙江省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0739", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-fee8-4ebf-8168-3592942557f3", + "version": null, + "code": "230883", + "name": "抚远市", + "gjmc": "抚远市", + "udtwb": { + "chComTextMDS": "0749" + }, + "pathInfo": { + "path": "000900080010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "navParaentId_Code": "230800", + "navParaentId_Name": "佳木斯市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0749", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fee8-4ebf-8168-3592942557f3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-45d3-4ab9-82d7-6d2e4bc34a73", + "version": null, + "code": "230882", + "name": "富锦市", + "gjmc": "富锦市", + "udtwb": { + "chComTextMDS": "0748" + }, + "pathInfo": { + "path": "000900080009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "navParaentId_Code": "230800", + "navParaentId_Name": "佳木斯市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0748", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-45d3-4ab9-82d7-6d2e4bc34a73", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6ad8-431b-9e59-11399062be9a", + "version": null, + "code": "230881", + "name": "同江市", + "gjmc": "同江市", + "udtwb": { + "chComTextMDS": "0747" + }, + "pathInfo": { + "path": "000900080008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "navParaentId_Code": "230800", + "navParaentId_Name": "佳木斯市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0747", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6ad8-431b-9e59-11399062be9a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7dab-4b43-ab59-d1714efb21b2", + "version": null, + "code": "230828", + "name": "汤原县", + "gjmc": "汤原县", + "udtwb": { + "chComTextMDS": "0746" + }, + "pathInfo": { + "path": "000900080007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "navParaentId_Code": "230800", + "navParaentId_Name": "佳木斯市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0746", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7dab-4b43-ab59-d1714efb21b2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2779-428c-98bf-c98f16be2446", + "version": null, + "code": "230826", + "name": "桦川县", + "gjmc": "桦川县", + "udtwb": { + "chComTextMDS": "0745" + }, + "pathInfo": { + "path": "000900080006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "navParaentId_Code": "230800", + "navParaentId_Name": "佳木斯市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0745", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2779-428c-98bf-c98f16be2446", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-69d2-416e-a241-4a1682e5fa53", + "version": null, + "code": "230822", + "name": "桦南县", + "gjmc": "桦南县", + "udtwb": { + "chComTextMDS": "0744" + }, + "pathInfo": { + "path": "000900080005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "navParaentId_Code": "230800", + "navParaentId_Name": "佳木斯市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0744", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-69d2-416e-a241-4a1682e5fa53", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d9b7-4764-9f02-4f20a0aafb90", + "version": null, + "code": "230811", + "name": "郊区", + "gjmc": "郊区", + "udtwb": { + "chComTextMDS": "0743" + }, + "pathInfo": { + "path": "000900080004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "navParaentId_Code": "230800", + "navParaentId_Name": "佳木斯市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0743", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d9b7-4764-9f02-4f20a0aafb90", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b14a-4266-ad2e-aed4e5b81b02", + "version": null, + "code": "230805", + "name": "东风区", + "gjmc": "东风区", + "udtwb": { + "chComTextMDS": "0742" + }, + "pathInfo": { + "path": "000900080003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "navParaentId_Code": "230800", + "navParaentId_Name": "佳木斯市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0742", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b14a-4266-ad2e-aed4e5b81b02", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-222a-4277-ae06-006388882963", + "version": null, + "code": "230804", + "name": "前进区", + "gjmc": "前进区", + "udtwb": { + "chComTextMDS": "0741" + }, + "pathInfo": { + "path": "000900080002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "navParaentId_Code": "230800", + "navParaentId_Name": "佳木斯市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0741", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-222a-4277-ae06-006388882963", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6dd2-4591-a358-e919bde97ef4", + "version": null, + "code": "230803", + "name": "向阳区", + "gjmc": "向阳区", + "udtwb": { + "chComTextMDS": "0740" + }, + "pathInfo": { + "path": "000900080001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "navParaentId_Code": "230800", + "navParaentId_Name": "佳木斯市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0740", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6dd2-4591-a358-e919bde97ef4", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-16f2-466d-8b63-5b8ef19f4c78", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "version": null, + "code": "230700", + "name": "伊春市", + "gjmc": "伊春市", + "udtwb": { + "chComTextMDS": "0721" + }, + "pathInfo": { + "path": "00090007", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "sequence": 7, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b8ad-4190-816f-fd987704296c", + "navParaentId_Code": "230000", + "navParaentId_Name": "黑龙江省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0721", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-74bc-4270-b9e8-ca09ced38f10", + "version": null, + "code": "230781", + "name": "铁力市", + "gjmc": "铁力市", + "udtwb": { + "chComTextMDS": "0738" + }, + "pathInfo": { + "path": "000900070017", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 17, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0738", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-74bc-4270-b9e8-ca09ced38f10", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a9a3-41e0-a16b-1dfe931d478e", + "version": null, + "code": "230722", + "name": "嘉荫县", + "gjmc": "嘉荫县", + "udtwb": { + "chComTextMDS": "0737" + }, + "pathInfo": { + "path": "000900070016", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 16, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0737", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a9a3-41e0-a16b-1dfe931d478e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7407-4c10-914a-b83dd5a641af", + "version": null, + "code": "230716", + "name": "上甘岭区", + "gjmc": "上甘岭区", + "udtwb": { + "chComTextMDS": "0736" + }, + "pathInfo": { + "path": "000900070015", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 15, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0736", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7407-4c10-914a-b83dd5a641af", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4057-42fb-9342-f402439b45b8", + "version": null, + "code": "230715", + "name": "红星区", + "gjmc": "红星区", + "udtwb": { + "chComTextMDS": "0735" + }, + "pathInfo": { + "path": "000900070014", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 14, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0735", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4057-42fb-9342-f402439b45b8", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-9f68-4fb6-b28c-842d52d69539", + "version": null, + "code": "230714", + "name": "乌伊岭区", + "gjmc": "乌伊岭区", + "udtwb": { + "chComTextMDS": "0734" + }, + "pathInfo": { + "path": "000900070013", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 13, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0734", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9f68-4fb6-b28c-842d52d69539", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ff24-4dd4-ba97-2a1a22d884d4", + "version": null, + "code": "230713", + "name": "带岭区", + "gjmc": "带岭区", + "udtwb": { + "chComTextMDS": "0733" + }, + "pathInfo": { + "path": "000900070012", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 12, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0733", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ff24-4dd4-ba97-2a1a22d884d4", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-990d-4136-9f6f-65ff04fff49a", + "version": null, + "code": "230712", + "name": "汤旺河区", + "gjmc": "汤旺河区", + "udtwb": { + "chComTextMDS": "0732" + }, + "pathInfo": { + "path": "000900070011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0732", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-990d-4136-9f6f-65ff04fff49a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8b74-439d-abf7-bdb30eddb435", + "version": null, + "code": "230711", + "name": "乌马河区", + "gjmc": "乌马河区", + "udtwb": { + "chComTextMDS": "0731" + }, + "pathInfo": { + "path": "000900070010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0731", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8b74-439d-abf7-bdb30eddb435", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-cc50-449d-b3e0-f52bb99c3e35", + "version": null, + "code": "230710", + "name": "五营区", + "gjmc": "五营区", + "udtwb": { + "chComTextMDS": "0730" + }, + "pathInfo": { + "path": "000900070009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0730", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-cc50-449d-b3e0-f52bb99c3e35", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e2d1-4065-bf19-f06fada54561", + "version": null, + "code": "230709", + "name": "金山屯区", + "gjmc": "金山屯区", + "udtwb": { + "chComTextMDS": "0729" + }, + "pathInfo": { + "path": "000900070008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0729", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e2d1-4065-bf19-f06fada54561", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2112-4aaf-ac2a-a8ac878d31a2", + "version": null, + "code": "230708", + "name": "美溪区", + "gjmc": "美溪区", + "udtwb": { + "chComTextMDS": "0728" + }, + "pathInfo": { + "path": "000900070007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0728", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2112-4aaf-ac2a-a8ac878d31a2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b41e-4309-a5e6-dbae0952ed57", + "version": null, + "code": "230707", + "name": "新青区", + "gjmc": "新青区", + "udtwb": { + "chComTextMDS": "0727" + }, + "pathInfo": { + "path": "000900070006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0727", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b41e-4309-a5e6-dbae0952ed57", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-652b-49c6-906b-8bbceea912e7", + "version": null, + "code": "230706", + "name": "翠峦区", + "gjmc": "翠峦区", + "udtwb": { + "chComTextMDS": "0726" + }, + "pathInfo": { + "path": "000900070005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0726", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-652b-49c6-906b-8bbceea912e7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ee5d-48e0-b081-6bc08a5946b6", + "version": null, + "code": "230705", + "name": "西林区", + "gjmc": "西林区", + "udtwb": { + "chComTextMDS": "0725" + }, + "pathInfo": { + "path": "000900070004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0725", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ee5d-48e0-b081-6bc08a5946b6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e04d-4b38-b7ea-d3a549d30617", + "version": null, + "code": "230704", + "name": "友好区", + "gjmc": "友好区", + "udtwb": { + "chComTextMDS": "0724" + }, + "pathInfo": { + "path": "000900070003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0724", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e04d-4b38-b7ea-d3a549d30617", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-49b1-44fc-8ddc-c50a090e54ca", + "version": null, + "code": "230703", + "name": "南岔区", + "gjmc": "南岔区", + "udtwb": { + "chComTextMDS": "0723" + }, + "pathInfo": { + "path": "000900070002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0723", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-49b1-44fc-8ddc-c50a090e54ca", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f126-45a0-9156-fb0b28f2f9e8", + "version": null, + "code": "230702", + "name": "伊春区", + "gjmc": "伊春区", + "udtwb": { + "chComTextMDS": "0722" + }, + "pathInfo": { + "path": "000900070001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-9f69-4862-b136-051fc6f106b5", + "navParaentId_Code": "230700", + "navParaentId_Name": "伊春市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0722", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f126-45a0-9156-fb0b28f2f9e8", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-9f69-4862-b136-051fc6f106b5", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6f96-471b-9c24-283056866a82", + "version": null, + "code": "230600", + "name": "大庆市", + "gjmc": "大庆市", + "udtwb": { + "chComTextMDS": "0711" + }, + "pathInfo": { + "path": "00090006", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "sequence": 6, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b8ad-4190-816f-fd987704296c", + "navParaentId_Code": "230000", + "navParaentId_Name": "黑龙江省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0711", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-daa5-4a37-80d5-060fe086904b", + "version": null, + "code": "230624", + "name": "杜尔伯特蒙古族自治县", + "gjmc": "杜尔伯特蒙古族自治县", + "udtwb": { + "chComTextMDS": "0720" + }, + "pathInfo": { + "path": "000900060009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-6f96-471b-9c24-283056866a82", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-6f96-471b-9c24-283056866a82", + "navParaentId_Code": "230600", + "navParaentId_Name": "大庆市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0720", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-daa5-4a37-80d5-060fe086904b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-cb7f-44f5-a6b3-59b252cf4247", + "version": null, + "code": "230623", + "name": "林甸县", + "gjmc": "林甸县", + "udtwb": { + "chComTextMDS": "0719" + }, + "pathInfo": { + "path": "000900060008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-6f96-471b-9c24-283056866a82", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-6f96-471b-9c24-283056866a82", + "navParaentId_Code": "230600", + "navParaentId_Name": "大庆市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0719", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-cb7f-44f5-a6b3-59b252cf4247", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b0aa-4493-af97-8445fd55622b", + "version": null, + "code": "230622", + "name": "肇源县", + "gjmc": "肇源县", + "udtwb": { + "chComTextMDS": "0718" + }, + "pathInfo": { + "path": "000900060007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-6f96-471b-9c24-283056866a82", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-6f96-471b-9c24-283056866a82", + "navParaentId_Code": "230600", + "navParaentId_Name": "大庆市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0718", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b0aa-4493-af97-8445fd55622b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2b3f-4fcd-9098-4dce360742fd", + "version": null, + "code": "230621", + "name": "肇州县", + "gjmc": "肇州县", + "udtwb": { + "chComTextMDS": "0717" + }, + "pathInfo": { + "path": "000900060006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-6f96-471b-9c24-283056866a82", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-6f96-471b-9c24-283056866a82", + "navParaentId_Code": "230600", + "navParaentId_Name": "大庆市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0717", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2b3f-4fcd-9098-4dce360742fd", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5a3d-47f3-abb9-c3f37a7603e7", + "version": null, + "code": "230606", + "name": "大同区", + "gjmc": "大同区", + "udtwb": { + "chComTextMDS": "0716" + }, + "pathInfo": { + "path": "000900060005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-6f96-471b-9c24-283056866a82", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-6f96-471b-9c24-283056866a82", + "navParaentId_Code": "230600", + "navParaentId_Name": "大庆市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0716", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5a3d-47f3-abb9-c3f37a7603e7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6372-4a9d-a10b-79dab89d6bdb", + "version": null, + "code": "230605", + "name": "红岗区", + "gjmc": "红岗区", + "udtwb": { + "chComTextMDS": "0715" + }, + "pathInfo": { + "path": "000900060004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-6f96-471b-9c24-283056866a82", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-6f96-471b-9c24-283056866a82", + "navParaentId_Code": "230600", + "navParaentId_Name": "大庆市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0715", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6372-4a9d-a10b-79dab89d6bdb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ac92-4705-8d4c-b2986ff7d01b", + "version": null, + "code": "230604", + "name": "让胡路区", + "gjmc": "让胡路区", + "udtwb": { + "chComTextMDS": "0714" + }, + "pathInfo": { + "path": "000900060003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-6f96-471b-9c24-283056866a82", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-6f96-471b-9c24-283056866a82", + "navParaentId_Code": "230600", + "navParaentId_Name": "大庆市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0714", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ac92-4705-8d4c-b2986ff7d01b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c5d4-4c65-8f78-9033c0547e4d", + "version": null, + "code": "230603", + "name": "龙凤区", + "gjmc": "龙凤区", + "udtwb": { + "chComTextMDS": "0713" + }, + "pathInfo": { + "path": "000900060002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-6f96-471b-9c24-283056866a82", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-6f96-471b-9c24-283056866a82", + "navParaentId_Code": "230600", + "navParaentId_Name": "大庆市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0713", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c5d4-4c65-8f78-9033c0547e4d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2190-4753-92da-4c64697e0dc9", + "version": null, + "code": "230602", + "name": "萨尔图区", + "gjmc": "萨尔图区", + "udtwb": { + "chComTextMDS": "0712" + }, + "pathInfo": { + "path": "000900060001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-6f96-471b-9c24-283056866a82", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-6f96-471b-9c24-283056866a82", + "navParaentId_Code": "230600", + "navParaentId_Name": "大庆市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0712", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2190-4753-92da-4c64697e0dc9", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6f96-471b-9c24-283056866a82", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "version": null, + "code": "230500", + "name": "双鸭山市", + "gjmc": "双鸭山市", + "udtwb": { + "chComTextMDS": "0702" + }, + "pathInfo": { + "path": "00090005", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "sequence": 5, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b8ad-4190-816f-fd987704296c", + "navParaentId_Code": "230000", + "navParaentId_Name": "黑龙江省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0702", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-d26e-4614-be6d-05e8eaa467f5", + "version": null, + "code": "230524", + "name": "饶河县", + "gjmc": "饶河县", + "udtwb": { + "chComTextMDS": "0710" + }, + "pathInfo": { + "path": "000900050008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "navParaentId_Code": "230500", + "navParaentId_Name": "双鸭山市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0710", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d26e-4614-be6d-05e8eaa467f5", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-77c0-4eb5-ad59-42a6a6549a14", + "version": null, + "code": "230523", + "name": "宝清县", + "gjmc": "宝清县", + "udtwb": { + "chComTextMDS": "0709" + }, + "pathInfo": { + "path": "000900050007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "navParaentId_Code": "230500", + "navParaentId_Name": "双鸭山市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0709", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-77c0-4eb5-ad59-42a6a6549a14", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a502-4bef-9351-ea8c7e89542f", + "version": null, + "code": "230522", + "name": "友谊县", + "gjmc": "友谊县", + "udtwb": { + "chComTextMDS": "0708" + }, + "pathInfo": { + "path": "000900050006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "navParaentId_Code": "230500", + "navParaentId_Name": "双鸭山市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0708", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a502-4bef-9351-ea8c7e89542f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c634-47d6-a9c6-bd76ccb719b6", + "version": null, + "code": "230521", + "name": "集贤县", + "gjmc": "集贤县", + "udtwb": { + "chComTextMDS": "0707" + }, + "pathInfo": { + "path": "000900050005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "navParaentId_Code": "230500", + "navParaentId_Name": "双鸭山市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0707", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c634-47d6-a9c6-bd76ccb719b6", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8393-46bd-adb7-5bcfcd148b1e", + "version": null, + "code": "230506", + "name": "宝山区", + "gjmc": "宝山区", + "udtwb": { + "chComTextMDS": "0706" + }, + "pathInfo": { + "path": "000900050004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "navParaentId_Code": "230500", + "navParaentId_Name": "双鸭山市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0706", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8393-46bd-adb7-5bcfcd148b1e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-cbef-4c06-a615-1cf729de2f4b", + "version": null, + "code": "230505", + "name": "四方台区", + "gjmc": "四方台区", + "udtwb": { + "chComTextMDS": "0705" + }, + "pathInfo": { + "path": "000900050003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "navParaentId_Code": "230500", + "navParaentId_Name": "双鸭山市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0705", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-cbef-4c06-a615-1cf729de2f4b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7d53-45de-9c03-9c814a5803bd", + "version": null, + "code": "230503", + "name": "岭东区", + "gjmc": "岭东区", + "udtwb": { + "chComTextMDS": "0704" + }, + "pathInfo": { + "path": "000900050002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "navParaentId_Code": "230500", + "navParaentId_Name": "双鸭山市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0704", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7d53-45de-9c03-9c814a5803bd", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0314-4d1c-a490-b05d7ce642ff", + "version": null, + "code": "230502", + "name": "尖山区", + "gjmc": "尖山区", + "udtwb": { + "chComTextMDS": "0703" + }, + "pathInfo": { + "path": "000900050001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "navParaentId_Code": "230500", + "navParaentId_Name": "双鸭山市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0703", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0314-4d1c-a490-b05d7ce642ff", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ca2d-40d9-8168-9e55be90c9a3", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f0c8-4c25-b072-a882a0d79736", + "version": null, + "code": "230400", + "name": "鹤岗市", + "gjmc": "鹤岗市", + "udtwb": { + "chComTextMDS": "0693" + }, + "pathInfo": { + "path": "00090004", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "sequence": 4, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b8ad-4190-816f-fd987704296c", + "navParaentId_Code": "230000", + "navParaentId_Name": "黑龙江省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0693", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-4e0e-4578-aadb-e53c76970620", + "version": null, + "code": "230422", + "name": "绥滨县", + "gjmc": "绥滨县", + "udtwb": { + "chComTextMDS": "0701" + }, + "pathInfo": { + "path": "000900040008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f0c8-4c25-b072-a882a0d79736", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f0c8-4c25-b072-a882a0d79736", + "navParaentId_Code": "230400", + "navParaentId_Name": "鹤岗市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0701", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4e0e-4578-aadb-e53c76970620", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-235c-46a9-b7b0-d827d4591293", + "version": null, + "code": "230421", + "name": "萝北县", + "gjmc": "萝北县", + "udtwb": { + "chComTextMDS": "0700" + }, + "pathInfo": { + "path": "000900040007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f0c8-4c25-b072-a882a0d79736", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f0c8-4c25-b072-a882a0d79736", + "navParaentId_Code": "230400", + "navParaentId_Name": "鹤岗市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0700", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-235c-46a9-b7b0-d827d4591293", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-d8ea-4396-bf70-8c3ba086672e", + "version": null, + "code": "230407", + "name": "兴山区", + "gjmc": "兴山区", + "udtwb": { + "chComTextMDS": "0699" + }, + "pathInfo": { + "path": "000900040006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f0c8-4c25-b072-a882a0d79736", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f0c8-4c25-b072-a882a0d79736", + "navParaentId_Code": "230400", + "navParaentId_Name": "鹤岗市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0699", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-d8ea-4396-bf70-8c3ba086672e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4495-43fb-b143-93460713b27b", + "version": null, + "code": "230406", + "name": "东山区", + "gjmc": "东山区", + "udtwb": { + "chComTextMDS": "0698" + }, + "pathInfo": { + "path": "000900040005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f0c8-4c25-b072-a882a0d79736", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f0c8-4c25-b072-a882a0d79736", + "navParaentId_Code": "230400", + "navParaentId_Name": "鹤岗市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0698", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4495-43fb-b143-93460713b27b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5147-4155-97b0-48b54dd8598d", + "version": null, + "code": "230405", + "name": "兴安区", + "gjmc": "兴安区", + "udtwb": { + "chComTextMDS": "0697" + }, + "pathInfo": { + "path": "000900040004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f0c8-4c25-b072-a882a0d79736", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f0c8-4c25-b072-a882a0d79736", + "navParaentId_Code": "230400", + "navParaentId_Name": "鹤岗市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0697", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5147-4155-97b0-48b54dd8598d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e5a9-47c0-b10f-f190fdb188e0", + "version": null, + "code": "230404", + "name": "南山区", + "gjmc": "南山区", + "udtwb": { + "chComTextMDS": "0696" + }, + "pathInfo": { + "path": "000900040003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f0c8-4c25-b072-a882a0d79736", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f0c8-4c25-b072-a882a0d79736", + "navParaentId_Code": "230400", + "navParaentId_Name": "鹤岗市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0696", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e5a9-47c0-b10f-f190fdb188e0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8210-4f33-afa9-a42e372b5bc7", + "version": null, + "code": "230403", + "name": "工农区", + "gjmc": "工农区", + "udtwb": { + "chComTextMDS": "0695" + }, + "pathInfo": { + "path": "000900040002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f0c8-4c25-b072-a882a0d79736", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f0c8-4c25-b072-a882a0d79736", + "navParaentId_Code": "230400", + "navParaentId_Name": "鹤岗市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0695", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8210-4f33-afa9-a42e372b5bc7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0c08-4f49-9c03-d750d87bfe7f", + "version": null, + "code": "230402", + "name": "向阳区", + "gjmc": "向阳区", + "udtwb": { + "chComTextMDS": "0694" + }, + "pathInfo": { + "path": "000900040001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-f0c8-4c25-b072-a882a0d79736", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-f0c8-4c25-b072-a882a0d79736", + "navParaentId_Code": "230400", + "navParaentId_Name": "鹤岗市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0694", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0c08-4f49-9c03-d750d87bfe7f", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f0c8-4c25-b072-a882a0d79736", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-92b8-448b-897a-89d167ed1114", + "version": null, + "code": "230300", + "name": "鸡西市", + "gjmc": "鸡西市", + "udtwb": { + "chComTextMDS": "0683" + }, + "pathInfo": { + "path": "00090003", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "sequence": 3, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b8ad-4190-816f-fd987704296c", + "navParaentId_Code": "230000", + "navParaentId_Name": "黑龙江省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0683", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-10e0-41d2-b315-3b947ad688d0", + "version": null, + "code": "230382", + "name": "密山市", + "gjmc": "密山市", + "udtwb": { + "chComTextMDS": "0692" + }, + "pathInfo": { + "path": "000900030009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-92b8-448b-897a-89d167ed1114", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-92b8-448b-897a-89d167ed1114", + "navParaentId_Code": "230300", + "navParaentId_Name": "鸡西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0692", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-10e0-41d2-b315-3b947ad688d0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-162d-473a-8844-455bb3c2f62f", + "version": null, + "code": "230381", + "name": "虎林市", + "gjmc": "虎林市", + "udtwb": { + "chComTextMDS": "0691" + }, + "pathInfo": { + "path": "000900030008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-92b8-448b-897a-89d167ed1114", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-92b8-448b-897a-89d167ed1114", + "navParaentId_Code": "230300", + "navParaentId_Name": "鸡西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0691", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-162d-473a-8844-455bb3c2f62f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e684-4940-ac53-5cfc3c5d72f9", + "version": null, + "code": "230321", + "name": "鸡东县", + "gjmc": "鸡东县", + "udtwb": { + "chComTextMDS": "0690" + }, + "pathInfo": { + "path": "000900030007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-92b8-448b-897a-89d167ed1114", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-92b8-448b-897a-89d167ed1114", + "navParaentId_Code": "230300", + "navParaentId_Name": "鸡西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0690", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e684-4940-ac53-5cfc3c5d72f9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7d91-42b0-b425-3a13e8f40daa", + "version": null, + "code": "230307", + "name": "麻山区", + "gjmc": "麻山区", + "udtwb": { + "chComTextMDS": "0689" + }, + "pathInfo": { + "path": "000900030006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-92b8-448b-897a-89d167ed1114", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-92b8-448b-897a-89d167ed1114", + "navParaentId_Code": "230300", + "navParaentId_Name": "鸡西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0689", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7d91-42b0-b425-3a13e8f40daa", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-942e-4d19-bd6b-a058fe8c6b57", + "version": null, + "code": "230306", + "name": "城子河区", + "gjmc": "城子河区", + "udtwb": { + "chComTextMDS": "0688" + }, + "pathInfo": { + "path": "000900030005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-92b8-448b-897a-89d167ed1114", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-92b8-448b-897a-89d167ed1114", + "navParaentId_Code": "230300", + "navParaentId_Name": "鸡西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0688", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-942e-4d19-bd6b-a058fe8c6b57", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-692d-4e78-ac00-1d7270dc52ca", + "version": null, + "code": "230305", + "name": "梨树区", + "gjmc": "梨树区", + "udtwb": { + "chComTextMDS": "0687" + }, + "pathInfo": { + "path": "000900030004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-92b8-448b-897a-89d167ed1114", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-92b8-448b-897a-89d167ed1114", + "navParaentId_Code": "230300", + "navParaentId_Name": "鸡西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0687", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-692d-4e78-ac00-1d7270dc52ca", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ca99-4f0c-ab86-cd5ea4ae1e52", + "version": null, + "code": "230304", + "name": "滴道区", + "gjmc": "滴道区", + "udtwb": { + "chComTextMDS": "0686" + }, + "pathInfo": { + "path": "000900030003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-92b8-448b-897a-89d167ed1114", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-92b8-448b-897a-89d167ed1114", + "navParaentId_Code": "230300", + "navParaentId_Name": "鸡西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0686", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ca99-4f0c-ab86-cd5ea4ae1e52", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-fe2a-4b95-ab29-3c3175f67a8d", + "version": null, + "code": "230303", + "name": "恒山区", + "gjmc": "恒山区", + "udtwb": { + "chComTextMDS": "0685" + }, + "pathInfo": { + "path": "000900030002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-92b8-448b-897a-89d167ed1114", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-92b8-448b-897a-89d167ed1114", + "navParaentId_Code": "230300", + "navParaentId_Name": "鸡西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0685", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-fe2a-4b95-ab29-3c3175f67a8d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-576a-4e11-97bb-71b9f7439aed", + "version": null, + "code": "230302", + "name": "鸡冠区", + "gjmc": "鸡冠区", + "udtwb": { + "chComTextMDS": "0684" + }, + "pathInfo": { + "path": "000900030001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-92b8-448b-897a-89d167ed1114", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-92b8-448b-897a-89d167ed1114", + "navParaentId_Code": "230300", + "navParaentId_Name": "鸡西市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0684", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-576a-4e11-97bb-71b9f7439aed", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-92b8-448b-897a-89d167ed1114", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "version": null, + "code": "230200", + "name": "齐齐哈尔市", + "gjmc": "齐齐哈尔市", + "udtwb": { + "chComTextMDS": "0666" + }, + "pathInfo": { + "path": "00090002", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "sequence": 2, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b8ad-4190-816f-fd987704296c", + "navParaentId_Code": "230000", + "navParaentId_Name": "黑龙江省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0666", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-f45d-4b3c-997a-3fc329fb7600", + "version": null, + "code": "230281", + "name": "讷河市", + "gjmc": "讷河市", + "udtwb": { + "chComTextMDS": "0682" + }, + "pathInfo": { + "path": "000900020016", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 16, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0682", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f45d-4b3c-997a-3fc329fb7600", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-1c84-4b5d-9a2f-379effa524c2", + "version": null, + "code": "230231", + "name": "拜泉县", + "gjmc": "拜泉县", + "udtwb": { + "chComTextMDS": "0681" + }, + "pathInfo": { + "path": "000900020015", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 15, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0681", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-1c84-4b5d-9a2f-379effa524c2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f2cc-453e-bbaf-cf6a6e8e0a07", + "version": null, + "code": "230230", + "name": "克东县", + "gjmc": "克东县", + "udtwb": { + "chComTextMDS": "0680" + }, + "pathInfo": { + "path": "000900020014", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 14, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0680", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f2cc-453e-bbaf-cf6a6e8e0a07", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-e616-4c35-ab01-fddf9dbb4f65", + "version": null, + "code": "230229", + "name": "克山县", + "gjmc": "克山县", + "udtwb": { + "chComTextMDS": "0679" + }, + "pathInfo": { + "path": "000900020013", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 13, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0679", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-e616-4c35-ab01-fddf9dbb4f65", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-0aca-48d0-a5ec-8c9b5dbc8fee", + "version": null, + "code": "230227", + "name": "富裕县", + "gjmc": "富裕县", + "udtwb": { + "chComTextMDS": "0678" + }, + "pathInfo": { + "path": "000900020012", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 12, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0678", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0aca-48d0-a5ec-8c9b5dbc8fee", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5aa2-421d-9390-a81c0a6c6bc7", + "version": null, + "code": "230225", + "name": "甘南县", + "gjmc": "甘南县", + "udtwb": { + "chComTextMDS": "0677" + }, + "pathInfo": { + "path": "000900020011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0677", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5aa2-421d-9390-a81c0a6c6bc7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ca4f-4a71-b195-be9b31d46d9e", + "version": null, + "code": "230224", + "name": "泰来县", + "gjmc": "泰来县", + "udtwb": { + "chComTextMDS": "0676" + }, + "pathInfo": { + "path": "000900020010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0676", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ca4f-4a71-b195-be9b31d46d9e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-beab-456a-a0a6-bf69147a7c4f", + "version": null, + "code": "230223", + "name": "依安县", + "gjmc": "依安县", + "udtwb": { + "chComTextMDS": "0675" + }, + "pathInfo": { + "path": "000900020009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0675", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-beab-456a-a0a6-bf69147a7c4f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-974c-4f95-9773-eba27b239c23", + "version": null, + "code": "230221", + "name": "龙江县", + "gjmc": "龙江县", + "udtwb": { + "chComTextMDS": "0674" + }, + "pathInfo": { + "path": "000900020008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0674", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-974c-4f95-9773-eba27b239c23", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-33ef-4836-94a4-034f6e3799f1", + "version": null, + "code": "230208", + "name": "梅里斯达斡尔族区", + "gjmc": "梅里斯达斡尔族区", + "udtwb": { + "chComTextMDS": "0673" + }, + "pathInfo": { + "path": "000900020007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0673", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-33ef-4836-94a4-034f6e3799f1", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-93f1-4580-ad37-b496d76d9ab2", + "version": null, + "code": "230207", + "name": "碾子山区", + "gjmc": "碾子山区", + "udtwb": { + "chComTextMDS": "0672" + }, + "pathInfo": { + "path": "000900020006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0672", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-93f1-4580-ad37-b496d76d9ab2", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-5ee7-4c41-afca-f60f782e4c4e", + "version": null, + "code": "230206", + "name": "富拉尔基区", + "gjmc": "富拉尔基区", + "udtwb": { + "chComTextMDS": "0671" + }, + "pathInfo": { + "path": "000900020005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0671", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-5ee7-4c41-afca-f60f782e4c4e", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3bab-42dc-82f3-69a90f7be147", + "version": null, + "code": "230205", + "name": "昂昂溪区", + "gjmc": "昂昂溪区", + "udtwb": { + "chComTextMDS": "0670" + }, + "pathInfo": { + "path": "000900020004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0670", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3bab-42dc-82f3-69a90f7be147", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-bde0-4b95-bcd9-d8db40bce221", + "version": null, + "code": "230204", + "name": "铁锋区", + "gjmc": "铁锋区", + "udtwb": { + "chComTextMDS": "0669" + }, + "pathInfo": { + "path": "000900020003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0669", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-bde0-4b95-bcd9-d8db40bce221", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-537c-4473-946d-386006b658e0", + "version": null, + "code": "230203", + "name": "建华区", + "gjmc": "建华区", + "udtwb": { + "chComTextMDS": "0668" + }, + "pathInfo": { + "path": "000900020002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0668", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-537c-4473-946d-386006b658e0", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-36e7-48ff-b1a3-894dbf6a6496", + "version": null, + "code": "230202", + "name": "龙沙区", + "gjmc": "龙沙区", + "udtwb": { + "chComTextMDS": "0667" + }, + "pathInfo": { + "path": "000900020001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "navParaentId_Code": "230200", + "navParaentId_Name": "齐齐哈尔市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0667", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-36e7-48ff-b1a3-894dbf6a6496", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-0c8c-4570-9246-ab2d4f69a8ea", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "version": null, + "code": "230100", + "name": "哈尔滨市", + "gjmc": "哈尔滨市", + "udtwb": { + "chComTextMDS": "0647" + }, + "pathInfo": { + "path": "00090001", + "layer": 2, + "isDetail": false + }, + "parentInfo": { + "parentElement": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "sequence": 1, + "layer": 2, + "isDetail": false + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-b8ad-4190-816f-fd987704296c", + "navParaentId_Code": "230000", + "navParaentId_Name": "黑龙江省" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0647", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [ + { + "data": { + "id": "yzsj0xzq-f4c0-464f-8d3a-1ee48837dfab", + "version": null, + "code": "230184", + "name": "五常市", + "gjmc": "五常市", + "udtwb": { + "chComTextMDS": "0665" + }, + "pathInfo": { + "path": "000900010018", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 18, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0665", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f4c0-464f-8d3a-1ee48837dfab", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a7a1-4840-9073-37708e68642d", + "version": null, + "code": "230183", + "name": "尚志市", + "gjmc": "尚志市", + "udtwb": { + "chComTextMDS": "0664" + }, + "pathInfo": { + "path": "000900010017", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 17, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0664", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a7a1-4840-9073-37708e68642d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-41b0-47d7-9f22-b503ee043a2d", + "version": null, + "code": "230129", + "name": "延寿县", + "gjmc": "延寿县", + "udtwb": { + "chComTextMDS": "0663" + }, + "pathInfo": { + "path": "000900010016", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 16, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0663", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-41b0-47d7-9f22-b503ee043a2d", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c2e6-412d-bf23-b1b0f340d24c", + "version": null, + "code": "230128", + "name": "通河县", + "gjmc": "通河县", + "udtwb": { + "chComTextMDS": "0662" + }, + "pathInfo": { + "path": "000900010015", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 15, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0662", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c2e6-412d-bf23-b1b0f340d24c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-c940-408c-bc0d-c60f0a2399d8", + "version": null, + "code": "230127", + "name": "木兰县", + "gjmc": "木兰县", + "udtwb": { + "chComTextMDS": "0661" + }, + "pathInfo": { + "path": "000900010014", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 14, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0661", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-c940-408c-bc0d-c60f0a2399d8", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-6a8a-485d-830b-28a05c47f579", + "version": null, + "code": "230126", + "name": "巴彦县", + "gjmc": "巴彦县", + "udtwb": { + "chComTextMDS": "0660" + }, + "pathInfo": { + "path": "000900010013", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 13, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0660", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-6a8a-485d-830b-28a05c47f579", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-8d23-40e0-9663-62ae07f0bb61", + "version": null, + "code": "230125", + "name": "宾县", + "gjmc": "宾县", + "udtwb": { + "chComTextMDS": "0659" + }, + "pathInfo": { + "path": "000900010012", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 12, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0659", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-8d23-40e0-9663-62ae07f0bb61", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f8d5-47ae-8b75-c1958117669a", + "version": null, + "code": "230124", + "name": "方正县", + "gjmc": "方正县", + "udtwb": { + "chComTextMDS": "0658" + }, + "pathInfo": { + "path": "000900010011", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 11, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0658", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f8d5-47ae-8b75-c1958117669a", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-38f2-428e-8b66-2239a65f44d7", + "version": null, + "code": "230123", + "name": "依兰县", + "gjmc": "依兰县", + "udtwb": { + "chComTextMDS": "0657" + }, + "pathInfo": { + "path": "000900010010", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 10, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0657", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-38f2-428e-8b66-2239a65f44d7", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-524c-4df1-b73f-f0f069336e03", + "version": null, + "code": "230113", + "name": "双城区", + "gjmc": "双城区", + "udtwb": { + "chComTextMDS": "0656" + }, + "pathInfo": { + "path": "000900010009", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 9, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0656", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-524c-4df1-b73f-f0f069336e03", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-020f-4e32-b8bb-6e3bd54a2cd9", + "version": null, + "code": "230112", + "name": "阿城区", + "gjmc": "阿城区", + "udtwb": { + "chComTextMDS": "0655" + }, + "pathInfo": { + "path": "000900010008", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 8, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0655", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-020f-4e32-b8bb-6e3bd54a2cd9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f55f-463b-b633-f719704e7b3f", + "version": null, + "code": "230111", + "name": "呼兰区", + "gjmc": "呼兰区", + "udtwb": { + "chComTextMDS": "0654" + }, + "pathInfo": { + "path": "000900010007", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 7, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0654", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f55f-463b-b633-f719704e7b3f", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-7a86-470c-8b01-c5b12ef03af9", + "version": null, + "code": "230110", + "name": "香坊区", + "gjmc": "香坊区", + "udtwb": { + "chComTextMDS": "0653" + }, + "pathInfo": { + "path": "000900010006", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 6, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0653", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-7a86-470c-8b01-c5b12ef03af9", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a5d2-44da-9b35-d25d587063e8", + "version": null, + "code": "230109", + "name": "松北区", + "gjmc": "松北区", + "udtwb": { + "chComTextMDS": "0652" + }, + "pathInfo": { + "path": "000900010005", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 5, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0652", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a5d2-44da-9b35-d25d587063e8", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-f3ba-48e8-8bf2-d0853c1a9e1b", + "version": null, + "code": "230108", + "name": "平房区", + "gjmc": "平房区", + "udtwb": { + "chComTextMDS": "0651" + }, + "pathInfo": { + "path": "000900010004", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 4, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0651", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-f3ba-48e8-8bf2-d0853c1a9e1b", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-4499-483f-8b30-bd15c81dffdf", + "version": null, + "code": "230104", + "name": "道外区", + "gjmc": "道外区", + "udtwb": { + "chComTextMDS": "0650" + }, + "pathInfo": { + "path": "000900010003", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 3, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0650", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-4499-483f-8b30-bd15c81dffdf", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-a1d9-4131-929e-801af0d72920", + "version": null, + "code": "230103", + "name": "南岗区", + "gjmc": "南岗区", + "udtwb": { + "chComTextMDS": "0649" + }, + "pathInfo": { + "path": "000900010002", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 2, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0649", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-a1d9-4131-929e-801af0d72920", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-11d1-45f1-83cf-0243579c8a90", + "version": null, + "code": "230102", + "name": "道里区", + "gjmc": "道里区", + "udtwb": { + "chComTextMDS": "0648" + }, + "pathInfo": { + "path": "000900010001", + "layer": 3, + "isDetail": true + }, + "parentInfo": { + "parentElement": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "sequence": 1, + "layer": 3, + "isDetail": true + }, + "navParaentId": { + "navParaentId": "dhsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "navParaentId_Code": "230100", + "navParaentId_Name": "哈尔滨市" + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0648", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": true, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-11d1-45f1-83cf-0243579c8a90", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-ceae-4421-a91d-5ade6f7df6a2", + "addtional": false + } + ], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b8ad-4190-816f-fd987704296c", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-2cc7-43a4-ab36-03690f822afb", + "version": null, + "code": "220000", + "name": "吉林省", + "gjmc": "吉林省", + "udtwb": { + "chComTextMDS": "0576" + }, + "pathInfo": { + "path": "0008", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 8, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0576", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-2cc7-43a4-ab36-03690f822afb", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b791-4c4e-a495-85d82a51dfba", + "version": null, + "code": "210000", + "name": "辽宁省", + "gjmc": "辽宁省", + "udtwb": { + "chComTextMDS": "0461" + }, + "pathInfo": { + "path": "0007", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 7, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0461", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b791-4c4e-a495-85d82a51dfba", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-34fd-41c8-8cec-f80bc24c6415", + "version": null, + "code": "150000", + "name": "内蒙古自治区", + "gjmc": "内蒙古自治区", + "udtwb": { + "chComTextMDS": "0345" + }, + "pathInfo": { + "path": "0006", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 6, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0345", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-34fd-41c8-8cec-f80bc24c6415", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3e44-40b4-9234-fd7920fb7055", + "version": null, + "code": "140000", + "name": "山西省", + "gjmc": "山西省", + "udtwb": { + "chComTextMDS": "0215" + }, + "pathInfo": { + "path": "0005", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 5, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0215", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3e44-40b4-9234-fd7920fb7055", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-dd4f-4ebd-88e7-83d307b39623", + "version": null, + "code": "130000", + "name": "河北省", + "gjmc": "河北省", + "udtwb": { + "chComTextMDS": "0035" + }, + "pathInfo": { + "path": "0003", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 3, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0035", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-dd4f-4ebd-88e7-83d307b39623", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-3b21-4682-9610-e56d4a72a016", + "version": null, + "code": "120000", + "name": "天津市", + "gjmc": "天津市", + "udtwb": { + "chComTextMDS": "0018" + }, + "pathInfo": { + "path": "0002", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 2, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0018", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-3b21-4682-9610-e56d4a72a016", + "addtional": false + }, + { + "data": { + "id": "yzsj0xzq-b2cd-49f2-9394-b12034aa832a", + "version": null, + "code": "110000", + "name": "北京市", + "gjmc": "北京市", + "udtwb": { + "chComTextMDS": "0001" + }, + "pathInfo": { + "path": "0001", + "layer": 1, + "isDetail": false + }, + "parentInfo": { + "parentElement": null, + "sequence": 1, + "layer": 1, + "isDetail": false + }, + "navParaentId": { + "navParaentId": null, + "navParaentId_Code": null, + "navParaentId_Name": null + }, + "dataType": "行政区", + "sfkz": false, + "sfqx": false, + "fjlx": "all", + "filterFirst": null, + "filterSecond": null, + "note": null, + "udtjb": { + "bh": "0001", + "mc": null, + "zs": null, + "fds": null, + "rq": null, + "rqsj": null, + "buer": null, + "bz": null, + "mj": null + } + }, + "icon": null, + "expandedIcon": null, + "collapsedIcon": null, + "children": [], + "leaf": false, + "expanded": false, + "selectable": true, + "parent": null, + "id": "yzsj0xzq-b2cd-49f2-9394-b12034aa832a", + "addtional": false + } + ], + "favoriteData": null, + "total": 0, + "pageInfo": null, + "treeInfo": { + "loadDataType": "all", + "layerType": "pathcode", + "dataField": "pathInfo", + "pathField": "path", + "layerField": "layer", + "isDetailField": "isDetail", + "onlySelectLeaf": false, + "parentField": "parentElement", + "treeDataIsInit": true + }, + "displayType": "TreeList", + "title": "分级码树帮助分层", + "navigation": null, + "displayInfo": { + "idField": "id", + "valueField": "id", + "textField": "name" + }, + "searchFields": [ + { + "label": "code", + "value": "Code" + }, + { + "label": "name", + "value": "Name" + }, + { + "label": "gjmc", + "value": "GJMC" + } + ], + "sortable": false, + "selectedData": null +} \ No newline at end of file -- Gitee From 1cdf3d8552405ebde85f2ccf05bb6adbbce8a08f Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Thu, 27 Mar 2025 15:17:58 +0800 Subject: [PATCH 131/153] =?UTF-8?q?chore:=20=E4=BF=AE=E5=A4=8D=E5=BF=85?= =?UTF-8?q?=E5=A1=AB=E3=80=81=E6=A0=A1=E9=AA=8C=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity-store-value-change-handler.ts | 6 +++- .../devkit/lib/effector/required-effector.ts | 35 ++++++++++++++----- .../devkit/lib/effector/validate-effector.ts | 8 +++-- packages/devkit/lib/expression/types.ts | 8 ++--- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts b/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts index 7f15622d08f..3a6cff40e87 100644 --- a/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts +++ b/packages/devkit/lib/change-handler/entity-store-value-change-handler.ts @@ -1,6 +1,6 @@ import { ChangeValueChange, EntityChangeType, EntityPathNode, EntityPathNodeType, RemoveEntityChange } from "../store"; import { Change, ChangeSource } from "../change-observer"; -import { ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType,ExpressionContextBuilder } from "../expression"; +import { ExpressionExecutor, ExpressionObject, ExpressionResult, ExpressionType, ExpressionContextBuilder } from "../expression"; import { DEPENDENCY_SPLITER, ENTITY_TEMPLATE } from "../expression-dependency-resolver"; import { AbstractChangeHandler } from "./abstract-change-handler"; import { EffectOption, EffectorFactory } from "../effector"; @@ -130,7 +130,11 @@ export class EntityStoreValueChangeHandler extends AbstractChangeHandler { return false; } const { entityPaths, propertyPaths } = this.resolveChangePath(change); + const { entityPaths: expressionEntityPaths, propertyPaths: expressionPropertyPaths } = this.resolvePath(expressionObject.path); const changePaths = entityPaths.concat(propertyPaths); + if (isEqual(changePaths, expressionEntityPaths.concat(expressionPropertyPaths))) { + return true; + } changePaths.splice(0, 0, ENTITY_TEMPLATE); return deps.includes(changePaths.join('/')); }); diff --git a/packages/devkit/lib/effector/required-effector.ts b/packages/devkit/lib/effector/required-effector.ts index ae4cf3eb4be..6a3c9f2bc4a 100644 --- a/packages/devkit/lib/effector/required-effector.ts +++ b/packages/devkit/lib/effector/required-effector.ts @@ -1,3 +1,4 @@ +import { isEmpty } from 'lodash-es'; import { RENDER_ENGINE_TOKEN, RenderEngine, ValidationState } from '../common'; import { ExpressionBindingType, ExpressionObject, ExpressionType } from '../expression'; import { Entity, EntityList } from '../store'; @@ -22,7 +23,17 @@ export class RequiredEffector implements Effector { if (!controlConfig) { return; } - this.updateControlValidation(controlConfig.name, value, expressionObject.message); + this.updateControlRequiredState(controlConfig.name, value); + const validationState = this.viewModel.getModule().getContext().getParam('validationState'); + const currentControlValue = this.viewModel.entityStore.getValueByPath(expressionObject.path); + if (validationState === ValidationState.Validating) { + const message = this.formatMessage(expressionObject.message, controlConfig.displayName); + if (isEmpty(currentControlValue) && value) { + this.updateControlValidation(controlConfig.name, false, message); + } else { + this.updateControlValidation(controlConfig.name, true, message); + } + } // const fullPath = this.resolveFullPath(expressionObject, option); // if (fullPath) { // this.updateFormState(fullPath, value); @@ -75,6 +86,9 @@ export class RequiredEffector implements Effector { }, [`[${id}]`]); return `/${entityEffectPaths.concat(propertyPaths).join('/')}`; } + private formatMessage(message: string | null | undefined, propertyName: string | undefined) { + return propertyName && message && message.replace(/\$property/g, propertyName) || undefined; + } /** * 检查是否需要处理该表达式 */ @@ -87,12 +101,10 @@ export class RequiredEffector implements Effector { return false; } - if (expressionObject.type !== ExpressionType.Validate) { + if (expressionObject.type !== ExpressionType.Required) { return false; } - - const validationState = this.viewModel.getModule().getContext().getParam('validationState'); - return validationState === ValidationState.Validating; + return true; } /** * 解析路径 @@ -136,13 +148,18 @@ export class RequiredEffector implements Effector { /** * 更新控件验证状态 */ - private updateControlValidation(controlName: string, isValid: boolean, message?: string) { + private updateControlValidation(elementId: string, isValid: boolean, message?: string) { const renderEngine = this.getRenderEngine(); const props = isValid - ? { errors: null, required: false } - : { errors: { required: { name: message } }, required: true }; + ? { errors: null } + : { errors: { required: { name: message } } }; - renderEngine.setProps(controlName, props); + renderEngine.setProps(elementId, props); + } + private updateControlRequiredState(elementId: string, isRequired: boolean) { + const renderEngine = this.getRenderEngine(); + const props = { required: isRequired }; + renderEngine.setProps(elementId, props); } /** diff --git a/packages/devkit/lib/effector/validate-effector.ts b/packages/devkit/lib/effector/validate-effector.ts index 246f5faf215..82eec440272 100644 --- a/packages/devkit/lib/effector/validate-effector.ts +++ b/packages/devkit/lib/effector/validate-effector.ts @@ -28,10 +28,12 @@ export class ValidateEffector implements Effector { if (!controlConfig) { return; } - - this.updateControlValidation(controlConfig.name, value, expressionObject.message); + const message = this.formatMessage(expressionObject.message, controlConfig.displayName); + this.updateControlValidation(controlConfig.name, value, message); + } + private formatMessage(message: string | null | undefined, propertyName: string | undefined) { + return propertyName && message && message.replace(/\$property/g, propertyName) || undefined; } - /** * 检查是否需要处理该表达式 */ diff --git a/packages/devkit/lib/expression/types.ts b/packages/devkit/lib/expression/types.ts index df1207557bf..9e9eb81de88 100644 --- a/packages/devkit/lib/expression/types.ts +++ b/packages/devkit/lib/expression/types.ts @@ -15,7 +15,7 @@ export enum ExpressionType { /** * 必填表达式 */ - Required = 'require', + Required = 'required', /** * 只读表达式 */ @@ -127,17 +127,17 @@ export interface Executor { } export const DEFAULT_EXPRESSION_VALIDATE_MESSAGE = { 'zh-CHS': { - require: `请输入'$property'`, + required: `请输入'$property'`, validate: `'$property'校验不通过`, dataPicking: '帮助前表达式校验不通过' }, 'en': { - require: `Please input '$property'`, + required: `Please input '$property'`, validate: `'$property' calibration failed`, dataPicking: 'Failed to verify the expression before help' }, 'zh-CHT': { - require: `請輸入'$property'`, + required: `請輸入'$property'`, validate: `'$property'校驗不通過`, dataPicking: '幫助前表達式校驗不通過' } -- Gitee From 8f4375a1365b59b0ef42048a4447d28d4aa4139b Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Thu, 27 Mar 2025 15:31:08 +0800 Subject: [PATCH 132/153] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=BC=BA?= =?UTF-8?q?=E5=B0=91=E6=9C=8D=E5=8A=A1=E6=8F=90=E4=BE=9B=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/renderer/src/callback-handler/providers.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/renderer/src/callback-handler/providers.ts b/packages/renderer/src/callback-handler/providers.ts index 1a18aada4c8..0fd5b4aa37a 100644 --- a/packages/renderer/src/callback-handler/providers.ts +++ b/packages/renderer/src/callback-handler/providers.ts @@ -12,9 +12,9 @@ import { FormNotifyService } from "@farris/command-services-vue"; export const callbackHandlerProviders: StaticProvider[] = [ { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeEditCallCallbackHandler, deps: [Module, FormMetadataService, ExpressionEvaluator], multi: true }, - { provide: CALLBACK_HANDLER_TOKEN, useClass: DictPickingCallbackHandler, deps: [Module, FormMetadataService, ExpressionEvaluator], multi: true }, + { provide: CALLBACK_HANDLER_TOKEN, useClass: DictPickingCallbackHandler, deps: [Module, FormMetadataService, , ExpressionRegistry, FormNotifyService], multi: true }, { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeLoadDataCallbackHandler, deps: [Module, FormMetadataService], multi: true }, { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeSelectDataCallbackHandler, deps: [Module, FormMetadataService], multi: true }, - { provide: CALLBACK_HANDLER_TOKEN, useClass: DictPickedCallbackHandler, deps: [Module, FormMetadataService, ExpressionRegistry, FormNotifyService], multi: true }, + { provide: CALLBACK_HANDLER_TOKEN, useClass: DictPickedCallbackHandler, deps: [Module, FormMetadataService], multi: true }, { provide: CallbackHandlerRegistry, useClass: CallbackHandlerRegistry, deps: [Injector] } ]; -- Gitee From 8d0ef7f25ff4b35927b05c6efbdb6c0c6a59d49e Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Thu, 27 Mar 2025 16:09:22 +0800 Subject: [PATCH 133/153] =?UTF-8?q?chore:=20=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=B6=88=E6=81=AF=E6=8F=90=E7=A4=BA=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/devkit/lib/effector/types.ts | 2 +- packages/devkit/lib/expression/expression-registry.ts | 1 + packages/devkit/lib/expression/types.ts | 3 ++- packages/renderer/src/callback-handler/providers.ts | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/devkit/lib/effector/types.ts b/packages/devkit/lib/effector/types.ts index 4610fb8daa3..6f3053e864a 100644 --- a/packages/devkit/lib/effector/types.ts +++ b/packages/devkit/lib/effector/types.ts @@ -17,7 +17,7 @@ export interface EffectOption { /** * 消息提示类型 */ - messageType?: ExpressionMessageType | null; + messageType?: string | null; } export interface Effector { diff --git a/packages/devkit/lib/expression/expression-registry.ts b/packages/devkit/lib/expression/expression-registry.ts index b4b526443f5..b3e046c6f14 100644 --- a/packages/devkit/lib/expression/expression-registry.ts +++ b/packages/devkit/lib/expression/expression-registry.ts @@ -30,6 +30,7 @@ export class ExpressionRegistry { type: rule.type, expression: expressionValue, message: rule.message, + messageType: rule.messageType || 'error', deps: [] }; // 构造表达式提示信息 diff --git a/packages/devkit/lib/expression/types.ts b/packages/devkit/lib/expression/types.ts index 9e9eb81de88..48e0383be20 100644 --- a/packages/devkit/lib/expression/types.ts +++ b/packages/devkit/lib/expression/types.ts @@ -59,6 +59,7 @@ export interface ExpressionRule { type: ExpressionType; value: string; message?: string; + messageType?: string; } export interface ExpressionConfig { target: string; @@ -112,7 +113,7 @@ export interface ExpressionObject { /** * 提示消息类型 */ - messageType?: ExpressionMessageType; + messageType?: string | null; /** * 表达式计算函数 */ diff --git a/packages/renderer/src/callback-handler/providers.ts b/packages/renderer/src/callback-handler/providers.ts index 0fd5b4aa37a..d27410d0418 100644 --- a/packages/renderer/src/callback-handler/providers.ts +++ b/packages/renderer/src/callback-handler/providers.ts @@ -12,7 +12,7 @@ import { FormNotifyService } from "@farris/command-services-vue"; export const callbackHandlerProviders: StaticProvider[] = [ { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeEditCallCallbackHandler, deps: [Module, FormMetadataService, ExpressionEvaluator], multi: true }, - { provide: CALLBACK_HANDLER_TOKEN, useClass: DictPickingCallbackHandler, deps: [Module, FormMetadataService, , ExpressionRegistry, FormNotifyService], multi: true }, + { provide: CALLBACK_HANDLER_TOKEN, useClass: DictPickingCallbackHandler, deps: [Module, FormMetadataService, ExpressionEvaluator, ExpressionRegistry, FormNotifyService], multi: true }, { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeLoadDataCallbackHandler, deps: [Module, FormMetadataService], multi: true }, { provide: CALLBACK_HANDLER_TOKEN, useClass: BeforeSelectDataCallbackHandler, deps: [Module, FormMetadataService], multi: true }, { provide: CALLBACK_HANDLER_TOKEN, useClass: DictPickedCallbackHandler, deps: [Module, FormMetadataService], multi: true }, -- Gitee From 9840e697bbf982512eb9bbc31a63c844a109f539 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Thu, 27 Mar 2025 16:12:50 +0800 Subject: [PATCH 134/153] =?UTF-8?q?chore:=20=E5=88=A0=E9=99=A4=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/command-services/lib/validation.service.ts | 1 - packages/renderer/src/form-engine/form-engine.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/command-services/lib/validation.service.ts b/packages/command-services/lib/validation.service.ts index b0a089c28a6..8d83ed90419 100644 --- a/packages/command-services/lib/validation.service.ts +++ b/packages/command-services/lib/validation.service.ts @@ -240,7 +240,6 @@ export class ValidationService extends BaseDataService { * 处理验证结果 */ private handleValidationResult(result: any, entity: Entity, path: string, entityPaths: string[], propertyPaths: string[], expressionObject: ExpressionObject) { - console.log(result, entity.toJSON(), path); const controlName = this.getControlName(entityPaths, propertyPaths); if (!controlName) { return; diff --git a/packages/renderer/src/form-engine/form-engine.ts b/packages/renderer/src/form-engine/form-engine.ts index eb50a877d46..45bb23cd6f4 100644 --- a/packages/renderer/src/form-engine/form-engine.ts +++ b/packages/renderer/src/form-engine/form-engine.ts @@ -16,7 +16,6 @@ export class FormEngine { ) { this.changeObserverRegistry.observers.forEach((observer: ChangeObserver) => { observer.observe((change: Change) => { - console.log(change); const results: Map = this.changeResolveService.resolve(change); if (results && results.size > 0) { results.forEach((configs: Configuration[], componentId: string) => { -- Gitee From 20d546b0e910e6f1d36adb3960ff07d0bf50dddb Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Thu, 27 Mar 2025 16:14:17 +0800 Subject: [PATCH 135/153] =?UTF-8?q?fix:=20=E5=A2=9E=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E8=A7=84=E5=88=99=E7=9A=84=E5=90=88=E6=B3=95?= =?UTF-8?q?=E6=80=A7=E6=A3=80=E6=9F=A5=EF=BC=8C=E4=B8=8D=E5=90=88=E6=B3=95?= =?UTF-8?q?=E6=97=B6=E4=B8=8D=E5=86=8D=E6=89=A7=E8=A1=8C=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form/form-array-store-initializer.ts | 4 +- .../lib/store/form/form-store-initializer.ts | 3 + .../devkit/lib/store/form/validation/types.ts | 15 ++- .../validators/custom-function-validator.ts | 20 +++- .../validation/validators/format-validator.ts | 96 +++++++++++++++++++ .../store/form/validation/validators/index.ts | 9 +- .../validators/max-date-validator.ts | 33 ++++++- .../validators/max-length-validator.ts | 19 ++++ .../validators/max-value-validator.ts | 20 ++++ .../validators/min-date-validator.ts | 28 +++++- .../validators/min-length-validator.ts | 19 ++++ .../validators/min-value-validator.ts | 21 ++++ .../validators/pattern-validator.ts | 20 ++++ .../validators/required-validator.ts | 15 +++ .../validation/validators/static-validator.ts | 27 ++++-- 15 files changed, 324 insertions(+), 25 deletions(-) create mode 100644 packages/devkit/lib/store/form/validation/validators/format-validator.ts diff --git a/packages/devkit/lib/store/form/form-array-store-initializer.ts b/packages/devkit/lib/store/form/form-array-store-initializer.ts index c5d4d07bfa1..b1e67d0633c 100644 --- a/packages/devkit/lib/store/form/form-array-store-initializer.ts +++ b/packages/devkit/lib/store/form/form-array-store-initializer.ts @@ -88,6 +88,8 @@ class FormArrayStoreInitializer { } entityStore.watchChange((change: any) => { + console.log(`----------${this.formArrayStore.getId()} : watch entityChange-----`) + console.log(change); this.updateFormArrayStore(); }); } @@ -196,8 +198,6 @@ class FormArrayStoreInitializer { return allIndexedGrandEntities; } - - /** * 是否是从从表 */ diff --git a/packages/devkit/lib/store/form/form-store-initializer.ts b/packages/devkit/lib/store/form/form-store-initializer.ts index 1461de3ceae..91305ae8cfd 100644 --- a/packages/devkit/lib/store/form/form-store-initializer.ts +++ b/packages/devkit/lib/store/form/form-store-initializer.ts @@ -98,6 +98,9 @@ class FormStoreInitializer { } entityStore.watchChange((change: any) => { + console.log(`----------${this.formStore.getId()} : watch entityChange-----`) + console.log(change); + controlConfigs.forEach((controlConfig) => { this.updateFormStore(); }); diff --git a/packages/devkit/lib/store/form/validation/types.ts b/packages/devkit/lib/store/form/validation/types.ts index 5d20083f005..5de3c04ff27 100644 --- a/packages/devkit/lib/store/form/validation/types.ts +++ b/packages/devkit/lib/store/form/validation/types.ts @@ -71,6 +71,14 @@ interface MinDateValidationRule extends ValidationRule { minDate: Date | string; } +/** + * 正则验证 + */ +interface FormatValidationRule extends ValidationRule { + name: 'format'; + format: 'mobilePhone' | 'landlinePhone' | 'mobileOrLandlinePhone' | 'postcode' | 'email' | 'idCardNumber' | 'carNumber' | 'subjectCode'; +} + /** * 正则验证 */ @@ -117,9 +125,8 @@ interface Validator { export { ValidationRule, RequiredValidationRule, StaticValidationRule, - MaxLengthValidationRule, MinLengthValidationRule, - MaxValueValidationRule, MinValueValidationRule, - MaxDateValidationRule, MinDateValidationRule, - PatternValidationRule, CustomValidatorFunction, CustomFunctionValidationRule, + MaxLengthValidationRule, MinLengthValidationRule, MaxValueValidationRule, MinValueValidationRule, + MaxDateValidationRule, MinDateValidationRule, FormatValidationRule, PatternValidationRule, + CustomValidatorFunction, CustomFunctionValidationRule, Validator, ValidationError, ValidationErrors }; diff --git a/packages/devkit/lib/store/form/validation/validators/custom-function-validator.ts b/packages/devkit/lib/store/form/validation/validators/custom-function-validator.ts index cc0346da08b..fcb9b548ee2 100644 --- a/packages/devkit/lib/store/form/validation/validators/custom-function-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/custom-function-validator.ts @@ -15,11 +15,11 @@ class CustomFunctionValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: CustomFunctionValidationRule): ValidationError | null { - const { name, customFn } = rule; - if (!customFn || typeof customFn !== 'function') { + if (!this.checkRule(rule)) { return null; } + const { name, customFn } = rule; if (customFn(value) === false) { const message = rule.message || '输入值不符合要求'; return { name, message, actualValue: value }; @@ -27,6 +27,22 @@ class CustomFunctionValidator extends BaseValidator { return null; } + + /** + * 检查规则是否合法 + */ + private checkRule(rule: CustomFunctionValidationRule): boolean { + if (!rule || rule.name !== this.name) { + return false; + } + + const { customFn } = rule; + if (!customFn || typeof customFn !== 'function') { + return false; + } + + return true; + } } export { CustomFunctionValidator }; diff --git a/packages/devkit/lib/store/form/validation/validators/format-validator.ts b/packages/devkit/lib/store/form/validation/validators/format-validator.ts new file mode 100644 index 00000000000..7e56ac6905c --- /dev/null +++ b/packages/devkit/lib/store/form/validation/validators/format-validator.ts @@ -0,0 +1,96 @@ +import { StringUtil, NumberUtil } from '../../../../common/index'; +import { ValidationError, FormatValidationRule } from '../types'; +import { BaseValidator } from './base-validator'; + +/** + * 格式验证器 + */ +class ForamtValidator extends BaseValidator { + + /** + * 名称 + */ + public name: string = 'stringFormat'; + + /** + * 格式正则 + */ + private formatConfigs = { + mobilePhone: { + pattern: '^1[0-9]{10}$', + message: '请输入有效的手机号' + }, + landlinePhone: { + pattern: '^(0[0-9]{2,3}\\-)?([2-9][0-9]{6,7})+(\\-[0-9]{1,4})?$', + message: '请输入有效的座机号/传真号' + }, + mobileOrLandlinePhone: { + pattern: '^(0[0-9]{2,3}\\-)?([2-9][0-9]{6,7})+(\\-[0-9]{1,4})?$|^1[0-9]{10}$', + message: '请输入有效的手机号/座机号/传真号' + }, + postcode: { + pattern: '^[1-9]\\d{5}(?!\\d)$', + message: '请输入有效的邮政编码' + }, + email: { + pattern: '^[A-Za-z\\d]+([-_.][A-Za-z\\d]+)*@([A-Za-z\\d]+[-.])+[A-Za-z]{2,5}$', + message: '请输入有效的电子邮箱' + }, + idCardNumber: { + pattern: '^[1-9]\\d{5}[1-9]\\d{3}((0[1-9])|(1[0-2]))(0[1-9]|([1|2][0-9])|3[0-1])((\\d{4})|\\d{3}X)$', + message: '请输入有效的身份证号码' + }, + carNumber: { + pattern: '^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$', + message: '请输入有效的车牌号' + }, + subjectCode: { + pattern: '^\\d{10}$', + message: '请输入有效的会计科目代码' + } + }; + + /** + * 验证方法 + */ + public validate(value: any, rule: FormatValidationRule): ValidationError | null { + if (!this.checkRule(rule)) { + return null; + } + + let { name, format } = rule; + const formatConfig = this.formatConfigs[format] + const regexStr = formatConfig.pattern; + const regex = new RegExp(regexStr); + + if (!regex.test(value)) { + const message = rule.message || formatConfig.message; + return { name, message, actualValue: value }; + } + + return null; + } + + /** + * 检查规则是否合法 + */ + private checkRule(rule: FormatValidationRule): boolean { + if (!rule || rule.name !== this.name) { + return false; + } + + const { format } = rule; + if (!format) { + return false; + } + + const formatConfig = this.formatConfigs[rule.foramt]; + if (!formatConfig) { + return false; + } + + return true; + } +} + +export { ForamtValidator }; \ No newline at end of file diff --git a/packages/devkit/lib/store/form/validation/validators/index.ts b/packages/devkit/lib/store/form/validation/validators/index.ts index e7470ee42d1..392ace3368f 100644 --- a/packages/devkit/lib/store/form/validation/validators/index.ts +++ b/packages/devkit/lib/store/form/validation/validators/index.ts @@ -6,14 +6,13 @@ import { MaxValueValidator } from './max-value-validator'; import { MinValueValidator } from './min-value-validator'; import { MaxDateValidator } from './max-date-validator'; import { MinDateValidator } from './min-date-validator'; +import { ForamtValidator } from './format-validator'; import { PatternValidator } from './pattern-validator'; import { CustomFunctionValidator } from './custom-function-validator' const validatorTypes = [ - RequiredValidator, StaticValidator, - MaxLengthValidator, MinLengthValidator, - MaxValueValidator, MinValueValidator, - MaxDateValidator, MinDateValidator, - PatternValidator, CustomFunctionValidator, + RequiredValidator, StaticValidator, MaxLengthValidator, MinLengthValidator, + MaxValueValidator, MinValueValidator, MaxDateValidator, MinDateValidator, + ForamtValidator, PatternValidator, CustomFunctionValidator, ]; export { validatorTypes }; diff --git a/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts b/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts index ba9e590c3fe..11aae0a63bf 100644 --- a/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts @@ -1,5 +1,5 @@ import { DateUtil } from '../../../../common/index'; -import { ValidationError, MinDateValidationRule } from '../types'; +import { ValidationError, MaxDateValidationRule } from '../types'; import { BaseValidator } from './base-validator'; /** @@ -15,7 +15,11 @@ class MaxDateValidator extends BaseValidator { /** * 验证方法 */ - public validate(value: any, rule: MinDateValidationRule): ValidationError | null { + public validate(value: any, rule: MaxDateValidationRule): ValidationError | null { + if (!this.checkRule(value)) { + return null; + } + let { name, maxDate, message } = rule; // 空日期,不校验 @@ -23,8 +27,8 @@ class MaxDateValidator extends BaseValidator { return null; } - value = (DateUtil.isDate(value) ? value : DateUtil.parse(value)) as Date; - maxDate = (DateUtil.isDate(maxDate) ? maxDate : DateUtil.parse(maxDate)) as Date; + value = DateUtil.parse(value) as Date; + maxDate = DateUtil.parse(maxDate) as Date; // 无法转换成日期对象的字符串,不校验 if (!value || !maxDate) { @@ -41,6 +45,27 @@ class MaxDateValidator extends BaseValidator { return null; } + + /** + * 检查规则是否合法 + */ + private checkRule(rule: MaxDateValidationRule): boolean { + if (!rule || rule.name !== this.name) { + return false; + } + + const { maxDate } = rule; + if (!maxDate || typeof maxDate !== 'string') { + return false; + } + + const minDateObj = DateUtil.parse(maxDate) as Date; + if (!minDateObj) { + return false; + } + + return true; + } } export { MaxDateValidator }; diff --git a/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts b/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts index e8966b60936..edafb01ae9a 100644 --- a/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts @@ -15,6 +15,9 @@ class MaxLengthValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: MaxLengthValidationRule): ValidationError | null { + if (!this.checkRule(value)) { + return null; + } // 非法值不校验 if (value === null || value === undefined || typeof value.length !== 'number') { @@ -34,6 +37,22 @@ class MaxLengthValidator extends BaseValidator { return null; } + + /** + * 检查规则是否合法 + */ + private checkRule(rule: MaxLengthValidationRule): boolean { + if (!rule || rule.name !== this.name) { + return false; + } + + const { maxLength } = rule; + if (!maxLength || typeof maxLength !== 'number' || isNaN(maxLength) || maxLength === 0) { + return false; + } + + return true; + } } export { MaxLengthValidator }; diff --git a/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts b/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts index 0faf73ffb77..3c23939e15d 100644 --- a/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts @@ -16,6 +16,10 @@ class MaxValueValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: MaxValueValidationRule): ValidationError | null { + if (!this.checkRule(value)) { + return null; + } + if (StringUtil.isString(value) === true) { value = parseFloat(value as string); } @@ -36,6 +40,22 @@ class MaxValueValidator extends BaseValidator { const error = { name, message, maxValue, actualValue: value }; return value > maxValue ? error : null; } + + /** + * 检查规则是否合法 + */ + private checkRule(rule: MaxValueValidationRule): boolean { + if (!rule || rule.name !== this.name) { + return false; + } + + const { maxValue } = rule; + if (typeof maxValue !== 'number' || isNaN(maxValue)) { + return false; + } + + return true; + } } export { MaxValueValidator }; diff --git a/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts b/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts index 639095dde0d..2c804f993f9 100644 --- a/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts @@ -16,6 +16,9 @@ class MinDateValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: MinDateValidationRule): ValidationError | null { + if (!this.checkRule(value)) { + return null; + } let { name, minDate, message } = rule; // 空日期,不校验 @@ -23,8 +26,8 @@ class MinDateValidator extends BaseValidator { return null; } - value = (DateUtil.isDate(value) ? value : DateUtil.parse(value)) as Date; - minDate = (DateUtil.isDate(minDate) ? minDate : DateUtil.parse(minDate)) as Date; + value = DateUtil.parse(value) as Date; + minDate = DateUtil.parse(minDate) as Date; // 无法转换成日期对象的字符串,不校验 if (!value || !minDate) { @@ -41,6 +44,27 @@ class MinDateValidator extends BaseValidator { return null; } + + /** + * 检查规则是否合法 + */ + private checkRule(rule: MinDateValidationRule): boolean { + if (!rule || rule.name !== this.name) { + return false; + } + + const { minDate } = rule; + if (!minDate || typeof minDate !== 'string') { + return false; + } + + const minDateObj = DateUtil.parse(minDate) as Date; + if (!minDateObj) { + return false; + } + + return true; + } } export { MinDateValidator }; diff --git a/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts b/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts index 522d0babf16..7bc7a910832 100644 --- a/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts @@ -15,6 +15,9 @@ class MinLengthValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: MinLengthValidationRule): ValidationError | null { + if (!this.checkRule(value)) { + return null; + } // 非法值,不校验 if (value === null || value === undefined || typeof value.length !== 'number') { @@ -34,6 +37,22 @@ class MinLengthValidator extends BaseValidator { return null; } + + /** + * 检查规则是否合法 + */ + private checkRule(rule: MinLengthValidationRule): boolean { + if (!rule || rule.name !== this.name) { + return false; + } + + const { minLength } = rule; + if (!minLength || typeof minLength !== 'number' || isNaN(minLength) || minLength === 0) { + return false; + } + + return true; + } } export { MinLengthValidator }; diff --git a/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts b/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts index 9b01b77b984..f02d1116f36 100644 --- a/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts @@ -16,6 +16,10 @@ class MinValueValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: MinValueValidationRule): ValidationError | null { + if (!this.checkRule(value)) { + return null; + } + if (StringUtil.isString(value) === true) { value = parseFloat(value as string); } @@ -37,6 +41,23 @@ class MinValueValidator extends BaseValidator { return value < minValue ? error : null; } + + /** + * 检查规则是否合法 + */ + private checkRule(rule: MinValueValidationRule): boolean { + if (!rule || rule.name !== this.name) { + return false; + } + + const { minValue } = rule; + if (typeof minValue !== 'number' || isNaN(minValue)) { + return false; + } + + return true; + } + } export { MinValueValidator }; diff --git a/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts b/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts index 44518de4f99..1c383b105de 100644 --- a/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts @@ -16,6 +16,10 @@ class PatternValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: PatternValidationRule): ValidationError | null { + if (!this.checkRule(value)) { + return null; + } + let { name, pattern } = rule; if (!pattern) { return null; @@ -36,6 +40,22 @@ class PatternValidator extends BaseValidator { return null; } + + /** + * 检查规则是否合法 + */ + private checkRule(rule: PatternValidationRule): boolean { + if (!rule || rule.name !== this.name) { + return false; + } + + const { pattern } = rule; + if (!pattern || typeof pattern !== 'string') { + return false; + } + + return true; + } } export { PatternValidator }; diff --git a/packages/devkit/lib/store/form/validation/validators/required-validator.ts b/packages/devkit/lib/store/form/validation/validators/required-validator.ts index 15f7aa27661..9f6df55f036 100644 --- a/packages/devkit/lib/store/form/validation/validators/required-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/required-validator.ts @@ -15,6 +15,10 @@ class RequiredValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: RequiredValidationRule): ValidationError | null { + if (!this.checkRule(value)) { + return null; + } + if (value === undefined || value == null || value.length === 0) { const name = rule.name; const message = rule.message || '输入的值不能为空'; @@ -24,6 +28,17 @@ class RequiredValidator extends BaseValidator { return null; } + + /** + * 检查规则是否合法 + */ + private checkRule(rule: RequiredValidationRule): boolean { + if (!rule || rule.name !== this.name) { + return false; + } + + return true; + } } export { RequiredValidator }; diff --git a/packages/devkit/lib/store/form/validation/validators/static-validator.ts b/packages/devkit/lib/store/form/validation/validators/static-validator.ts index b2b8a213997..9f8683bc30d 100644 --- a/packages/devkit/lib/store/form/validation/validators/static-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/static-validator.ts @@ -15,14 +15,29 @@ class StaticValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: StaticValidationRule): ValidationError | null { - if (!rule.valid) { - const name = rule.name; - const message = rule.message || '输入的值不符合要求'; - const error = { name, message, actualValue: value }; - return error; + if (!this.checkRule(rule)) { + return null; } - return null; + if (rule.valid === true) { + return null; + } + + const name = rule.name; + const message = rule.message || '输入的值不符合要求'; + const error = { name, message, actualValue: value }; + return error; + } + + /** + * 检查规则是否合法 + */ + private checkRule(rule: StaticValidationRule): boolean { + if (!rule || rule.name !== this.name) { + return false; + } + + return true; } } -- Gitee From 7916a3cf666a4a9bda8fca8b2cd5c12e384b990a Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Thu, 27 Mar 2025 16:48:58 +0800 Subject: [PATCH 136/153] =?UTF-8?q?fix:=20=E6=A0=B9=E6=8D=AE=E6=9C=80?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E8=A1=A8=E5=8D=95DOM=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E5=90=8D=EF=BC=8C=E8=B0=83=E6=95=B4=E7=94=9F=E6=88=90Form?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E7=9A=84=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config-builders/form/form-array-store-config-builder.ts | 2 +- .../src/config-builders/form/form-store-config-builder.ts | 2 +- .../src/config-builders/form/validation-rule-creator.ts | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts b/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts index 09f827480f0..796f1967040 100644 --- a/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts +++ b/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts @@ -27,7 +27,7 @@ class FormArrayStoreConfigBuilder { const stateConfig = this.buildStateConfig(viewModelNode); const storeConfig: FormArrayStoreConfig = { id: viewModelNode.code + '-form-array-store', - displayName: viewModelNode.name, + displayName: vmComponentNode.name, bindingPath: viewModelNode.bindTo, state: stateConfig }; diff --git a/packages/renderer/src/config-builders/form/form-store-config-builder.ts b/packages/renderer/src/config-builders/form/form-store-config-builder.ts index b1561a09031..a6da226c0b1 100644 --- a/packages/renderer/src/config-builders/form/form-store-config-builder.ts +++ b/packages/renderer/src/config-builders/form/form-store-config-builder.ts @@ -27,7 +27,7 @@ class FormStoreConfigBuilder { const stateConfig = this.buildStateConfig(viewModelNode, vmComponentNode); const storeConfig: FormStoreConfig = { id: viewModelNode.code + '-form-store', - displayName: viewModelNode.name, + displayName: vmComponentNode.name, bindingPath: viewModelNode.bindTo, state: stateConfig }; diff --git a/packages/renderer/src/config-builders/form/validation-rule-creator.ts b/packages/renderer/src/config-builders/form/validation-rule-creator.ts index d889b5fb47d..25d1f04b8d2 100644 --- a/packages/renderer/src/config-builders/form/validation-rule-creator.ts +++ b/packages/renderer/src/config-builders/form/validation-rule-creator.ts @@ -36,7 +36,7 @@ class ValidationRuleCreator { * 必填 */ public required(controlNode: any): RequiredValidationRule | undefined { - const { require: required } = controlNode.editor; + const { required } = controlNode.editor; if (!this.isValidValue(required)) { return; } @@ -115,7 +115,7 @@ class ValidationRuleCreator { * 最大日期 */ public maxDate(controlNode: any): MaxDateValidationRule | undefined { - const maxDate = controlNode.editor.maxValue; + const { maxDate } = controlNode.editor; if (!this.isValidValue(maxDate)) { return; } @@ -130,7 +130,7 @@ class ValidationRuleCreator { * 最小日期 */ public minDate(controlNode: any): MinDateValidationRule | undefined { - const minDate = controlNode.editor.minValue; + const { minDate } = controlNode.editor; if (!this.isValidValue(minDate)) { return; } -- Gitee From 8aa86194d34b6f04232caa3a8ec7a5d1eec052d7 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Thu, 27 Mar 2025 21:52:29 +0800 Subject: [PATCH 137/153] =?UTF-8?q?fix:=20=E5=AE=8C=E5=96=84=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../store/form/form-array-store-initializer.ts | 2 -- .../lib/store/form/form-store-initializer.ts | 3 --- .../validators/max-date-validator.ts | 2 +- .../validators/max-length-validator.ts | 18 ++++++++++++++---- .../validators/max-value-validator.ts | 18 ++++++++++++------ .../validators/min-date-validator.ts | 2 +- .../validators/min-length-validator.ts | 18 ++++++++++++++---- .../validators/min-value-validator.ts | 18 ++++++++++++------ .../validation/validators/pattern-validator.ts | 2 +- .../validators/required-validator.ts | 2 +- .../src/composition/use-module-config.ts | 3 +-- .../form/validation-rule-creator.ts | 18 +++++++++++++++--- .../config-builders/module-config-builder.ts | 3 +++ 13 files changed, 75 insertions(+), 34 deletions(-) diff --git a/packages/devkit/lib/store/form/form-array-store-initializer.ts b/packages/devkit/lib/store/form/form-array-store-initializer.ts index b1e67d0633c..3a5e692fb07 100644 --- a/packages/devkit/lib/store/form/form-array-store-initializer.ts +++ b/packages/devkit/lib/store/form/form-array-store-initializer.ts @@ -88,8 +88,6 @@ class FormArrayStoreInitializer { } entityStore.watchChange((change: any) => { - console.log(`----------${this.formArrayStore.getId()} : watch entityChange-----`) - console.log(change); this.updateFormArrayStore(); }); } diff --git a/packages/devkit/lib/store/form/form-store-initializer.ts b/packages/devkit/lib/store/form/form-store-initializer.ts index 91305ae8cfd..1461de3ceae 100644 --- a/packages/devkit/lib/store/form/form-store-initializer.ts +++ b/packages/devkit/lib/store/form/form-store-initializer.ts @@ -98,9 +98,6 @@ class FormStoreInitializer { } entityStore.watchChange((change: any) => { - console.log(`----------${this.formStore.getId()} : watch entityChange-----`) - console.log(change); - controlConfigs.forEach((controlConfig) => { this.updateFormStore(); }); diff --git a/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts b/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts index 11aae0a63bf..7bf733e9ecf 100644 --- a/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts @@ -16,7 +16,7 @@ class MaxDateValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: MaxDateValidationRule): ValidationError | null { - if (!this.checkRule(value)) { + if (!this.checkRule(rule)) { return null; } diff --git a/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts b/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts index edafb01ae9a..920962e4685 100644 --- a/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts @@ -15,13 +15,23 @@ class MaxLengthValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: MaxLengthValidationRule): ValidationError | null { - if (!this.checkRule(value)) { + if (!this.checkRule(rule)) { return null; } - // 非法值不校验 - if (value === null || value === undefined || typeof value.length !== 'number') { - return null; + // 空值和NaN,视为空字符串 + if (value === null || value === undefined) { + value = ''; + } + + // 非字符串类型且具有toString方法的值,先转换成字符串再比较 + if (typeof value !== 'string' && typeof value.toString === 'function') { + value = value.toString(); + } + + // 转换后仍不是字符串的情况,无法进行比较,不触发校验 + if (typeof value !== 'string') { + return null } const maxLength = rule.maxLength; diff --git a/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts b/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts index 3c23939e15d..5f7987b859e 100644 --- a/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts @@ -16,20 +16,26 @@ class MaxValueValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: MaxValueValidationRule): ValidationError | null { - if (!this.checkRule(value)) { + if (!this.checkRule(rule)) { return null; } - if (StringUtil.isString(value) === true) { + // 空值无法进行比较,不触发校验 + if (value === null || value === undefined) { + return null; + } + + // 如果是字符串先转换成数字,再比较 + if (typeof value === 'string') { value = parseFloat(value as string); } - // 值为空时不校验 - if (NumberUtil.isEmptyNumber(value)) { - return null + // 转换后仍不是数字,无法比较,不触发校验 + if (typeof value !== 'number') { + return null; } - // 值为NaN时不校验 + // 转换后值为NaN时,无法比较,不触发校验 // https://www.w3.org/TR/html5/forms.html#attr-input-max if (isNaN(value) === true) { return null; diff --git a/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts b/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts index 2c804f993f9..a3c6e9d6427 100644 --- a/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts @@ -16,7 +16,7 @@ class MinDateValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: MinDateValidationRule): ValidationError | null { - if (!this.checkRule(value)) { + if (!this.checkRule(rule)) { return null; } let { name, minDate, message } = rule; diff --git a/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts b/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts index 7bc7a910832..e91005de71b 100644 --- a/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts @@ -15,13 +15,23 @@ class MinLengthValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: MinLengthValidationRule): ValidationError | null { - if (!this.checkRule(value)) { + if (!this.checkRule(rule)) { return null; } - // 非法值,不校验 - if (value === null || value === undefined || typeof value.length !== 'number') { - return null; + // 空值和NaN,视为空字符串 + if (value === null || value === undefined || (typeof value === 'number' && isNaN(value))) { + value = ''; + } + + // 非字符串类型且具有toString方法的值,先转换成字符串再比较 + if (typeof value !== 'string' && typeof value.toString === 'function') { + value = value.toString(); + } + + // 转换后仍不是字符串的情况,无法进行比较,不触发校验 + if (typeof value !== 'string') { + return null } const actualLength = value.length; diff --git a/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts b/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts index f02d1116f36..cd2bb727209 100644 --- a/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts @@ -16,20 +16,26 @@ class MinValueValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: MinValueValidationRule): ValidationError | null { - if (!this.checkRule(value)) { + if (!this.checkRule(rule)) { return null; } - if (StringUtil.isString(value) === true) { + // 空值无法进行比较,不触发校验 + if (value === null || value === undefined) { + return null; + } + + // 如果是字符串先转换成数字,再比较 + if (typeof value === 'string') { value = parseFloat(value as string); } - // 值为空时不校验 - if (NumberUtil.isEmptyNumber(value)) { - return null + // 转换后仍不是数字,无法比较,不触发校验 + if (typeof value !== 'number') { + return null; } - // 值为NaN时不校验 + // 转换后值为NaN时,无法比较,不触发校验 // https://www.w3.org/TR/html5/forms.html#attr-input-max if (isNaN(value) === true) { return null; diff --git a/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts b/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts index 1c383b105de..c8fd3580087 100644 --- a/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts @@ -16,7 +16,7 @@ class PatternValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: PatternValidationRule): ValidationError | null { - if (!this.checkRule(value)) { + if (!this.checkRule(rule)) { return null; } diff --git a/packages/devkit/lib/store/form/validation/validators/required-validator.ts b/packages/devkit/lib/store/form/validation/validators/required-validator.ts index 9f6df55f036..222119da5d3 100644 --- a/packages/devkit/lib/store/form/validation/validators/required-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/required-validator.ts @@ -15,7 +15,7 @@ class RequiredValidator extends BaseValidator { * 验证方法 */ public validate(value: any, rule: RequiredValidationRule): ValidationError | null { - if (!this.checkRule(value)) { + if (!this.checkRule(rule)) { return null; } diff --git a/packages/renderer/src/composition/use-module-config.ts b/packages/renderer/src/composition/use-module-config.ts index e087e68a2c6..6ded0a31424 100644 --- a/packages/renderer/src/composition/use-module-config.ts +++ b/packages/renderer/src/composition/use-module-config.ts @@ -49,8 +49,7 @@ export function useModuleConfig(metadata: Ref, uiProviders: StaticProvider[], re ...eventHanderProviders, ...resolverProviders, ...callbackHandlerProviders, - ...htmlTemplateTransformers, - ...BifDevkitProviders, + ...htmlTemplateTransformers ] }; const moduleConfigBuilder = new ModuleConfigBuilder(moduleMetaContext); diff --git a/packages/renderer/src/config-builders/form/validation-rule-creator.ts b/packages/renderer/src/config-builders/form/validation-rule-creator.ts index 25d1f04b8d2..bc3734f80e8 100644 --- a/packages/renderer/src/config-builders/form/validation-rule-creator.ts +++ b/packages/renderer/src/config-builders/form/validation-rule-creator.ts @@ -46,7 +46,7 @@ class ValidationRuleCreator { } const displayName = this.getDisplayName(controlNode); - const message = `请输入正确的'${displayName}'`; + const message = `请输入'${displayName}'`; return { name: 'required', message }; } @@ -55,7 +55,13 @@ class ValidationRuleCreator { * 最大长度 */ public maxLength(controlNode: any): MaxLengthValidationRule | undefined { - const { maxLength } = controlNode.editor; + const { type, maxLength } = controlNode.editor; + + // 数值控件上的maxLength不视为校验规则 + if (type === 'number-spinner') { + return; + } + if (!this.isValidValue(maxLength)) { return; } @@ -70,7 +76,13 @@ class ValidationRuleCreator { * 最小长度 */ public minLength(controlNode: any): MinLengthValidationRule | undefined { - const { minLength } = controlNode.editor; + const { type, minLength } = controlNode.editor; + + // 数值控件上的minLength不视为校验规则 + if (type === 'number-spinner') { + return; + } + if (!this.isValidValue(minLength)) { return; } diff --git a/packages/renderer/src/config-builders/module-config-builder.ts b/packages/renderer/src/config-builders/module-config-builder.ts index e9c41e8a287..70d7cdc0223 100644 --- a/packages/renderer/src/config-builders/module-config-builder.ts +++ b/packages/renderer/src/config-builders/module-config-builder.ts @@ -89,6 +89,9 @@ class ModuleConfigBuilder { this.buildExpressionConfigs(this.formMeta); this.moduleConfig.id = this.formMeta.module.code; this.moduleConfig.providers = this.context.moduleProviders; + + console.log('--------------------moduleConfig--------------------'); + console.log(this.moduleConfig); return this.moduleConfig; } -- Gitee From 478ad98b776f361f8f7d1646f1b4b6cf0720ad06 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Thu, 27 Mar 2025 21:58:32 +0800 Subject: [PATCH 138/153] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4console.log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/renderer/src/config-builders/module-config-builder.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/renderer/src/config-builders/module-config-builder.ts b/packages/renderer/src/config-builders/module-config-builder.ts index 70d7cdc0223..1d5ff2b2a8d 100644 --- a/packages/renderer/src/config-builders/module-config-builder.ts +++ b/packages/renderer/src/config-builders/module-config-builder.ts @@ -90,8 +90,6 @@ class ModuleConfigBuilder { this.moduleConfig.id = this.formMeta.module.code; this.moduleConfig.providers = this.context.moduleProviders; - console.log('--------------------moduleConfig--------------------'); - console.log(this.moduleConfig); return this.moduleConfig; } -- Gitee From f0ecf88b128d3d78deb88e1a8c4b69a036e915a7 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Fri, 28 Mar 2025 17:05:54 +0800 Subject: [PATCH 139/153] =?UTF-8?q?fix:=20=E8=B0=83=E6=95=B4=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E8=A1=A8=E5=8D=95=E6=98=BE=E7=A4=BA=E5=90=8D=E7=9A=84?= =?UTF-8?q?=E8=A7=84=E5=88=99=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/config-builders/form/form-array-store-config-builder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts b/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts index 796f1967040..09f827480f0 100644 --- a/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts +++ b/packages/renderer/src/config-builders/form/form-array-store-config-builder.ts @@ -27,7 +27,7 @@ class FormArrayStoreConfigBuilder { const stateConfig = this.buildStateConfig(viewModelNode); const storeConfig: FormArrayStoreConfig = { id: viewModelNode.code + '-form-array-store', - displayName: vmComponentNode.name, + displayName: viewModelNode.name, bindingPath: viewModelNode.bindTo, state: stateConfig }; -- Gitee From f7bb04a62218adc177023ce01981dde2b2dafffd Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Mon, 31 Mar 2025 19:39:41 +0800 Subject: [PATCH 140/153] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8lookup?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=94=AF=E6=8C=81=E5=AF=BC=E8=88=AA=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .ls-lint.yml | 6 +- .../components/cell/src/cell.component.tsx | 1 + .../components/cell/src/cell.props.ts | 4 +- .../components/cell/src/cell.scss | 2 +- .../common/src/style/mixins/hairline.scss | 120 +- .../components/content-list-nav.component.tsx | 42 +- .../content-list-tree.component.tsx | 76 +- .../src/components/header.component.tsx | 6 +- .../lookup/src/composition/types.ts | 48 +- .../src/composition/use-data-service.ts | 21 +- .../src/composition/use-load-list-data.ts | 56 +- .../src/composition/use-load-nav-list-data.ts | 73 +- .../src/composition/use-load-tree-data.ts | 60 +- .../src/composition/use-lookup-panel-state.ts | 11 +- .../src/composition/use-render-component.tsx | 98 +- .../src/composition/use-request-params.ts | 122 + .../lookup/src/composition/use-request.ts | 53 +- .../src/composition/use-search-service.ts | 27 +- .../src/composition/use-selcted-service.ts | 24 +- .../src/composition/use-tree-data-service.ts | 64 +- .../lookup/src/lookup-panel.component.tsx | 4 +- .../lookup/src/lookup-panel.props.ts | 4 + .../components/lookup/src/lookup-panel.scss | 15 + packages/mobile-ui-vue/demos/lookup/index.vue | 4 + .../mobile-ui-vue/demos/lookup/nav-list.vue | 18 + packages/mobile-ui-vue/demos/lookup/tree.vue | 4 +- .../assets/datas/lookup/lookup-nav-list.json | 43860 ++++++++++++++++ .../assets/datas/lookup/lookup-treedata.json | 2 +- 28 files changed, 44503 insertions(+), 322 deletions(-) create mode 100644 packages/mobile-ui-vue/components/lookup/src/composition/use-request-params.ts create mode 100644 packages/mobile-ui-vue/demos/lookup/nav-list.vue create mode 100644 packages/mobile-ui-vue/public/assets/datas/lookup/lookup-nav-list.json diff --git a/.ls-lint.yml b/.ls-lint.yml index c7441214e0e..42127f57572 100644 --- a/.ls-lint.yml +++ b/.ls-lint.yml @@ -3,9 +3,9 @@ ls: # .dir: kebab-case | regex:__[A-Za-z0-9]+__ .scss: kebab-case .vue: kebab-case - .js: kebab-case | pointcase - .ts: kebab-case | pointcase - .tsx: kebab-case | pointcase + .js: kebab-case + .ts: kebab-case + .tsx: kebab-case .component.tsx: kebab-case .design.component.tsx: kebab-case .item.component.tsx: kebab-case diff --git a/packages/mobile-ui-vue/components/cell/src/cell.component.tsx b/packages/mobile-ui-vue/components/cell/src/cell.component.tsx index 91d99b8d71e..143adb4f813 100644 --- a/packages/mobile-ui-vue/components/cell/src/cell.component.tsx +++ b/packages/mobile-ui-vue/components/cell/src/cell.component.tsx @@ -152,6 +152,7 @@ export default defineComponent({ const cellClass = computed(() => { return { [bem()]: true, + [bem('', 'bottom-border')]: props.showHairline, [bem('', 'noborder')]: !props.border, [bem('', 'required')]: props.required, [bem('', 'center')]: props.center, diff --git a/packages/mobile-ui-vue/components/cell/src/cell.props.ts b/packages/mobile-ui-vue/components/cell/src/cell.props.ts index bbb7e9caa9d..81b0909c50e 100644 --- a/packages/mobile-ui-vue/components/cell/src/cell.props.ts +++ b/packages/mobile-ui-vue/components/cell/src/cell.props.ts @@ -36,7 +36,9 @@ export const cellProps = { rightIcon: { type: String, default: '' }, - extra: { type: [String, Number], default: '' } + extra: { type: [String, Number], default: '' }, + + showHairline: { type: Boolean, default: false }, }; export type CellProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/cell/src/cell.scss b/packages/mobile-ui-vue/components/cell/src/cell.scss index 9ef3e12824d..59b2da1419b 100644 --- a/packages/mobile-ui-vue/components/cell/src/cell.scss +++ b/packages/mobile-ui-vue/components/cell/src/cell.scss @@ -23,7 +23,7 @@ position: relative; display: flex; overflow: hidden; - &-bottom-border, + &--bottom-border, &:not(:last-child) { @include hairline('bottom'); &::after { diff --git a/packages/mobile-ui-vue/components/common/src/style/mixins/hairline.scss b/packages/mobile-ui-vue/components/common/src/style/mixins/hairline.scss index fada3b45587..24cdf7798a3 100644 --- a/packages/mobile-ui-vue/components/common/src/style/mixins/hairline.scss +++ b/packages/mobile-ui-vue/components/common/src/style/mixins/hairline.scss @@ -14,101 +14,71 @@ $direction, $color: #ddd, $radius: 0, - $type: solid + $type: solid, ) { @if ($direction == 'top') { border-top: 1px $type $color; position: relative; - html:not([data-scale]) & { - @media (min-resolution: 1dppx) { - border-top: none; - &::before { - @include scale-hairline-common($color, 0, auto, auto, 0); - width: 100%; - height: 1px; - transform-origin: 50% 50%; - transform: scaleY(0.5); - - } - } + border-top: none; + &::before { + @include scale-hairline-common($color, 0, auto, auto, 0); + width: 100%; + height: 1px; + transform-origin: 50% 50%; + transform: scaleY(0.5); } } @else if ($direction == 'bottom') { border-bottom: 1px $type $color; position: relative; - html:not([data-scale]) & { - @media (min-resolution: 1dppx) { - border-bottom: none; - &::after { - @include scale-hairline-common($color, auto, auto, 0, 0); - width: 100%; - height: 1px; - transform-origin: 50% 100%; - transform: scaleY(0.5); - - } - } + border-bottom: none; + &::after { + @include scale-hairline-common($color, auto, auto, 0, 0); + width: 100%; + height: 1px; + transform-origin: 50% 100%; + transform: scaleY(0.5); } } @else if ($direction == 'left') { border-left: 1px $type $color; position: relative; - html:not([data-scale]) & { - @media (min-resolution: 1dppx) { - border-left: none; - &::before { - @include scale-hairline-common($color, 0, auto, auto, 0); - width: 1px; - height: 100%; - transform-origin: 100% 50%; - transform: scaleX(0.5); - - } - } + border-left: none; + &::before { + @include scale-hairline-common($color, 0, auto, auto, 0); + width: 1px; + height: 100%; + transform-origin: 100% 50%; + transform: scaleX(0.5); } } @else if ($direction == 'right') { border-right: 1px $type $color; position: relative; - html:not([data-scale]) & { - @media (min-resolution: 1dppx) { - border-right: none; - &::after { - @include scale-hairline-common($color, 0, 0, auto, auto); - width: 1px; - height: 100%; - background: $color; - transform-origin: 100% 50%; - transform: scaleX(0.5); - } - } + border-right: none; + &::after { + @include scale-hairline-common($color, 0, 0, auto, auto); + width: 1px; + height: 100%; + background: $color; + transform-origin: 100% 50%; + transform: scaleX(0.5); } } @else if ($direction == 'all') { border: 1px $type $color; border-radius: $radius; - html:not([data-scale]) & { - @media (min-resolution: 2dppx) { - position: relative; - border: none; - &::before { - content: ''; - position: absolute; - left: 0; - top: 0; - width: 200%; - height: 200%; - border: 1px $type $color; - border-radius: $radius * 2; - transform-origin: 0 0; - transform: scale(0.5); - box-sizing: border-box; - pointer-events: none; - - // @media (min-resolution: 3dppx) { - // width: 300%; - // height: 300%; - // border-radius: @radius * 3; - // transform: scale(0.33); - // } - } - } + position: relative; + border: none; + &::before { + content: ''; + position: absolute; + left: 0; + top: 0; + width: 200%; + height: 200%; + border: 1px $type $color; + border-radius: $radius * 2; + transform-origin: 0 0; + transform: scale(0.5); + box-sizing: border-box; + pointer-events: none; } } } diff --git a/packages/mobile-ui-vue/components/lookup/src/components/content-list-nav.component.tsx b/packages/mobile-ui-vue/components/lookup/src/components/content-list-nav.component.tsx index c16e439547e..c56c9007392 100644 --- a/packages/mobile-ui-vue/components/lookup/src/components/content-list-nav.component.tsx +++ b/packages/mobile-ui-vue/components/lookup/src/components/content-list-nav.component.tsx @@ -1,11 +1,49 @@ import { defineComponent } from 'vue'; +import { useBem } from '@/components/common'; +import List from '@/components/list'; +import { ListDataItem, useLookupPanelState, useRenderComponent } from '../composition'; +import { LOOKUP_PANEL_NAME } from '../lookup-panel.props'; export default defineComponent({ setup() { + const { bem } = useBem(LOOKUP_PANEL_NAME); + + const { dataService, treeDataServie } = useLookupPanelState(); + const { treeData, getLoadDataType, getTreeList, getParents } = treeDataServie; + const { listData, loadData } = dataService; + + const handleLoadChild = (item?: ListDataItem) => { + const loadDataType = getLoadDataType(); + if (loadDataType === 'async') { + const options = { parent: item }; + loadData(options); + } else { + treeData.treeList = getTreeList(item); + treeData.parents = getParents(item); + } + }; + + const { renderListItem, renderTreeItem, renderBreadcrumb } = useRenderComponent({ handleLoadChild }); + + const renderList = () => { + return ( + + {listData.dataList.map(item => renderListItem(item))} + {treeData.treeList.map(item => renderTreeItem(item))} + + ); + }; + return () => ( -
    - navlist +
    + {renderBreadcrumb()} + {renderList()}
    ); } diff --git a/packages/mobile-ui-vue/components/lookup/src/components/content-list-tree.component.tsx b/packages/mobile-ui-vue/components/lookup/src/components/content-list-tree.component.tsx index 28a49bf5b03..84b1583b0d7 100644 --- a/packages/mobile-ui-vue/components/lookup/src/components/content-list-tree.component.tsx +++ b/packages/mobile-ui-vue/components/lookup/src/components/content-list-tree.component.tsx @@ -1,8 +1,6 @@ -import { computed, defineComponent } from 'vue'; -import { stopPropagation, useBem } from '@/components/common'; +import { defineComponent } from 'vue'; +import { useBem } from '@/components/common'; import List from '@/components/list'; -import Icon from '@/components/icon'; -import Cell from '@/components/cell'; import { ListDataItem, useLookupPanelState, useRenderComponent } from '../composition'; import { LOOKUP_PANEL_NAME } from '../lookup-panel.props'; @@ -11,10 +9,9 @@ export default defineComponent({ const { bem } = useBem(LOOKUP_PANEL_NAME); - const { renderListChecker } = useRenderComponent(); - const { dataService, treeDataServie, getTextValue, handleChange } = useLookupPanelState(); - const { treeData, getLoadDataType, getIsDetail, getTreeList, getParents, getKey } = treeDataServie; - const { listData, loadData } = dataService; + const { dataService, treeDataServie } = useLookupPanelState(); + const { treeData, getLoadDataType, getTreeList, getParents } = treeDataServie; + const { loadData } = dataService; const handleLoadChild = (item?: ListDataItem) => { const loadDataType = getLoadDataType(); @@ -22,77 +19,24 @@ export default defineComponent({ const options = { parent: item }; loadData(options); } else { - listData.dataList = getTreeList(item); + treeData.treeList = getTreeList(item); treeData.parents = getParents(item); } }; - const renderArrowIcon = (item: ListDataItem) => { - const isDetail = getIsDetail(item) || false; - return () => !isDetail && ; - }; - - const getTreeItemSlots = (item: ListDataItem) => { - return { - rightIcon: renderArrowIcon(item) - }; - }; - - const renderTreeItem = (item: ListDataItem) => { - return ( -
    - {renderListChecker(item)} - handleChange(item)} - onRightIconClick={(event: Event) => { stopPropagation(event); handleLoadChild(item);}} - > -
    - ); - }; + const { renderTreeItem, renderBreadcrumb } = useRenderComponent({ handleLoadChild }); const renderList = () => { return ( - - {listData.dataList.map(item => renderTreeItem(item))} + + {treeData.treeList.map(item => renderTreeItem(item))} ); }; - const breadcrumbs = computed(()=>{ - const items: {text: string, showIcon: boolean, item?: ListDataItem }[] = treeData.parents.map((item, index)=> { - return { - item, - text: getTextValue(item.data), - showIcon: index !== treeData.parents.length - 1 - }; - }); - items.unshift({ text: '全部', showIcon: true }); - return items; - }); - - const renderBreadcrumb = () => { - return
    - { - breadcrumbs.value.map(breadcrumb => ( -
    handleLoadChild(breadcrumb.item)}> - { breadcrumb.text } - { breadcrumb.showIcon && } -
    - )) - } -
    ; - }; - return () => (
    - {renderBreadcrumb() } + {renderBreadcrumb()} {renderList()}
    ); diff --git a/packages/mobile-ui-vue/components/lookup/src/components/header.component.tsx b/packages/mobile-ui-vue/components/lookup/src/components/header.component.tsx index 3c7f5c90529..e3deac7be7b 100644 --- a/packages/mobile-ui-vue/components/lookup/src/components/header.component.tsx +++ b/packages/mobile-ui-vue/components/lookup/src/components/header.component.tsx @@ -11,10 +11,10 @@ export default defineComponent({ const { bem } = useBem(LOOKUP_PANEL_NAME); - const { panelProps, dataService, searchService, seletedService, getTextValue, handleClose } = useLookupPanelState(); + const { panelProps, dataService, searchService, seletedService, getTextValue, handleChange, handleClose } = useLookupPanelState(); const { listData } = dataService; const { searchListData, resetListData, searchData } = searchService; - const { selectedListData, selectedLength, toggleSelecte } = seletedService; + const { selectedListData, selectedLength } = seletedService; const selectedCollapsed = computed(() => { return selectedLength.value >= panelProps.selectedCollapseLimit; @@ -35,7 +35,7 @@ export default defineComponent({ 等{selectedLength.value}个
    : selectedListData.dataList.map(item => ( -
    toggleSelecte(item)}> +
    handleChange(item, false)}> {getTextValue(item)}
    )) diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/types.ts b/packages/mobile-ui-vue/components/lookup/src/composition/types.ts index 365a85424b2..2f4e7ba17ba 100644 --- a/packages/mobile-ui-vue/components/lookup/src/composition/types.ts +++ b/packages/mobile-ui-vue/components/lookup/src/composition/types.ts @@ -53,25 +53,34 @@ export interface SearchParams { parentID?: string; } +export type SelectedInfo = { + selected: boolean, + selectedIds: string[] +}; + +export type RelationFilter = Array<{ fieldName: string; fieldValue: string }> + export interface BuildParamsOptions { searchParams?: SearchParams, context?: BeforeLoadDataContext, pageIndex?: number, - selectedInfo?: string[], + selectedInfo?: SelectedInfo, enableFullTree?: boolean, + relationFilter?: RelationFilter, loadTreeDataType?: 'all' | 'async' | 'default' } export interface LookupRequestParams { - pageIndex: number; - pageSize: number; + pageIndex?: number; + pageSize?: number; searchValue?: string; - selectedInfo?: string[]; + selectedInfo?: SelectedInfo; /** 自定义查询数据 */ customData?: any; loadTreeDataType?: LoadTreeDataType; /** 构造完整树 */ enableFullTree?: boolean; + useFullTree?: boolean; /** 导航帮助对应关系条件 */ relationFilter?: Array<{ fieldName: string; fieldValue: any }>; /** 左树右列表帮助,左树为分层分级码加载时,点击节点的分级码 */ @@ -109,6 +118,11 @@ export interface SearchField { label: string; } +export interface LookupRelation { + groupField: string, + helpField: string +} + export interface ListLookupHttpResult { displayType?: string; items: Record[]; @@ -121,10 +135,11 @@ export interface ListLookupHttpResult { export interface TreeLookupHttpResult extends ListLookupHttpResult { treeInfo: TreeInfo; + relations?: LookupRelation[] } export interface NavListLookupHttpResult extends TreeLookupHttpResult { - navigation?: ListLookupHttpResult; + navigation: TreeLookupHttpResult; } export interface LookupHttpService { @@ -147,13 +162,15 @@ export type LookupListData = { } export type LookupTreeData = { + treeList: ListDataItem[], parents: ListDataItem[], - treeInfo: TreeInfo + treeInfo: TreeInfo, + relations?: LookupRelation[] } export type LoadDataOptions = { context?: BeforeLoadDataContext, - parent?: ListDataItem + parent?: ListDataItem | TreeDataItem }; @@ -161,7 +178,7 @@ export interface DataService { listData: LookupListData, loadData: (options?: LoadDataOptions) => void, resetListData: () => void, - initLoadData: () => void + initLoad: () => void }; export type SearchListData = LookupListData & { @@ -183,17 +200,20 @@ export type SelectedListData = { export interface SeletedService { selectedListData: SelectedListData, selectedLength: ComputedRef, - toggleSelecte: (item: ListDataItem) => void, + initSelected: (items: ListDataItem[]) => void, + toggleSelecte: (item: ListDataItem, alwaysSelect?: boolean) => void, toggleSelecteAll: (items: ListDataItem[]) => void, isSelected: (item: ListDataItem) => boolean, isSelectedAll: (items: ListDataItem[]) => boolean, clearSelected: () => void, getIdValue: () => string, getTextValue: () => string + getSelectedInfo: () => SelectedInfo }; export interface TreeDataServie { treeData: LookupTreeData, + resetData: () => void, updateTreeData: (result: TreeLookupHttpResult) => void, getTreeList: (item?: ListDataItem) => ListDataItem[], getParents: (item?: ListDataItem) => ListDataItem[], @@ -201,7 +221,9 @@ export interface TreeDataServie { getLoadDataType: ()=> 'all' | 'async', getLayerType: ()=> 'pathcode' | 'parentId', getParentKey: (item: ListDataItem)=> string; - getKey: (item: ListDataItem)=> string; + getItemKey: (item: ListDataItem)=> string; + getLayer: (item: ListDataItem)=> number; + getRelations: (item: ListDataItem)=> RelationFilter | undefined; } export type LookupPanelState = { @@ -212,3 +234,9 @@ export type LookupPanelState = { searchService: SearchService, treeDataServie: TreeDataServie }; + +export type UseRenderComponent = (events?: { handleLoadChild: (item?: ListDataItem) => void; })=> { + renderListItem: (item: ListDataItem) => any; + renderTreeItem: (item: ListDataItem) => any; + renderBreadcrumb: () => any; +}; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-data-service.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-data-service.ts index 6e05d0f8495..98e35d9b307 100644 --- a/packages/mobile-ui-vue/components/lookup/src/composition/use-data-service.ts +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-data-service.ts @@ -1,12 +1,14 @@ import { reactive } from "vue"; import { isFunction } from "@/components/common"; import { LookupPanelProps } from "../lookup-panel.props"; -import { BeforeLoadDataContext, LookupDisplayType, LookupListData, TreeDataServie } from "./types"; +import { BeforeLoadDataContext, LookupDisplayType, LookupListData, SeletedService, TreeDataServie } from "./types"; import { useLoadListData } from "./use-load-list-data"; import { useLoadNavListData } from "./use-load-nav-list-data"; import { useLoadTreeData } from "./use-load-tree-data"; -export const useDataService = (props: LookupPanelProps, treeDataServie: TreeDataServie) => { +export const useDataService = (props: LookupPanelProps, services: {treeDataServie: TreeDataServie, seletedService: SeletedService}) => { + const { treeDataServie, seletedService } = services; + const listData = reactive({ dataList: [], totalPage: 0, @@ -24,23 +26,24 @@ export const useDataService = (props: LookupPanelProps, treeDataServie: TreeData listData.pageIndex = 1; listData.finished = false; listData.enableShow = true; + treeDataServie.resetData(); }; const getLoadDataInstance = () => { switch (props.displayType) { case LookupDisplayType.List:{ - return useLoadListData(props, listData); + return useLoadListData(props, listData, seletedService); } case LookupDisplayType.Tree: { - return useLoadTreeData(props, listData, treeDataServie); + return useLoadTreeData(props, listData, services); } case LookupDisplayType.NAVLIST:{ - return useLoadNavListData(props, listData); + return useLoadNavListData(props, listData, services); } } }; - const { loadData } = getLoadDataInstance(); + const { loadData, initLoadData } = getLoadDataInstance(); const beforeLoadData = () => { const asyncTarget = isFunction(props.beforeLoadData) && props.beforeLoadData(); @@ -51,16 +54,16 @@ export const useDataService = (props: LookupPanelProps, treeDataServie: TreeData } }; - const initLoadData = () => { + const initLoad = () => { beforeLoadData().then((context?: BeforeLoadDataContext) => { - loadData({context}); + initLoadData(context); }); }; return { listData, loadData, - initLoadData, + initLoad, resetListData }; }; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-load-list-data.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-load-list-data.ts index 40921d5c316..9cb5b1aaedb 100644 --- a/packages/mobile-ui-vue/components/lookup/src/composition/use-load-list-data.ts +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-load-list-data.ts @@ -1,44 +1,52 @@ import { LookupPanelProps } from "../lookup-panel.props"; -import { LoadDataType, LookupListData, ListLookupHttpResult, LoadDataOptions } from "./types"; +import { LoadDataType, LookupListData, ListLookupHttpResult, LoadDataOptions, SeletedService, BeforeLoadDataContext } from "./types"; import { useRequest } from "./use-request"; +import { useRequestParams } from "./use-request-params"; -export const useLoadListData = (props: LookupPanelProps, listData: LookupListData) => { - const { getData, buildParams } = useRequest(props); +export const useLoadListData = (props: LookupPanelProps, listData: LookupListData, seletedService: SeletedService) => { + const { getData } = useRequest(props); + const { buildParams } = useRequestParams(props); - const updateData = (data: ListLookupHttpResult) => { - listData.dataList = listData.dataList.concat(data.items); - const pageSize = data.pageInfo?.pageSize ?? props.pageSize; - if (data.total && pageSize) { - listData.totalPage = Math.ceil(data.total / pageSize); + const { initSelected, getSelectedInfo } = seletedService; + + const updateData = (result: ListLookupHttpResult) => { + listData.loading = false; + listData.dataList = listData.dataList.concat(result.items); + const pageSize = result.pageInfo?.pageSize ?? props.pageSize; + if (result.total && pageSize) { + listData.totalPage = Math.ceil(result.total / pageSize); } }; const loadData = (options: LoadDataOptions = {}) => { - const { context } = options; - if (listData.totalPage && (listData.pageIndex > listData.totalPage)) { listData.finished = true; return; } - if (props.uri) { - const extraParams = { context, pageIndex: listData.pageIndex }; - const params = buildParams(LoadDataType.all, extraParams); - - getData(params).then(result => { - updateData(result); - listData.loading = false; - }); + const extraParams = { pageIndex: listData.pageIndex }; + const params = buildParams(LoadDataType.all, extraParams); - } else { - listData.dataList = props.data; - listData.loading = false; - listData.finished = true; - }; + getData(params).then(result => { + updateData(result); + }); }; + const initLoadData = (context?: BeforeLoadDataContext)=>{ + const selectedInfo = getSelectedInfo(); + const extraParams = { context, selectedInfo }; + const params = buildParams(LoadDataType.all, extraParams); + + getData(params).then(result => { + updateData(result); + if(result.selectedData) { + initSelected(result.selectedData); + } + }); + }; return { - loadData + loadData, + initLoadData }; }; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-load-nav-list-data.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-load-nav-list-data.ts index c7856e67b70..24f8a67dacd 100644 --- a/packages/mobile-ui-vue/components/lookup/src/composition/use-load-nav-list-data.ts +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-load-nav-list-data.ts @@ -1,17 +1,74 @@ -import { reactive } from "vue"; import { LookupPanelProps } from "../lookup-panel.props"; -import { LoadDataType, LookupListData } from "./types"; import { useRequest } from "./use-request"; +import { LoadDataOptions, LoadDataType, LookupListData, TreeDataServie, SearchParams, BuildParamsOptions, NavListLookupHttpResult, ListDataItem, SeletedService, BeforeLoadDataContext } from "./types"; +import { useRequestParams } from "./use-request-params"; -export const useLoadNavListData = (props: LookupPanelProps, listData: LookupListData) => { - const { getData, buildParams } = useRequest(props); +export const useLoadNavListData = (props: LookupPanelProps, listData: LookupListData, services: {treeDataServie: TreeDataServie, seletedService: SeletedService}) => { + const { treeDataServie, seletedService } = services; + const { getData } = useRequest(props); + const { buildParams } = useRequestParams(props); + const { initSelected, getSelectedInfo } = seletedService; + + const { treeData, getTreeList, getLayerType, getLayer, getItemKey, updateTreeData, getRelations } = treeDataServie; + + const getParams = (options: LoadDataOptions = {})=>{ + const { context, parent } = options; + + const parentKey = parent ? getItemKey(parent) : ''; + const layer = parent ? getLayer(parent) : 1; + + const layerType = getLayerType(); + + const searchParams: SearchParams = { parentLayer: layer }; + + if(layerType === 'parentId') { + searchParams.parentID = parentKey; + } else { + searchParams.parentPath = parentKey; + } + + const extraParams: BuildParamsOptions = { + context, + searchParams + }; + + if(treeData.relations && parent){ + extraParams.relationFilter = getRelations(parent); + } + + return buildParams(LoadDataType.all, extraParams); + }; + + const updateData = (result: NavListLookupHttpResult, parent?: ListDataItem) => { + listData.dataList = result.items; + updateTreeData(result.navigation); + treeData.treeList = getTreeList(parent); + }; - const loadData = (context?: Record) => { - const params = buildParams(LoadDataType.all, context?.data); - return getData(params); + const loadData = (options: LoadDataOptions = {}) => { + const { parent } = options; + + const params = getParams(options); + + getData(params).then(result => { + updateData(result, parent); + }); + }; + const initLoadData = (context?: BeforeLoadDataContext)=>{ + const selectedInfo = getSelectedInfo(); + const extraParams = { context, selectedInfo }; + const params = buildParams(LoadDataType.all, extraParams); + + getData(params).then(result => { + updateData(result); + if(result.selectedData) { + initSelected(result.selectedData); + } + }); }; return { - loadData + loadData, + initLoadData }; }; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-load-tree-data.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-load-tree-data.ts index abe4f7c6970..18d6c0385c4 100644 --- a/packages/mobile-ui-vue/components/lookup/src/composition/use-load-tree-data.ts +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-load-tree-data.ts @@ -1,46 +1,47 @@ import { LookupPanelProps } from "../lookup-panel.props"; import { useRequest } from "./use-request"; -import { LoadDataOptions, LoadDataType, TreeLookupHttpResult, LookupListData, TreeDataServie, BeforeLoadDataContext, SearchParams, BuildParamsOptions, ListDataItem } from "./types"; +import { LoadDataOptions, LoadDataType, TreeLookupHttpResult, LookupListData, TreeDataServie, SearchParams, BuildParamsOptions, ListDataItem, SeletedService, BeforeLoadDataContext } from "./types"; +import { useRequestParams } from "./use-request-params"; -export const useLoadTreeData = (props: LookupPanelProps, listData: LookupListData, treeDataServie: TreeDataServie) => { - const { getData, buildParams } = useRequest(props); +export const useLoadTreeData = (props: LookupPanelProps, listData: LookupListData, services: {treeDataServie: TreeDataServie, seletedService: SeletedService}) => { + const { treeDataServie, seletedService } = services; - const { getTreeList, getLayerType, getKey, updateTreeData } = treeDataServie; - + const { getData } = useRequest(props); + const { buildParams } = useRequestParams(props); - const updateData = (data: TreeLookupHttpResult, parent?: ListDataItem) => { - updateTreeData(data); - listData.dataList = getTreeList(parent); - }; + const { initSelected, getSelectedInfo } = seletedService; + + const { treeData, getTreeList, getLayerType, getLayer, getItemKey, updateTreeData } = treeDataServie; const getParams = (options: LoadDataOptions = {})=>{ - const { context, parent } = options; + const { parent } = options; - const key = parent ? getKey(parent) : ''; + const parentKey = parent ? getItemKey(parent) : ''; + const layer = parent ? getLayer(parent) : 1; const layerType = getLayerType(); - const searchParams: SearchParams = { }; + const searchParams: SearchParams = { parentLayer: layer }; if(layerType === 'parentId') { - searchParams.parentID = key; + searchParams.parentID = parentKey; } else { - searchParams.parentPath = key; - searchParams.parentLayer = 0; + searchParams.parentPath = parentKey; } const extraParams: BuildParamsOptions = { - context, - searchParams, - enableFullTree: true, - loadTreeDataType: 'default' + searchParams }; - + console.log('line of 35 🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀\n', 'searchParams:', searchParams); const type = parent ? LoadDataType.children : LoadDataType.all; return buildParams(type, extraParams); }; - + + const updateData = (result: TreeLookupHttpResult, parent?: ListDataItem) => { + updateTreeData(result); + treeData.treeList = getTreeList(parent); + }; const loadData = (options: LoadDataOptions = {}) => { const { parent } = options; @@ -48,12 +49,25 @@ export const useLoadTreeData = (props: LookupPanelProps, listData: LookupListDat const params = getParams(options); getData(params).then(result => { - console.log('line of 9 🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀\n', 'useLoadTreeData:', result); updateData(result, parent); }); }; + const initLoadData = (context?: BeforeLoadDataContext)=>{ + const selectedInfo = getSelectedInfo(); + const extraParams = { context, selectedInfo }; + const params = buildParams(LoadDataType.all, extraParams); + + getData(params).then(result => { + updateData(result); + if(result.selectedData) { + initSelected(result.selectedData); + } + }); + }; + return { - loadData + loadData, + initLoadData }; }; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-lookup-panel-state.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-lookup-panel-state.ts index 22017b801eb..3d7021fa1d3 100644 --- a/packages/mobile-ui-vue/components/lookup/src/composition/use-lookup-panel-state.ts +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-lookup-panel-state.ts @@ -1,5 +1,5 @@ import { computed, inject, provide } from "vue"; -import { ListDataItem, LookupPanelState } from "./types"; +import { ListDataItem, LookupDisplayType, LookupPanelState } from "./types"; export const useLookupPanelState = (key = 'LookupPanelState') => { @@ -27,7 +27,7 @@ export const useLookupPanelState = (key = 'LookupPanelState') => { } return []; }); - + const getTextValue = (item: ListDataItem) => { return item[panelProps.textField]; }; @@ -49,9 +49,10 @@ export const useLookupPanelState = (key = 'LookupPanelState') => { panelContext.emit('confirm', textValue); }; - const handleChange = (item: Record) => { - seletedService.toggleSelecte(item); - panelContext.emit('change', item); + const handleChange = (data: ListDataItem, alwaysSelect = true) => { + alwaysSelect = panelProps.multiSelect ? false : alwaysSelect; + seletedService.toggleSelecte(data, alwaysSelect); + panelContext.emit('change', data); if (!panelProps.multiSelect) { handleConfirm(); } diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-render-component.tsx b/packages/mobile-ui-vue/components/lookup/src/composition/use-render-component.tsx index 34473cba071..3b80136c0df 100644 --- a/packages/mobile-ui-vue/components/lookup/src/composition/use-render-component.tsx +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-render-component.tsx @@ -1,14 +1,33 @@ -import { stopPropagation, useBem } from "@/components/common"; -import Cell from "@/components/cell"; +import { computed } from "vue"; +import { getValue, stopPropagation, useBem } from "@/components/common"; import { Checker, CheckerShapeMap } from "@/components/checker"; -import { ListDataItem, TreeDataServie } from "./types"; +import Icon from "@/components/icon"; +import Cell from "@/components/cell"; +import { ListDataItem, LookupDisplayType, UseRenderComponent } from "./types"; import { useLookupPanelState } from "./use-lookup-panel-state"; import { LOOKUP_PANEL_NAME } from "../lookup-panel.props"; -export const useRenderComponent = () => { +export const useRenderComponent: UseRenderComponent = (events) => { const { bem } = useBem(LOOKUP_PANEL_NAME); - const { panelProps, seletedService, getTextValue, handleChange } = useLookupPanelState(); + const { handleLoadChild } = events || { handleLoadChild: () => { } }; + + const { panelProps, seletedService, treeDataServie, getTextValue, handleChange } = useLookupPanelState(); + + const renderAvatar = (item: ListDataItem) => { + const avatar = getValue(panelProps.avatarField, item); + let avatarText: string = getTextValue(item); + avatarText = avatarText ? avatarText.slice(-2) : ''; + + return panelProps.enableAvatar && ( +
    + {avatar ? + : + {avatarText} + } +
    + ); + }; const renderListChecker = (item: ListDataItem) => { return panelProps.multiSelect && ( @@ -25,13 +44,76 @@ export const useRenderComponent = () => { return (
    {renderListChecker(item)} - handleChange(item)}> + {renderAvatar(item)} + handleChange(item)}> +
    + ); + }; + + const { treeData, getIsDetail } = treeDataServie; + + const breadcrumbs = computed(() => { + const items: { text: string, showIcon: boolean, item?: ListDataItem }[] = treeData.parents.map(item => { + return { + item, + text: getTextValue(item.data), + showIcon: true + }; + }); + items.unshift({ text: '全部', showIcon: true }); + items[items.length - 1].showIcon = false; + return items; + }); + + const renderBreadcrumb = () => { + return ( +
    + { + breadcrumbs.value.map(breadcrumb => ( +
    handleLoadChild(breadcrumb.item)}> + {breadcrumb.text} + {breadcrumb.showIcon && } +
    + )) + } +
    + ); + }; + + const renderArrowIcon = (item: ListDataItem) => { + const isDetail = getIsDetail(item) || false; + const isNavList = panelProps.displayType === LookupDisplayType.NAVLIST; + return () => (!isDetail || isNavList) && ; + }; + + const getTreeItemSlots = (item: ListDataItem) => { + return { + rightIcon: renderArrowIcon(item) + }; + }; + + const handleTreeItemClick = (item: ListDataItem)=>{ + return panelProps.displayType === LookupDisplayType.Tree ? handleChange(item.data) : handleLoadChild(item); + }; + + const renderTreeItem = (item: ListDataItem) => { + return ( +
    + {renderListChecker(item)} + handleTreeItemClick(item)} + onRightIconClick={(event: Event) => { stopPropagation(event); handleLoadChild(item); }} + >
    ); }; return { - renderListChecker, - renderListItem + renderListItem, + renderTreeItem, + renderBreadcrumb }; }; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-request-params.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-request-params.ts new file mode 100644 index 00000000000..557ec4557b9 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-request-params.ts @@ -0,0 +1,122 @@ +import { LookupPanelProps } from "../lookup-panel.props"; +import { BuildParamsOptions, LoadDataType, LoadTreeDataType, LookupDisplayType, LookupRequestParams, SearchParams } from "./types"; + +export const useRequestParams = (props: LookupPanelProps) => { + const getCommonParams = (options: BuildParamsOptions = {}): LookupRequestParams => { + const { context, selectedInfo } = options; + + const requestParams: LookupRequestParams = { }; + + selectedInfo && (requestParams.selectedInfo = selectedInfo); + + if (context?.data) { + requestParams.customData = context.data; + } + + return requestParams; + }; + + const getListParams = (options: BuildParamsOptions = {})=>{ + const { pageIndex = 1 } = options; + const requestParams: LookupRequestParams = { + pageIndex: pageIndex, + pageSize: props.pageSize + }; + return requestParams; + }; + + const getTreeParams = (type: LoadDataType, options: BuildParamsOptions = {})=>{ + const { pageIndex = 1 } = options; + + if(type === LoadDataType.search) { + return { + useFullTree: false, + enableFullTree: false, + loadTreeDataType: LoadTreeDataType.all, + pageSize: props.pageSize, + pageIndex: pageIndex + }; + } + + const requestParams: LookupRequestParams = { + enableFullTree: props.enableFullTree, + loadTreeDataType: LoadTreeDataType.default + }; + + return requestParams; + }; + + const getNavListParams = (type: LoadDataType, options: BuildParamsOptions = {})=>{ + const { pageIndex = 1, relationFilter } = options; + + if(type === LoadDataType.list) { + return { + useFullTree: false, + enableFullTree: false, + loadTreeDataType: LoadTreeDataType.all, + pageSize: props.pageSize, + pageIndex: pageIndex + }; + } + + const requestParams: LookupRequestParams = { + pageIndex: pageIndex, + pageSize: 0, + useFullTree: false, + loadTreeDataType: LoadTreeDataType.default + }; + + relationFilter && (requestParams.relationFilter = relationFilter); + + return requestParams; + }; + + const getParams = (type: LoadDataType, options: BuildParamsOptions)=>{ + const commonParams = getCommonParams(options); + if(props.displayType === LookupDisplayType.List) { + return {...commonParams, ...getListParams(options)}; + } else if(props.displayType === LookupDisplayType.Tree) { + return {...commonParams, ...getTreeParams(type, options)}; + } else { + return {...commonParams, ...getNavListParams(type, options)}; + } + }; + + const getSearchValue = (type: LoadDataType, searchParams?: SearchParams) => { + const searchValue: SearchParams = { + category: type + }; + if(type=== LoadDataType.search) { + searchValue.searchField = searchParams?.searchField; + searchValue.searchValue = searchParams?.searchValue; + } else if(type=== LoadDataType.children || props.displayType === LookupDisplayType.NAVLIST){ + searchValue.parentLayer = searchParams?.parentLayer; + searchValue.parentPath = searchParams?.parentPath; + searchValue.parentID = searchParams?.parentID; + } + + return JSON.stringify(searchValue); + }; + + const buildParams = (type: LoadDataType, options: BuildParamsOptions = {}): LookupRequestParams => { + + const { searchParams } = options; + + const commonParams = getCommonParams(options); + + const params = getParams(type, options); + + const searchValue = getSearchValue(type, searchParams); + + return { + ...commonParams, + ...params, + searchValue: searchValue + }; + }; + + + return { + buildParams + }; +}; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-request.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-request.ts index 0f21f5cbe81..a453d9fdc2e 100644 --- a/packages/mobile-ui-vue/components/lookup/src/composition/use-request.ts +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-request.ts @@ -1,6 +1,6 @@ import { inject } from "vue"; import { LOOKUP_HTTP_SERVICE_TOKEN, LookupPanelProps } from "../lookup-panel.props"; -import { BuildParamsOptions, ListLookupHttpResult, LoadDataType, LookupHttpService, LookupRequestParams, NavListLookupHttpResult, SearchParams, TreeLookupHttpResult } from "./types"; +import { ListLookupHttpResult, LookupHttpService, LookupRequestParams, NavListLookupHttpResult, TreeLookupHttpResult } from "./types"; export const useRequest = (props: LookupPanelProps) => { const httpService = inject(LOOKUP_HTTP_SERVICE_TOKEN); @@ -12,56 +12,7 @@ export const useRequest = (props: LookupPanelProps) => { return httpService.getData(props.uri, params); }; - const buildParams = (type: LoadDataType, options: BuildParamsOptions = {}): LookupRequestParams => { - - const { context, pageIndex = 1, searchParams } = options; - - const requestParams: LookupRequestParams = { - pageIndex: pageIndex, - pageSize: props.pageSize, - }; - const searchValue: SearchParams = { - category: type - }; - - switch (type) { - case 'all': - - break; - case 'list': - - break; - case 'search': - searchValue.searchField = searchParams?.searchField; - searchValue.searchValue = searchParams?.searchValue; - break; - case 'fav': - - break; - case 'children': - - break; - case 'nav': - - break; - - default: - break; - } - - if (context?.data) { - requestParams.customData = context.data; - } - - return { - ...requestParams, - searchValue: JSON.stringify(searchValue) - }; - }; - - return { - getData, - buildParams + getData }; }; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-search-service.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-search-service.ts index e7a08db4210..dbf29f26b3f 100644 --- a/packages/mobile-ui-vue/components/lookup/src/composition/use-search-service.ts +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-search-service.ts @@ -1,7 +1,8 @@ import { reactive } from "vue"; -import { LoadDataType, ListLookupHttpResult, SearchListData, SearchService } from "./types"; +import { LoadDataType, ListLookupHttpResult, SearchListData, SearchService, LookupDisplayType } from "./types"; import { useRequest } from "./use-request"; import { LookupPanelProps } from "../lookup-panel.props"; +import { useRequestParams } from "./use-request-params"; export const useSearchService = (props: LookupPanelProps): SearchService => { @@ -23,14 +24,24 @@ export const useSearchService = (props: LookupPanelProps): SearchService => { searchListData.searchValue = ''; }; + const getDataItems = (data: ListLookupHttpResult)=>{ + if(props.displayType === LookupDisplayType.Tree) { + return data.items.map(item=> item.data); + } + return data.items; + }; + const updateData = (data: ListLookupHttpResult) => { - searchListData.dataList = searchListData.dataList.concat(data.items); + const items = getDataItems(data); + + searchListData.dataList = searchListData.dataList.concat(items); if (data.total && props.pageSize) { searchListData.totalPage = Math.ceil(data.total / props.pageSize); } }; - const { getData, buildParams } = useRequest(props); + const { getData } = useRequest(props); + const { buildParams } = useRequestParams(props); const searchData = () => { if (searchListData.totalPage && (searchListData.pageIndex > searchListData.totalPage)) { searchListData.finished = true; @@ -41,8 +52,14 @@ export const useSearchService = (props: LookupPanelProps): SearchService => { searchValue: searchListData.searchValue }; - const params = buildParams(LoadDataType.search, { searchParams, pageIndex: searchListData.pageIndex }); - params.pageIndex = searchListData.pageIndex; + const extraParams = { + searchParams, + pageIndex: searchListData.pageIndex + }; + + const type = props.displayType === LookupDisplayType.NAVLIST ? LoadDataType.list : LoadDataType.search; + + const params = buildParams(LoadDataType.search, extraParams); getData(params).then(result => { updateData(result); diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-selcted-service.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-selcted-service.ts index 4603479f912..388ca6cba90 100644 --- a/packages/mobile-ui-vue/components/lookup/src/composition/use-selcted-service.ts +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-selcted-service.ts @@ -12,6 +12,10 @@ export const useSelectedService = (props: LookupPanelProps): SeletedService => { const selectedLength = computed(() => selectedListData.dataList.length); + const initSelected = (items: ListDataItem[])=>{ + selectedListData.dataList = items; + }; + const clearSelected = () => { selectedListData.dataList.length = 0; }; @@ -33,9 +37,14 @@ export const useSelectedService = (props: LookupPanelProps): SeletedService => { }; const toggleSelecte = (item: ListDataItem, alwaysSelect = false) => { + console.log('line of 36 🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀\n', 'item:', item); if (!props.multiSelect) { - clearSelected(); - selectedListData.dataList.push(item); + if(!isSelected(item) || alwaysSelect){ + clearSelected(); + selectedListData.dataList.push(item); + } else { + clearSelected(); + } return; } if (isSelectedLimit()) { @@ -73,15 +82,24 @@ export const useSelectedService = (props: LookupPanelProps): SeletedService => { return selectedListData.dataList.map(item => item[props.idField]).join(props.separator); }; + const getSelectedInfo = ()=>{ + return { + selectedIds: getIdValue().split(','), + selected: true + }; + }; + return { selectedListData, selectedLength, + initSelected, toggleSelecte, toggleSelecteAll, clearSelected, isSelected, isSelectedAll, getTextValue, - getIdValue + getIdValue, + getSelectedInfo }; }; diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-tree-data-service.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-tree-data-service.ts index 21852a42965..170622f6913 100644 --- a/packages/mobile-ui-vue/components/lookup/src/composition/use-tree-data-service.ts +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-tree-data-service.ts @@ -1,9 +1,10 @@ import { reactive } from "vue"; -import { ListDataItem, LookupTreeData, TreeInfo, TreeLookupHttpResult } from "./types"; +import { ListDataItem, LookupTreeData, NavListLookupHttpResult, TreeInfo, TreeLookupHttpResult } from "./types"; import { getValue } from "@/components/common"; export const useTreeDataServie = () => { const treeDataMap: Map }> = new Map(); const treeData = reactive({ + treeList: [], parents: [], treeInfo: { loadDataType: 'async', @@ -14,8 +15,22 @@ export const useTreeDataServie = () => { layerField: '', isDetailField: '', onlySelectLeaf: false - } + }, + relations: undefined }); + + const resetData = ()=>{ + treeData.parents = []; + }; + + const getRelations = (item: ListDataItem)=>{ + return treeData.relations?.map(relation=> { + return { + fieldName: relation.helpField, + fieldValue: getValue(relation.groupField, item.data) + }; + }); + }; const getTreeInfoPath = (key: keyof TreeInfo) => { const { dataField } = treeData.treeInfo; @@ -41,7 +56,7 @@ export const useTreeDataServie = () => { return Number(getValue(isDetailPath, item.data)); }; - const getKey = (item: ListDataItem) => { + const getItemKey = (item: ListDataItem) => { const { dataField, parentField, pathField } = treeData.treeInfo; const keyField = getLayerType() === 'parentId' ? parentField : pathField; const parentPath = `${dataField}.${keyField}`; @@ -74,9 +89,16 @@ export const useTreeDataServie = () => { }; const addTreeDataMap = (item: ListDataItem) => { + const itemKey = getItemKey(item); + const currentItem = treeDataMap.get(itemKey); + if (!currentItem) { + const layer = getLayer(item); + const children = new Map(); + treeDataMap.set(itemKey, { layer, children }); + } + const parentKey = getParentKey(item); const parent = treeDataMap.get(parentKey); - const itemKey = getKey(item); if (parent) { parent.children.set(itemKey, item); } else { @@ -87,18 +109,19 @@ export const useTreeDataServie = () => { } }; - const treeToMap = (items: ListDataItem[], parent = '') => { + const treeToMap = (items: ListDataItem[]) => { items.forEach(item => { addTreeDataMap(item); if (item.children && item.children.length > 0) { - treeToMap(item.children, item.id); + treeToMap(item.children); } }); }; const updateTreeData = (result: TreeLookupHttpResult) => { - const { items, treeInfo } = result; + const { items, treeInfo, relations } = result; treeData.treeInfo = treeInfo; + treeData.relations = relations; const { loadDataType } = treeData.treeInfo; if (loadDataType === 'async') { @@ -108,31 +131,29 @@ export const useTreeDataServie = () => { } else { treeToMap(items); } - - console.log('line of 138 🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀\n', 'TreeDataMap:', treeDataMap); }; const getTreeList = (item?: ListDataItem) => { - const key = item ? getKey(item) : ''; - const { children } = treeDataMap.get(key) || {}; + const itemKey = item ? getItemKey(item) : ''; + const { children } = treeDataMap.get(itemKey) || {}; return children ? Array.from(children.values()) : []; }; const getParents = (item?: ListDataItem) => { - let parentKey = item ? getKey(item) : ''; + let itemKey = item ? getItemKey(item) : ''; const parents: ListDataItem[] = []; - let currentNode = treeDataMap.get(parentKey); + let currentNode = treeDataMap.get(itemKey); if (currentNode) { // 终止条件:当前节点无父节点或到达根节点(level=0) while (currentNode.layer > 0) { const layer = currentNode.layer || 0; Array.from(treeDataMap.keys()).forEach(key => { - const item = treeDataMap.get(key); - if (item && item.layer === layer - 1) { - const target = item.children.get(parentKey); + const node = treeDataMap.get(key); + if (node && node.layer === layer - 1) { + const target = node.children.get(itemKey); if (target) { - currentNode = item; - parentKey = key; + currentNode = node; + itemKey = key; parents.unshift(target); }; } @@ -147,13 +168,16 @@ export const useTreeDataServie = () => { return { treeData, + resetData, updateTreeData, getTreeList, getParents, getIsDetail, - getKey, + getItemKey, getParentKey, getLoadDataType, - getLayerType + getLayerType, + getLayer, + getRelations }; }; diff --git a/packages/mobile-ui-vue/components/lookup/src/lookup-panel.component.tsx b/packages/mobile-ui-vue/components/lookup/src/lookup-panel.component.tsx index fdfa9574c30..db0c75e1ba7 100644 --- a/packages/mobile-ui-vue/components/lookup/src/lookup-panel.component.tsx +++ b/packages/mobile-ui-vue/components/lookup/src/lookup-panel.component.tsx @@ -19,14 +19,14 @@ export default defineComponent({ const { setState } = useLookupPanelState(); const treeDataServie = useTreeDataServie(); - const dataService = useDataService(props, treeDataServie); const seletedService = useSelectedService(props); const searchService = useSearchService(props); + const dataService = useDataService(props, { treeDataServie, seletedService }); setState({ panelProps: props, panelContext: context, dataService, treeDataServie, seletedService, searchService }); expose({ getTextValue: seletedService.getTextValue, - initLoadData: dataService.initLoadData + initLoadData: dataService.initLoad }); const renderLookupHeader = () => { diff --git a/packages/mobile-ui-vue/components/lookup/src/lookup-panel.props.ts b/packages/mobile-ui-vue/components/lookup/src/lookup-panel.props.ts index f9f76fe9ce8..a8a6fe5a20a 100644 --- a/packages/mobile-ui-vue/components/lookup/src/lookup-panel.props.ts +++ b/packages/mobile-ui-vue/components/lookup/src/lookup-panel.props.ts @@ -32,6 +32,10 @@ export const commonLookupProps = { enableSearch: { type: Boolean, default: true }, + enableAvatar: { type: Boolean, default: false }, + + avatarField: { type: String, default: '' }, + selectedData: { type: Object, default: null }, searchFields: { type: Array as PropType, default: [] }, diff --git a/packages/mobile-ui-vue/components/lookup/src/lookup-panel.scss b/packages/mobile-ui-vue/components/lookup/src/lookup-panel.scss index f1962f1b5f2..d93ac7ba260 100644 --- a/packages/mobile-ui-vue/components/lookup/src/lookup-panel.scss +++ b/packages/mobile-ui-vue/components/lookup/src/lookup-panel.scss @@ -124,6 +124,7 @@ align-items: center; color: var(--fm-primary-color); padding-right: 8px; + flex-shrink: 0; &:last-child { color: var(--fm-text-color-light); } @@ -134,4 +135,18 @@ } } + @include e(avatar){ + display: flex; + justify-content: center; + flex-shrink: 0; + width: 32px; + height: 32px; + line-height: 32px; + margin-left: 16px; + font-size: 12px; + color: var(--fm-white); + background: var(--fm-gradient-blue); + border-radius: var(--fm-radius-max); + } + } \ No newline at end of file diff --git a/packages/mobile-ui-vue/demos/lookup/index.vue b/packages/mobile-ui-vue/demos/lookup/index.vue index 07ff15ef694..7452fcfc56b 100644 --- a/packages/mobile-ui-vue/demos/lookup/index.vue +++ b/packages/mobile-ui-vue/demos/lookup/index.vue @@ -11,10 +11,14 @@ + + + diff --git a/packages/mobile-ui-vue/demos/lookup/nav-list.vue b/packages/mobile-ui-vue/demos/lookup/nav-list.vue new file mode 100644 index 00000000000..c7f72811a9c --- /dev/null +++ b/packages/mobile-ui-vue/demos/lookup/nav-list.vue @@ -0,0 +1,18 @@ + + diff --git a/packages/mobile-ui-vue/demos/lookup/tree.vue b/packages/mobile-ui-vue/demos/lookup/tree.vue index 8ed9bed0572..2cb7b625046 100644 --- a/packages/mobile-ui-vue/demos/lookup/tree.vue +++ b/packages/mobile-ui-vue/demos/lookup/tree.vue @@ -1,5 +1,5 @@ diff --git a/packages/mobile-ui-vue/demos/lookup/nav-list.vue b/packages/mobile-ui-vue/demos/lookup/nav-list.vue index c7f72811a9c..c8587489765 100644 --- a/packages/mobile-ui-vue/demos/lookup/nav-list.vue +++ b/packages/mobile-ui-vue/demos/lookup/nav-list.vue @@ -1,18 +1,10 @@ diff --git a/packages/mobile-ui-vue/demos/lookup/tree.vue b/packages/mobile-ui-vue/demos/lookup/tree.vue index 2cb7b625046..d792cdd37ff 100644 --- a/packages/mobile-ui-vue/demos/lookup/tree.vue +++ b/packages/mobile-ui-vue/demos/lookup/tree.vue @@ -1,18 +1,10 @@ diff --git a/packages/mobile-ui-vue/farris.config.mjs b/packages/mobile-ui-vue/farris.config.mjs index 8c6ebba73a6..7c008eaa28b 100644 --- a/packages/mobile-ui-vue/farris.config.mjs +++ b/packages/mobile-ui-vue/farris.config.mjs @@ -15,12 +15,21 @@ export default { outDir: fileURLToPath(new URL(`./${outDir}`, import.meta.url)), externals: { include: externals, - filter: (externals)=> { + filter: (externals) => { return (id) => { return externals.find((item) => item && id.indexOf(item) === 0); }; } }, + server: { + proxy: { + "/api": { + target: "http://localhost:5300", + changeOrigin: true, + secure: false + } + } + }, externalDependencies, minify: true, target: 'es2015', -- Gitee From 76e6a064c35fa7585abf2e63f5d1e28559f60619 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Wed, 2 Apr 2025 11:38:23 +0800 Subject: [PATCH 142/153] =?UTF-8?q?fix:=20input=E5=8F=8Atextarea=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E8=BF=90=E8=A1=8C=E6=97=B6=E6=97=A0=E6=95=88=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E9=9A=90=E8=97=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/property-config/input-group.property-config.ts | 1 + .../textarea/src/property-config/textarea.property-config.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/ui-vue/components/input-group/src/property-config/input-group.property-config.ts b/packages/ui-vue/components/input-group/src/property-config/input-group.property-config.ts index 763844bf85d..498a4f3712e 100644 --- a/packages/ui-vue/components/input-group/src/property-config/input-group.property-config.ts +++ b/packages/ui-vue/components/input-group/src/property-config/input-group.property-config.ts @@ -29,6 +29,7 @@ export class InputGroupProperty extends InputBaseProperty { enableViewPassword: { description: "", title: "启用密码", + visible: false, type: "boolean" }, }); diff --git a/packages/ui-vue/components/textarea/src/property-config/textarea.property-config.ts b/packages/ui-vue/components/textarea/src/property-config/textarea.property-config.ts index ae9d3ed8631..88b87c35ab6 100644 --- a/packages/ui-vue/components/textarea/src/property-config/textarea.property-config.ts +++ b/packages/ui-vue/components/textarea/src/property-config/textarea.property-config.ts @@ -34,6 +34,7 @@ export class TextareaProperty extends InputBaseProperty { autoHeight: { description: "", title: "自动高度", + visible: false, type: "boolean" }, }); -- Gitee From 536ee88e31776b86a7aa5e50b7f7913b3457b912 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Wed, 2 Apr 2025 13:47:17 +0800 Subject: [PATCH 143/153] =?UTF-8?q?fix:=20=E5=88=A0=E9=99=A4console.log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/lookup/src/components/content-list.component.tsx | 1 - .../components/lookup/src/composition/use-load-nav-list-data.ts | 1 - .../components/lookup/src/composition/use-selcted-service.ts | 1 - 3 files changed, 3 deletions(-) diff --git a/packages/mobile-ui-vue/components/lookup/src/components/content-list.component.tsx b/packages/mobile-ui-vue/components/lookup/src/components/content-list.component.tsx index 083ec305c07..e698a366fce 100644 --- a/packages/mobile-ui-vue/components/lookup/src/components/content-list.component.tsx +++ b/packages/mobile-ui-vue/components/lookup/src/components/content-list.component.tsx @@ -17,7 +17,6 @@ export default defineComponent({ const handleLoad = ()=>{ listData.pageIndex++; - console.log('line of 20 🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀\n', 'pageIndex:', listData.pageIndex); loadData(); }; const renderList = () => { diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-load-nav-list-data.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-load-nav-list-data.ts index 172abe05fd2..1b302115a1d 100644 --- a/packages/mobile-ui-vue/components/lookup/src/composition/use-load-nav-list-data.ts +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-load-nav-list-data.ts @@ -64,7 +64,6 @@ export const useLoadNavListData = (props: LookupPanelProps, listData: LookupList const selectedInfo = getSelectedInfo(); const extraParams = { context, pageSize: 1, selectedInfo }; const params = buildParams(LoadDataType.all, extraParams); - console.log('line of 62 🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀\n', 'params:', params); getData(params).then(result => { updateData(result); initSelected(result.selectedData); diff --git a/packages/mobile-ui-vue/components/lookup/src/composition/use-selcted-service.ts b/packages/mobile-ui-vue/components/lookup/src/composition/use-selcted-service.ts index ea4f4e59027..60ee378870b 100644 --- a/packages/mobile-ui-vue/components/lookup/src/composition/use-selcted-service.ts +++ b/packages/mobile-ui-vue/components/lookup/src/composition/use-selcted-service.ts @@ -39,7 +39,6 @@ export const useSelectedService = (props: LookupPanelProps): SeletedService => { }; const toggleSelecte = (item: ListDataItem, alwaysSelect = false) => { - console.log('line of 36 🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀\n', 'item:', item); if (!props.multiSelect) { if(!isSelected(item) || alwaysSelect){ clearSelected(); -- Gitee From 4be323ebb87be8e091f582a6c0f2d6c365e8f691 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Wed, 2 Apr 2025 14:10:43 +0800 Subject: [PATCH 144/153] =?UTF-8?q?fix:=20=E5=AE=8C=E5=96=84=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E8=A7=84=E5=88=99=E4=B8=AD=E5=AF=B9=E7=A9=BA=E5=80=BC?= =?UTF-8?q?=E5=92=8C=E9=9D=9E=E6=B3=95=E5=80=BC=E7=9A=84=E5=A4=84=E7=90=86?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/devkit/lib/common/utils/DateUtil.ts | 2 +- .../validators/max-date-validator.ts | 12 ++++-- .../validators/max-length-validator.ts | 19 ++++----- .../validators/max-value-validator.ts | 16 ++++---- .../validators/min-date-validator.ts | 12 ++++-- .../validators/min-length-validator.ts | 18 ++++----- .../validators/min-value-validator.ts | 16 ++++---- .../validators/pattern-validator.ts | 13 +++++- .../validators/required-validator.ts | 3 +- .../validation/validators/validator-util.ts | 40 +++++++++++++++++++ 10 files changed, 104 insertions(+), 47 deletions(-) diff --git a/packages/devkit/lib/common/utils/DateUtil.ts b/packages/devkit/lib/common/utils/DateUtil.ts index 952c4131907..8ea62599c54 100644 --- a/packages/devkit/lib/common/utils/DateUtil.ts +++ b/packages/devkit/lib/common/utils/DateUtil.ts @@ -46,7 +46,7 @@ class DateUtil { if (this.isDate(date) === true) { return date as Date; } - + const parsedDate = parseISO(date as string); if (isNaN(parsedDate.getTime())) { return null; diff --git a/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts b/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts index 7bf733e9ecf..0b7f9d3d86d 100644 --- a/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/max-date-validator.ts @@ -1,5 +1,6 @@ import { DateUtil } from '../../../../common/index'; import { ValidationError, MaxDateValidationRule } from '../types'; +import { ValidatorUtil } from './validator-util'; import { BaseValidator } from './base-validator'; /** @@ -20,13 +21,18 @@ class MaxDateValidator extends BaseValidator { return null; } - let { name, maxDate, message } = rule; + // 输入值为空,不触发校验 + if (ValidatorUtil.isEmptyInput(value)) { + return null; + } - // 空日期,不校验 - if (DateUtil.isEmptyDate(value)) { + // 输入值不是日期字符串,不触发校验 + if (typeof value !== 'string') { return null; } + let { name, maxDate, message } = rule; + value = DateUtil.parse(value) as Date; maxDate = DateUtil.parse(maxDate) as Date; diff --git a/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts b/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts index 920962e4685..02a7cc8257b 100644 --- a/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/max-length-validator.ts @@ -1,4 +1,5 @@ import { ValidationError, MaxLengthValidationRule } from '../types'; +import { ValidatorUtil } from './validator-util'; import { BaseValidator } from './base-validator'; /** @@ -19,20 +20,16 @@ class MaxLengthValidator extends BaseValidator { return null; } - // 空值和NaN,视为空字符串 - if (value === null || value === undefined) { - value = ''; - } - - // 非字符串类型且具有toString方法的值,先转换成字符串再比较 - if (typeof value !== 'string' && typeof value.toString === 'function') { - value = value.toString(); + // 输入值为空,不触发校验 + if (ValidatorUtil.isEmptyInput(value)) { + return null; } - // 转换后仍不是字符串的情况,无法进行比较,不触发校验 - if (typeof value !== 'string') { - return null + // 输入值不是类似字符串的值,不触发校验 + if (!ValidatorUtil.isStringLike(value)) { + return null; } + value = '' + value; const maxLength = rule.maxLength; const actualLength = value.length; diff --git a/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts b/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts index 5f7987b859e..ce9314e5a83 100644 --- a/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/max-value-validator.ts @@ -1,5 +1,5 @@ -import { StringUtil, NumberUtil } from '../../../../common/index'; import { ValidationError, MaxValueValidationRule } from '../types'; +import { ValidatorUtil } from './validator-util'; import { BaseValidator } from './base-validator'; /** @@ -20,19 +20,19 @@ class MaxValueValidator extends BaseValidator { return null; } - // 空值无法进行比较,不触发校验 - if (value === null || value === undefined) { + // 输入值为空,不触发校验 + if (ValidatorUtil.isEmptyInput(value)) { return null; } - // 如果是字符串先转换成数字,再比较 - if (typeof value === 'string') { - value = parseFloat(value as string); + // 输入值不是类似数字(非数字、非字符串)的值,不触发校验 + if (!ValidatorUtil.isNumberLike(value)) { + return null; } - // 转换后仍不是数字,无法比较,不触发校验 + // 如果是字符串先转换成数字,再比较 if (typeof value !== 'number') { - return null; + value = parseFloat(value); } // 转换后值为NaN时,无法比较,不触发校验 diff --git a/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts b/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts index a3c6e9d6427..897a2ebe6da 100644 --- a/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/min-date-validator.ts @@ -1,5 +1,6 @@ import { DateUtil } from '../../../../common/index'; import { ValidationError, MinDateValidationRule } from '../types'; +import { ValidatorUtil } from './validator-util'; import { BaseValidator } from './base-validator'; /** @@ -19,13 +20,18 @@ class MinDateValidator extends BaseValidator { if (!this.checkRule(rule)) { return null; } - let { name, minDate, message } = rule; - // 空日期,不校验 - if (DateUtil.isEmptyDate(value)) { + // 输入值为空,不触发校验 + if (ValidatorUtil.isEmptyInput(value)) { return null; } + // 输入值不是日期字符串,不触发校验 + if (typeof value !== 'string') { + return null; + } + + let { name, minDate, message } = rule; value = DateUtil.parse(value) as Date; minDate = DateUtil.parse(minDate) as Date; diff --git a/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts b/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts index e91005de71b..39ebd4e5b5a 100644 --- a/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/min-length-validator.ts @@ -1,4 +1,5 @@ import { ValidationError, MinLengthValidationRule } from '../types'; +import { ValidatorUtil } from './validator-util'; import { BaseValidator } from './base-validator'; /** @@ -19,19 +20,14 @@ class MinLengthValidator extends BaseValidator { return null; } - // 空值和NaN,视为空字符串 - if (value === null || value === undefined || (typeof value === 'number' && isNaN(value))) { - value = ''; - } - - // 非字符串类型且具有toString方法的值,先转换成字符串再比较 - if (typeof value !== 'string' && typeof value.toString === 'function') { - value = value.toString(); + // 空输入,不触发校验 + if (ValidatorUtil.isEmptyInput(value)) { + return null; } - // 转换后仍不是字符串的情况,无法进行比较,不触发校验 - if (typeof value !== 'string') { - return null + // 输入值不是类似字符串的值,不触发校验 + if (!ValidatorUtil.isStringLike(value)) { + return null; } const actualLength = value.length; diff --git a/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts b/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts index cd2bb727209..6fe9959dd31 100644 --- a/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/min-value-validator.ts @@ -1,5 +1,5 @@ -import { StringUtil, NumberUtil } from '../../../../common/index'; import { ValidationError, MinValueValidationRule } from '../types'; +import { ValidatorUtil } from './validator-util'; import { BaseValidator } from './base-validator'; /** @@ -20,19 +20,19 @@ class MinValueValidator extends BaseValidator { return null; } - // 空值无法进行比较,不触发校验 - if (value === null || value === undefined) { + // 输入值为空,不触发校验 + if (ValidatorUtil.isEmptyInput(value)) { return null; } - // 如果是字符串先转换成数字,再比较 - if (typeof value === 'string') { - value = parseFloat(value as string); + // 输入值不是类似数字(非数字、非字符串)的值,不触发校验 + if (!ValidatorUtil.isNumberLike(value)) { + return null; } - // 转换后仍不是数字,无法比较,不触发校验 + // 如果是字符串先转换成数字,再比较 if (typeof value !== 'number') { - return null; + value = parseFloat(value); } // 转换后值为NaN时,无法比较,不触发校验 diff --git a/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts b/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts index c8fd3580087..4052935f0c7 100644 --- a/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/pattern-validator.ts @@ -1,5 +1,6 @@ import { StringUtil } from '../../../../common/index'; import { ValidationError, PatternValidationRule } from '../types'; +import { ValidatorUtil } from './validator-util'; import { BaseValidator } from './base-validator'; /** @@ -20,6 +21,16 @@ class PatternValidator extends BaseValidator { return null; } + if (ValidatorUtil.isEmptyInput(value)) { + return null; + } + + // 输入值不是类似字符串的值,不触发校验 + if (!ValidatorUtil.isStringLike(value)) { + return null; + } + value = '' + value; + let { name, pattern } = rule; if (!pattern) { return null; @@ -27,7 +38,7 @@ class PatternValidator extends BaseValidator { let regex: RegExp; if (StringUtil.isString(pattern)) { - let regexStr = pattern as string; + let regexStr = pattern as string; regex = new RegExp(regexStr); } else { regex = pattern as RegExp; diff --git a/packages/devkit/lib/store/form/validation/validators/required-validator.ts b/packages/devkit/lib/store/form/validation/validators/required-validator.ts index 222119da5d3..3f3c4b4524e 100644 --- a/packages/devkit/lib/store/form/validation/validators/required-validator.ts +++ b/packages/devkit/lib/store/form/validation/validators/required-validator.ts @@ -1,4 +1,5 @@ import { ValidationError, RequiredValidationRule } from '../types'; +import { ValidatorUtil } from './validator-util'; import { BaseValidator } from './base-validator'; /** @@ -19,7 +20,7 @@ class RequiredValidator extends BaseValidator { return null; } - if (value === undefined || value == null || value.length === 0) { + if (ValidatorUtil.isEmptyInput(value)) { const name = rule.name; const message = rule.message || '输入的值不能为空'; const error = { name, message, actualValue: value }; diff --git a/packages/devkit/lib/store/form/validation/validators/validator-util.ts b/packages/devkit/lib/store/form/validation/validators/validator-util.ts index 6f7cf59d8a6..4f18568ba64 100644 --- a/packages/devkit/lib/store/form/validation/validators/validator-util.ts +++ b/packages/devkit/lib/store/form/validation/validators/validator-util.ts @@ -10,6 +10,46 @@ class ValidatorUtil { public static hasValidLength(value: any): boolean { return value != null && typeof value.length === 'number'; } + + /** + * 是否为空输入 + */ + public static isEmptyInput(value: any): boolean { + if (value === null || value === undefined || value === '') { + return true; + } + + return false; + } + + /** + * 是否是类字符串的值 + */ + public static isStringLike(value: any): boolean { + + // 排除不是字符串、数字、布尔的值 + if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') { + return false + } + + // 排除NaN + if (typeof value === 'number' && isNaN(value)) { + return false; + } + + return true; + } + + /** + * 是否是类似数字的值 + */ + public static isNumberLike(value: any): boolean { + if (typeof value !== 'string' && typeof value !== 'number') { + return false; + } + + return true; + } } export { ValidatorUtil }; \ No newline at end of file -- Gitee From 167c6005692d14be714cbe87618582c20c9d74c9 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Wed, 2 Apr 2025 19:14:43 +0800 Subject: [PATCH 145/153] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E6=96=B0?= =?UTF-8?q?=E5=A2=9Efilter=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/src/utils/index.ts | 1 + .../common/src/utils/src/query-filter.ts | 40 ++++++++++++++ .../mobile-ui-vue/components/filter/index.ts | 7 +++ .../src/components/portal.component.tsx | 0 .../filter/src/compositions/type.ts | 12 +++++ .../filter/src/filter-panel.component.tsx | 20 +++++++ .../filter/src/filter-panel.props.ts | 9 ++++ .../components/filter/src/filter-panel.scss | 2 + .../filter/src/filter.component.tsx | 54 +++++++++++++++++++ .../components/filter/src/filter.props.ts | 8 +++ .../components/filter/src/filter.scss | 2 + packages/mobile-ui-vue/components/index.scss | 1 + packages/mobile-ui-vue/components/index.ts | 3 ++ packages/mobile-ui-vue/demos/filter/base.vue | 8 +++ packages/mobile-ui-vue/demos/filter/index.vue | 9 ++++ packages/mobile-ui-vue/src/menu-data.ts | 6 +++ 16 files changed, 182 insertions(+) create mode 100644 packages/mobile-ui-vue/components/common/src/utils/src/query-filter.ts create mode 100644 packages/mobile-ui-vue/components/filter/index.ts create mode 100644 packages/mobile-ui-vue/components/filter/src/components/portal.component.tsx create mode 100644 packages/mobile-ui-vue/components/filter/src/compositions/type.ts create mode 100644 packages/mobile-ui-vue/components/filter/src/filter-panel.component.tsx create mode 100644 packages/mobile-ui-vue/components/filter/src/filter-panel.props.ts create mode 100644 packages/mobile-ui-vue/components/filter/src/filter-panel.scss create mode 100644 packages/mobile-ui-vue/components/filter/src/filter.component.tsx create mode 100644 packages/mobile-ui-vue/components/filter/src/filter.props.ts create mode 100644 packages/mobile-ui-vue/components/filter/src/filter.scss create mode 100644 packages/mobile-ui-vue/demos/filter/base.vue create mode 100644 packages/mobile-ui-vue/demos/filter/index.vue diff --git a/packages/mobile-ui-vue/components/common/src/utils/index.ts b/packages/mobile-ui-vue/components/common/src/utils/index.ts index fdea8007927..b386cd07450 100644 --- a/packages/mobile-ui-vue/components/common/src/utils/index.ts +++ b/packages/mobile-ui-vue/components/common/src/utils/index.ts @@ -10,3 +10,4 @@ export * from './src/with-install'; export * from './src/date'; export * from './src/string'; export * from './src/use-appearance'; +export * from './src/query-filter'; diff --git a/packages/mobile-ui-vue/components/common/src/utils/src/query-filter.ts b/packages/mobile-ui-vue/components/common/src/utils/src/query-filter.ts new file mode 100644 index 00000000000..90717af9bf9 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/src/utils/src/query-filter.ts @@ -0,0 +1,40 @@ + +export enum FilterCompareType { + Equal = 0, + NotEqual = 1, + Greater = 2, + GreaterOrEqual = 3, + Less = 4, + LessOrEqual = 5, + Like = 6, + LikeStartWith = 7, + LikeEndWith = 8, + NotLike = 9, + NotLikeStartWith = 10, + NotLikeEndWith = 11, + Is = 12, + IsNot = 13, + In = 14, + NotIn = 15, +} + +export enum FilterRelation { + Empty, + And, + Or, +} + +export enum FilterExpressType { + Value = 0, + Expression = 1, +} + +export interface FilterCondition { + FilterField: string + Compare: FilterCompareType + Value: string + Relation: FilterRelation + Expresstype: FilterExpressType + Lbracket: string + Rbracket: string +} diff --git a/packages/mobile-ui-vue/components/filter/index.ts b/packages/mobile-ui-vue/components/filter/index.ts new file mode 100644 index 00000000000..1665ba73b10 --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/index.ts @@ -0,0 +1,7 @@ +import { withInstall, } from '@components/common'; +import FilterInstallless from './src/filter.component'; +const Filter = withInstall(FilterInstallless); + + +export { Filter }; +export default Filter; diff --git a/packages/mobile-ui-vue/components/filter/src/components/portal.component.tsx b/packages/mobile-ui-vue/components/filter/src/components/portal.component.tsx new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/mobile-ui-vue/components/filter/src/compositions/type.ts b/packages/mobile-ui-vue/components/filter/src/compositions/type.ts new file mode 100644 index 00000000000..5ec6048dd5e --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/src/compositions/type.ts @@ -0,0 +1,12 @@ +type FieldControl = { + controltype: string + [key: string]: any +} + +export type FieldConfig = { + id: string + labelCode: string + code: string + name: string + control: FieldControl +}; diff --git a/packages/mobile-ui-vue/components/filter/src/filter-panel.component.tsx b/packages/mobile-ui-vue/components/filter/src/filter-panel.component.tsx new file mode 100644 index 00000000000..bbd2273640b --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/src/filter-panel.component.tsx @@ -0,0 +1,20 @@ +import { defineComponent } from 'vue'; +import { useBem } from '@/components/common'; +import { FILTER_PANEL_NAME, filterPanelProps } from './filter-panel.props'; + +export default defineComponent({ + name: FILTER_PANEL_NAME, + props: filterPanelProps, + emits: [''], + setup(props, context) { + + const { bem } = useBem(FILTER_PANEL_NAME); + + + return () => ( +
    + FILTER_PANEL +
    + ); + } +}); diff --git a/packages/mobile-ui-vue/components/filter/src/filter-panel.props.ts b/packages/mobile-ui-vue/components/filter/src/filter-panel.props.ts new file mode 100644 index 00000000000..fb8120887e9 --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/src/filter-panel.props.ts @@ -0,0 +1,9 @@ +import { ExtractPropTypes } from 'vue'; +export const FILTER_PANEL_NAME = "FmFilterPanel"; + + +export const filterPanelProps = { + +}; + +export type FilterPanelProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/filter/src/filter-panel.scss b/packages/mobile-ui-vue/components/filter/src/filter-panel.scss new file mode 100644 index 00000000000..87bf00568e6 --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/src/filter-panel.scss @@ -0,0 +1,2 @@ +@use '../../common/src/style/mixins/index.scss' as *; + diff --git a/packages/mobile-ui-vue/components/filter/src/filter.component.tsx b/packages/mobile-ui-vue/components/filter/src/filter.component.tsx new file mode 100644 index 00000000000..6539cd93436 --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/src/filter.component.tsx @@ -0,0 +1,54 @@ +import { defineComponent, ref } from 'vue'; +import { useBem } from '@/components/common'; +import { FILTER_NAME, filterProps } from './filter.props'; +import FilterPanel from './filter-panel.component'; +import Icon from '@/components/icon'; +import Search from '@/components/search'; +import Popup from '@/components/popup'; + +export default defineComponent({ + name: FILTER_NAME, + props: filterProps, + emits: ['click'], + setup(props, context) { + + const { bem } = useBem(FILTER_NAME); + + const showFilterPopup = ref(false); + const handleClickPortalIcon = ()=>{ + showFilterPopup.value = true; + }; + + const renderFilterPortal = ()=>{ + return ( +
    +
    + +
    +
    + +
    +
    + ); + }; + const renderFilterPopup = ()=>{ + return ( + + + + ); + }; + + return () => ( +
    + {renderFilterPortal()} + {renderFilterPopup()} +
    + ); + } +}); diff --git a/packages/mobile-ui-vue/components/filter/src/filter.props.ts b/packages/mobile-ui-vue/components/filter/src/filter.props.ts new file mode 100644 index 00000000000..7e4de38e013 --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/src/filter.props.ts @@ -0,0 +1,8 @@ +import { ExtractPropTypes } from 'vue'; +export const FILTER_NAME = "FmFilter"; + +export const filterProps = { + +}; + +export type FilterProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/filter/src/filter.scss b/packages/mobile-ui-vue/components/filter/src/filter.scss new file mode 100644 index 00000000000..87bf00568e6 --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/src/filter.scss @@ -0,0 +1,2 @@ +@use '../../common/src/style/mixins/index.scss' as *; + diff --git a/packages/mobile-ui-vue/components/index.scss b/packages/mobile-ui-vue/components/index.scss index 0832f1da227..6eb23ef1ffb 100644 --- a/packages/mobile-ui-vue/components/index.scss +++ b/packages/mobile-ui-vue/components/index.scss @@ -33,6 +33,7 @@ @use './date-picker/src/date-picker.scss'; @use './lookup/src/lookup.scss'; @use './search/src/search.scss'; +@use './filter/src/filter.scss'; @use './page-container/src/page-container.scss'; @use './page-body-container/src/page-body-container.scss'; @use './page-header-container/src/page-header-container.scss'; diff --git a/packages/mobile-ui-vue/components/index.ts b/packages/mobile-ui-vue/components/index.ts index 1de9986d9c6..4dce0f2c0b6 100644 --- a/packages/mobile-ui-vue/components/index.ts +++ b/packages/mobile-ui-vue/components/index.ts @@ -63,6 +63,7 @@ import PageFooterContainer from './page-footer-container'; import Component from './component'; import ContentContainer from './content-container'; import FloatContainer from './float-container'; +import Filter from './filter'; import Modal from './modal'; import DynamicView from './dynamic-view'; @@ -97,6 +98,7 @@ const components = [ Rate, Form, FormItem, + Filter, Popup, Picker, PickerGroup, @@ -158,6 +160,7 @@ export { Rate, Form, FormItem, + Filter, Popup, Picker, PickerGroup, diff --git a/packages/mobile-ui-vue/demos/filter/base.vue b/packages/mobile-ui-vue/demos/filter/base.vue new file mode 100644 index 00000000000..e67c3f14a51 --- /dev/null +++ b/packages/mobile-ui-vue/demos/filter/base.vue @@ -0,0 +1,8 @@ + + diff --git a/packages/mobile-ui-vue/demos/filter/index.vue b/packages/mobile-ui-vue/demos/filter/index.vue new file mode 100644 index 00000000000..0289592a08f --- /dev/null +++ b/packages/mobile-ui-vue/demos/filter/index.vue @@ -0,0 +1,9 @@ + + + diff --git a/packages/mobile-ui-vue/src/menu-data.ts b/packages/mobile-ui-vue/src/menu-data.ts index fc5d4681430..330a5feb231 100644 --- a/packages/mobile-ui-vue/src/menu-data.ts +++ b/packages/mobile-ui-vue/src/menu-data.ts @@ -204,6 +204,12 @@ export default { url: "/demos/tag", component: "/tag", }, + { + title: "筛选", + name: "filter", + url: "/demos/filter", + component: "/filter", + }, ], }, ] -- Gitee From 12dd91f392795b923e220805118a326226f6b425 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Wed, 2 Apr 2025 19:20:33 +0800 Subject: [PATCH 146/153] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96time-picker?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E6=97=B6=E5=B1=9E=E6=80=A7=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/property-config/time-picker.property-config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui-vue/components/time-picker/src/property-config/time-picker.property-config.ts b/packages/ui-vue/components/time-picker/src/property-config/time-picker.property-config.ts index ee80c482e3f..d9f3a937b47 100644 --- a/packages/ui-vue/components/time-picker/src/property-config/time-picker.property-config.ts +++ b/packages/ui-vue/components/time-picker/src/property-config/time-picker.property-config.ts @@ -29,7 +29,7 @@ export class TimePickerProperty extends InputBaseProperty { }, showHeader: { description: "", - title: "是否显示头部区域", + title: "是否显示时分秒标题", type: "boolean" }, use12Hours: { -- Gitee From 32d161b83d48525ef3575232291b02d0aafbdb27 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Wed, 2 Apr 2025 19:53:12 +0800 Subject: [PATCH 147/153] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96combo-list?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E6=97=B6=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../combo-list/src/property-config/combo-list.property-config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/ui-vue/components/combo-list/src/property-config/combo-list.property-config.ts b/packages/ui-vue/components/combo-list/src/property-config/combo-list.property-config.ts index eb633a1d16b..62e087adc00 100644 --- a/packages/ui-vue/components/combo-list/src/property-config/combo-list.property-config.ts +++ b/packages/ui-vue/components/combo-list/src/property-config/combo-list.property-config.ts @@ -64,6 +64,7 @@ export class ComboListProperty extends InputBaseProperty { multiSelect: { description: "", title: "启用多选", + visible: false, type: "boolean" }, maxLength: { -- Gitee From 16b541e86f5adb6ea7bd002912032cfdf0043c42 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Fri, 4 Apr 2025 15:41:46 +0800 Subject: [PATCH 148/153] =?UTF-8?q?feature:=201=E3=80=81=E8=A1=A5=E5=85=A8?= =?UTF-8?q?=E6=A0=B8=E5=BF=83=E8=BE=93=E5=85=A5=E6=8E=A7=E4=BB=B6=E7=9A=84?= =?UTF-8?q?Schema=EF=BC=9B2=E3=80=81=E5=8C=85=E8=A3=85=E6=95=B0=E5=AD=97?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E6=A1=86=E6=8E=A7=E4=BB=B6=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile-render/src/components/index.ts | 0 .../metadata/form/form-metadata-converter.ts | 38 +++++++- .../form/form-metadata-data-service.ts | 1 + .../mobile-render/src/views/page/page.vue | 1 - .../src/date-picker-input.props.ts | 4 +- ...ema.json => date-picker-input.schema.json} | 65 ++++++++------ .../date-time-picker-input/index.ts | 11 +++ .../src/date-time-picker-input.props.ts | 10 +++ .../schema/datetime-picker-input.schema.json | 89 +++++++++++++++++++ .../src/schema/schema-mapper.ts | 7 ++ .../src/schema/schema-resolver.ts | 5 ++ .../src/schema/form-item.schema.json | 5 ++ .../src/schema/input-group.schema.json | 54 +++++------ .../components/number-input/index.ts | 17 ++++ .../src/number-input.component.tsx | 32 +++++++ .../number-input/src/number-input.props.ts | 18 ++++ .../src/schema/number-input.schema.json} | 65 +++++++------- .../number-input/src/schema/schema-mapper.ts | 7 ++ .../src/schema/schema-resolver.ts | 5 ++ .../components/picker-input/index.ts | 10 +-- .../picker-input/src/picker-input.props.ts | 4 +- ...t.schema.json => picker-input.schema.json} | 69 +++++++------- packages/mobile-ui-vue/components/register.ts | 8 +- .../switch/src/schema/switch.schema.json | 68 ++++++-------- .../textarea/src/schema/textarea.schema.json | 88 ++++++++++++++++++ .../components/textarea/src/textarea.props.ts | 2 +- 26 files changed, 507 insertions(+), 176 deletions(-) create mode 100644 packages/mobile-render/src/components/index.ts rename packages/mobile-ui-vue/components/date-picker-input/src/schema/{schema.json => date-picker-input.schema.json} (54%) create mode 100644 packages/mobile-ui-vue/components/date-time-picker-input/src/schema/datetime-picker-input.schema.json create mode 100644 packages/mobile-ui-vue/components/date-time-picker-input/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/date-time-picker-input/src/schema/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/number-input/index.ts create mode 100644 packages/mobile-ui-vue/components/number-input/src/number-input.component.tsx create mode 100644 packages/mobile-ui-vue/components/number-input/src/number-input.props.ts rename packages/mobile-ui-vue/components/{textarea/src/schema/input.schema.json => number-input/src/schema/number-input.schema.json} (54%) create mode 100644 packages/mobile-ui-vue/components/number-input/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/number-input/src/schema/schema-resolver.ts rename packages/mobile-ui-vue/components/picker-input/src/schema/{enum-field-input.schema.json => picker-input.schema.json} (58%) create mode 100644 packages/mobile-ui-vue/components/textarea/src/schema/textarea.schema.json diff --git a/packages/mobile-render/src/components/index.ts b/packages/mobile-render/src/components/index.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/mobile-render/src/services/metadata/form/form-metadata-converter.ts b/packages/mobile-render/src/services/metadata/form/form-metadata-converter.ts index 031732a573d..a42fd77acb5 100644 --- a/packages/mobile-render/src/services/metadata/form/form-metadata-converter.ts +++ b/packages/mobile-render/src/services/metadata/form/form-metadata-converter.ts @@ -1,3 +1,4 @@ +import { schemaMap } from '@farris/mobile-ui-vue'; import { ConverterContext, ConverterFactory } from './converters'; /** @@ -13,6 +14,7 @@ class FormMetadataConverter { */ private context: ConverterContext; + /** * 转换器工厂 */ @@ -37,6 +39,7 @@ class FormMetadataConverter { this.convertSchemas(); this.convertViewModels(); this.convertComponents(); + this.removeUnSupportedComponents(); } /** @@ -78,7 +81,7 @@ class FormMetadataConverter { /** * 转换组件结构 */ - private convertComponent(component: any) { + private convertComponent(component: any): void { const componentConverter = this.converterFactory.create(component.type); componentConverter.convert(component); @@ -89,6 +92,39 @@ class FormMetadataConverter { }); } } + + /** + * 移除不受支持的组件 + */ + private removeUnSupportedComponents(): void { + console.group('----------unSupported components----------'); + const vmComponents = this.context.getVmComponents(); + vmComponents.forEach((vmComponent) => { + this.removeUnSupportComponent(vmComponent, null); + }); + console.groupEnd(); + } + + /** + * 移除不受支持的组件 + */ + private removeUnSupportComponent(component: any, parentComponent: any) { + const componentSchema = schemaMap[component.type]; + if (parentComponent && !componentSchema) { + const componentIndex = parentComponent.contents.indexOf(component); + parentComponent.contents.splice(componentIndex, 1); + console.log('unsupported component: ' + component.type); + return; + } + + // 递归删除下级不支持的组件 + if (Array.isArray(component.contents)) { + const childComponents = [...component.contents]; + childComponents.forEach((childComponent: any) => { + this.removeUnSupportComponent(childComponent, component); + }); + } + } } export { FormMetadataConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/form-metadata-data-service.ts b/packages/mobile-render/src/services/metadata/form/form-metadata-data-service.ts index 4961f267cc6..347642594ad 100644 --- a/packages/mobile-render/src/services/metadata/form/form-metadata-data-service.ts +++ b/packages/mobile-render/src/services/metadata/form/form-metadata-data-service.ts @@ -18,6 +18,7 @@ export class FormMetadataDataService { * 根据Path加载元数据 */ public loadByFullPath(metadataFullPath: string): Promise { + // metadataFullPath = 'Jiwt/JiwtFarrisVueModule/PCFormTest0327/bo-pcformtest0327-front/metadata/components/PCListCardAd032801.frm'; return this.repository.load(metadataFullPath).then((response: any) => { return this.createMetadata(response); }); diff --git a/packages/mobile-render/src/views/page/page.vue b/packages/mobile-render/src/views/page/page.vue index 2be674fbe26..54897741441 100644 --- a/packages/mobile-render/src/views/page/page.vue +++ b/packages/mobile-render/src/views/page/page.vue @@ -28,7 +28,6 @@ provide(DYNAMIC_VIEW_CONTEXT, dynamicViewContext); diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.props.ts b/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.props.ts index 16e9a703ae5..1517ce91152 100644 --- a/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.props.ts +++ b/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.props.ts @@ -3,7 +3,7 @@ import { buttonEditProps } from '@/components/button-edit'; import { datePickerProps } from '@/components/date-picker'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; -import inputSchema from './schema/schema.json'; +import datePickerInputSchema from './schema/date-picker-input.schema.json'; import { createPropsResolver } from '@/components/dynamic-resolver'; export const DATA_PICKER_INPUT_NAME = 'FmDatePickerInput'; @@ -17,4 +17,4 @@ export const datePickerInputProps = { export type DatePickerInputProps = ExtractPropTypes; -export const propsResolver = createPropsResolver(datePickerInputProps, inputSchema, schemaMapper, schemaResolver); +export const propsResolver = createPropsResolver(datePickerInputProps, datePickerInputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema.json b/packages/mobile-ui-vue/components/date-picker-input/src/schema/date-picker-input.schema.json similarity index 54% rename from packages/mobile-ui-vue/components/date-picker-input/src/schema/schema.json rename to packages/mobile-ui-vue/components/date-picker-input/src/schema/date-picker-input.schema.json index 1674a23b089..3e41dfe0296 100644 --- a/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema.json +++ b/packages/mobile-ui-vue/components/date-picker-input/src/schema/date-picker-input.schema.json @@ -2,20 +2,20 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://farris-design.gitee.io/date-picker.schema.json", "title": "date-picker", - "description": "A Farris Input Component", + "description": "日期", "type": "object", "properties": { "id": { - "description": "The unique identifier for a Date Picker", + "description": "标识", "type": "string" }, "type": { - "description": "The type string of Date Picker component", + "description": "控件类型", "type": "string", - "default": "date-picker" + "default": "textarea" }, "appearance": { - "description": "", + "description": "外观", "type": "object", "properties": { "class": { @@ -28,44 +28,51 @@ "default": {} }, "binding": { - "description": "", + "description": "绑定", "type": "object", "default": {} }, - "title": { - "description": "", - "type": "string", - "default": "" + "required": { + "description": "必填", + "type": "boolean", + "default": false }, - "label": { - "description": "", - "type": "string", - "default": "" + "readonly": { + "description": "只读", + "type": "boolean", + "default": false }, - "lableWidth": { - "description": "", - "type": "number" + "disabled": { + "description": "禁用", + "type": "boolean", + "default": false }, "placeholder": { - "description": "", + "description": "提示文本", + "type": "string" + }, + "title": { + "description": "标题", "type": "string", "default": "" }, - "visible": { - "description": "", - "type": "boolean", - "default": true - }, "displayFormat": { - "description": "", - "type": "string", - "default": "YYYY-MM-DD" + "description": "展示格式", + "type": "enum", + "default": "yyyy-MM-dd" }, - "readonly": { - "type": "string", - "default": false + "maxDate": { + "description": "最大日期", + "type": "string" + }, + "minDate": { + "description": "最小日期", + "type": "string" } }, + "events": [ + "onUpdate:modelValue" + ], "required": [ "type" ], diff --git a/packages/mobile-ui-vue/components/date-time-picker-input/index.ts b/packages/mobile-ui-vue/components/date-time-picker-input/index.ts index 52edd797cc7..bebfdac2b33 100644 --- a/packages/mobile-ui-vue/components/date-time-picker-input/index.ts +++ b/packages/mobile-ui-vue/components/date-time-picker-input/index.ts @@ -1,7 +1,18 @@ import { withInstall } from '@components/common'; import DateTimePickerInputInstallless from './src/date-time-picker-input.component'; +import { propsResolver } from './src/date-time-picker-input.props'; + +const DATE_TIME_PICKER_REGISTERED_NAME = 'datetime-picker'; const DateTimePickerInput = withInstall(DateTimePickerInputInstallless); +DateTimePickerInput.register = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[DATE_TIME_PICKER_REGISTERED_NAME] = DateTimePickerInput; + propsResolverMap[DATE_TIME_PICKER_REGISTERED_NAME] = propsResolver; +}; + export { DateTimePickerInput }; export default DateTimePickerInput; diff --git a/packages/mobile-ui-vue/components/date-time-picker-input/src/date-time-picker-input.props.ts b/packages/mobile-ui-vue/components/date-time-picker-input/src/date-time-picker-input.props.ts index c2c76ae490e..fce39a903db 100644 --- a/packages/mobile-ui-vue/components/date-time-picker-input/src/date-time-picker-input.props.ts +++ b/packages/mobile-ui-vue/components/date-time-picker-input/src/date-time-picker-input.props.ts @@ -2,6 +2,11 @@ import { ExtractPropTypes } from 'vue'; import { buttonEditProps } from '@/components/button-edit'; import { dateTimePickerProps } from '@/components/date-time-picker'; +import { createPropsResolver } from '../../dynamic-resolver'; +import { schemaResolver } from './schema/schema-resolver'; +import { schemaMapper } from './schema/schema-mapper'; +import dateTimePickerInputSchema from './schema/datetime-picker-input.schema.json' + export const DATA_TIME_PICKER_INPUT_NAME = 'FmDateTimePickerInput'; export const dateTimePickerInputProps = { @@ -10,3 +15,8 @@ export const dateTimePickerInputProps = { }; export type DateTimePickerInputProps = ExtractPropTypes; + +export const propsResolver = createPropsResolver( + dateTimePickerInputProps, dateTimePickerInputSchema, schemaMapper, schemaResolver +); + diff --git a/packages/mobile-ui-vue/components/date-time-picker-input/src/schema/datetime-picker-input.schema.json b/packages/mobile-ui-vue/components/date-time-picker-input/src/schema/datetime-picker-input.schema.json new file mode 100644 index 00000000000..62379aa1532 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-time-picker-input/src/schema/datetime-picker-input.schema.json @@ -0,0 +1,89 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/date-picker.schema.json", + "title": "datetime-picker", + "description": "日期时间", + "type": "object", + "properties": { + "id": { + "description": "标识", + "type": "string" + }, + "type": { + "description": "控件类型", + "type": "string", + "default": "textarea" + }, + "appearance": { + "description": "外观", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "binding": { + "description": "绑定", + "type": "object", + "default": {} + }, + "required": { + "description": "必填", + "type": "boolean", + "default": false + }, + "readonly": { + "description": "只读", + "type": "boolean", + "default": false + }, + "disabled": { + "description": "禁用", + "type": "boolean", + "default": false + }, + "placeholder": { + "description": "提示文本", + "type": "string" + }, + "title": { + "description": "标题", + "type": "string", + "default": "" + }, + "displayFormat": { + "description": "展示格式", + "type": "enum", + "default": "yyyy-MM-dd HH:mm:ss" + }, + "maxDate": { + "description": "最大日期", + "type": "string" + }, + "minDate": { + "description": "最小日期", + "type": "string" + }, + "onUpdate:modelValue": { + "description": "值更新事件", + "type": "string" + } + }, + "events": [ + "onUpdate:modelValue" + ], + "required": [ + "type" + ], + "ignore": [ + "id", + "appearance", + "binding", + "visible" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/date-time-picker-input/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/date-time-picker-input/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..46cfbbda3f2 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-time-picker-input/src/schema/schema-mapper.ts @@ -0,0 +1,7 @@ +import { MapperFunction, resolveAppearance } from '@/components/dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance], + ['displayFormat','format'] +]); + diff --git a/packages/mobile-ui-vue/components/date-time-picker-input/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/date-time-picker-input/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..660e1e609e1 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-time-picker-input/src/schema/schema-resolver.ts @@ -0,0 +1,5 @@ +import { DynamicResolver } from "@/components/dynamic-resolver"; + +export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { + return schema; +} diff --git a/packages/mobile-ui-vue/components/form-item/src/schema/form-item.schema.json b/packages/mobile-ui-vue/components/form-item/src/schema/form-item.schema.json index e49a2109836..50535220949 100644 --- a/packages/mobile-ui-vue/components/form-item/src/schema/form-item.schema.json +++ b/packages/mobile-ui-vue/components/form-item/src/schema/form-item.schema.json @@ -41,6 +41,11 @@ "description": "", "type": "object", "default": {} + }, + "visible": { + "description": "", + "type": "boolean", + "default": true } }, diff --git a/packages/mobile-ui-vue/components/input-group/src/schema/input-group.schema.json b/packages/mobile-ui-vue/components/input-group/src/schema/input-group.schema.json index e867f1daace..e32325c6299 100644 --- a/packages/mobile-ui-vue/components/input-group/src/schema/input-group.schema.json +++ b/packages/mobile-ui-vue/components/input-group/src/schema/input-group.schema.json @@ -6,16 +6,16 @@ "type": "object", "properties": { "id": { - "description": "", + "description": "标识", "type": "string" }, "type": { - "description": "", + "description": "控件类型", "type": "string", "default": "input-group" }, "appearance": { - "description": "", + "description": "外观", "type": "object", "properties": { "class": { @@ -28,46 +28,38 @@ "default": {} }, "binding": { - "description": "", + "description": "绑定", "type": "object", "default": {} }, - "onUpdate:modelValue": { - "description": "值变化事件", - "type": "string", - "default": "" - }, - "disable": { - "type": "string", + "required": { + "description": "必填", + "type": "boolean", "default": false }, "readonly": { - "type": "string", + "description": "只读", + "type": "boolean", "default": false }, - "title": { - "description": "", - "type": "string", - "default": "" + "disabled": { + "description": "禁用", + "type": "boolean", + "default": false }, - "label": { - "description": "", - "type": "string", - "default": "" + "placeholder": { + "description": "提示文本", + "type": "string" }, - "lableWidth": { - "description": "", - "type": "number" + "formatValidation": { + "description": "验证类型", + "type": "object", + "default": {} }, - "placeholder": { - "description": "", + "onUpdate:modelValue": { + "description": "值更新事件", "type": "string", "default": "" - }, - "visible": { - "description": "", - "type": "boolean", - "default": true } }, "events": [ @@ -79,6 +71,6 @@ "ignore": [ "id", "appearance", - "visible" + "binding" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/number-input/index.ts b/packages/mobile-ui-vue/components/number-input/index.ts new file mode 100644 index 00000000000..3aba94f6d73 --- /dev/null +++ b/packages/mobile-ui-vue/components/number-input/index.ts @@ -0,0 +1,17 @@ +import { withInstall } from '@components/common'; +import NumberInputInstallless from './src/number-input.component'; +import { propsResolver } from './src/number-input.props'; + +export * from './src/number-input.props'; + +const NUMBER_INPUT_REGISTERED_NAME = 'textarea'; + +const NumberInput = withInstall(NumberInputInstallless); + +NumberInput.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { + componentMap[NUMBER_INPUT_REGISTERED_NAME] = NumberInput; + propsResolverMap[NUMBER_INPUT_REGISTERED_NAME] = propsResolver; +}; + +export { NumberInput }; +export default NumberInput; diff --git a/packages/mobile-ui-vue/components/number-input/src/number-input.component.tsx b/packages/mobile-ui-vue/components/number-input/src/number-input.component.tsx new file mode 100644 index 00000000000..cf790e987a7 --- /dev/null +++ b/packages/mobile-ui-vue/components/number-input/src/number-input.component.tsx @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { defineComponent } from 'vue'; +import { useBem } from '@/components/common'; +import InputGroup from "@/components/input-group"; +import { NUMBER_INPUT_NAME, numberInputProps, NumberInputProps } from './number-input.props'; + +export default defineComponent({ + name: NUMBER_INPUT_NAME, + props: numberInputProps, + setup(props: NumberInputProps) { + const { bem } = useBem(NUMBER_INPUT_NAME); + + return () => ( + + ); + } +}); diff --git a/packages/mobile-ui-vue/components/number-input/src/number-input.props.ts b/packages/mobile-ui-vue/components/number-input/src/number-input.props.ts new file mode 100644 index 00000000000..836ba36b0af --- /dev/null +++ b/packages/mobile-ui-vue/components/number-input/src/number-input.props.ts @@ -0,0 +1,18 @@ +import { ExtractPropTypes } from 'vue'; +import { inputCommonProps } from '@/components/input-group'; +import { createPropsResolver } from '@/components/dynamic-resolver'; +import numberInputSchema from './schema/number-input.schema.json'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; + +export const NUMBER_INPUT_NAME = 'FmNumberInput'; + +export const numberInputProps = { + ...inputCommonProps, + enableNull: { type: Boolean, default: undefined }, + precision: { type: Number, default: 2 } +} as Record; + +export type NumberInputProps = ExtractPropTypes; + +export const propsResolver = createPropsResolver(numberInputProps, numberInputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/textarea/src/schema/input.schema.json b/packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json similarity index 54% rename from packages/mobile-ui-vue/components/textarea/src/schema/input.schema.json rename to packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json index 577a7d531f6..18701d21eb9 100644 --- a/packages/mobile-ui-vue/components/textarea/src/schema/input.schema.json +++ b/packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json @@ -1,21 +1,21 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://farris-design.gitee.io/textarea.schema.json", - "title": "textarea", - "description": "A Farris Input Component", + "title": "number-input", + "description": "数字输入框", "type": "object", "properties": { "id": { - "description": "The unique identifier for a Input Group", + "description": "标识", "type": "string" }, "type": { - "description": "The type string of Input Group component", + "description": "类型", "type": "string", "default": "textarea" }, "appearance": { - "description": "", + "description": "外观", "type": "object", "properties": { "class": { @@ -28,52 +28,57 @@ "default": {} }, "binding": { - "description": "", + "description": "绑定", "type": "object", "default": {} }, + "required": { + "description": "必填", + "type": "boolean", + "default": false + }, "readonly": { - "type": "string", + "description": "只读", + "type": "boolean", "default": false }, - "label": { - "description": "", - "type": "string", - "default": "" + "disabled": { + "description": "禁用", + "type": "boolean", + "default": false }, "placeholder": { - "description": "", + "description": "提示文本", "type": "string", "default": "" }, - "visible": { - "description": "", - "type": "boolean", - "default": true - }, - "rows": { - "description": "", + "precision": { + "description": "精度", "type": "number", - "default": "" + "default": 0 }, - "showCount": { - "description": "", - "type": "boolean", - "default": true + "max": { + "description": "最小值", + "type": "number" }, - "maxLength": { - "description": "", - "type": "number", - "default": 50 + "min": { + "description": "最大值", + "type": "number" + }, + "onUpdate:modelValue": { + "description": "值更新事件", + "type": "string" } }, + "events": [ + "onUpdate:modelValue" + ], "required": [ "type" ], "ignore": [ "id", "appearance", - "binding", - "visible" + "binding" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/number-input/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/number-input/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..acb5af1fe4f --- /dev/null +++ b/packages/mobile-ui-vue/components/number-input/src/schema/schema-mapper.ts @@ -0,0 +1,7 @@ +import { MapperFunction, resolveAppearance } from '@/components/dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance], + ['showCount','showWordLimit'], + ['maxLength','maxlength'] +]); diff --git a/packages/mobile-ui-vue/components/number-input/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/number-input/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..660e1e609e1 --- /dev/null +++ b/packages/mobile-ui-vue/components/number-input/src/schema/schema-resolver.ts @@ -0,0 +1,5 @@ +import { DynamicResolver } from "@/components/dynamic-resolver"; + +export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { + return schema; +} diff --git a/packages/mobile-ui-vue/components/picker-input/index.ts b/packages/mobile-ui-vue/components/picker-input/index.ts index 02d38dfc325..515eb4c1a77 100644 --- a/packages/mobile-ui-vue/components/picker-input/index.ts +++ b/packages/mobile-ui-vue/components/picker-input/index.ts @@ -7,17 +7,17 @@ export * from './src/picker-input.props'; export * from './src/composition/use-picker-input-state'; -const ENUM_FIELD_REGISTERED_NAME = 'enum-field'; +const PICKER_INPUT_REGISTERED_NAME = 'picker'; const PickerInput = withInstall(PickerInputInstallless); PickerInput.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { - componentMap[ENUM_FIELD_REGISTERED_NAME] = PickerInput; - propsResolverMap[ENUM_FIELD_REGISTERED_NAME] = propsResolver; + componentMap[PICKER_INPUT_REGISTERED_NAME] = PickerInput; + propsResolverMap[PICKER_INPUT_REGISTERED_NAME] = propsResolver; }; PickerInput.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record) => { - componentMap[ENUM_FIELD_REGISTERED_NAME] = EnumFieldInputDesign; - propsResolverMap[ENUM_FIELD_REGISTERED_NAME] = propsResolver; + componentMap[PICKER_INPUT_REGISTERED_NAME] = EnumFieldInputDesign; + propsResolverMap[PICKER_INPUT_REGISTERED_NAME] = propsResolver; }; export { PickerInput }; diff --git a/packages/mobile-ui-vue/components/picker-input/src/picker-input.props.ts b/packages/mobile-ui-vue/components/picker-input/src/picker-input.props.ts index 7a91fbf147f..792d41cf765 100644 --- a/packages/mobile-ui-vue/components/picker-input/src/picker-input.props.ts +++ b/packages/mobile-ui-vue/components/picker-input/src/picker-input.props.ts @@ -2,7 +2,7 @@ import { ExtractPropTypes } from 'vue'; import { buttonEditProps } from '@/components/button-edit'; import { pickerProps } from '@/components/picker'; import { createPropsResolver } from '@/components/dynamic-resolver'; -import inputSchema from './schema/enum-field-input.schema.json'; +import pickerInputSchema from './schema/picker-input.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; @@ -15,4 +15,4 @@ export const pickerInputProps = { export type PickerInputProps = ExtractPropTypes; -export const propsResolver = createPropsResolver(pickerInputProps, inputSchema, schemaMapper, schemaResolver); +export const propsResolver = createPropsResolver(pickerInputProps, pickerInputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/picker-input/src/schema/enum-field-input.schema.json b/packages/mobile-ui-vue/components/picker-input/src/schema/picker-input.schema.json similarity index 58% rename from packages/mobile-ui-vue/components/picker-input/src/schema/enum-field-input.schema.json rename to packages/mobile-ui-vue/components/picker-input/src/schema/picker-input.schema.json index 7cf654531f3..96ed7c41d0b 100644 --- a/packages/mobile-ui-vue/components/picker-input/src/schema/enum-field-input.schema.json +++ b/packages/mobile-ui-vue/components/picker-input/src/schema/picker-input.schema.json @@ -1,21 +1,21 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://farris-design.gitee.io/enum-field.schema.json", - "title": "enum-field", - "description": "A Farris Input Component", + "title": "picker", + "description": "A Farris Picker Component", "type": "object", "properties": { "id": { - "description": "The unique identifier for a Input Group", + "description": "标志", "type": "string" }, "type": { - "description": "The type string of Input Group component", + "description": "控件类型", "type": "string", "default": "enum-field" }, "appearance": { - "description": "", + "description": "外观", "type": "object", "properties": { "class": { @@ -28,56 +28,63 @@ "default": {} }, "binding": { - "description": "", + "description": "绑定", "type": "object", "default": {} }, + "required": { + "description": "必填", + "type": "boolean", + "default": false + }, "readonly": { - "type": "string", + "description": "只读", + "type": "boolean", "default": false }, + "disabled": { + "description": "禁用", + "type": "boolean", + "default": false + }, + "placeholder": { + "description": "提示文本", + "type": "string" + }, "title": { - "description": "", + "description": "标题", "type": "string", "default": "" }, - "label": { - "description": "", + "valueField": { + "description": "值字段", "type": "string", - "default": "" + "default": "id" }, - "lableWidth": { - "description": "", - "type": "number" - }, - "visible": { - "description": "", - "type": "boolean", - "default": true + "textField": { + "description": "显示字段", + "type": "string", + "default": "name" }, "data": { - "description": "", + "description": "数据", "type": "array", "default": [] }, - "enableClear": { - "description": "", - "type": "boolean", - "default": false - }, - "editable": { - "description": "", - "type": "boolean", - "default": false + "onUpdate:modelValue": { + "description": "值更新事件", + "type": "string" } }, + "events": [ + "onUpdate:modelValue" + ], "required": [ "type" ], "ignore": [ "id", "appearance", - "binding", - "visible" + "binding" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/register.ts b/packages/mobile-ui-vue/components/register.ts index 7138d16210d..d651ac11ae8 100644 --- a/packages/mobile-ui-vue/components/register.ts +++ b/packages/mobile-ui-vue/components/register.ts @@ -14,6 +14,12 @@ import Listview from './list-view'; import Form from './form'; import FormItem from './form-item'; import InputGroup from './input-group'; +import Textarea from './textarea'; +import NumberInput from './number-input'; +import Switch from './switch'; +import DatePicker from './date-picker-input'; +import DateTimePicker from './date-time-picker-input'; +import Picker from './picker-input'; const componentMap: Record = {}; const propsConverterMap: Record = {}; @@ -35,7 +41,7 @@ function registerComponents() { Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, ContentContainer, FloatContainer, Navbar, Button, ButtonGroup, Listview, - Form, FormItem, InputGroup + Form, FormItem, InputGroup, Textarea, NumberInput, Switch, DatePicker, DateTimePicker, Picker ]; componentsToRegister.forEach((componentToRegister) => { componentToRegister.register(componentMap, propsConverterMap, propConfigsConverterMap, resolverMap); diff --git a/packages/mobile-ui-vue/components/switch/src/schema/switch.schema.json b/packages/mobile-ui-vue/components/switch/src/schema/switch.schema.json index 075e96d7a81..0971b3eeb09 100644 --- a/packages/mobile-ui-vue/components/switch/src/schema/switch.schema.json +++ b/packages/mobile-ui-vue/components/switch/src/schema/switch.schema.json @@ -6,16 +6,16 @@ "type": "object", "properties": { "id": { - "description": "", + "description": "标志", "type": "string" }, "type": { - "description": "", + "description": "控件类型", "type": "string", "default": "switch" }, "appearance": { - "description": "", + "description": "外观", "type": "object", "properties": { "class": { @@ -28,56 +28,41 @@ "default": {} }, "binding": { - "description": "", + "description": "绑定", "type": "object", "default": {} }, - "onUpdate:modelValue": { - "description": "值变化事件", - "type": "string", - "default": "" - }, - "disable": { - "type": "string", + "required": { + "description": "必填", + "type": "boolean", "default": false }, "readonly": { - "type": "string", + "description": "只读", + "type": "boolean", "default": false }, - "title": { - "description": "", - "type": "string", - "default": "" - }, - "label": { - "description": "", - "type": "string", - "default": "" - }, - "lableWidth": { - "description": "", - "type": "number" - }, - "visible": { - "description": "", + "disabled": { + "description": "禁用", "type": "boolean", - "default": true + "default": false }, - "onBackground": { - "description": "", - "type": "string", - "default": "" + "onColor": { + "description": "打开时背景色", + "type": "string" }, - "offBackground": { - "description": "", - "type": "string", - "default": "" + "offColor": { + "description": "关闭时背景色", + "type": "string" }, "size": { - "description": "", - "type": "number", - "default": 22 + "description": "尺寸", + "type": "enum", + "default": "medium" + }, + "onUpdate:modelValue": { + "description": "值更新事件", + "type": "string" } }, "events": [ @@ -89,7 +74,6 @@ "ignore": [ "id", "appearance", - "binding", - "visible" + "binding" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/textarea/src/schema/textarea.schema.json b/packages/mobile-ui-vue/components/textarea/src/schema/textarea.schema.json new file mode 100644 index 00000000000..e7609147997 --- /dev/null +++ b/packages/mobile-ui-vue/components/textarea/src/schema/textarea.schema.json @@ -0,0 +1,88 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/textarea.schema.json", + "title": "textarea", + "description": "多行文本", + "type": "object", + "properties": { + "id": { + "description": "标识", + "type": "string" + }, + "type": { + "description": "控件类型", + "type": "string", + "default": "textarea" + }, + "appearance": { + "description": "外观", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "binding": { + "description": "绑定", + "type": "object", + "default": {} + }, + "required": { + "description": "必填", + "type": "boolean", + "default": false + }, + "readonly": { + "description": "只读", + "type": "boolean", + "default": false + }, + "disabled": { + "description": "禁用", + "type": "boolean", + "default": false + }, + "placeholder": { + "description": "提示文本", + "type": "string" + }, + "maxLength": { + "description": "最大字数", + "type": "number" + }, + "showCount": { + "description": "显示最大字数", + "type": "boolean", + "default": true + }, + "rows": { + "description": "最大行数", + "type": "number" + }, + "autoHeight": { + "description": "自动高度", + "type": "boolean", + "default": false + }, + "onUpdate:modelValue": { + "description": "值更新事件", + "type": "string" + } + }, + "events": [ + "onUpdate:modelValue" + ], + "required": [ + "type" + ], + "ignore": [ + "id", + "appearance", + "binding" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts b/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts index 9472bad5408..48beaf60bcc 100644 --- a/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts +++ b/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts @@ -1,7 +1,7 @@ import { ExtractPropTypes } from 'vue'; import { inputCommonProps } from '@/components/input-group'; import { createPropsResolver } from '@/components/dynamic-resolver'; -import textareaSchema from './schema/input.schema.json'; +import textareaSchema from './schema/textarea.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; -- Gitee From 12f36382b4ce30357d190db1eda0db23e404422a Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Fri, 4 Apr 2025 16:07:13 +0800 Subject: [PATCH 149/153] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8filter?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=94=AF=E6=8C=81=E6=96=87=E6=9C=AC=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E3=80=81=E6=95=B0=E5=AD=97=E7=B1=BB=E5=9E=8B=E3=80=81?= =?UTF-8?q?=E6=95=B0=E5=AD=97=E5=8C=BA=E9=97=B4=E7=B1=BB=E5=9E=8B=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/src/style/mixins/bem.scss | 14 +- .../components/common/src/utils/src/common.ts | 6 +- .../mobile-ui-vue/components/filter/index.ts | 3 +- .../filter/src/components/field.component.tsx | 30 ++++ .../src/components/portal.component.tsx | 0 .../filter/src/compositions/index.ts | 4 + .../filter/src/compositions/type.ts | 48 ++++++- .../filter/src/compositions/use-condition.ts | 135 ++++++++++++++++++ .../compositions/use-filter-panel-state.ts | 46 ++++++ .../src/compositions/use-filter-state.ts | 73 ++++++++++ .../compositions/use-render-field-item.tsx | 97 +++++++++++++ .../filter/src/filter-panel.component.tsx | 52 ++++++- .../filter/src/filter-panel.props.ts | 10 +- .../components/filter/src/filter-panel.scss | 45 ++++++ .../filter/src/filter.component.tsx | 47 +++--- .../components/filter/src/filter.props.ts | 12 +- .../components/filter/src/filter.scss | 15 ++ packages/mobile-ui-vue/components/index.scss | 1 + .../src/composition/use-input-event.ts | 1 + .../input-group/src/input-group.component.tsx | 1 + .../input-group/src/input-group.props.ts | 4 +- .../input-group/src/input-group.scss | 8 +- .../components/lookup/src/lookup-panel.scss | 14 +- .../mobile-ui-vue/components/popup/index.ts | 3 +- .../components/popup/src/popup.props.ts | 8 +- packages/mobile-ui-vue/demos/filter/base.vue | 71 ++++++++- packages/mobile-ui-vue/demos/filter/index.vue | 2 +- 27 files changed, 691 insertions(+), 59 deletions(-) create mode 100644 packages/mobile-ui-vue/components/filter/src/components/field.component.tsx delete mode 100644 packages/mobile-ui-vue/components/filter/src/components/portal.component.tsx create mode 100644 packages/mobile-ui-vue/components/filter/src/compositions/index.ts create mode 100644 packages/mobile-ui-vue/components/filter/src/compositions/use-condition.ts create mode 100644 packages/mobile-ui-vue/components/filter/src/compositions/use-filter-panel-state.ts create mode 100644 packages/mobile-ui-vue/components/filter/src/compositions/use-filter-state.ts create mode 100644 packages/mobile-ui-vue/components/filter/src/compositions/use-render-field-item.tsx diff --git a/packages/mobile-ui-vue/components/common/src/style/mixins/bem.scss b/packages/mobile-ui-vue/components/common/src/style/mixins/bem.scss index 1e7a5ced1fd..3bf74ebb5f9 100644 --- a/packages/mobile-ui-vue/components/common/src/style/mixins/bem.scss +++ b/packages/mobile-ui-vue/components/common/src/style/mixins/bem.scss @@ -108,20 +108,18 @@ $state-prefix: 'is-'; } */ -@mixin e($element, $parent: null) { +@mixin e($element, $inheritParent: false) { $E: $element !global; $selector: &; $currentSelector: ""; $insertSelector: ""; - @if($parent){ - @each $unit in $parent { - $insertSelector: #{$insertSelector + $unit + $element-separator}; - } - } - @each $unit in $element { - $currentSelector: #{$currentSelector + "." + $B + $element-separator + $insertSelector + $unit + ","}; + @if $inheritParent { + $currentSelector: #{$currentSelector + $selector + $element-separator + $unit + ","}; + } @else { + $currentSelector: #{$currentSelector + "." + $B + $element-separator + $insertSelector + $unit + ","}; + } } @if hitAllSpecialNestRule($selector) { diff --git a/packages/mobile-ui-vue/components/common/src/utils/src/common.ts b/packages/mobile-ui-vue/components/common/src/utils/src/common.ts index b6acefce85f..b2be798cc21 100644 --- a/packages/mobile-ui-vue/components/common/src/utils/src/common.ts +++ b/packages/mobile-ui-vue/components/common/src/utils/src/common.ts @@ -64,8 +64,10 @@ export const setValue = (obj: Record, field: string, val: any) => { } if (field.indexOf('.') > 0) { const fieldMap = field.split('.'); - const target = fieldMap.reduce((record, fieldItem) => { - record[fieldItem] = isObject(record[fieldItem]) || {}; + const target = fieldMap.slice(0, -1).reduce((record, fieldItem) => { + if(!isObject(record[fieldItem])) { + record[fieldItem] = {}; + } return record[fieldItem]; }, obj); diff --git a/packages/mobile-ui-vue/components/filter/index.ts b/packages/mobile-ui-vue/components/filter/index.ts index 1665ba73b10..999a8428e0e 100644 --- a/packages/mobile-ui-vue/components/filter/index.ts +++ b/packages/mobile-ui-vue/components/filter/index.ts @@ -1,7 +1,8 @@ import { withInstall, } from '@components/common'; import FilterInstallless from './src/filter.component'; +import { ControlType } from './src/compositions'; const Filter = withInstall(FilterInstallless); -export { Filter }; +export { Filter, ControlType }; export default Filter; diff --git a/packages/mobile-ui-vue/components/filter/src/components/field.component.tsx b/packages/mobile-ui-vue/components/filter/src/components/field.component.tsx new file mode 100644 index 00000000000..19f0065771e --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/src/components/field.component.tsx @@ -0,0 +1,30 @@ +import { useBem } from '@/components/common'; +import { defineComponent } from 'vue'; +import { FILTER_PANEL_NAME } from '../filter-panel.props'; + +export default defineComponent({ + props: { + name: String, + title: String + }, + setup(props, context) { + const { slots } = context; + + const { bem } = useBem(FILTER_PANEL_NAME); + + + return () => ( +
    +
    + { props.title } +
    + +
    +
    +
    + { slots.default && slots.default() } +
    +
    + ); + } +}); diff --git a/packages/mobile-ui-vue/components/filter/src/components/portal.component.tsx b/packages/mobile-ui-vue/components/filter/src/components/portal.component.tsx deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/packages/mobile-ui-vue/components/filter/src/compositions/index.ts b/packages/mobile-ui-vue/components/filter/src/compositions/index.ts new file mode 100644 index 00000000000..29f3fa62385 --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/src/compositions/index.ts @@ -0,0 +1,4 @@ +export * from './type'; +export * from './use-condition'; +export * from './use-filter-panel-state'; +export * from './use-render-field-item'; diff --git a/packages/mobile-ui-vue/components/filter/src/compositions/type.ts b/packages/mobile-ui-vue/components/filter/src/compositions/type.ts index 5ec6048dd5e..476a532cb63 100644 --- a/packages/mobile-ui-vue/components/filter/src/compositions/type.ts +++ b/packages/mobile-ui-vue/components/filter/src/compositions/type.ts @@ -1,12 +1,48 @@ -type FieldControl = { - controltype: string - [key: string]: any +import { FilterCondition } from "@/components/common"; + +export enum ControlType { + InputGroup = 'input-group', + DatePicker = 'date-picker', + DateTimePicker = 'datetime-picker', + Number = 'number', + NumberRange = 'number-range', + List = 'combo-list', + RadioGroup = 'radio-group', + Lookup = 'lookup', } export type FieldConfig = { - id: string - labelCode: string code: string name: string - control: FieldControl + controlType: ControlType + editor: Record +}; + +export type ConfirmPayload = { + data: Record, + conditions: FilterCondition[] +} + +export type ChangePayload = { + code: string, + value: any, + data: Record +} + +export type SearchPayload = { + value: string, + conditions: FilterCondition[] +} + +export interface FilterPanelEmits { + change: (payload: ChangePayload) => void + confirm: (payload: ConfirmPayload) => void +} + +export interface FilterEmits { + 'modelValue:searchValue': (payload: string) => void, + 'modelValue': (payload: string) => void, + change: (payload: ChangePayload) => void + confirm: (payload: ConfirmPayload) => void + search: (payload: SearchPayload) => void }; diff --git a/packages/mobile-ui-vue/components/filter/src/compositions/use-condition.ts b/packages/mobile-ui-vue/components/filter/src/compositions/use-condition.ts new file mode 100644 index 00000000000..03b90d3d45b --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/src/compositions/use-condition.ts @@ -0,0 +1,135 @@ +import { FilterCondition, FilterCompareType, FilterExpressType, FilterRelation, isDef, isString } from "@/components/common"; +import { ControlType, FieldConfig } from "./type"; +export const userCondition = () => { + const ConditionTemplate: FilterCondition = { + FilterField: '', + Compare: FilterCompareType.Like, + Value: '', + Relation: FilterRelation.And, + Expresstype: FilterExpressType.Value, + Lbracket: '', + Rbracket: '', + }; + + + const addBrackets = (conditions: FilterCondition[])=>{ + const conditionsLength = conditions.length; + if(conditionsLength === 0) { + return; + } + const firstCondition = conditions[0]; + const lastCondition = conditions[conditions.length - 1]; + firstCondition.Lbracket = firstCondition.Lbracket + '('; + lastCondition.Rbracket = lastCondition.Rbracket + ')'; + }; + + const setEndConditionRelation = (conditions: FilterCondition[], relation: FilterRelation)=>{ + const lastCondition = conditions[conditions.length - 1]; + if(lastCondition){ + lastCondition.Relation = relation; + } + }; + + const getCondition = (config: FieldConfig, value: any) => { + if(!isDef(value)) { + return []; + } + const { code, controlType } = config; + const conditions: FilterCondition[] = []; + switch (controlType) { + case ControlType.DatePicker: + case ControlType.DateTimePicker: + case ControlType.Number: + case ControlType.RadioGroup:{ + const condition = { ...ConditionTemplate, FilterField: code, Value: value, Compare: FilterCompareType.Equal }; + conditions.push(condition); + break; + } + case ControlType.NumberRange:{ + const { start, end } = value; + + const startCondition = { ...ConditionTemplate, FilterField: code, Value: start, Compare: FilterCompareType.GreaterOrEqual }; + const endCondition = { ...ConditionTemplate, FilterField: code, Value: end, Compare: FilterCompareType.LessOrEqual }; + + if(isDef(start) && isDef(end)) { + startCondition.Lbracket = '('; + endCondition.Rbracket = ')'; + conditions.push(startCondition); + conditions.push(endCondition); + } else if(isDef(start)){ + conditions.push(startCondition); + } else { + conditions.push(endCondition); + } + break; + } + case ControlType.Lookup:{ + break; + } + case ControlType.List:{ + break; + } + default:{ + const condition = { ...ConditionTemplate, FilterField: code, Value: value }; + conditions.push(condition); + break; + } + + } + return conditions; + }; + + const getConditions = (configs: FieldConfig[], data: Record): FilterCondition[] => { + const conditions: FilterCondition[] = []; + + configs.map(config => { + const { code } = config; + const value = data[code]; + const condition = getCondition(config, value); + conditions.push(...condition); + }); + + setEndConditionRelation(conditions, FilterRelation.Empty); + addBrackets(conditions); + return conditions; + }; + + const getSearchConditions = (searchFields: string | string[], value: string) => { + if(!searchFields) { + return []; + } + const searchFieldsMap = isString(searchFields) ? searchFields.split(',') : searchFields; + const searchFieldsLength = searchFieldsMap.length; + + const conditions = searchFieldsMap.map((field, index)=>{ + return { + ...ConditionTemplate, + Value: value, + FilterField: field, + Relation: index === searchFieldsLength - 1 ? FilterRelation.Empty : FilterRelation.Or + }; + }); + + addBrackets(conditions); + + return conditions; + }; + + const contactConditions = (firstConditions: FilterCondition[], lastConditions: FilterCondition[])=>{ + if(firstConditions.length === 0) { + return lastConditions; + } else if(lastConditions.length === 0) { + return firstConditions; + } + + setEndConditionRelation(firstConditions, FilterRelation.And); + + return [...firstConditions, ...lastConditions]; + }; + + return { + getConditions, + getSearchConditions, + contactConditions + }; +}; diff --git a/packages/mobile-ui-vue/components/filter/src/compositions/use-filter-panel-state.ts b/packages/mobile-ui-vue/components/filter/src/compositions/use-filter-panel-state.ts new file mode 100644 index 00000000000..3348291182d --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/src/compositions/use-filter-panel-state.ts @@ -0,0 +1,46 @@ +import { computed, reactive, watch } from "vue"; +import { FilterPanelProps } from "../filter-panel.props"; +import { userCondition } from "./use-condition"; + +export const useFilterPanelState = (props: FilterPanelProps)=>{ + const filterData = reactive({}); + + const resetData = ()=>{ + Object.keys(filterData).forEach(key => { + delete filterData[key]; + }); + }; + + const getModelValue = (name: string)=>{ + return props.modelValue ? props.modelValue[name] : undefined; + }; + + const initFilterData = ()=>{ + props.configs.map(config=>{ + const { code } = config; + filterData[code] = getModelValue(code); + }); + }; + + watch(()=> [props.modelValue, props.configs], initFilterData, { immediate: true }); + + const { getConditions } = userCondition(); + const filterConditions = computed(()=>{ + return getConditions(props.configs, filterData); + }); + + const getFilterPanelState = ()=>{ + return { + data: filterData, + conditions: filterConditions.value + }; + }; + + return { + filterData, + filterConditions, + resetData, + getFilterPanelState + }; + +}; diff --git a/packages/mobile-ui-vue/components/filter/src/compositions/use-filter-state.ts b/packages/mobile-ui-vue/components/filter/src/compositions/use-filter-state.ts new file mode 100644 index 00000000000..f14420dbedc --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/src/compositions/use-filter-state.ts @@ -0,0 +1,73 @@ +import { computed, onMounted, reactive, ref, SetupContext, shallowRef, watch } from "vue"; +import { userCondition } from "./use-condition"; +import { FilterProps } from "../filter.props"; +import { ChangePayload, ConfirmPayload, FilterEmits } from "./type"; +import { FilterCondition } from "@/components/common"; + +export const useFilterState = (props: FilterProps, context: SetupContext)=>{ + const { emit } = context; + + const showFilterPanel = ref(false); + + let filterConditions: FilterCondition[] = []; + let searchConditions: FilterCondition[] = []; + + const filterPanelRef = shallowRef(); + onMounted(()=>{ + // 如果存在初始条件 + if(filterPanelRef.value) { + const { conditions } = filterPanelRef.value.getFilterPanelState() || {}; + conditions && (filterConditions = conditions); + } + }); + + const { getSearchConditions, contactConditions } = userCondition(); + + + const searchValue = ref(props.searchValue); + + const updateSearchConditions = ()=>{ + searchConditions = getSearchConditions(props.searchFields, searchValue.value); + }; + + watch(()=> props.searchValue, ()=>{ + searchValue.value = props.searchValue; + updateSearchConditions(); + }, { immediate: true }); + + const handleSearch = (value: string)=>{ + searchValue.value = value; + + updateSearchConditions(); + const contactedConditions = contactConditions(filterConditions, searchConditions); + emit('search', { conditions: contactedConditions, value: searchValue.value }); + + emit('modelValue:searchValue', value); + }; + + const handleConfirm = (value: ConfirmPayload)=>{ + showFilterPanel.value = false; + + const { conditions, data } = value; + filterConditions = conditions; + + const contactedConditions = contactConditions(filterConditions, searchConditions); + + emit('confirm', { conditions: contactedConditions, data }); + }; + + const handleChange = (value: ChangePayload)=>{ + emit('change', value); + }; + + return { + searchValue, + searchConditions, + filterPanelRef, + showFilterPanel, + handleSearch, + handleChange, + handleConfirm + }; + +}; diff --git a/packages/mobile-ui-vue/components/filter/src/compositions/use-render-field-item.tsx b/packages/mobile-ui-vue/components/filter/src/compositions/use-render-field-item.tsx new file mode 100644 index 00000000000..d64ff833a84 --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/src/compositions/use-render-field-item.tsx @@ -0,0 +1,97 @@ +import { InputGroup } from "@/components/input-group"; +import { ControlType, FieldConfig, FilterPanelEmits } from "./type"; +import { getValue, setValue, useBem } from "@/components/common"; +import { FILTER_PANEL_NAME } from "../filter-panel.props"; +import { SetupContext } from "vue"; + +export const useRenderFieldItem = (filterData: Record, context: SetupContext) => { + const { emit } = context; + + const { bem } = useBem(FILTER_PANEL_NAME); + + const handleChange = (code: string, value: any) => { + setValue(filterData, code, value); + emit('change', { code, value, data: filterData }); + }; + + const renderInput = (inputProps = {}) => { + return ( + + ); + }; + + const renderInputGroup = (config: FieldConfig) =>{ + const { code, editor = {} } = config; + const inputProps = { + ...editor, + modelValue: getValue(code, filterData), + onChange: (value: any) => handleChange(code, value) + }; + + return renderInput(inputProps); + }; + + const renderNumber = (config: FieldConfig) => { + const { code, editor = {} } = config; + const inputProps = { + ...editor, + type: 'number', + modelValue: getValue(code, filterData), + onChange: (value: any) => handleChange(code, value) + }; + + return renderInput(inputProps); + }; + + const renderNumberRange = (config: FieldConfig) => { + const { code } = config; + const startCode = `${code}.start`; + const endCode = `${code}.end`; + + return ( +
    + {renderNumber({...config, code: startCode})} + + {renderNumber({...config, code: endCode})} +
    + ); + }; + + const renderFieldItem = (config: FieldConfig) => { + const { controlType } = config; + switch (controlType) { + case ControlType.DatePicker: + + break; + case ControlType.DateTimePicker: + + break; + case ControlType.Number: + return renderNumber(config); + break; + case ControlType.NumberRange: + return renderNumberRange(config); + break; + case ControlType.List: + + break; + case ControlType.RadioGroup: + + break; + case ControlType.Lookup: + + break; + default: + return renderInputGroup(config); + } + }; + + return { + renderFieldItem + }; + +}; diff --git a/packages/mobile-ui-vue/components/filter/src/filter-panel.component.tsx b/packages/mobile-ui-vue/components/filter/src/filter-panel.component.tsx index bbd2273640b..2b797eee385 100644 --- a/packages/mobile-ui-vue/components/filter/src/filter-panel.component.tsx +++ b/packages/mobile-ui-vue/components/filter/src/filter-panel.component.tsx @@ -1,19 +1,63 @@ -import { defineComponent } from 'vue'; +import { computed, defineComponent, SetupContext, watch } from 'vue'; import { useBem } from '@/components/common'; +import ButtonGroup from '@/components/button-group'; import { FILTER_PANEL_NAME, filterPanelProps } from './filter-panel.props'; +import { FieldConfig, FilterPanelEmits, useFilterPanelState, useRenderFieldItem } from './compositions'; +import FieldComponent from './components/field.component'; export default defineComponent({ name: FILTER_PANEL_NAME, props: filterPanelProps, - emits: [''], - setup(props, context) { + setup(props, context: SetupContext) { + const { emit, expose } = context; const { bem } = useBem(FILTER_PANEL_NAME); + const { filterData, filterConditions, resetData, getFilterPanelState } = useFilterPanelState(props); + + expose({ getFilterPanelState }); + + /* content */ + const fieldConfigs = computed(() => { + return props.configs; + }); + const { renderFieldItem } = useRenderFieldItem(filterData, context); + const getFieldSlots = (config: FieldConfig)=>{ + return { + default: () => renderFieldItem(config) + }; + }; + const renerContent = () => { + return ( +
    + {fieldConfigs.value.map(config => { + return ; + })} +
    + ); + }; + + /* footer */ + const handleConfirm = ()=>{ + emit('confirm', { data: filterData, conditions: filterConditions.value }); + }; + const buttonItems = [ + { text: '重置', onClick: resetData}, + { text: '确定', plain: true, onClick: handleConfirm} + ]; + + const renderFooter = () => { + return ( +
    + +
    + ); + }; return () => (
    - FILTER_PANEL + {renerContent()} + {renderFooter()}
    ); } diff --git a/packages/mobile-ui-vue/components/filter/src/filter-panel.props.ts b/packages/mobile-ui-vue/components/filter/src/filter-panel.props.ts index fb8120887e9..6a7e52b2dc1 100644 --- a/packages/mobile-ui-vue/components/filter/src/filter-panel.props.ts +++ b/packages/mobile-ui-vue/components/filter/src/filter-panel.props.ts @@ -1,9 +1,15 @@ -import { ExtractPropTypes } from 'vue'; +import { ExtractPropTypes, PropType } from 'vue'; +import { PopupPosition } from '@/components/popup'; +import { FieldConfig } from './compositions/type'; export const FILTER_PANEL_NAME = "FmFilterPanel"; export const filterPanelProps = { - + modelValue: { type: Object as PropType>, default: ()=>({}) }, + + configs: { type: Array as PropType, default: () => [] }, + + position: { type: String as PropType, default: PopupPosition.left }, }; export type FilterPanelProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/filter/src/filter-panel.scss b/packages/mobile-ui-vue/components/filter/src/filter-panel.scss index 87bf00568e6..317bf32379b 100644 --- a/packages/mobile-ui-vue/components/filter/src/filter-panel.scss +++ b/packages/mobile-ui-vue/components/filter/src/filter-panel.scss @@ -1,2 +1,47 @@ @use '../../common/src/style/mixins/index.scss' as *; +@include b(filter-panel){ + height: 100%; + display: flex; + flex-direction: column; + padding: 8px 16px; + @include e(content) { + flex: 1; + } + @include e(footer) { + padding: 8px 16px; + } + + @include e(field){ + @include not-first-child-margin(16px, top); + @include e(title, true){ + display: flex; + align-items: center; + justify-content: space-between; + line-height: 22px; + } + @include e(content, true){ + padding-top: 12px; + } + @include e(range, true){ + display: flex; + align-items: center; + @include e(splitter, true){ + width: 8px; + margin: 0 8px; + border: 1px solid #999; + } + } + } + + + @include e(input) { + padding: 6px 8px; + line-height: 18px; + font-size: 13px; + color: var(--fm-primary-color); + background: var(--fm-background); + border-radius: var(--fm-radius-md); + overflow: hidden; + } +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/filter/src/filter.component.tsx b/packages/mobile-ui-vue/components/filter/src/filter.component.tsx index 6539cd93436..218daa9df04 100644 --- a/packages/mobile-ui-vue/components/filter/src/filter.component.tsx +++ b/packages/mobile-ui-vue/components/filter/src/filter.component.tsx @@ -1,45 +1,58 @@ -import { defineComponent, ref } from 'vue'; +import { computed, defineComponent, ref, SetupContext } from 'vue'; import { useBem } from '@/components/common'; -import { FILTER_NAME, filterProps } from './filter.props'; -import FilterPanel from './filter-panel.component'; import Icon from '@/components/icon'; import Search from '@/components/search'; import Popup from '@/components/popup'; +import { FILTER_NAME, filterProps } from './filter.props'; +import FilterPanel from './filter-panel.component'; +import { FilterEmits } from './compositions'; +import { useFilterState } from './compositions/use-filter-state'; export default defineComponent({ name: FILTER_NAME, props: filterProps, - emits: ['click'], - setup(props, context) { + setup(props, context: SetupContext) { const { bem } = useBem(FILTER_NAME); - const showFilterPopup = ref(false); - const handleClickPortalIcon = ()=>{ - showFilterPopup.value = true; + + const { searchValue, filterPanelRef, showFilterPanel, handleSearch, handleChange, handleConfirm } = useFilterState(props, context); + + const handleIconClick = ()=>{ + showFilterPanel.value = true; }; const renderFilterPortal = ()=>{ return (
    -
    - -
    -
    - -
    + +
    ); }; + + + const filterPanelProps = computed(()=>{ + return { + modelValue: props.modelValue, + configs: props.configs, + position: props.position, + }; + }); const renderFilterPopup = ()=>{ return ( - + ); }; diff --git a/packages/mobile-ui-vue/components/filter/src/filter.props.ts b/packages/mobile-ui-vue/components/filter/src/filter.props.ts index 7e4de38e013..d523c995ce4 100644 --- a/packages/mobile-ui-vue/components/filter/src/filter.props.ts +++ b/packages/mobile-ui-vue/components/filter/src/filter.props.ts @@ -1,8 +1,16 @@ -import { ExtractPropTypes } from 'vue'; +import { ExtractPropTypes, PropType } from 'vue'; +import { filterPanelProps } from './filter-panel.props'; + export const FILTER_NAME = "FmFilter"; export const filterProps = { - + ...filterPanelProps, + + placeholder: { type: String, default: '' }, + + searchValue: { type: String, default: '' }, + + searchFields:{ type: [String, Array] as PropType, default: '' } }; export type FilterProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/filter/src/filter.scss b/packages/mobile-ui-vue/components/filter/src/filter.scss index 87bf00568e6..2d3f9236ba0 100644 --- a/packages/mobile-ui-vue/components/filter/src/filter.scss +++ b/packages/mobile-ui-vue/components/filter/src/filter.scss @@ -1,2 +1,17 @@ @use '../../common/src/style/mixins/index.scss' as *; +@use './filter-panel.scss'; +@include b(filter){ + @include e(portal) { + display: flex; + align-items: center; + padding: 8px 16px; + @include e(icon, true) { + font-size: 20px; + } + @include e(search, true) { + flex: 1; + padding: 0 0 0 8px; + } + } +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/index.scss b/packages/mobile-ui-vue/components/index.scss index 6eb23ef1ffb..dc287913497 100644 --- a/packages/mobile-ui-vue/components/index.scss +++ b/packages/mobile-ui-vue/components/index.scss @@ -34,6 +34,7 @@ @use './lookup/src/lookup.scss'; @use './search/src/search.scss'; @use './filter/src/filter.scss'; + @use './page-container/src/page-container.scss'; @use './page-body-container/src/page-body-container.scss'; @use './page-header-container/src/page-header-container.scss'; diff --git a/packages/mobile-ui-vue/components/input-group/src/composition/use-input-event.ts b/packages/mobile-ui-vue/components/input-group/src/composition/use-input-event.ts index e3c15ed0527..353ce8cfe8b 100644 --- a/packages/mobile-ui-vue/components/input-group/src/composition/use-input-event.ts +++ b/packages/mobile-ui-vue/components/input-group/src/composition/use-input-event.ts @@ -42,6 +42,7 @@ export function useInputEvent(props: InputProps, context: SetupContext, state: I const handleValueChange = (value: string | number) => { if (changed) { + changed = false; updateInnerValue(value); const modelValue = getModelValue(innerValue.value); updateValue(modelValue); diff --git a/packages/mobile-ui-vue/components/input-group/src/input-group.component.tsx b/packages/mobile-ui-vue/components/input-group/src/input-group.component.tsx index 818b4556f52..292eb1adb46 100644 --- a/packages/mobile-ui-vue/components/input-group/src/input-group.component.tsx +++ b/packages/mobile-ui-vue/components/input-group/src/input-group.component.tsx @@ -118,6 +118,7 @@ export default defineComponent({ const bodyClass = computed(() => { const className = [bem('body')]; props.showBorder && className.push(bem('body', 'border')); + props.bodyClass && className.push(props.bodyClass); return className; }); diff --git a/packages/mobile-ui-vue/components/input-group/src/input-group.props.ts b/packages/mobile-ui-vue/components/input-group/src/input-group.props.ts index 8116d20d776..bd08263d37c 100644 --- a/packages/mobile-ui-vue/components/input-group/src/input-group.props.ts +++ b/packages/mobile-ui-vue/components/input-group/src/input-group.props.ts @@ -36,7 +36,9 @@ export const inputCommonProps = { formatter: { type: Function as PropType<(v: string | number) => string | number> }, - maxlength: { type: Number, default: undefined } + maxlength: { type: Number, default: undefined }, + + bodyClass: { type: String, default: '' }, }; const inputNumberProps = { diff --git a/packages/mobile-ui-vue/components/input-group/src/input-group.scss b/packages/mobile-ui-vue/components/input-group/src/input-group.scss index ccc93d470c9..a88f7777506 100644 --- a/packages/mobile-ui-vue/components/input-group/src/input-group.scss +++ b/packages/mobile-ui-vue/components/input-group/src/input-group.scss @@ -19,6 +19,8 @@ display: flex; align-items: center; min-height: 24px; + color: var(--fm-input-group-color); + font-size: var(--fm-input-group-size); &--border { border: 1px solid var(--fm-input-group-border-color); padding: 4px 8px; @@ -33,11 +35,11 @@ padding: 0; border: 0; resize: none; + color: inherit; + font-size: inherit; + outline: none; line-height: inherit; background-color: transparent; - color: var(--fm-input-group-color); - font-size: var(--fm-input-group-size); - outline: none; &::placeholder { color: var(--fm-input-group-sub-color); } diff --git a/packages/mobile-ui-vue/components/lookup/src/lookup-panel.scss b/packages/mobile-ui-vue/components/lookup/src/lookup-panel.scss index d93ac7ba260..748938b5c74 100644 --- a/packages/mobile-ui-vue/components/lookup/src/lookup-panel.scss +++ b/packages/mobile-ui-vue/components/lookup/src/lookup-panel.scss @@ -15,17 +15,17 @@ @include e(header) { background-color: var(--fm-background-white); - @include e(search, header) { + @include e(search, true) { @include hairline(bottom) } - @include e(selected-wrapper, header) { + @include e(selected-wrapper, true) { display: flex; padding: 6px 16px; overflow: auto; } - @include e(selected-item, header) { + @include e(selected-item, true) { font-size: 14px; line-height: 20px; word-break: keep-all; @@ -91,7 +91,7 @@ display: flex; flex-direction: column; - @include e(footer-left, popup-selected) { + @include e(footer-left, true) { color: var(--fm-primary-color); } } @@ -105,7 +105,7 @@ @include e(empty) { padding: 12px 16px; - @include e(text, empty) { + @include e(text, true) { text-align: center; color: var(--fm-text-color-light); } @@ -119,7 +119,7 @@ overflow: auto; @include hairline('bottom', var(--fm-border-color)); - @include e(item, breadcrumb) { + @include e(item, true) { display: flex; align-items: center; color: var(--fm-primary-color); @@ -129,7 +129,7 @@ color: var(--fm-text-color-light); } } - @include e(icon, breadcrumb) { + @include e(icon, true) { font-size: 10px; padding-left: 4px; } diff --git a/packages/mobile-ui-vue/components/popup/index.ts b/packages/mobile-ui-vue/components/popup/index.ts index 57a8867d413..026d398aeea 100644 --- a/packages/mobile-ui-vue/components/popup/index.ts +++ b/packages/mobile-ui-vue/components/popup/index.ts @@ -1,8 +1,9 @@ import { withInstall } from '@components/common'; import PopupInstallless from './src/popup.component'; +import { PopupPosition } from './src/popup.props'; const Popup = withInstall(PopupInstallless); export * from './src/popup.props'; -export { Popup }; +export { Popup, PopupPosition }; export default Popup; diff --git a/packages/mobile-ui-vue/components/popup/src/popup.props.ts b/packages/mobile-ui-vue/components/popup/src/popup.props.ts index 059226d3217..3a49ab2608c 100644 --- a/packages/mobile-ui-vue/components/popup/src/popup.props.ts +++ b/packages/mobile-ui-vue/components/popup/src/popup.props.ts @@ -18,6 +18,12 @@ import { ExtractPropTypes, PropType, TeleportProps } from 'vue'; export const POPUP_NAME = 'fm-popup'; +export enum PopupPosition { + right = 'right', + left = 'left', + center = 'center' +} + export const popupProps = { show: { type: Boolean, default: false }, @@ -25,7 +31,7 @@ export const popupProps = { height: { type: String, default: '' }, - position: { type: String, default: 'center' }, + position: { type: String as PropType, default: PopupPosition.center }, duration: { type: Number, default: undefined }, diff --git a/packages/mobile-ui-vue/demos/filter/base.vue b/packages/mobile-ui-vue/demos/filter/base.vue index e67c3f14a51..5f4ca5067b1 100644 --- a/packages/mobile-ui-vue/demos/filter/base.vue +++ b/packages/mobile-ui-vue/demos/filter/base.vue @@ -1,8 +1,73 @@ diff --git a/packages/mobile-ui-vue/demos/filter/index.vue b/packages/mobile-ui-vue/demos/filter/index.vue index 0289592a08f..34bea0429a0 100644 --- a/packages/mobile-ui-vue/demos/filter/index.vue +++ b/packages/mobile-ui-vue/demos/filter/index.vue @@ -1,5 +1,5 @@ -- Gitee From fc13d8030e78bd8296c46ae200a18ab0b37a4e46 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Sat, 5 Apr 2025 11:21:23 +0800 Subject: [PATCH 150/153] =?UTF-8?q?fix:=201=E3=80=81=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E8=80=81=E8=BE=93=E5=85=A5=E6=8E=A7=E4=BB=B6DOM=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E7=9A=84=E5=85=BC=E5=AE=B9=E5=A4=84=E7=90=86=EF=BC=9B?= =?UTF-8?q?2=E3=80=81=E5=90=8C=E6=AD=A5PC=E7=AB=AFForm=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=9E=84=E9=80=A0=E9=80=BB=E8=BE=91=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/mobile-render/package.json | 4 - .../component-converters/datebox-converter.ts | 38 ++++++ .../enum-field-converter.ts | 25 ++++ .../converters/component-converters/index.ts | 7 +- .../component-converters/input-converter.ts | 7 +- .../multi-textbox-converter.ts | 25 ++++ .../numeric-box-converter.ts | 24 ++++ .../switch-field-converter.ts | 24 ++++ .../component-converters/textbox-converter.ts | 10 +- .../form/converters/converter-factory.ts | 10 +- .../metadata/form/entity-schema-query.ts | 18 +-- .../form/normalizers/form-item-normalizer.ts | 3 - .../entity-store-config-builder.ts | 3 +- .../form/form-array-store-config-builder.ts | 68 +++++----- .../form/form-control-config-builder.ts | 45 ++++--- .../form/form-store-config-builder.ts | 36 +++--- .../form/validation-rule-creator.ts | 117 +++++++++++++++--- 17 files changed, 360 insertions(+), 104 deletions(-) create mode 100644 packages/mobile-render/src/services/metadata/form/converters/component-converters/datebox-converter.ts create mode 100644 packages/mobile-render/src/services/metadata/form/converters/component-converters/enum-field-converter.ts create mode 100644 packages/mobile-render/src/services/metadata/form/converters/component-converters/multi-textbox-converter.ts create mode 100644 packages/mobile-render/src/services/metadata/form/converters/component-converters/numeric-box-converter.ts create mode 100644 packages/mobile-render/src/services/metadata/form/converters/component-converters/switch-field-converter.ts diff --git a/packages/mobile-render/package.json b/packages/mobile-render/package.json index 4d4e8df8e10..2f167a8cdc7 100644 --- a/packages/mobile-render/package.json +++ b/packages/mobile-render/package.json @@ -30,7 +30,6 @@ "vue-router": "^4.3.0" }, "devDependencies": { - "@farris/cli": "workspace:^", "@rushstack/eslint-patch": "^1.8.0", "@vue/eslint-config-prettier": "^9.0.0", "@vue/eslint-config-typescript": "^13.0.0", @@ -68,11 +67,8 @@ "shelljs": "^0.8.4", "typescript": "^4.6.4", "vite": "^4.1.4", - "vite-plugin-md": "^0.20.0", "vite-plugin-banner": "^0.8.0", "vite-svg-loader": "^4.0.0", - "vitepress": "1.0.0-alpha.8", - "vitepress-theme-demoblock": "1.4.2", "vitest": "^0.29.2", "vue-tsc": "^1.2.0" } diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/datebox-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/datebox-converter.ts new file mode 100644 index 00000000000..f9fc549982f --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/datebox-converter.ts @@ -0,0 +1,38 @@ +import { JsonUtil } from '../../../../../utils/index'; +import { InputConverter } from "./input-converter"; + +/** + * 日期选择框转换器 + */ +class DateBoxConverter extends InputConverter { + + /** + * 执行转换 + */ + public convert(input: any): void { + const originInput = JsonUtil.cloneJsonObj(input); + super.convert(input); + + const editorType = this.getEditorType(originInput.showType); + input.editor = Object.assign(input.editor, { + type: editorType, + title: undefined, + displayFormat: originInput.format, + maxDate: originInput.maxValue, + minDate: originInput.minValue + }); + } + + /** + * 根据显示类型获取编辑器类型 + */ + private getEditorType(showType: string) { + if (showType === 'datetime') { + return 'datetime-picker'; + } else { + return 'date-picker'; + } + } +} + +export { DateBoxConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/enum-field-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/enum-field-converter.ts new file mode 100644 index 00000000000..d1bcac80906 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/enum-field-converter.ts @@ -0,0 +1,25 @@ +import { JsonUtil } from '../../../../../utils/index'; +import { InputConverter } from "./input-converter"; + +/** + * 枚举选择框转换器 + */ +class EnumFieldConverter extends InputConverter { + + /** + * 执行转换 + */ + public convert(input: any): void { + const originInput = JsonUtil.cloneJsonObj(input); + super.convert(input); + input.editor = Object.assign(input.editor, { + type: 'picker', + title: undefined, + data: originInput.enumData, + valueField: originInput.valueField, + textField: originInput.textField + }); + } +} + +export { EnumFieldConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/index.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/index.ts index 56616ac3116..ff1345376c0 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/index.ts +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/index.ts @@ -3,6 +3,11 @@ export * from './page-content-container-converter'; export * from './button-converter'; export * from './button-group-converter'; export * from './listview-converter'; + export * from './input-converter'; export * from './textbox-converter'; - +export * from './multi-textbox-converter'; +export * from './numeric-box-converter'; +export * from './switch-field-converter'; +export * from './datebox-converter'; +export * from './enum-field-converter'; diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/input-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/input-converter.ts index 9f58c57aac8..180bc5e7ac2 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/input-converter.ts +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/input-converter.ts @@ -26,7 +26,12 @@ class InputConverter extends ComponentConverter { input.type = 'form-item'; input.label = originInput.title; input.binding = originInput.binding; - input.editor = originInput; + input.editor = { + required: originInput.require, + readonly: originInput.readonly, + disabled: originInput.disable, + placeholder: originInput.placeholder + }; } } diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/multi-textbox-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/multi-textbox-converter.ts new file mode 100644 index 00000000000..34e898537ca --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/multi-textbox-converter.ts @@ -0,0 +1,25 @@ +import { JsonUtil } from '../../../../../utils/index'; +import { InputConverter } from "./input-converter"; + +/** + * 多行文本输入框转换器 + */ +class MultiTextBoxConverter extends InputConverter { + + /** + * 执行转换 + */ + public convert(input: any): void { + const originInput = JsonUtil.cloneJsonObj(input); + super.convert(input); + input.editor = Object.assign(input.editor, { + type: 'textarea', + maxLength: originInput.maxLength, + showCount: originInput.showWordLimit, + rows: undefined, + autoSize: originInput.autoSize + }); + } +} + +export { MultiTextBoxConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/numeric-box-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/numeric-box-converter.ts new file mode 100644 index 00000000000..6065875f5d8 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/numeric-box-converter.ts @@ -0,0 +1,24 @@ +import { JsonUtil } from '../../../../../utils/index'; +import { InputConverter } from "./input-converter"; + +/** + * 数值输入框转换器 + */ +class NumericBoxConverter extends InputConverter { + + /** + * 执行转换 + */ + public convert(input: any): void { + const originInput = JsonUtil.cloneJsonObj(input); + super.convert(input); + input.editor = Object.assign(input.editor, { + type: 'number-input', + precision: originInput.precision, + max: originInput.maxValue, + min: originInput.minValue + }); + } +} + +export { NumericBoxConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/switch-field-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/switch-field-converter.ts new file mode 100644 index 00000000000..a50e4167676 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/switch-field-converter.ts @@ -0,0 +1,24 @@ +import { JsonUtil } from '../../../../../utils/index'; +import { InputConverter } from "./input-converter"; + +/** + * 开关转换器 + */ +class SwitchFieldConverter extends InputConverter { + + /** + * 执行转换 + */ + public convert(input: any): void { + const originInput = JsonUtil.cloneJsonObj(input); + super.convert(input); + input.editor = Object.assign(input.editor, { + type: 'switch', + onColor: undefined, + offColor: undefined, + size: undefined + }); + } +} + +export { SwitchFieldConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/textbox-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/textbox-converter.ts index 8b5df4e3a73..9c060fca030 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/textbox-converter.ts +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/textbox-converter.ts @@ -1,7 +1,8 @@ +import { JsonUtil } from '../../../../../utils/index'; import { InputConverter } from "./input-converter"; /** - * 按钮组件转换器 + * 单行文本输入框转换器 */ class TextBoxConverter extends InputConverter { @@ -9,8 +10,13 @@ class TextBoxConverter extends InputConverter { * 执行转换 */ public convert(input: any): void { + const originInput = JsonUtil.cloneJsonObj(input); super.convert(input); - input.editor.type = 'input-group'; + input.editor = Object.assign(input.editor, { + type: 'input-group', + maxLength: originInput.maxLength, + formatValidation: undefined + }); } } diff --git a/packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts b/packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts index 03246b603ea..b7f82f815f5 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts +++ b/packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts @@ -3,8 +3,8 @@ import { ConverterContext } from './converter-context'; import { SchemasConverter } from './schemas-converter'; import { ViewModelsConverter } from './viewodels-converter'; import { - ComponentConverter, PageContentContainerConverter, ButtonConverter, ButtonGroupConverter, - ListViewConverter, TextBoxConverter + ComponentConverter, PageContentContainerConverter, ButtonConverter, ButtonGroupConverter, ListViewConverter, + TextBoxConverter, MultiTextBoxConverter, NumericBoxConverter, SwitchFieldConverter, DateBoxConverter, EnumFieldConverter } from './component-converters'; type ComponentConverterConstructor = new (context: ConverterContext) => ComponentConverter; @@ -67,7 +67,13 @@ class ConverterFactory { this.cmpConverterCtors.set('Button', ButtonConverter); this.cmpConverterCtors.set('ButtonGroup', ButtonGroupConverter); this.cmpConverterCtors.set('ListView', ListViewConverter); + this.cmpConverterCtors.set('TextBox', TextBoxConverter); + this.cmpConverterCtors.set('MultiTextbox', MultiTextBoxConverter); + this.cmpConverterCtors.set('NumericBox', NumericBoxConverter); + this.cmpConverterCtors.set('SwitchField', SwitchFieldConverter); + this.cmpConverterCtors.set('DateBox', DateBoxConverter); + this.cmpConverterCtors.set('EnumField', EnumFieldConverter); } } diff --git a/packages/mobile-render/src/services/metadata/form/entity-schema-query.ts b/packages/mobile-render/src/services/metadata/form/entity-schema-query.ts index 217844f2c8f..2c3440545ef 100644 --- a/packages/mobile-render/src/services/metadata/form/entity-schema-query.ts +++ b/packages/mobile-render/src/services/metadata/form/entity-schema-query.ts @@ -110,16 +110,18 @@ class EntitySchemaQuery { if (fieldSchema.$type === 'ComplexField') { // 关联字段 - if (fieldSchema.type.$type === 'EntityType') { - const assoFieldSchemas = fieldSchema.type.fields; - this.collectFieldSchemas(assoFieldSchemas, wrappedEntitySchema); - } + // if (fieldSchema.type.$type === 'EntityType') { + // const assoFieldSchemas = fieldSchema.type.fields; + // this.collectFieldSchemas(assoFieldSchemas, wrappedEntitySchema); + // } // 业务字段 - if (fieldSchema.type.$type === 'ObjectType') { - const udtFieldSchemas = fieldSchema.type.fields; - this.collectFieldSchemas(udtFieldSchemas, wrappedEntitySchema); - } + // if (fieldSchema.type.$type === 'ObjectType') { + // const udtFieldSchemas = fieldSchema.type.fields; + // this.collectFieldSchemas(udtFieldSchemas, wrappedEntitySchema); + // } + const assoOrUdtFieldSchemas = fieldSchema.type.fields; + this.collectFieldSchemas(assoOrUdtFieldSchemas, wrappedEntitySchema); } } diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/form-item-normalizer.ts b/packages/mobile-render/src/services/metadata/form/normalizers/form-item-normalizer.ts index 01d244ef382..5618197f299 100644 --- a/packages/mobile-render/src/services/metadata/form/normalizers/form-item-normalizer.ts +++ b/packages/mobile-render/src/services/metadata/form/normalizers/form-item-normalizer.ts @@ -21,9 +21,6 @@ class FormItemNormalizer extends ComponentNormalizer { public normalizeEditor(editor: any, viewModelId: string) { const editorSchema = schemaMap[editor.type]; super.normalize(editor, editorSchema, viewModelId); - - // 标记binding为双向绑定 - editor.binding.direction = 'TwoWay'; } } diff --git a/packages/mobile-render/src/services/module-config/entity-store-config-builder.ts b/packages/mobile-render/src/services/module-config/entity-store-config-builder.ts index c1e7bd8b5b5..3af353f8f82 100644 --- a/packages/mobile-render/src/services/module-config/entity-store-config-builder.ts +++ b/packages/mobile-render/src/services/module-config/entity-store-config-builder.ts @@ -56,7 +56,8 @@ class EntityStoreConfigBuilder { const fieldConfigs = this.buildEntityFieldConfigs(fields, entities); const entityConfig = { idKey, - fields: fieldConfigs + fields: fieldConfigs, + code: entitySchemaNode.code }; return entityConfig; } diff --git a/packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts b/packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts index b7ff429bae0..7cf9181aac0 100644 --- a/packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts +++ b/packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts @@ -23,9 +23,15 @@ class FormArrayStoreConfigBuilder { * 构造配置 */ public build(viewModelNode: any): FormArrayStoreConfig { - const stateConfig = this.buildStateConfig(viewModelNode); + const vmComponentNode = this.formMetaQuery.getVmComponentByVmId(viewModelNode.id); + if (!vmComponentNode) { + throw new Error(`Component(viewModel=${viewModelNode.id}) not found`); + } + + const stateConfig = this.buildStateConfig(viewModelNode, vmComponentNode); const storeConfig: FormArrayStoreConfig = { id: viewModelNode.code + '-form-array-store', + displayName: viewModelNode.name, bindingPath: viewModelNode.bindTo, state: stateConfig }; @@ -36,12 +42,7 @@ class FormArrayStoreConfigBuilder { /** * 获取表单状态配置 */ - private buildStateConfig(viewModelNode: any): FormArrayStateConfig { - const vmComponentNode = this.getVmComponentNode(viewModelNode); - if (!vmComponentNode) { - throw new Error(`Component(viewModel=${viewModelNode.id}) not found`); - } - + private buildStateConfig(viewModelNode: any, vmComponentNode: any): FormArrayStateConfig { const controlConfigs = this.buildControlConfigs(viewModelNode, vmComponentNode); const stateConfig: FormArrayStateConfig = { controls: controlConfigs @@ -53,13 +54,19 @@ class FormArrayStoreConfigBuilder { * 构造控件配置集合 */ private buildControlConfigs(viewModelNode: any, vmComponentNode: any): FormControlConfig[] { - const wrappedControlNodes = this.collectWrappedControlNodes(vmComponentNode); - const controlConfigBuilder = new FormControlConfigBuilder(); + // 模拟批量编辑场景 + const mockVmComponentNode = this.getMockVmComponentNode(viewModelNode); + if (!mockVmComponentNode) { + return []; + } + + const formGroupNodes = this.collectFormGroupNodes(mockVmComponentNode); + const controlConfigBuilder = new FormControlConfigBuilder(this.formMetaQuery); const controlConfigs: FormControlConfig[] = []; - wrappedControlNodes.forEach((wrappedControlNode) => { - const controlNode = wrappedControlNode.component; - const controlConfig = controlConfigBuilder.build(viewModelNode, controlNode.editor); + formGroupNodes.forEach((formGroupNode) => { + const controlNode = formGroupNode; + const controlConfig = controlConfigBuilder.build(viewModelNode, controlNode); controlConfigs.push(controlConfig); }); @@ -69,40 +76,35 @@ class FormArrayStoreConfigBuilder { /** * 获取列表对应卡片的表单组件 */ - private getVmComponentNode(viewModelNode: any): any { - const listVmComponentNode = this.formMetaQuery.getVmComponentByVmId(viewModelNode.id); - - // 对用对应卡片的组件模拟批量编辑场景 - const vmComponentNodes = this.formMetaQuery.getVmComponents(); - const cardVmComponentNode = vmComponentNodes.find((vmComponentNode) => { - return vmComponentNode !== listVmComponentNode && vmComponentNode.bindTo === listVmComponentNode.bindTo; + private getMockVmComponentNode(listViewModelNode: any): any { + const allViewModels = this.formMetaQuery.getViewModels() as any[]; + const cardViewModelNode = allViewModels.find((viewModelNode) => { + return viewModelNode !== listViewModelNode && viewModelNode.bindTo === listViewModelNode.bindTo; }); - - if (!listVmComponentNode && !cardVmComponentNode) { - throw new Error(`Component(viewModel=${viewModelNode.id}) not found`); - } - return cardVmComponentNode ? cardVmComponentNode : listVmComponentNode; + const cardVmComponentNode = this.formMetaQuery.getVmComponentByVmId(cardViewModelNode.id); + return cardVmComponentNode; } /** - * 搜集当前VM组件下的所有输入控件 + * 搜集表单控件集合 */ - private collectWrappedControlNodes(vmComponentNode: any): any[] { + public collectFormGroupNodes(parentVmComponentNode: any): any[] { const wrappedComponentNodes = this.formMetaQuery.getWrappedComponents(); - const wrappedControlNode = [] as any[]; + const formGroupNodes = [] as any[]; wrappedComponentNodes.forEach((wrappedComponentNode) => { - if (wrappedComponentNode.viewModelComponent !== vmComponentNode) { + const { component, viewModelComponent } = wrappedComponentNode; + if (viewModelComponent !== parentVmComponentNode) { return; } - - const componentType = wrappedComponentNode.component.type; - if (componentType === 'form-item') { - wrappedControlNode.push(wrappedComponentNode); + if (component.type !== 'form-item') { + return; } + + formGroupNodes.push(component); }); - return wrappedControlNode; + return formGroupNodes; } } diff --git a/packages/mobile-render/src/services/module-config/form/form-control-config-builder.ts b/packages/mobile-render/src/services/module-config/form/form-control-config-builder.ts index d85d8103b86..efa89816412 100644 --- a/packages/mobile-render/src/services/module-config/form/form-control-config-builder.ts +++ b/packages/mobile-render/src/services/module-config/form/form-control-config-builder.ts @@ -1,4 +1,5 @@ import { FormControlConfig } from '@farris/devkit-vue'; +import { FormMetadataQuery } from '../../metadata/index'; import { ValidationRuleCreator } from './validation-rule-creator'; /** @@ -6,6 +7,11 @@ import { ValidationRuleCreator } from './validation-rule-creator'; */ class FormControlConfigBuilder { + /** + * 表单元数据查询 + */ + private formMetaQuery: FormMetadataQuery; + /** * 验证规则创建器 */ @@ -14,7 +20,8 @@ class FormControlConfigBuilder { /** * 构造函数 */ - constructor() { + constructor(formMetaQuery: FormMetadataQuery) { + this.formMetaQuery = formMetaQuery; this.validationRuleCreator = new ValidationRuleCreator(); } @@ -23,10 +30,11 @@ class FormControlConfigBuilder { */ public build(viewModelNode: any, controlNode: any): FormControlConfig { const name = controlNode.id; + const displayName = this.getDisplayName(controlNode); const bindingType = this.getBindingType(controlNode); const bindingPath = this.getBindingPath(viewModelNode, controlNode); const validationRules = this.getValidationRules(controlNode); - const controlConfig = { name, bindingType, bindingPath, validationRules }; + const controlConfig = { name, displayName, bindingType, bindingPath, validationRules }; return controlConfig; } @@ -35,36 +43,45 @@ class FormControlConfigBuilder { * 获取绑定类型 */ private getBindingType(controlNode: any): string { - const bindingType = controlNode.binding.type; - if (bindingType === 'EntityField') { + const { type } = controlNode.binding; + if (type === 'EntityField') { return 'EntityState'; - } else if (bindingType === 'Variable') { + } else if (type === 'Variable') { return 'UIState'; + } else { + throw new Error(`BindingType(type=${type}) unsupported`); } - - throw new Error(`BindingType(type=${bindingType}) unsupported`); } /** * 获取绑定路径 */ private getBindingPath(viewModelNode: any, controlNode: any): string { - const { bindTo } = viewModelNode; - - // Form和FormArray已经记录了实体路径,FormControl上使用相对短路径 - if (bindTo === '/') { - return controlNode.binding.path; + const { type, path } = controlNode.binding; + if (type === 'EntityField') { + const { bindTo } = viewModelNode; + return bindTo === '/' ? path : path.replace(bindTo, ''); + } else if (type === 'Variable') { + return path; } else { - return controlNode.binding.path.replace(bindTo, ''); + throw new Error(`BindingType(type=${type}) unsupported`); } } /** - * 获取绑定路径 + * 获取验证规则 */ private getValidationRules(controlNode: any) { return this.validationRuleCreator.createRules(controlNode); } + + /** + * 获取控件显示名称 + */ + private getDisplayName(controlNode: any) { + const displayName = controlNode.type === 'form-group' ? controlNode.label: controlNode.title; + return displayName; + } } export { FormControlConfigBuilder }; diff --git a/packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts b/packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts index e4c73b30000..303e51ced71 100644 --- a/packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts +++ b/packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts @@ -23,9 +23,11 @@ class FormStoreConfigBuilder { * 构造配置 */ public build(viewModelNode: any): FormStoreConfig { - const stateConfig = this.buildStateConfig(viewModelNode); + const vmComponentNode = this.formMetaQuery.getVmComponentByVmId(viewModelNode.id); + const stateConfig = this.buildStateConfig(viewModelNode, vmComponentNode); const storeConfig: FormStoreConfig = { id: viewModelNode.code + '-form-store', + displayName: viewModelNode.name, bindingPath: viewModelNode.bindTo, state: stateConfig }; @@ -36,8 +38,7 @@ class FormStoreConfigBuilder { /** * 获取表单状态配置 */ - private buildStateConfig(viewModelNode: any): FormStateConfig { - const vmComponentNode = this.formMetaQuery.getVmComponentByVmId(viewModelNode.id); + private buildStateConfig(viewModelNode: any, vmComponentNode: any): FormStateConfig { if (!vmComponentNode) { throw new Error(`Component(viewModel=${viewModelNode.id}) not found`); } @@ -54,13 +55,13 @@ class FormStoreConfigBuilder { * 构造控件配置集合 */ private buildControlConfigs(viewModelNode: any, vmComponentNode: any): FormControlConfig[] { - const wrappedControlNodes = this.collectWrappedControlNodes(vmComponentNode); - const controlConfigBuilder = new FormControlConfigBuilder(); + const formGroupNodes = this.collectFormGroupNodes(vmComponentNode); + const controlConfigBuilder = new FormControlConfigBuilder(this.formMetaQuery); const controlConfigs: FormControlConfig[] = []; - wrappedControlNodes.forEach((wrappedControlNode) => { - const controlNode = wrappedControlNode.component; - const controlConfig = controlConfigBuilder.build(viewModelNode, controlNode.editor); + formGroupNodes.forEach((formGroupNode) => { + const controlNode = formGroupNode; + const controlConfig = controlConfigBuilder.build(viewModelNode, controlNode); controlConfigs.push(controlConfig); }); @@ -68,23 +69,24 @@ class FormStoreConfigBuilder { } /** - * 搜集当前VM组件下的所有输入控件 + * 搜集表单控件集合 */ - private collectWrappedControlNodes(vmComponentNode: any): any[] { + public collectFormGroupNodes(parentVmComponentNode: any): any[] { const wrappedComponentNodes = this.formMetaQuery.getWrappedComponents(); - const wrappedControlNode = [] as any[]; + const formGroupNodes = [] as any[]; wrappedComponentNodes.forEach((wrappedComponentNode) => { - if (wrappedComponentNode.viewModelComponent !== vmComponentNode) { + const { component, viewModelComponent } = wrappedComponentNode; + if (viewModelComponent !== parentVmComponentNode) { return; } - - const componentType = wrappedComponentNode.component.type; - if (componentType === 'form-item') { - wrappedControlNode.push(wrappedComponentNode); + if (component.type !== 'form-item') { + return; } + + formGroupNodes.push(component); }); - return wrappedControlNode; + return formGroupNodes; } } diff --git a/packages/mobile-render/src/services/module-config/form/validation-rule-creator.ts b/packages/mobile-render/src/services/module-config/form/validation-rule-creator.ts index 342e9a0a595..0b656ee9574 100644 --- a/packages/mobile-render/src/services/module-config/form/validation-rule-creator.ts +++ b/packages/mobile-render/src/services/module-config/form/validation-rule-creator.ts @@ -1,7 +1,7 @@ import { ValidationRule, RequiredValidationRule, MaxLengthValidationRule, MinLengthValidationRule, MaxValueValidationRule, MinValueValidationRule, MaxDateValidationRule, MinDateValidationRule, - PatternValidationRule, CustomFunctionValidationRule, + PatternValidationRule, CustomFunctionValidationRule, ObjectUtil, StringUtil } from '@farris/devkit-vue'; /** @@ -33,91 +33,141 @@ class ValidationRuleCreator { } /** - * 最大长度 + * 必填 */ public required(controlNode: any): RequiredValidationRule | undefined { - if (!controlNode.require) { + const { required } = controlNode.editor; + if (!this.isValidValue(required)) { return; } - return { name: 'required' }; + if (!required) { + return; + } + + const displayName = this.getDisplayName(controlNode); + const message = `请输入'${displayName}'`; + + return { name: 'required', message }; } /** * 最大长度 */ public maxLength(controlNode: any): MaxLengthValidationRule | undefined { - if (!controlNode.maxLength) { + const { type, maxLength } = controlNode.editor; + + // 数值控件上的maxLength不视为校验规则 + if (type === 'number-input') { return; } - return { name: 'maxLength', maxLength: controlNode.maxLength }; + if (!this.isValidValue(maxLength)) { + return; + } + + const displayName = this.getDisplayName(controlNode); + const message = `'${displayName}'的值不应大于${maxLength}个字符`; + + return { name: 'maxLength', maxLength, message }; } /** * 最小长度 */ public minLength(controlNode: any): MinLengthValidationRule | undefined { - if (!controlNode.minLength) { + const { type, minLength } = controlNode.editor; + + // 数值控件上的minLength不视为校验规则 + if (type === 'number-input') { return; } - return { name: 'minLength', minLength: controlNode.minLength }; + if (!this.isValidValue(minLength)) { + return; + } + + const displayName = this.getDisplayName(controlNode); + const message = `'${displayName}'的值不应小于${minLength}个字符`; + + return { name: 'minLength', minLength, message }; } /** * 最大值 */ public maxValue(controlNode: any): MaxValueValidationRule | undefined { - if (!controlNode.maxValue) { + const { max: maxValue } = controlNode.editor; + if (!this.isValidValue(maxValue)) { return; } - return { name: 'maxValue', maxValue: controlNode.maxValue }; + const displayName = this.getDisplayName(controlNode); + const message = `'${displayName}'的值不应大于${maxValue}`; + + return { name: 'maxValue', maxValue, message }; } /** * 最小值 */ public minValue(controlNode: any): MinValueValidationRule | undefined { - if (!controlNode.minValue) { + const { min: minValue } = controlNode.editor; + if (!this.isValidValue(minValue)) { return; } - return { name: 'minValue', minValue: controlNode.minValue }; + const displayName = this.getDisplayName(controlNode); + const message = `'${displayName}'的值不应小于${minValue}`; + + return { name: 'minValue', minValue: minValue, message }; } /** * 最大日期 */ public maxDate(controlNode: any): MaxDateValidationRule | undefined { - if (!controlNode.maxDate) { + const { maxDate } = controlNode.editor; + if (!this.isValidValue(maxDate)) { return; } - return { name: 'maxDate', maxDate: controlNode.maxDate }; + const displayName = this.getDisplayName(controlNode); + const message = `'${displayName}'的值不应晚于${maxDate}`; + + return { name: 'maxDate', maxDate, message }; } /** * 最小日期 */ public minDate(controlNode: any): MinDateValidationRule | undefined { - if (!controlNode.minDate) { + const { minDate } = controlNode.editor; + if (!this.isValidValue(minDate)) { return; } - return { name: 'minDate', minDate: controlNode.minDate }; + const displayName = this.getDisplayName(controlNode); + const message = `'${displayName}'的值不应早于${minDate}`; + + return { name: 'minDate', minDate, message }; } /** * 正则表达式 */ public pattern(controlNode: any): PatternValidationRule | undefined { - if (!controlNode.formatValidation) { + const { formatValidation } = controlNode.editor; + if (!ObjectUtil.isObject(formatValidation)) { return; } - return { name: 'pattern', pattern: controlNode.expression }; + const { type, expression, message } = formatValidation; + if (type === 'none') { + return; + } + + return { name: 'pattern', pattern: expression, message: message }; } /** @@ -126,6 +176,37 @@ class ValidationRuleCreator { public customFunction(controlNode: any): CustomFunctionValidationRule | null { return null; } + + /** + * 是否是合法规则值 + */ + private isValidValue(value: any): boolean { + + // 空值,不校验 + if (value === null || value === undefined) { + return false; + } + + // 对象类型,不校验 + if (ObjectUtil.isObject(value) === true) { + return false; + } + + // 自定义的表达式不校验 + if (StringUtil.isString(value) && value.includes('viewModel')) { + return false; + } + + return true; + } + + /** + * 获取显示名称 + */ + private getDisplayName(controlNode: any): string { + const displayName = controlNode.type === 'form-group' ? controlNode.label : controlNode.title; + return displayName; + } } export { ValidationRuleCreator }; -- Gitee From e1cf8d77a3e2351e8e61d47561edbd0a8dae9c2b Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Sat, 5 Apr 2025 14:35:11 +0800 Subject: [PATCH 151/153] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8picker?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=BB=84=E4=BB=B6=E8=B0=83=E6=95=B4=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E7=BB=93=E6=9E=84=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/composition/use-button-edit-props.ts | 2 +- .../components/date-picker-input/index.ts | 21 --- .../src/date-picker-input.component.tsx | 60 --------- .../src/date-picker-input.props.ts | 20 --- .../components/date-picker-panel/index.ts | 9 ++ .../src/composition/index.ts | 0 .../src/composition/use-date-columns.ts | 10 +- .../src/date-picker-panel.component.tsx | 49 +++++++ .../src/date-picker-panel.props.ts | 34 +++++ .../src/date-picker-panel.scss} | 0 .../components/date-picker/index.ts | 14 +- .../date-picker/src/date-picker.component.tsx | 91 +++++-------- .../date-picker/src/date-picker.props.ts | 40 ++---- .../designer/date-picker.design.component.tsx | 6 +- .../src/designer/use-designer-rules.ts | 0 .../src/property-config/date-format.ts | 0 .../date-picker.property-config.ts | 0 .../src/schema/schema-mapper.ts | 0 .../src/schema/schema-resolver.ts | 0 .../src/schema/schema.json | 0 .../date-time-picker-input/index.ts | 7 - .../src/date-time-picker-input.component.tsx | 45 ------- .../src/date-time-picker-input.props.ts | 12 -- .../date-time-picker-panel/index.ts | 9 ++ .../src/composition/index.ts | 0 .../src/composition/use-date-state.ts | 6 +- .../src/composition/use-date-time-value.ts | 4 +- .../src/composition/use-time-state.ts | 6 +- .../src/date-time-picker-panel.component.tsx | 68 ++++++++++ .../src/date-time-picker-panel.props.ts | 35 +++++ .../src/date-time-picker-panel.scss} | 0 .../components/date-time-picker/index.ts | 6 +- .../src/date-time-picker.component.tsx | 115 +++++----------- .../src/date-time-picker.props.ts | 35 +---- .../designer-canvas/src/components/maps.ts | 6 +- .../compositions/use-render-field-item.tsx | 11 ++ packages/mobile-ui-vue/components/index.scss | 2 +- packages/mobile-ui-vue/components/index.ts | 40 ++---- .../src/composition/use-input-event.ts | 18 +-- .../src/composition/use-input-state.ts | 3 + .../src/composition/use-lookup-state.ts | 6 +- .../composition/use-picker-group-context.ts | 2 +- .../components/picker-input/index.ts | 24 ---- .../src/composition/use-picker-input-state.ts | 42 ------ .../src/picker-input.component.tsx | 45 ------- .../picker-input/src/picker-input.props.ts | 18 --- .../components/picker-panel/index.ts | 11 ++ .../src/components/column.component.tsx | 4 +- .../src/components/column.props.ts | 0 .../src/composition/index.ts | 4 +- .../src/composition/use-column-touch.ts | 0 .../src/composition/use-columns.ts | 4 +- .../composition/use-picker-panel-context.ts} | 4 +- .../src/composition/use-picker-panel-state.ts | 35 +++++ .../src/picker-panel.component.tsx | 98 ++++++++++++++ .../picker-panel/src/picker-panel.props.ts | 30 +++++ .../picker-panel/src/picker-panel.scss | 76 +++++++++++ .../src/types/index.ts | 4 +- .../mobile-ui-vue/components/picker/index.ts | 19 ++- .../src/composition/use-picker-state.ts | 55 ++++---- .../enum-field-input.design.component.tsx | 9 +- .../src/designer/use-designer-rules.ts | 0 .../picker/src/picker.component.tsx | 127 ++++-------------- .../components/picker/src/picker.props.ts | 34 ++--- .../components/picker/src/picker.scss | 76 ----------- .../enum-field-input.property-config.ts | 0 .../src/schema/enum-field-input.schema.json | 0 .../src/schema/schema-mapper.ts | 0 .../src/schema/schema-resolver.ts | 0 .../components/time-picker-input/index.ts | 7 - .../src/time-picker-input.component.tsx | 45 ------- .../src/time-picker-input.props.ts | 14 -- .../components/time-picker-panel/index.ts | 9 ++ .../src/composition/index.ts | 0 .../src/composition/use-time-columns.ts | 13 +- .../src/time-picker-panel.component.tsx | 49 +++++++ .../src/time-picker-panel.props.ts | 34 +++++ .../src/time-picker-panel.scss | 0 .../components/time-picker/index.ts | 2 - .../time-picker/src/time-picker.component.tsx | 86 +++++------- .../time-picker/src/time-picker.props.ts | 36 ++--- .../mobile-ui-vue/demos/date-picker/basic.vue | 6 +- .../demos/date-picker/formatter.vue | 4 +- .../mobile-ui-vue/demos/date-picker/index.vue | 3 - .../mobile-ui-vue/demos/date-picker/input.vue | 6 +- .../demos/date-picker/min-max.vue | 8 +- .../mobile-ui-vue/demos/date-picker/type.vue | 6 +- .../demos/date-time-picker/basic.vue | 5 +- .../demos/date-time-picker/formatter.vue | 4 +- .../demos/date-time-picker/input.vue | 5 +- .../demos/date-time-picker/max&min.vue | 4 +- .../demos/date-time-picker/type.vue | 5 +- packages/mobile-ui-vue/demos/filter/base.vue | 4 +- .../mobile-ui-vue/demos/form/control-type.vue | 12 +- packages/mobile-ui-vue/demos/picker/basic.vue | 4 +- .../demos/picker/child-column.vue | 6 +- packages/mobile-ui-vue/demos/picker/group.vue | 11 +- packages/mobile-ui-vue/demos/picker/input.vue | 6 +- .../demos/picker/muti-column.vue | 4 +- .../mobile-ui-vue/demos/time-picker/basic.vue | 6 +- .../demos/time-picker/formatter.vue | 4 +- .../mobile-ui-vue/demos/time-picker/index.vue | 2 +- .../mobile-ui-vue/demos/time-picker/input.vue | 5 +- .../demos/time-picker/min-max.vue | 7 +- .../mobile-ui-vue/demos/time-picker/type.vue | 6 +- 105 files changed, 954 insertions(+), 985 deletions(-) delete mode 100644 packages/mobile-ui-vue/components/date-picker-input/index.ts delete mode 100644 packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.component.tsx delete mode 100644 packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.props.ts create mode 100644 packages/mobile-ui-vue/components/date-picker-panel/index.ts rename packages/mobile-ui-vue/components/{date-picker => date-picker-panel}/src/composition/index.ts (100%) rename packages/mobile-ui-vue/components/{date-picker => date-picker-panel}/src/composition/use-date-columns.ts (93%) create mode 100644 packages/mobile-ui-vue/components/date-picker-panel/src/date-picker-panel.component.tsx create mode 100644 packages/mobile-ui-vue/components/date-picker-panel/src/date-picker-panel.props.ts rename packages/mobile-ui-vue/components/{date-time-picker/src/date-time-picker.scss => date-picker-panel/src/date-picker-panel.scss} (100%) rename packages/mobile-ui-vue/components/{date-picker-input => date-picker}/src/designer/date-picker.design.component.tsx (91%) rename packages/mobile-ui-vue/components/{date-picker-input => date-picker}/src/designer/use-designer-rules.ts (100%) rename packages/mobile-ui-vue/components/{date-picker-input => date-picker}/src/property-config/date-format.ts (100%) rename packages/mobile-ui-vue/components/{date-picker-input => date-picker}/src/property-config/date-picker.property-config.ts (100%) rename packages/mobile-ui-vue/components/{date-picker-input => date-picker}/src/schema/schema-mapper.ts (100%) rename packages/mobile-ui-vue/components/{date-picker-input => date-picker}/src/schema/schema-resolver.ts (100%) rename packages/mobile-ui-vue/components/{date-picker-input => date-picker}/src/schema/schema.json (100%) delete mode 100644 packages/mobile-ui-vue/components/date-time-picker-input/index.ts delete mode 100644 packages/mobile-ui-vue/components/date-time-picker-input/src/date-time-picker-input.component.tsx delete mode 100644 packages/mobile-ui-vue/components/date-time-picker-input/src/date-time-picker-input.props.ts create mode 100644 packages/mobile-ui-vue/components/date-time-picker-panel/index.ts rename packages/mobile-ui-vue/components/{date-time-picker => date-time-picker-panel}/src/composition/index.ts (100%) rename packages/mobile-ui-vue/components/{date-time-picker => date-time-picker-panel}/src/composition/use-date-state.ts (71%) rename packages/mobile-ui-vue/components/{date-time-picker => date-time-picker-panel}/src/composition/use-date-time-value.ts (93%) rename packages/mobile-ui-vue/components/{date-time-picker => date-time-picker-panel}/src/composition/use-time-state.ts (85%) create mode 100644 packages/mobile-ui-vue/components/date-time-picker-panel/src/date-time-picker-panel.component.tsx create mode 100644 packages/mobile-ui-vue/components/date-time-picker-panel/src/date-time-picker-panel.props.ts rename packages/mobile-ui-vue/components/{picker-input/src/picker-input.scss => date-time-picker-panel/src/date-time-picker-panel.scss} (100%) delete mode 100644 packages/mobile-ui-vue/components/picker-input/index.ts delete mode 100644 packages/mobile-ui-vue/components/picker-input/src/composition/use-picker-input-state.ts delete mode 100644 packages/mobile-ui-vue/components/picker-input/src/picker-input.component.tsx delete mode 100644 packages/mobile-ui-vue/components/picker-input/src/picker-input.props.ts create mode 100644 packages/mobile-ui-vue/components/picker-panel/index.ts rename packages/mobile-ui-vue/components/{picker => picker-panel}/src/components/column.component.tsx (92%) rename packages/mobile-ui-vue/components/{picker => picker-panel}/src/components/column.props.ts (100%) rename packages/mobile-ui-vue/components/{picker => picker-panel}/src/composition/index.ts (43%) rename packages/mobile-ui-vue/components/{picker => picker-panel}/src/composition/use-column-touch.ts (100%) rename packages/mobile-ui-vue/components/{picker => picker-panel}/src/composition/use-columns.ts (95%) rename packages/mobile-ui-vue/components/{picker/src/composition/use-picker-context.ts => picker-panel/src/composition/use-picker-panel-context.ts} (84%) create mode 100644 packages/mobile-ui-vue/components/picker-panel/src/composition/use-picker-panel-state.ts create mode 100644 packages/mobile-ui-vue/components/picker-panel/src/picker-panel.component.tsx create mode 100644 packages/mobile-ui-vue/components/picker-panel/src/picker-panel.props.ts create mode 100644 packages/mobile-ui-vue/components/picker-panel/src/picker-panel.scss rename packages/mobile-ui-vue/components/{picker => picker-panel}/src/types/index.ts (91%) rename packages/mobile-ui-vue/components/{picker-input => picker}/src/designer/enum-field-input.design.component.tsx (91%) rename packages/mobile-ui-vue/components/{picker-input => picker}/src/designer/use-designer-rules.ts (100%) rename packages/mobile-ui-vue/components/{picker-input => picker}/src/property-config/enum-field-input.property-config.ts (100%) rename packages/mobile-ui-vue/components/{picker-input => picker}/src/schema/enum-field-input.schema.json (100%) rename packages/mobile-ui-vue/components/{picker-input => picker}/src/schema/schema-mapper.ts (100%) rename packages/mobile-ui-vue/components/{picker-input => picker}/src/schema/schema-resolver.ts (100%) delete mode 100644 packages/mobile-ui-vue/components/time-picker-input/index.ts delete mode 100644 packages/mobile-ui-vue/components/time-picker-input/src/time-picker-input.component.tsx delete mode 100644 packages/mobile-ui-vue/components/time-picker-input/src/time-picker-input.props.ts create mode 100644 packages/mobile-ui-vue/components/time-picker-panel/index.ts rename packages/mobile-ui-vue/components/{time-picker => time-picker-panel}/src/composition/index.ts (100%) rename packages/mobile-ui-vue/components/{time-picker => time-picker-panel}/src/composition/use-time-columns.ts (90%) create mode 100644 packages/mobile-ui-vue/components/time-picker-panel/src/time-picker-panel.component.tsx create mode 100644 packages/mobile-ui-vue/components/time-picker-panel/src/time-picker-panel.props.ts create mode 100644 packages/mobile-ui-vue/components/time-picker-panel/src/time-picker-panel.scss diff --git a/packages/mobile-ui-vue/components/button-edit/src/composition/use-button-edit-props.ts b/packages/mobile-ui-vue/components/button-edit/src/composition/use-button-edit-props.ts index 85e0b32b083..0db4a07b91c 100644 --- a/packages/mobile-ui-vue/components/button-edit/src/composition/use-button-edit-props.ts +++ b/packages/mobile-ui-vue/components/button-edit/src/composition/use-button-edit-props.ts @@ -1,7 +1,7 @@ import { computed, ref, watch } from "vue"; import { ButtonEditProps } from "../button-edit.props"; -export const useButtonEditProps = (props: Omit)=>{ +export const useButtonEditProps = (props: Omit)=>{ const showPopup = ref(false); watch(()=>props.show, (newValue)=>{ diff --git a/packages/mobile-ui-vue/components/date-picker-input/index.ts b/packages/mobile-ui-vue/components/date-picker-input/index.ts deleted file mode 100644 index ec026ee8f75..00000000000 --- a/packages/mobile-ui-vue/components/date-picker-input/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { withInstall } from '@components/common'; -import DatePickerInputInstallless from './src/date-picker-input.component'; -import DatePickerDesign from './src/designer/date-picker.design.component'; -import { propsResolver } from './src/date-picker-input.props'; - -const DATE_PICKER_REGISTERED_NAME = 'date-picker'; - -const DatePickerInput = withInstall(DatePickerInputInstallless); - -DatePickerInput.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { - componentMap[DATE_PICKER_REGISTERED_NAME] = DatePickerInput; - propsResolverMap[DATE_PICKER_REGISTERED_NAME] = propsResolver; -}; -DatePickerInput.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record) => { - componentMap[DATE_PICKER_REGISTERED_NAME] = DatePickerDesign; - propsResolverMap[DATE_PICKER_REGISTERED_NAME] = propsResolver; -}; - - -export { DatePickerInput }; -export default DatePickerInput; diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.component.tsx b/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.component.tsx deleted file mode 100644 index bd3212c1693..00000000000 --- a/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.component.tsx +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { SetupContext, computed, defineComponent } from 'vue'; -import { useBem } from '@components/common'; -import { DatePicker } from '@/components/date-picker'; -import { ButtonEdit } from '@/components/button-edit'; -import { usePickerInputState } from '@/components/picker-input'; -import { datePickerInputProps, DatePickerInputProps, DATA_PICKER_INPUT_NAME } from './date-picker-input.props'; - -export default defineComponent({ - name: DATA_PICKER_INPUT_NAME, - props: datePickerInputProps, - emits: ['change', 'confirm', 'update:modelValue'], - setup(props: DatePickerInputProps, context) { - const { bem } = useBem(DATA_PICKER_INPUT_NAME); - - const { buttonEditProps, inputValue, showPopup, componentRef, handleChange, handleConfirm } = usePickerInputState(props, context); - - const pickerProps = computed(() => { - return { - ref: componentRef, - title: props.title, - type: props.type, - format: props.format, - maxDate: props.maxDate, - minDate: props.minDate, - visiableOptionCount: props.visiableOptionCount, - optionFormatter: props.optionFormatter, - onChange: handleChange, - onConfirm: handleConfirm, - onCancel: () => showPopup.value = false - }; - }); - - return () => ( - - - - ); - } -}); diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.props.ts b/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.props.ts deleted file mode 100644 index 16e9a703ae5..00000000000 --- a/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.props.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ExtractPropTypes } from 'vue'; -import { buttonEditProps } from '@/components/button-edit'; -import { datePickerProps } from '@/components/date-picker'; -import { schemaMapper } from './schema/schema-mapper'; -import { schemaResolver } from './schema/schema-resolver'; -import inputSchema from './schema/schema.json'; -import { createPropsResolver } from '@/components/dynamic-resolver'; - -export const DATA_PICKER_INPUT_NAME = 'FmDatePickerInput'; - -export const datePickerInputProps = { - ...buttonEditProps, - ...datePickerProps, - - round: { type: Boolean, default: false } -}; - -export type DatePickerInputProps = ExtractPropTypes; - -export const propsResolver = createPropsResolver(datePickerInputProps, inputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/date-picker-panel/index.ts b/packages/mobile-ui-vue/components/date-picker-panel/index.ts new file mode 100644 index 00000000000..0877370f290 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-picker-panel/index.ts @@ -0,0 +1,9 @@ +import { withInstall } from '@components/common'; +import DatePickerPanelInstallless from './src/date-picker-panel.component'; + +export * from './src/date-picker-panel.props'; + +const DatePickerPanel = withInstall(DatePickerPanelInstallless); + +export { DatePickerPanel }; +export default DatePickerPanel; diff --git a/packages/mobile-ui-vue/components/date-picker/src/composition/index.ts b/packages/mobile-ui-vue/components/date-picker-panel/src/composition/index.ts similarity index 100% rename from packages/mobile-ui-vue/components/date-picker/src/composition/index.ts rename to packages/mobile-ui-vue/components/date-picker-panel/src/composition/index.ts diff --git a/packages/mobile-ui-vue/components/date-picker/src/composition/use-date-columns.ts b/packages/mobile-ui-vue/components/date-picker-panel/src/composition/use-date-columns.ts similarity index 93% rename from packages/mobile-ui-vue/components/date-picker/src/composition/use-date-columns.ts rename to packages/mobile-ui-vue/components/date-picker-panel/src/composition/use-date-columns.ts index 48fc4373bd1..9a579d243cd 100644 --- a/packages/mobile-ui-vue/components/date-picker/src/composition/use-date-columns.ts +++ b/packages/mobile-ui-vue/components/date-picker-panel/src/composition/use-date-columns.ts @@ -1,5 +1,5 @@ import { computed, watch, ref } from 'vue'; -import { Column, Columns, PickerChange } from '@components/picker'; +import { Column, Columns, PickerChange } from '@components/picker-panel'; import { compareDate, formatDate, @@ -9,7 +9,7 @@ import { isString, parseDate } from '@components/common'; -import { DatePickerProps, DatePickerTypeMap } from '../date-picker.props'; +import { DatePickerPanelProps, DatePickerPanelTypeMap } from '../date-picker-panel.props'; enum DateColumn { Year = 'year', @@ -25,7 +25,7 @@ type DateRecord = { type ColumnsMap = ('year' | 'month' | 'day')[]; -export const useDateColumns = (props: DatePickerProps) => { +export const useDateColumns = (props: DatePickerPanelProps) => { const textField = 'text'; const valueField = 'value'; @@ -145,7 +145,7 @@ export const useDateColumns = (props: DatePickerProps) => { const columnsMap = computed(() => { const type = - props.type === DatePickerTypeMap.Date ? DatePickerTypeMap.YearMonthDay : props.type; + props.type === DatePickerPanelTypeMap.Date ? DatePickerPanelTypeMap.YearMonthDay : props.type; return type.split('-') as ColumnsMap; }); @@ -180,7 +180,7 @@ export const useDateColumns = (props: DatePickerProps) => { const result = new Date(year, month - 1, day); - if (props.type === DatePickerTypeMap.Date || props.type === DatePickerTypeMap.YearMonthDay) { + if (props.type === DatePickerPanelTypeMap.Date || props.type === DatePickerPanelTypeMap.YearMonthDay) { return result; } return formatDate(result, props.format); diff --git a/packages/mobile-ui-vue/components/date-picker-panel/src/date-picker-panel.component.tsx b/packages/mobile-ui-vue/components/date-picker-panel/src/date-picker-panel.component.tsx new file mode 100644 index 00000000000..94cdd80fe65 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-picker-panel/src/date-picker-panel.component.tsx @@ -0,0 +1,49 @@ +import { defineComponent, SetupContext } from 'vue'; +import { PickerPanel, PickerChange } from '@components/picker-panel'; +import { useBem } from '@components/common'; +import { useDateColumns } from './composition'; +import { datePickerPanelProps, DATE_PICKER_PANEL_NAME } from './date-picker-panel.props'; + +export default defineComponent({ + name: DATE_PICKER_PANEL_NAME, + inheritAttrs: false, + props: datePickerPanelProps, + emits: ['change', 'confirm', 'cancel'], + setup(props, context: SetupContext<("change" | "confirm" | "cancel")[]>) { + const { emit, expose } = context; + + const { dateColumns, innerValue, textField, valueField, getDateValue, getTextValue } = useDateColumns(props); + + expose({ getTextValue }); + + const handleChange = (changes: PickerChange)=>{ + emit('change', getDateValue(changes)); + }; + + const handleConfirm = ()=>{ + emit('confirm', getDateValue()); + }; + + const handleCanCel = ()=>{ + emit('cancel'); + }; + + const { bem } = useBem(DATE_PICKER_PANEL_NAME); + + return () => ( + + ); + } +}); diff --git a/packages/mobile-ui-vue/components/date-picker-panel/src/date-picker-panel.props.ts b/packages/mobile-ui-vue/components/date-picker-panel/src/date-picker-panel.props.ts new file mode 100644 index 00000000000..f31162f43a2 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-picker-panel/src/date-picker-panel.props.ts @@ -0,0 +1,34 @@ +import { ExtractPropTypes, PropType } from 'vue'; + +export const DATE_PICKER_PANEL_NAME = 'FmDatePickerPanel'; + +export const enum DatePickerPanelTypeMap { + Year = 'year', + YearMonth = 'year-month', + YearMonthDay = 'year-month-day', + Date= 'date', +} + +export type DatePickerType = `${DatePickerPanelTypeMap}`; + +export const datePickerPanelProps = { + title: { type: String, default: '' }, + + type: { type: String as PropType, default: DatePickerPanelTypeMap.Date }, + + modelValue: { type: [String, Date], default: '' }, + + format: { type: String, default: 'YYYY-MM-DD' }, + + maxDate: { type: Date, default: undefined }, + + minDate: { type: Date, default: undefined }, + + optionFormatter: { type: Function as PropType<(type: string, value: string) => string>, default: undefined }, + + visiableOptionCount: { type: Number, default: 5 }, + + showToolbar: { type: Boolean, default: true } +}; + +export type DatePickerPanelProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker.scss b/packages/mobile-ui-vue/components/date-picker-panel/src/date-picker-panel.scss similarity index 100% rename from packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker.scss rename to packages/mobile-ui-vue/components/date-picker-panel/src/date-picker-panel.scss diff --git a/packages/mobile-ui-vue/components/date-picker/index.ts b/packages/mobile-ui-vue/components/date-picker/index.ts index 661eed49e2e..33346892f23 100644 --- a/packages/mobile-ui-vue/components/date-picker/index.ts +++ b/packages/mobile-ui-vue/components/date-picker/index.ts @@ -1,9 +1,21 @@ import { withInstall } from '@components/common'; import DatePickerInstallless from './src/date-picker.component'; +import DatePickerDesign from './src/designer/date-picker.design.component'; +import { propsResolver } from './src/date-picker.props'; -export * from './src/date-picker.props'; +const DATE_PICKER_REGISTERED_NAME = 'date-picker'; const DatePicker = withInstall(DatePickerInstallless); +DatePicker.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { + componentMap[DATE_PICKER_REGISTERED_NAME] = DatePicker; + propsResolverMap[DATE_PICKER_REGISTERED_NAME] = propsResolver; +}; +DatePicker.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record) => { + componentMap[DATE_PICKER_REGISTERED_NAME] = DatePickerDesign; + propsResolverMap[DATE_PICKER_REGISTERED_NAME] = propsResolver; +}; + + export { DatePicker }; export default DatePicker; diff --git a/packages/mobile-ui-vue/components/date-picker/src/date-picker.component.tsx b/packages/mobile-ui-vue/components/date-picker/src/date-picker.component.tsx index f3a5760ce84..6a41221cc76 100644 --- a/packages/mobile-ui-vue/components/date-picker/src/date-picker.component.tsx +++ b/packages/mobile-ui-vue/components/date-picker/src/date-picker.component.tsx @@ -1,65 +1,44 @@ -/** - * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { defineComponent, SetupContext } from 'vue'; -import { Picker, PickerChange } from '@components/picker'; +import { computed, defineComponent } from 'vue'; import { useBem } from '@components/common'; -import { useDateColumns } from './composition'; -import { datePickerProps, DatePickerProps, DATE_PICKER_NAME } from './date-picker.props'; +import { DatePickerPanel } from '@/components/date-picker-panel'; +import { ButtonEdit } from '@/components/button-edit'; +import { usePickerInputState } from '@/components/picker'; +import { datePickerProps, DATA_PICKER_NAME } from './date-picker.props'; export default defineComponent({ - name: DATE_PICKER_NAME, - inheritAttrs: false, + name: DATA_PICKER_NAME, props: datePickerProps, - emits: ['change', 'confirm', 'cancel'], - setup(props: DatePickerProps, context: SetupContext<("change" | "confirm" | "cancel")[]>) { - const { emit, expose } = context; - - const { dateColumns, innerValue, textField, valueField, getDateValue, getTextValue } = useDateColumns(props); - - expose({ getTextValue }); - - const handleChange = (changes: PickerChange)=>{ - emit('change', getDateValue(changes)); - }; - - const handleConfirm = ()=>{ - emit('confirm', getDateValue()); - }; - - const handleCanCel = ()=>{ - emit('cancel'); - }; - - const { bem } = useBem(DATE_PICKER_NAME); + emits: ['change', 'confirm', 'update:modelValue'], + setup(props, context) { + const { bem } = useBem(DATA_PICKER_NAME); + + const { buttonEditProps, inputValue, showPopup, componentRef, handleChange, handleConfirm } = usePickerInputState(props, context); + + const pickerProps = computed(() => { + return { + ref: componentRef, + title: props.title, + type: props.type, + format: props.format, + maxDate: props.maxDate, + minDate: props.minDate, + visiableOptionCount: props.visiableOptionCount, + optionFormatter: props.optionFormatter, + onChange: handleChange, + onConfirm: handleConfirm, + onCancel: () => showPopup.value = false + }; + }); return () => ( - + + + ); } }); diff --git a/packages/mobile-ui-vue/components/date-picker/src/date-picker.props.ts b/packages/mobile-ui-vue/components/date-picker/src/date-picker.props.ts index 2b334ebfe88..cd1edc9b051 100644 --- a/packages/mobile-ui-vue/components/date-picker/src/date-picker.props.ts +++ b/packages/mobile-ui-vue/components/date-picker/src/date-picker.props.ts @@ -1,34 +1,20 @@ -import { ExtractPropTypes, PropType } from 'vue'; +import { ExtractPropTypes } from 'vue'; +import { buttonEditProps } from '@/components/button-edit'; +import { datePickerPanelProps } from '@/components/date-picker-panel'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; +import inputSchema from './schema/schema.json'; +import { createPropsResolver } from '@/components/dynamic-resolver'; -export const DATE_PICKER_NAME = 'FmDatePicker'; - -export const enum DatePickerTypeMap { - Year = 'year', - YearMonth = 'year-month', - YearMonthDay = 'year-month-day', - Date= 'date', -} - -export type DatePickerType = `${DatePickerTypeMap}`; +export const DATA_PICKER_NAME = 'FmDatePicker'; export const datePickerProps = { - title: { type: String, default: '' }, - - type: { type: String as PropType, default: DatePickerTypeMap.Date }, - - modelValue: { type: [String, Date], default: '' }, - - format: { type: String, default: 'YYYY-MM-DD' }, + ...buttonEditProps, + ...datePickerPanelProps, - maxDate: { type: Date, default: undefined }, - - minDate: { type: Date, default: undefined }, - - optionFormatter: { type: Function as PropType<(type: string, value: string) => string>, default: undefined }, - - visiableOptionCount: { type: Number, default: 5 }, - - showToolbar: { type: Boolean, default: true } + round: { type: Boolean, default: false } }; export type DatePickerProps = ExtractPropTypes; + +export const propsResolver = createPropsResolver(datePickerProps, inputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/designer/date-picker.design.component.tsx b/packages/mobile-ui-vue/components/date-picker/src/designer/date-picker.design.component.tsx similarity index 91% rename from packages/mobile-ui-vue/components/date-picker-input/src/designer/date-picker.design.component.tsx rename to packages/mobile-ui-vue/components/date-picker/src/designer/date-picker.design.component.tsx index 48ba7cbf587..58e12ca2f0c 100644 --- a/packages/mobile-ui-vue/components/date-picker-input/src/designer/date-picker.design.component.tsx +++ b/packages/mobile-ui-vue/components/date-picker/src/designer/date-picker.design.component.tsx @@ -18,14 +18,14 @@ import { computed, defineComponent, inject, onMounted, readonly, ref, SetupConte import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; import { useDesignerRules } from './use-designer-rules'; -import { datePickerInputProps, DatePickerInputProps } from '../date-picker-input.props'; +import { datePickerProps, DatePickerProps } from '../date-picker.props'; import DatePickerInput from '../..'; export default defineComponent({ name: 'FmDatePickerInputDesign', - props: datePickerInputProps, + props: datePickerProps, emits: [], - setup(props: DatePickerInputProps, context: SetupContext) { + setup(props: DatePickerProps, context: SetupContext) { const elementRef = ref(); const designItemContext = inject('design-item-context') as DesignerItemContext; const designerHostService = inject('designer-host-service'); diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/date-picker/src/designer/use-designer-rules.ts similarity index 100% rename from packages/mobile-ui-vue/components/date-picker-input/src/designer/use-designer-rules.ts rename to packages/mobile-ui-vue/components/date-picker/src/designer/use-designer-rules.ts diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/property-config/date-format.ts b/packages/mobile-ui-vue/components/date-picker/src/property-config/date-format.ts similarity index 100% rename from packages/mobile-ui-vue/components/date-picker-input/src/property-config/date-format.ts rename to packages/mobile-ui-vue/components/date-picker/src/property-config/date-format.ts diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/property-config/date-picker.property-config.ts b/packages/mobile-ui-vue/components/date-picker/src/property-config/date-picker.property-config.ts similarity index 100% rename from packages/mobile-ui-vue/components/date-picker-input/src/property-config/date-picker.property-config.ts rename to packages/mobile-ui-vue/components/date-picker/src/property-config/date-picker.property-config.ts diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/date-picker/src/schema/schema-mapper.ts similarity index 100% rename from packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-mapper.ts rename to packages/mobile-ui-vue/components/date-picker/src/schema/schema-mapper.ts diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/date-picker/src/schema/schema-resolver.ts similarity index 100% rename from packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-resolver.ts rename to packages/mobile-ui-vue/components/date-picker/src/schema/schema-resolver.ts diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema.json b/packages/mobile-ui-vue/components/date-picker/src/schema/schema.json similarity index 100% rename from packages/mobile-ui-vue/components/date-picker-input/src/schema/schema.json rename to packages/mobile-ui-vue/components/date-picker/src/schema/schema.json diff --git a/packages/mobile-ui-vue/components/date-time-picker-input/index.ts b/packages/mobile-ui-vue/components/date-time-picker-input/index.ts deleted file mode 100644 index 52edd797cc7..00000000000 --- a/packages/mobile-ui-vue/components/date-time-picker-input/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { withInstall } from '@components/common'; -import DateTimePickerInputInstallless from './src/date-time-picker-input.component'; - -const DateTimePickerInput = withInstall(DateTimePickerInputInstallless); - -export { DateTimePickerInput }; -export default DateTimePickerInput; diff --git a/packages/mobile-ui-vue/components/date-time-picker-input/src/date-time-picker-input.component.tsx b/packages/mobile-ui-vue/components/date-time-picker-input/src/date-time-picker-input.component.tsx deleted file mode 100644 index ba7226b1277..00000000000 --- a/packages/mobile-ui-vue/components/date-time-picker-input/src/date-time-picker-input.component.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { computed, defineComponent } from 'vue'; -import { useBem } from '@components/common'; -import DateTimePicker from '@/components/date-time-picker'; -import { usePickerInputState } from '@/components/picker-input'; -import ButtonEdit from '@/components/button-edit'; -import { dateTimePickerInputProps, DateTimePickerInputProps, DATA_TIME_PICKER_INPUT_NAME } from './date-time-picker-input.props'; - -export default defineComponent({ - name: DATA_TIME_PICKER_INPUT_NAME, - props: dateTimePickerInputProps, - emits: ['change', 'confirm', 'update:modelValue'], - setup(props: DateTimePickerInputProps, context) { - - const { bem } = useBem(DATA_TIME_PICKER_INPUT_NAME); - - const { buttonEditProps, inputValue, showPopup, componentRef, handleChange, handleConfirm } = usePickerInputState(props, context); - - const pickerProps = computed(() => { - return { - ref: componentRef, - title: props.title, - type: props.type, - format: props.format, - maxDate: props.maxDate, - minDate: props.minDate, - visiableOptionCount: props.visiableOptionCount, - optionFormatter: props.optionFormatter, - onChange: handleChange, - onConfirm: handleConfirm, - onCancel: () => showPopup.value = false - }; - }); - - return () => ( - - - - ); - } -}); diff --git a/packages/mobile-ui-vue/components/date-time-picker-input/src/date-time-picker-input.props.ts b/packages/mobile-ui-vue/components/date-time-picker-input/src/date-time-picker-input.props.ts deleted file mode 100644 index c2c76ae490e..00000000000 --- a/packages/mobile-ui-vue/components/date-time-picker-input/src/date-time-picker-input.props.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ExtractPropTypes } from 'vue'; -import { buttonEditProps } from '@/components/button-edit'; -import { dateTimePickerProps } from '@/components/date-time-picker'; - -export const DATA_TIME_PICKER_INPUT_NAME = 'FmDateTimePickerInput'; - -export const dateTimePickerInputProps = { - ...buttonEditProps, - ...dateTimePickerProps -}; - -export type DateTimePickerInputProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/date-time-picker-panel/index.ts b/packages/mobile-ui-vue/components/date-time-picker-panel/index.ts new file mode 100644 index 00000000000..645fdabd526 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-time-picker-panel/index.ts @@ -0,0 +1,9 @@ +import { withInstall } from '@components/common'; +import DateTimePickerPanelInstallless from './src/date-time-picker-panel.component'; + +export * from './src/date-time-picker-panel.props'; + +const DateTimePickerPanel = withInstall(DateTimePickerPanelInstallless); + +export { DateTimePickerPanel }; +export default DateTimePickerPanel; diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/composition/index.ts b/packages/mobile-ui-vue/components/date-time-picker-panel/src/composition/index.ts similarity index 100% rename from packages/mobile-ui-vue/components/date-time-picker/src/composition/index.ts rename to packages/mobile-ui-vue/components/date-time-picker-panel/src/composition/index.ts diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/composition/use-date-state.ts b/packages/mobile-ui-vue/components/date-time-picker-panel/src/composition/use-date-state.ts similarity index 71% rename from packages/mobile-ui-vue/components/date-time-picker/src/composition/use-date-state.ts rename to packages/mobile-ui-vue/components/date-time-picker-panel/src/composition/use-date-state.ts index c65dfec992e..fe06825975b 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/composition/use-date-state.ts +++ b/packages/mobile-ui-vue/components/date-time-picker-panel/src/composition/use-date-state.ts @@ -1,10 +1,10 @@ import { computed, ref } from "vue"; -import { DatePickerType, DatePickerTypeMap } from "@components/date-picker"; -import { DateTimePickerProps } from "../date-time-picker.props"; +import { DatePickerType, DatePickerPanelTypeMap } from "@/components/date-picker-panel"; +import { DateTimePickerProps } from "../date-time-picker-panel.props"; export const useDateState = (props: DateTimePickerProps) => { const dateType = computed(() => { - return (props.type.split(" ")[0] as DatePickerType) || DatePickerTypeMap.Date; + return (props.type.split(" ")[0] as DatePickerType) || DatePickerPanelTypeMap.Date; }); const dateFormat = computed(() => { return props.format.split(" ")[0] || 'YYYY-MM-DD'; diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/composition/use-date-time-value.ts b/packages/mobile-ui-vue/components/date-time-picker-panel/src/composition/use-date-time-value.ts similarity index 93% rename from packages/mobile-ui-vue/components/date-time-picker/src/composition/use-date-time-value.ts rename to packages/mobile-ui-vue/components/date-time-picker-panel/src/composition/use-date-time-value.ts index a0bcd35f3ae..42dfddc6969 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/composition/use-date-time-value.ts +++ b/packages/mobile-ui-vue/components/date-time-picker-panel/src/composition/use-date-time-value.ts @@ -1,5 +1,5 @@ -import { reactive, watch } from "vue"; -import { DateTimePickerProps } from "../date-time-picker.props"; +import { watch } from "vue"; +import { DateTimePickerProps } from "../date-time-picker-panel.props"; import { compareDate, formatDate, isDate, parseDate } from "@components/common"; import { DateState } from "./use-date-state"; import { TimeState } from "./use-time-state"; diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/composition/use-time-state.ts b/packages/mobile-ui-vue/components/date-time-picker-panel/src/composition/use-time-state.ts similarity index 85% rename from packages/mobile-ui-vue/components/date-time-picker/src/composition/use-time-state.ts rename to packages/mobile-ui-vue/components/date-time-picker-panel/src/composition/use-time-state.ts index 0cdb82adced..64ea1686339 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/composition/use-time-state.ts +++ b/packages/mobile-ui-vue/components/date-time-picker-panel/src/composition/use-time-state.ts @@ -1,6 +1,6 @@ import { computed, ref } from "vue"; -import { TimePickerType, TimePickerTypeMap } from "@components/time-picker"; -import { DateTimePickerProps } from "../date-time-picker.props"; +import { TimePickerType, TimePickerPanelTypeMap } from "@components/time-picker-panel"; +import { DateTimePickerProps } from "../date-time-picker-panel.props"; import { formatDate, isEqualDate } from "@components/common"; import { DateState } from "./use-date-state"; @@ -8,7 +8,7 @@ export const useTimeState = (props: DateTimePickerProps, datePropsComposition: D const { dateValue } = datePropsComposition; const timeType = computed(() => { - return (props.type.split(" ")[1] as TimePickerType) || TimePickerTypeMap.Time; + return (props.type.split(" ")[1] as TimePickerType) || TimePickerPanelTypeMap.Time; }); const timeFormat = computed(() => { return props.format.split(" ")[1] || 'HH:mm:ss'; diff --git a/packages/mobile-ui-vue/components/date-time-picker-panel/src/date-time-picker-panel.component.tsx b/packages/mobile-ui-vue/components/date-time-picker-panel/src/date-time-picker-panel.component.tsx new file mode 100644 index 00000000000..233b2625b5c --- /dev/null +++ b/packages/mobile-ui-vue/components/date-time-picker-panel/src/date-time-picker-panel.component.tsx @@ -0,0 +1,68 @@ +import { defineComponent } from 'vue'; +import { DatePickerPanel } from '@/components/date-picker-panel'; +import { TimePickerPanel } from '@components/time-picker-panel'; +import PickerGroup from '@/components/picker-group'; +import { useDateState, useDateTimeValue, useTimeState } from './composition'; +import { dateTimePickerPanelProps, DATE_TIME_PICKER_PANEL_NAME } from './date-time-picker-panel.props'; + +export default defineComponent({ + name: DATE_TIME_PICKER_PANEL_NAME, + props: dateTimePickerPanelProps, + emits: ['change', 'confirm', 'update:modelValue'], + setup(props, context) { + const { emit, expose } = context; + + const dateStateComposition = useDateState(props); + const { dateValue, dateType, dateFormat } = dateStateComposition; + const timeStateComposition = useTimeState(props, dateStateComposition); + const { timeValue, timeType, timeFormat, maxTime, minTime } = timeStateComposition; + + const { setDateValue, setTimeValue, getDateValue, getTextValue } = useDateTimeValue(props, dateStateComposition, timeStateComposition); + + expose({ getTextValue }); + + const handleDateChange = (value: Date) => { + setDateValue(value); + emit('change', getDateValue()); + }; + const handleTimeChange = (value: string) => { + setTimeValue(value); + emit('change', getDateValue()); + }; + + const handleConfirm = () => { + const value = getDateValue(); + emit('confirm', value); + emit('update:modelValue', value); + }; + + return () => ( + + + + + ); + } +}); diff --git a/packages/mobile-ui-vue/components/date-time-picker-panel/src/date-time-picker-panel.props.ts b/packages/mobile-ui-vue/components/date-time-picker-panel/src/date-time-picker-panel.props.ts new file mode 100644 index 00000000000..2031f614f54 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-time-picker-panel/src/date-time-picker-panel.props.ts @@ -0,0 +1,35 @@ +import { ExtractPropTypes, PropType } from 'vue'; +import { DatePickerPanelTypeMap } from '@/components/date-picker-panel'; +import { TimePickerPanelTypeMap } from '@components/time-picker-panel'; + +export const DATE_TIME_PICKER_PANEL_NAME = 'FmDateTimePickerPanel'; + +export const enum DateTimeTypeMap { + DateTime = `${DatePickerPanelTypeMap.Date} ${TimePickerPanelTypeMap.Time}`, + DateHour = `${DatePickerPanelTypeMap.Date} ${TimePickerPanelTypeMap.Hours}`, + DateMinute = `${DatePickerPanelTypeMap.Date} ${TimePickerPanelTypeMap.HoursMinutes}` +} + +type DateTimeType = `${DateTimeTypeMap}`; + +export const dateTimePickerPanelProps = { + title: { type: String, default: '' }, + + type: { type: String as PropType, default: DateTimeTypeMap.DateTime }, + + modelValue: { type: [String, Date], default: '' }, + + format: { type: String, default: 'YYYY-MM-DD HH:mm:ss' }, + + maxDate: { type: Date, default: undefined }, + + minDate: { type: Date, default: undefined }, + + optionFormatter: { type: Function as PropType<(type: string, value: string) => string>, default: undefined }, + + visiableOptionCount: { type: Number, default: 5 }, + + showToolbar: { type: Boolean, default: true } +}; + +export type DateTimePickerPanelProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/picker-input/src/picker-input.scss b/packages/mobile-ui-vue/components/date-time-picker-panel/src/date-time-picker-panel.scss similarity index 100% rename from packages/mobile-ui-vue/components/picker-input/src/picker-input.scss rename to packages/mobile-ui-vue/components/date-time-picker-panel/src/date-time-picker-panel.scss diff --git a/packages/mobile-ui-vue/components/date-time-picker/index.ts b/packages/mobile-ui-vue/components/date-time-picker/index.ts index 78682c9348b..7de2255ccd2 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/index.ts +++ b/packages/mobile-ui-vue/components/date-time-picker/index.ts @@ -1,9 +1,7 @@ import { withInstall } from '@components/common'; -import DateTimePickerInstallless from './src/date-time-picker.component'; +import DateTimePickerInputInstallless from './src/date-time-picker.component'; -export * from './src/date-time-picker.props'; - -const DateTimePicker = withInstall(DateTimePickerInstallless); +const DateTimePicker = withInstall(DateTimePickerInputInstallless); export { DateTimePicker }; export default DateTimePicker; diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker.component.tsx b/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker.component.tsx index f67d2e88ab2..8ef05e3f377 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker.component.tsx +++ b/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker.component.tsx @@ -1,88 +1,45 @@ -/** - * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { defineComponent, reactive, ref, SetupContext } from 'vue'; -import { DatePicker } from '@components/date-picker'; -import { TimePicker } from '@components/time-picker'; -import PickerGroup from '@/components/picker-group'; -import { useDateState, useDateTimeValue, useTimeState } from './composition'; -import { - dateTimePickerProps, - DateTimePickerProps, - DATE_TIME_PICKER_NAME -} from './date-time-picker.props'; +import { computed, defineComponent } from 'vue'; +import { useBem } from '@components/common'; +import { DateTimePickerPanel } from '@/components/date-time-picker-panel'; +import { usePickerInputState } from '@/components/picker'; +import ButtonEdit from '@/components/button-edit'; +import { dateTimePickerProps, DATA_TIME_PICKER_NAME } from './date-time-picker.props'; export default defineComponent({ - name: DATE_TIME_PICKER_NAME, + name: DATA_TIME_PICKER_NAME, props: dateTimePickerProps, emits: ['change', 'confirm', 'update:modelValue'], - setup(props: DateTimePickerProps, context) { - const { emit, expose } = context; - - const dateStateComposition = useDateState(props); - const { dateValue, dateType, dateFormat } = dateStateComposition; - const timeStateComposition = useTimeState(props, dateStateComposition); - const { timeValue, timeType, timeFormat, maxTime, minTime } = timeStateComposition; - - const { setDateValue, setTimeValue, getDateValue, getTextValue } = useDateTimeValue(props, dateStateComposition, timeStateComposition); - - expose({ getTextValue }); - - const handleDateChange = (value: Date) => { - setDateValue(value); - emit('change', getDateValue()); - }; - const handleTimeChange = (value: string) => { - setTimeValue(value); - emit('change', getDateValue()); - }; - - const handleConfirm = () => { - const value = getDateValue(); - emit('confirm', value); - emit('update:modelValue', value); - }; + setup(props, context) { + + const { bem } = useBem(DATA_TIME_PICKER_NAME); + + const { buttonEditProps, inputValue, showPopup, componentRef, handleChange, handleConfirm } = usePickerInputState(props, context); + + const pickerProps = computed(() => { + return { + ref: componentRef, + title: props.title, + type: props.type, + format: props.format, + maxDate: props.maxDate, + minDate: props.minDate, + visiableOptionCount: props.visiableOptionCount, + optionFormatter: props.optionFormatter, + onChange: handleChange, + onConfirm: handleConfirm, + onCancel: () => showPopup.value = false + }; + }); return () => ( - - - - + + + ); } }); diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker.props.ts b/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker.props.ts index 2c4962f45aa..04ec7a44d19 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker.props.ts +++ b/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker.props.ts @@ -1,35 +1,12 @@ -import { ExtractPropTypes, PropType } from 'vue'; -import { DatePickerTypeMap } from '@components/date-picker'; -import { TimePickerTypeMap } from '@components/time-picker'; +import { ExtractPropTypes } from 'vue'; +import { buttonEditProps } from '@/components/button-edit'; +import { dateTimePickerPanelProps } from '@/components/date-time-picker-panel'; -export const DATE_TIME_PICKER_NAME = 'FmDateTimePicker'; - -export const enum DateTimeTypeMap { - DateTime = `${DatePickerTypeMap.Date} ${TimePickerTypeMap.Time}`, - DateHour = `${DatePickerTypeMap.Date} ${TimePickerTypeMap.Hours}`, - DateMinute = `${DatePickerTypeMap.Date} ${TimePickerTypeMap.HoursMinutes}` -} - -type DateTimeType = `${DateTimeTypeMap}`; +export const DATA_TIME_PICKER_NAME = 'FmDateTimePicker'; export const dateTimePickerProps = { - title: { type: String, default: '' }, - - type: { type: String as PropType, default: DateTimeTypeMap.DateTime }, - - modelValue: { type: [String, Date], default: '' }, - - format: { type: String, default: 'YYYY-MM-DD HH:mm:ss' }, - - maxDate: { type: Date, default: undefined }, - - minDate: { type: Date, default: undefined }, - - optionFormatter: { type: Function as PropType<(type: string, value: string) => string>, default: undefined }, - - visiableOptionCount: { type: Number, default: 5 }, - - showToolbar: { type: Boolean, default: true } + ...buttonEditProps, + ...dateTimePickerPanelProps }; export type DateTimePickerProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/components/maps.ts b/packages/mobile-ui-vue/components/designer-canvas/src/components/maps.ts index 8c1e55a382d..c44e05d5c1b 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/components/maps.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/components/maps.ts @@ -1,4 +1,4 @@ -import { CheckboxGroup, ContentContainer, DatePickerInput, FormItem, PageHeaderContainer, PickerInput, RadioGroup, Switch } from "@/components"; +import { CheckboxGroup, ContentContainer, DatePicker, FormItem, PageHeaderContainer, Picker, RadioGroup, Switch } from "@/components"; import Button from "@/components/button"; import Component from "@/components/component"; import FloatContainer from "@/components/float-container"; @@ -36,11 +36,11 @@ function loadDesignerRegister() { FloatContainer.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); ContentContainer.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); FormItem.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); - DatePickerInput.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + DatePicker.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); Textarea.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); RadioGroup.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); Switch.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); - PickerInput.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + Picker.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); CheckboxGroup.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); } diff --git a/packages/mobile-ui-vue/components/filter/src/compositions/use-render-field-item.tsx b/packages/mobile-ui-vue/components/filter/src/compositions/use-render-field-item.tsx index d64ff833a84..dcf0685e275 100644 --- a/packages/mobile-ui-vue/components/filter/src/compositions/use-render-field-item.tsx +++ b/packages/mobile-ui-vue/components/filter/src/compositions/use-render-field-item.tsx @@ -60,6 +60,17 @@ export const useRenderFieldItem = (filterData: Record, context: Set
    ); }; + const renderDatePicker = (config: FieldConfig) => { + const { code, editor = {} } = config; + const inputProps = { + ...editor, + type: 'number', + modelValue: getValue(code, filterData), + onChange: (value: any) => handleChange(code, value) + }; + + return renderInput(inputProps); + }; const renderFieldItem = (config: FieldConfig) => { const { controlType } = config; diff --git a/packages/mobile-ui-vue/components/index.scss b/packages/mobile-ui-vue/components/index.scss index dc287913497..83715e439ca 100644 --- a/packages/mobile-ui-vue/components/index.scss +++ b/packages/mobile-ui-vue/components/index.scss @@ -28,7 +28,7 @@ @use './tab-bar/src/tab-bar.scss'; @use './tabs/src/tabs.scss'; @use './tag/src/tag.scss'; -@use './picker/src/picker.scss'; +@use './picker-panel/src/picker-panel.scss'; @use './picker-group/src/picker-group.scss'; @use './date-picker/src/date-picker.scss'; @use './lookup/src/lookup.scss'; diff --git a/packages/mobile-ui-vue/components/index.ts b/packages/mobile-ui-vue/components/index.ts index 4dce0f2c0b6..bd9961ce460 100644 --- a/packages/mobile-ui-vue/components/index.ts +++ b/packages/mobile-ui-vue/components/index.ts @@ -1,19 +1,3 @@ -/** - * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - import { App, Plugin } from 'vue'; import Button from './button'; import ButtonEdit from './button-edit'; @@ -38,13 +22,13 @@ import Popup from './popup'; import Overlay from './overlay'; import Picker from './picker'; import PickerGroup from './picker-group'; -import PickerInput from './picker-input'; +import PickerPanel from './picker-panel'; import DatePicker from './date-picker'; -import DatePickerInput from './date-picker-input'; +import DatePickerPanel from './date-picker-panel'; import DateTimePicker from "./date-time-picker"; -import DateTimePickerInput from "./date-time-picker-input"; +import DateTimePickerPanel from "./date-time-picker-panel"; import TimePicker from './time-picker'; -import TimePickerInput from './time-picker-input'; +import TimePickerPanel from './time-picker-panel'; import Loading from './loading'; import PullRefresh from './pull-refresh'; import List from './list'; @@ -83,9 +67,9 @@ const components = [ CheckboxGroup, Checker, DatePicker, - DatePickerInput, + DatePickerPanel, DateTimePicker, - DateTimePickerInput, + DateTimePickerPanel, Icon, InputGroup, Navbar, @@ -102,9 +86,9 @@ const components = [ Popup, Picker, PickerGroup, - PickerInput, + PickerPanel, TimePicker, - TimePickerInput, + TimePickerPanel, TabBar, Loading, PullRefresh, @@ -145,9 +129,9 @@ export { Checkbox, CheckboxGroup, DatePicker, - DatePickerInput, + DatePickerPanel, DateTimePicker, - DateTimePickerInput, + DateTimePickerPanel, Icon, InputGroup, Navbar, @@ -164,9 +148,9 @@ export { Popup, Picker, PickerGroup, - PickerInput, + PickerPanel, TimePicker, - TimePickerInput, + TimePickerPanel, TabBar, Loading, PullRefresh, diff --git a/packages/mobile-ui-vue/components/input-group/src/composition/use-input-event.ts b/packages/mobile-ui-vue/components/input-group/src/composition/use-input-event.ts index 353ce8cfe8b..0058bfbb291 100644 --- a/packages/mobile-ui-vue/components/input-group/src/composition/use-input-event.ts +++ b/packages/mobile-ui-vue/components/input-group/src/composition/use-input-event.ts @@ -26,7 +26,7 @@ export function useInputEvent(props: InputProps, context: SetupContext, state: I updateOn, updatable, showClear, - getModelValue, + valueModified, updateValue, updateInnerValue, updateDisplayValue @@ -38,23 +38,19 @@ export function useInputEvent(props: InputProps, context: SetupContext, state: I } }; - let changed = false; - const handleValueChange = (value: string | number) => { - if (changed) { - changed = false; - updateInnerValue(value); - const modelValue = getModelValue(innerValue.value); - updateValue(modelValue); - emit('change', modelValue); - emit('update:modelValue', modelValue); + if (valueModified.value) { + valueModified.value = false; + updateValue(value); + emit('change', innerValue.value); + emit('update:modelValue', innerValue.value); } else { updateValue(value); } }; const handleInput = (value: string | number) => { - changed = true; + valueModified.value = true; displayValue.value = value; if (updateOn.value === 'change') { handleValueChange(value); diff --git a/packages/mobile-ui-vue/components/input-group/src/composition/use-input-state.ts b/packages/mobile-ui-vue/components/input-group/src/composition/use-input-state.ts index b73cf4761b7..6f1fe83499d 100644 --- a/packages/mobile-ui-vue/components/input-group/src/composition/use-input-state.ts +++ b/packages/mobile-ui-vue/components/input-group/src/composition/use-input-state.ts @@ -44,6 +44,7 @@ export function useInputState(props: InputProps, inputRef: Ref(''); const displayValue = ref(''); + const valueModified = ref(false); // 处理自定义格式化函数 const getDisplayValue = (value: string | number) => { @@ -60,6 +61,7 @@ export function useInputState(props: InputProps, inputRef: Ref { + value = getModelValue(value); updateInnerValue(value); updateDisplayValue(innerValue.value); }; @@ -108,6 +110,7 @@ export function useInputState(props: InputProps, inputRef: Ref, @@ -28,14 +28,14 @@ export const useLookupState = ( updateInputValue(); }); - const handleConfirm = (value: any[]) => { + const handleConfirm = (value: string) => { showPopup.value = false; updateInputValue(); emit('confirm', value); emit('update:modelValue', value); }; - const handleChange = (value: ColumnItem) => { + const handleChange = (value: ListDataItem) => { emit('change', value); }; diff --git a/packages/mobile-ui-vue/components/picker-group/src/composition/use-picker-group-context.ts b/packages/mobile-ui-vue/components/picker-group/src/composition/use-picker-group-context.ts index eb00f48bc6e..325a116c3bd 100644 --- a/packages/mobile-ui-vue/components/picker-group/src/composition/use-picker-group-context.ts +++ b/packages/mobile-ui-vue/components/picker-group/src/composition/use-picker-group-context.ts @@ -1,6 +1,6 @@ import { onMounted, reactive, ref, watch } from 'vue'; import { useChildrenContexts } from '@components/common'; -import { GroupContext, GroupItem, PickerContext, PickerGroupKey } from '@/components/picker'; +import { GroupContext, GroupItem, PickerContext, PickerGroupKey } from '@/components/picker-panel'; export const usePickerGroupContext = () => { const innerValue = ref(); diff --git a/packages/mobile-ui-vue/components/picker-input/index.ts b/packages/mobile-ui-vue/components/picker-input/index.ts deleted file mode 100644 index 02d38dfc325..00000000000 --- a/packages/mobile-ui-vue/components/picker-input/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { withInstall } from '@components/common'; -import PickerInputInstallless from "./src/picker-input.component"; -import { propsResolver } from './src/picker-input.props'; -import EnumFieldInputDesign from './src/designer/enum-field-input.design.component'; - -export * from './src/picker-input.props'; -export * from './src/composition/use-picker-input-state'; - - -const ENUM_FIELD_REGISTERED_NAME = 'enum-field'; - -const PickerInput = withInstall(PickerInputInstallless); - -PickerInput.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { - componentMap[ENUM_FIELD_REGISTERED_NAME] = PickerInput; - propsResolverMap[ENUM_FIELD_REGISTERED_NAME] = propsResolver; -}; -PickerInput.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record) => { - componentMap[ENUM_FIELD_REGISTERED_NAME] = EnumFieldInputDesign; - propsResolverMap[ENUM_FIELD_REGISTERED_NAME] = propsResolver; -}; - -export { PickerInput }; -export default PickerInput; diff --git a/packages/mobile-ui-vue/components/picker-input/src/composition/use-picker-input-state.ts b/packages/mobile-ui-vue/components/picker-input/src/composition/use-picker-input-state.ts deleted file mode 100644 index f30617a8cd8..00000000000 --- a/packages/mobile-ui-vue/components/picker-input/src/composition/use-picker-input-state.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { SetupContext, onMounted, shallowRef } from 'vue'; -import { ButtonEditProps, useButtonEditProps } from '@/components/button-edit'; -import { ColumnItem } from '@/components/picker'; - -export const usePickerInputState = ( - props: Omit, - context: SetupContext<('change' | 'confirm' | 'update:modelValue')[]> -) => { - const { emit } = context; - - const { inputValue, showPopup, buttonEditProps } = useButtonEditProps(props); - - const componentRef = shallowRef(); - const updateInputValue = () => { - const { getTextValue } = componentRef.value; - inputValue.value = getTextValue(); - }; - - onMounted(() => { - updateInputValue(); - }); - - const handleConfirm = (value: any[]) => { - showPopup.value = false; - updateInputValue(); - emit('confirm', value); - emit('update:modelValue', value); - }; - - const handleChange = (value: ColumnItem) => { - emit('change', value); - }; - - return { - inputValue, - showPopup, - buttonEditProps, - componentRef, - handleChange, - handleConfirm - }; -}; diff --git a/packages/mobile-ui-vue/components/picker-input/src/picker-input.component.tsx b/packages/mobile-ui-vue/components/picker-input/src/picker-input.component.tsx deleted file mode 100644 index c2a5ac125ff..00000000000 --- a/packages/mobile-ui-vue/components/picker-input/src/picker-input.component.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { computed, defineComponent} from 'vue'; -import { ButtonEdit } from '@/components/button-edit'; -import { useBem } from '@components/common'; -import { Picker } from '@/components/picker'; -import { pickerInputProps, PickerInputProps, PICKER_INPUT_NAME } from './picker-input.props'; -import { usePickerInputState } from './composition/use-picker-input-state'; - -export default defineComponent({ - name: PICKER_INPUT_NAME, - props: pickerInputProps, - emits: ['change', 'confirm', 'update:modelValue'], - setup(props: PickerInputProps, context) { - - const { bem } = useBem(PICKER_INPUT_NAME); - - const { buttonEditProps, inputValue, showPopup, componentRef, handleChange, handleConfirm } = usePickerInputState(props, context); - - const pickerProps = computed(() => { - return { - ref: componentRef, - modelValue: props.modelValue, - title: props.title, - columns: props.columns, - valueField: props.valueField, - textField: props.textField, - childrenField: props.childrenField, - visiableOptionCount: props.visiableOptionCount, - onChange: handleChange, - onConfirm: handleConfirm, - onCancel: () => showPopup.value = false - }; - }); - - return () => ( - - - - ); - } -}); diff --git a/packages/mobile-ui-vue/components/picker-input/src/picker-input.props.ts b/packages/mobile-ui-vue/components/picker-input/src/picker-input.props.ts deleted file mode 100644 index 7a91fbf147f..00000000000 --- a/packages/mobile-ui-vue/components/picker-input/src/picker-input.props.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ExtractPropTypes } from 'vue'; -import { buttonEditProps } from '@/components/button-edit'; -import { pickerProps } from '@/components/picker'; -import { createPropsResolver } from '@/components/dynamic-resolver'; -import inputSchema from './schema/enum-field-input.schema.json'; -import { schemaMapper } from './schema/schema-mapper'; -import { schemaResolver } from './schema/schema-resolver'; - -export const PICKER_INPUT_NAME = 'FmPickerInput'; - -export const pickerInputProps = { - ...buttonEditProps, - ...pickerProps -}; - -export type PickerInputProps = ExtractPropTypes; - -export const propsResolver = createPropsResolver(pickerInputProps, inputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/picker-panel/index.ts b/packages/mobile-ui-vue/components/picker-panel/index.ts new file mode 100644 index 00000000000..cb110a37565 --- /dev/null +++ b/packages/mobile-ui-vue/components/picker-panel/index.ts @@ -0,0 +1,11 @@ +import { withInstall } from '@components/common'; +import PickerPanelInstallless from './src/picker-panel.component'; + +export * from './src/picker-panel.props'; +export * from './src/types'; +export { PickerGroupKey } from './src/composition'; + +const PickerPanel = withInstall(PickerPanelInstallless); + +export { PickerPanel }; +export default PickerPanel; diff --git a/packages/mobile-ui-vue/components/picker/src/components/column.component.tsx b/packages/mobile-ui-vue/components/picker-panel/src/components/column.component.tsx similarity index 92% rename from packages/mobile-ui-vue/components/picker/src/components/column.component.tsx rename to packages/mobile-ui-vue/components/picker-panel/src/components/column.component.tsx index e1518bc8d4e..47495b4e140 100644 --- a/packages/mobile-ui-vue/components/picker/src/components/column.component.tsx +++ b/packages/mobile-ui-vue/components/picker-panel/src/components/column.component.tsx @@ -1,6 +1,6 @@ import { CSSProperties, SetupContext, computed, defineComponent } from 'vue'; import { addUnit, useBem } from '@components/common'; -import { PICKER_NAME } from '../picker.props'; +import { PICKER_PANEL_NAME } from '../picker-panel.props'; import { useColumnTouch } from '../composition'; import { ColumnProps, columnProps } from './column.props'; @@ -8,7 +8,7 @@ export default defineComponent({ props: columnProps, emits: ['change'], setup(props: ColumnProps, context: SetupContext<('change')[]>) { - const { bem } = useBem(PICKER_NAME); + const { bem } = useBem(PICKER_PANEL_NAME); const { translateY, diff --git a/packages/mobile-ui-vue/components/picker/src/components/column.props.ts b/packages/mobile-ui-vue/components/picker-panel/src/components/column.props.ts similarity index 100% rename from packages/mobile-ui-vue/components/picker/src/components/column.props.ts rename to packages/mobile-ui-vue/components/picker-panel/src/components/column.props.ts diff --git a/packages/mobile-ui-vue/components/picker/src/composition/index.ts b/packages/mobile-ui-vue/components/picker-panel/src/composition/index.ts similarity index 43% rename from packages/mobile-ui-vue/components/picker/src/composition/index.ts rename to packages/mobile-ui-vue/components/picker-panel/src/composition/index.ts index 7e511dd694d..8f25c94d995 100644 --- a/packages/mobile-ui-vue/components/picker/src/composition/index.ts +++ b/packages/mobile-ui-vue/components/picker-panel/src/composition/index.ts @@ -1,4 +1,4 @@ export * from './use-columns'; -export * from './use-picker-state'; export * from './use-column-touch'; -export * from './use-picker-context'; +export * from './use-picker-panel-state'; +export * from './use-picker-panel-context'; diff --git a/packages/mobile-ui-vue/components/picker/src/composition/use-column-touch.ts b/packages/mobile-ui-vue/components/picker-panel/src/composition/use-column-touch.ts similarity index 100% rename from packages/mobile-ui-vue/components/picker/src/composition/use-column-touch.ts rename to packages/mobile-ui-vue/components/picker-panel/src/composition/use-column-touch.ts diff --git a/packages/mobile-ui-vue/components/picker/src/composition/use-columns.ts b/packages/mobile-ui-vue/components/picker-panel/src/composition/use-columns.ts similarity index 95% rename from packages/mobile-ui-vue/components/picker/src/composition/use-columns.ts rename to packages/mobile-ui-vue/components/picker-panel/src/composition/use-columns.ts index a02d2da02c9..1e8dde43617 100644 --- a/packages/mobile-ui-vue/components/picker/src/composition/use-columns.ts +++ b/packages/mobile-ui-vue/components/picker-panel/src/composition/use-columns.ts @@ -1,9 +1,9 @@ import { computed, } from 'vue'; import { isArray, isFunction, isObject } from '@components/common'; -import { PickerProps } from '../picker.props'; +import { PickerPanelProps } from '../picker-panel.props'; import { Column, ColumnItem, Columns, UseColumns, UsePickerState, ValueType } from '../types'; -export const useColumns = (props: PickerProps, pickerState: UsePickerState): UseColumns => { +export const useColumns = (props: PickerPanelProps, pickerState: UsePickerState): UseColumns => { const { innerValue, setValueByIndex, getValueByIndex } = pickerState; const getFirstColumnItem = (column: Column) => { diff --git a/packages/mobile-ui-vue/components/picker/src/composition/use-picker-context.ts b/packages/mobile-ui-vue/components/picker-panel/src/composition/use-picker-panel-context.ts similarity index 84% rename from packages/mobile-ui-vue/components/picker/src/composition/use-picker-context.ts rename to packages/mobile-ui-vue/components/picker-panel/src/composition/use-picker-panel-context.ts index 366fe24da69..6af411f4e0d 100644 --- a/packages/mobile-ui-vue/components/picker/src/composition/use-picker-context.ts +++ b/packages/mobile-ui-vue/components/picker-panel/src/composition/use-picker-panel-context.ts @@ -1,11 +1,11 @@ import { getCurrentInstance, watch } from 'vue'; import { random, useParentContext } from '@components/common'; -import { PickerProps } from '../picker.props'; +import { PickerPanelProps } from '../picker-panel.props'; import { GroupContext, PickerContext } from '../types'; export const PickerGroupKey = Symbol('PickerGroupKey'); -export const usePickerContext = (props: PickerProps) => { +export const usePickerContext = (props: PickerPanelProps) => { const name = random(1000, 10000); const instance = getCurrentInstance(); const context: PickerContext = { name, instance }; diff --git a/packages/mobile-ui-vue/components/picker-panel/src/composition/use-picker-panel-state.ts b/packages/mobile-ui-vue/components/picker-panel/src/composition/use-picker-panel-state.ts new file mode 100644 index 00000000000..8625d6eb6e1 --- /dev/null +++ b/packages/mobile-ui-vue/components/picker-panel/src/composition/use-picker-panel-state.ts @@ -0,0 +1,35 @@ +import { ref, watch } from 'vue'; +import { isArray, isDef, isString } from '@components/common'; +import { PickerPanelProps } from '../picker-panel.props'; +import { UsePickerState, ValueType } from '../types'; + +export const usePickerState = (props: PickerPanelProps): UsePickerState => { + const formatValue = (value: string | ValueType[]) => + isArray(value) ? value : isString(value) ? value.split(',') : isDef(value) ? [value] : []; + + const innerValue = ref(formatValue(props.modelValue)); + + const setValueByIndex = (index: number, value: ValueType) => { + innerValue.value[index] = value; + }; + + const getValueByIndex = (index: number) => { + return innerValue.value[index]; + }; + + watch( + () => props.modelValue, + (newValue) => { + innerValue.value = formatValue(newValue); + } + ); + + const lineHeight = 44; + + return { + innerValue, + lineHeight, + setValueByIndex, + getValueByIndex + }; +}; diff --git a/packages/mobile-ui-vue/components/picker-panel/src/picker-panel.component.tsx b/packages/mobile-ui-vue/components/picker-panel/src/picker-panel.component.tsx new file mode 100644 index 00000000000..ee373d59394 --- /dev/null +++ b/packages/mobile-ui-vue/components/picker-panel/src/picker-panel.component.tsx @@ -0,0 +1,98 @@ +import { CSSProperties, computed, defineComponent } from 'vue'; +import { useBem, addUnit } from '@components/common'; +import { pickerPanelProps, PICKER_PANEL_NAME } from './picker-panel.props'; +import { useColumns, usePickerState, usePickerContext } from './composition'; +import ColumnComponent from './components/column.component'; +import { PickerChange, ValueType } from './types'; + +export default defineComponent({ + name: PICKER_PANEL_NAME, + props: pickerPanelProps, + emits: ['change', 'confirm', 'cancel', 'update:modelValue'], + setup(props, context) { + const { emit, expose } = context; + + // add context to picker group + usePickerContext(props); + + const pickerStateComposition = usePickerState(props); + const { innerValue, lineHeight, setValueByIndex } = pickerStateComposition; + + const { columns, getPickeds, getValue, getTextValue, setDefaultValue } = useColumns(props, pickerStateComposition); + + expose({ getTextValue, getValue, getPickeds }); + + const { bem } = useBem(PICKER_PANEL_NAME); + + const onChange = (change: PickerChange) => { + const { value, index } = change; + emit('change', change); + setValueByIndex(index, value[props.valueField] as ValueType); + }; + + const onConfirm = () => { + setDefaultValue(); + emit('confirm', innerValue.value); + emit('update:modelValue', innerValue.value); + }; + + const onCancel = () => { + emit('cancel'); + }; + + const renderToolbar = () => ( +
    +
    + {props.cancelText} +
    +
    + {props.title} +
    +
    + {props.confirmText} +
    +
    + ); + + const columnsStyle = computed(() => { + const columnsHeight = (props.visiableOptionCount + 1) * lineHeight; + return { + height: addUnit(columnsHeight) + }; + }); + + const maskStyle = computed(() => { + const sizeY = (props.visiableOptionCount * lineHeight) / 2; + return { + backgroundSize: `100% ${addUnit(sizeY)}` + }; + }); + + const renderColumns = () => ( +
    +
    + {columns.value.map((column, index) => ( + + ))} +
    +
    +
    +
    + ); + + return () => ( +
    + {props.showToolbar && renderToolbar()} + {renderColumns()} +
    + ); + } +}); diff --git a/packages/mobile-ui-vue/components/picker-panel/src/picker-panel.props.ts b/packages/mobile-ui-vue/components/picker-panel/src/picker-panel.props.ts new file mode 100644 index 00000000000..cce7bde03ac --- /dev/null +++ b/packages/mobile-ui-vue/components/picker-panel/src/picker-panel.props.ts @@ -0,0 +1,30 @@ +import { ExtractPropTypes, PropType } from 'vue'; +import { Column, ColumnItem, Columns, ValueType } from "./types"; + +export const PICKER_PANEL_NAME = 'FmPickerPanel'; + +export const pickerPanelProps = { + modelValue: { type: [String, Array], default: '' }, + + columns: { type: Array as PropType, default: () => [] }, + + title: { type: String, default: '' }, + + valueField: { type: String, default: 'value' }, + + textField: { type: String, default: 'text' }, + + childrenField: { type: String, default: 'children' }, + + cancelText: { type: String, default: '取消' }, + + confirmText: { type: String, default: '确定' }, + + optionFormatter: { type: Function as PropType<(index: number, item: ColumnItem) => string>, default: undefined }, + + visiableOptionCount: { type: Number, default: 5 }, + + showToolbar: { type: Boolean, default: true } +}; + +export type PickerPanelProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/picker-panel/src/picker-panel.scss b/packages/mobile-ui-vue/components/picker-panel/src/picker-panel.scss new file mode 100644 index 00000000000..19e58de7c5f --- /dev/null +++ b/packages/mobile-ui-vue/components/picker-panel/src/picker-panel.scss @@ -0,0 +1,76 @@ +@use '../../common/src/style/mixins/index.scss' as *; + +:root { + --fm-picker-background: var(--fm-white); + --fm-picker-toolbar-height: 44px; +} +.fm-picker-panel { + position: relative; + background-color: var(--fm-picker-background); + user-select: none; + &__toolbar { + display: flex; + justify-content: space-between; + align-items: center; + height: var(--fm-picker-toolbar-height); + &-left, + &-right { + padding: 0 16px; + } + &-title { + font-weight: 500; + font-size: 16px; + max-width: 50%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + } + &__content { + position: relative; + display: flex; + cursor: grab; + } + &__columns { + display: flex; + flex: 1; + overflow: hidden; + + } + &__column { + flex: 1; + &-item { + display: flex; + align-items: center; + justify-content: center; + height: 44px; + } + } + &__mask { + position: absolute; + top: 0; + left: 0; + z-index: 1; + width: 100%; + height: 100%; + background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.4)), + linear-gradient(0deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.4)); + background-repeat: no-repeat; + background-position: top, bottom; + transform: translateZ(0); + pointer-events: none; + } + &__frame { + position: absolute; + top: 50%; + left: 16px; + right: 16px; + height: 88px; + z-index: 2; + pointer-events: none; + border-width: 1px 0; + border-style: solid; + border-color: #ebedf0; + transform: translateY(-50%) scaleY(0.5); + } +} diff --git a/packages/mobile-ui-vue/components/picker/src/types/index.ts b/packages/mobile-ui-vue/components/picker-panel/src/types/index.ts similarity index 91% rename from packages/mobile-ui-vue/components/picker/src/types/index.ts rename to packages/mobile-ui-vue/components/picker-panel/src/types/index.ts index a3a8bc61ae2..b42d6b7d200 100644 --- a/packages/mobile-ui-vue/components/picker/src/types/index.ts +++ b/packages/mobile-ui-vue/components/picker-panel/src/types/index.ts @@ -7,11 +7,11 @@ export type ColumnItem = { [key: string]: ValueType | Column; }; -export type Column = ColumnItem[]; +export type Column = T[]; export type Columns = Column[]; -export type PickerChange = { index: number; value: ColumnItem }; +export type PickerChange = { index: number; value: T }; export interface UsePickerState { innerValue: Ref; diff --git a/packages/mobile-ui-vue/components/picker/index.ts b/packages/mobile-ui-vue/components/picker/index.ts index dbecc9f6d75..70833a65e2e 100644 --- a/packages/mobile-ui-vue/components/picker/index.ts +++ b/packages/mobile-ui-vue/components/picker/index.ts @@ -1,11 +1,24 @@ import { withInstall } from '@components/common'; -import PickerInstallless from './src/picker.component'; +import PickerInstallless from "./src/picker.component"; +import { propsResolver } from './src/picker.props'; +import EnumFieldInputDesign from './src/designer/enum-field-input.design.component'; export * from './src/picker.props'; -export * from './src/types'; -export { PickerGroupKey } from './src/composition'; +export * from './src/composition/use-picker-state'; + + +const ENUM_FIELD_REGISTERED_NAME = 'enum-field'; const Picker = withInstall(PickerInstallless); +Picker.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { + componentMap[ENUM_FIELD_REGISTERED_NAME] = Picker; + propsResolverMap[ENUM_FIELD_REGISTERED_NAME] = propsResolver; +}; +Picker.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record) => { + componentMap[ENUM_FIELD_REGISTERED_NAME] = EnumFieldInputDesign; + propsResolverMap[ENUM_FIELD_REGISTERED_NAME] = propsResolver; +}; + export { Picker }; export default Picker; diff --git a/packages/mobile-ui-vue/components/picker/src/composition/use-picker-state.ts b/packages/mobile-ui-vue/components/picker/src/composition/use-picker-state.ts index 0492000a48a..380f3235416 100644 --- a/packages/mobile-ui-vue/components/picker/src/composition/use-picker-state.ts +++ b/packages/mobile-ui-vue/components/picker/src/composition/use-picker-state.ts @@ -1,35 +1,42 @@ -import { ref, watch } from 'vue'; -import { isArray, isDef, isString } from '@components/common'; -import { PickerProps } from '../picker.props'; -import { UsePickerState, ValueType } from '../types'; +import { SetupContext, onMounted, shallowRef } from 'vue'; +import { ButtonEditProps, useButtonEditProps } from '@/components/button-edit'; +import { ColumnItem } from '@/components/picker-panel'; -export const usePickerState = (props: PickerProps): UsePickerState => { - const formatValue = (value: string | ValueType[]) => - isArray(value) ? value : isString(value) ? value.split(',') : isDef(value) ? [value] : []; +export const usePickerInputState = ( + props: Omit, + context: SetupContext<('change' | 'confirm' | 'update:modelValue')[]> +) => { + const { emit } = context; - const innerValue = ref(formatValue(props.modelValue)); + const { inputValue, showPopup, buttonEditProps } = useButtonEditProps(props); - const setValueByIndex = (index: number, value: ValueType) => { - innerValue.value[index] = value; + const componentRef = shallowRef(); + const updateInputValue = () => { + const { getTextValue } = componentRef.value; + inputValue.value = getTextValue(); }; - const getValueByIndex = (index: number) => { - return innerValue.value[index]; - }; + onMounted(() => { + updateInputValue(); + }); - watch( - () => props.modelValue, - (newValue) => { - innerValue.value = formatValue(newValue); - } - ); + const handleConfirm = (value: any[]) => { + showPopup.value = false; + updateInputValue(); + emit('confirm', value); + emit('update:modelValue', value); + }; - const lineHeight = 44; + const handleChange = (value: ColumnItem) => { + emit('change', value); + }; return { - innerValue, - lineHeight, - setValueByIndex, - getValueByIndex + inputValue, + showPopup, + buttonEditProps, + componentRef, + handleChange, + handleConfirm }; }; diff --git a/packages/mobile-ui-vue/components/picker-input/src/designer/enum-field-input.design.component.tsx b/packages/mobile-ui-vue/components/picker/src/designer/enum-field-input.design.component.tsx similarity index 91% rename from packages/mobile-ui-vue/components/picker-input/src/designer/enum-field-input.design.component.tsx rename to packages/mobile-ui-vue/components/picker/src/designer/enum-field-input.design.component.tsx index 3ccda1531ed..3f8befcd97a 100644 --- a/packages/mobile-ui-vue/components/picker-input/src/designer/enum-field-input.design.component.tsx +++ b/packages/mobile-ui-vue/components/picker/src/designer/enum-field-input.design.component.tsx @@ -15,15 +15,16 @@ * limitations under the License. */ import { computed, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; -import { PickerInput, pickerInputProps, PickerInputProps } from '../..'; import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas'; +import { pickerProps } from '../picker.props'; +import Picker from '../picker.component'; import { useEnumFieldDesignerRules } from './use-designer-rules';; export default defineComponent({ name: 'FmEnumFieldInputDesign', - props: pickerInputProps, + props: pickerProps, emits: [] as (string[] & ThisType) | undefined, - setup(props: PickerInputProps, context: SetupContext) { + setup(props, context: SetupContext) { const elementRef = ref(); const designerHostService = inject('designer-host-service'); const designItemContext = inject('design-item-context') as DesignerItemContext; @@ -67,7 +68,7 @@ export default defineComponent({ return () => { return ( - + ); }; } diff --git a/packages/mobile-ui-vue/components/picker-input/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/picker/src/designer/use-designer-rules.ts similarity index 100% rename from packages/mobile-ui-vue/components/picker-input/src/designer/use-designer-rules.ts rename to packages/mobile-ui-vue/components/picker/src/designer/use-designer-rules.ts diff --git a/packages/mobile-ui-vue/components/picker/src/picker.component.tsx b/packages/mobile-ui-vue/components/picker/src/picker.component.tsx index 93f8973f897..86c50474f40 100644 --- a/packages/mobile-ui-vue/components/picker/src/picker.component.tsx +++ b/packages/mobile-ui-vue/components/picker/src/picker.component.tsx @@ -1,114 +1,45 @@ -/** - * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { CSSProperties, computed, defineComponent } from 'vue'; -import { useBem, addUnit } from '@components/common'; -import { PickerProps, pickerProps, PICKER_NAME } from './picker.props'; -import { useColumns, usePickerState, usePickerContext } from './composition'; -import ColumnComponent from './components/column.component'; -import { PickerChange, ValueType } from './types'; +import { computed, defineComponent} from 'vue'; +import { ButtonEdit } from '@/components/button-edit'; +import { useBem } from '@components/common'; +import { PickerPanel } from '@/components/picker-panel'; +import { pickerProps, PICKER_NAME } from './picker.props'; +import { usePickerInputState } from './composition/use-picker-state'; export default defineComponent({ name: PICKER_NAME, props: pickerProps, - emits: ['change', 'confirm', 'cancel', 'update:modelValue'], - setup(props: PickerProps, context) { - const { emit, expose } = context; - - // add context to picker group - usePickerContext(props); - - const pickerStateComposition = usePickerState(props); - const { innerValue, lineHeight, setValueByIndex } = pickerStateComposition; - - const { columns, getPickeds, getValue, getTextValue, setDefaultValue } = useColumns(props, pickerStateComposition); - - expose({ getTextValue, getValue, getPickeds }); + emits: ['change', 'confirm', 'update:modelValue'], + setup(props, context) { const { bem } = useBem(PICKER_NAME); - const onChange = (change: PickerChange) => { - const { value, index } = change; - emit('change', change); - setValueByIndex(index, value[props.valueField] as ValueType); - }; - - const onConfirm = () => { - setDefaultValue(); - emit('confirm', innerValue.value); - emit('update:modelValue', innerValue.value); - }; + const { buttonEditProps, inputValue, showPopup, componentRef, handleChange, handleConfirm } = usePickerInputState(props, context); - const onCancel = () => { - emit('cancel'); - }; - - const renderToolbar = () => ( -
    -
    - {props.cancelText} -
    -
    - {props.title} -
    -
    - {props.confirmText} -
    -
    - ); - - const columnsStyle = computed(() => { - const columnsHeight = (props.visiableOptionCount + 1) * lineHeight; + const pickerProps = computed(() => { return { - height: addUnit(columnsHeight) + ref: componentRef, + modelValue: props.modelValue, + title: props.title, + columns: props.columns, + valueField: props.valueField, + textField: props.textField, + childrenField: props.childrenField, + visiableOptionCount: props.visiableOptionCount, + onChange: handleChange, + onConfirm: handleConfirm, + onCancel: () => showPopup.value = false }; }); - const maskStyle = computed(() => { - const sizeY = (props.visiableOptionCount * lineHeight) / 2; - return { - backgroundSize: `100% ${addUnit(sizeY)}` - }; - }); - - const renderColumns = () => ( -
    -
    - {columns.value.map((column, index) => ( - - ))} -
    -
    -
    -
    - ); - return () => ( -
    - {props.showToolbar && renderToolbar()} - {renderColumns()} -
    + + + ); } }); diff --git a/packages/mobile-ui-vue/components/picker/src/picker.props.ts b/packages/mobile-ui-vue/components/picker/src/picker.props.ts index 15078852c60..d91aaf24cb4 100644 --- a/packages/mobile-ui-vue/components/picker/src/picker.props.ts +++ b/packages/mobile-ui-vue/components/picker/src/picker.props.ts @@ -1,30 +1,18 @@ -import { ExtractPropTypes, PropType } from 'vue'; -import { Column, ColumnItem, Columns, ValueType } from "./types"; +import { ExtractPropTypes } from 'vue'; +import { buttonEditProps } from '@/components/button-edit'; +import { pickerPanelProps } from '@/components/picker-panel'; +import { createPropsResolver } from '@/components/dynamic-resolver'; +import inputSchema from './schema/enum-field-input.schema.json'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; export const PICKER_NAME = 'FmPicker'; export const pickerProps = { - modelValue: { type: [String, Array], default: '' }, - - columns: { type: Array as PropType, default: () => [] }, - - title: { type: String, default: '' }, - - valueField: { type: String, default: 'value' }, - - textField: { type: String, default: 'text' }, - - childrenField: { type: String, default: 'children' }, - - cancelText: { type: String, default: '取消' }, - - confirmText: { type: String, default: '确定' }, - - optionFormatter: { type: Function as PropType<(index: number, item: ColumnItem) => string>, default: undefined }, - - visiableOptionCount: { type: Number, default: 5 }, - - showToolbar: { type: Boolean, default: true } + ...buttonEditProps, + ...pickerPanelProps }; export type PickerProps = ExtractPropTypes; + +export const propsResolver = createPropsResolver(pickerProps, inputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/picker/src/picker.scss b/packages/mobile-ui-vue/components/picker/src/picker.scss index f82ac03c0b7..e69de29bb2d 100644 --- a/packages/mobile-ui-vue/components/picker/src/picker.scss +++ b/packages/mobile-ui-vue/components/picker/src/picker.scss @@ -1,76 +0,0 @@ -@use '../../common/src/style/mixins/index.scss' as *; - -:root { - --fm-picker-background: var(--fm-white); - --fm-picker-toolbar-height: 44px; -} -.fm-picker { - position: relative; - background-color: var(--fm-picker-background); - user-select: none; - &__toolbar { - display: flex; - justify-content: space-between; - align-items: center; - height: var(--fm-picker-toolbar-height); - &-left, - &-right { - padding: 0 16px; - } - &-title { - font-weight: 500; - font-size: 16px; - max-width: 50%; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - } - &__content { - position: relative; - display: flex; - cursor: grab; - } - &__columns { - display: flex; - flex: 1; - overflow: hidden; - - } - &__column { - flex: 1; - &-item { - display: flex; - align-items: center; - justify-content: center; - height: 44px; - } - } - &__mask { - position: absolute; - top: 0; - left: 0; - z-index: 1; - width: 100%; - height: 100%; - background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.4)), - linear-gradient(0deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.4)); - background-repeat: no-repeat; - background-position: top, bottom; - transform: translateZ(0); - pointer-events: none; - } - &__frame { - position: absolute; - top: 50%; - left: 16px; - right: 16px; - height: 88px; - z-index: 2; - pointer-events: none; - border-width: 1px 0; - border-style: solid; - border-color: #ebedf0; - transform: translateY(-50%) scaleY(0.5); - } -} diff --git a/packages/mobile-ui-vue/components/picker-input/src/property-config/enum-field-input.property-config.ts b/packages/mobile-ui-vue/components/picker/src/property-config/enum-field-input.property-config.ts similarity index 100% rename from packages/mobile-ui-vue/components/picker-input/src/property-config/enum-field-input.property-config.ts rename to packages/mobile-ui-vue/components/picker/src/property-config/enum-field-input.property-config.ts diff --git a/packages/mobile-ui-vue/components/picker-input/src/schema/enum-field-input.schema.json b/packages/mobile-ui-vue/components/picker/src/schema/enum-field-input.schema.json similarity index 100% rename from packages/mobile-ui-vue/components/picker-input/src/schema/enum-field-input.schema.json rename to packages/mobile-ui-vue/components/picker/src/schema/enum-field-input.schema.json diff --git a/packages/mobile-ui-vue/components/picker-input/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/picker/src/schema/schema-mapper.ts similarity index 100% rename from packages/mobile-ui-vue/components/picker-input/src/schema/schema-mapper.ts rename to packages/mobile-ui-vue/components/picker/src/schema/schema-mapper.ts diff --git a/packages/mobile-ui-vue/components/picker-input/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/picker/src/schema/schema-resolver.ts similarity index 100% rename from packages/mobile-ui-vue/components/picker-input/src/schema/schema-resolver.ts rename to packages/mobile-ui-vue/components/picker/src/schema/schema-resolver.ts diff --git a/packages/mobile-ui-vue/components/time-picker-input/index.ts b/packages/mobile-ui-vue/components/time-picker-input/index.ts deleted file mode 100644 index b8ced42ff2f..00000000000 --- a/packages/mobile-ui-vue/components/time-picker-input/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { withInstall } from '@components/common'; -import TimePickerInputInstallless from './src/time-picker-input.component'; - -const TimePickerInput = withInstall(TimePickerInputInstallless); - -export { TimePickerInput }; -export default TimePickerInput; diff --git a/packages/mobile-ui-vue/components/time-picker-input/src/time-picker-input.component.tsx b/packages/mobile-ui-vue/components/time-picker-input/src/time-picker-input.component.tsx deleted file mode 100644 index 37286092b95..00000000000 --- a/packages/mobile-ui-vue/components/time-picker-input/src/time-picker-input.component.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { computed, defineComponent } from 'vue'; -import { useBem } from '@components/common'; -import TimePicker from '@/components/time-picker'; -import ButtonEdit from '@/components/button-edit'; -import { usePickerInputState } from '@/components/picker-input'; -import { timePickerInputProps, TimePickerInputProps, TIME_PICKER_INPUT_NAME } from './time-picker-input.props'; - -export default defineComponent({ - name: TIME_PICKER_INPUT_NAME, - props: timePickerInputProps, - emits: ['change', 'confirm', 'update:modelValue'], - setup(props: TimePickerInputProps, context) { - - const { bem } = useBem(TIME_PICKER_INPUT_NAME); - - const { buttonEditProps, inputValue, showPopup, componentRef, handleChange, handleConfirm } = usePickerInputState(props, context); - - const pickerProps = computed(() => { - return { - ref: componentRef, - title: props.title, - type: props.type, - format: props.format, - maxTime: props.maxTime, - minTime: props.minTime, - visiableOptionCount: props.visiableOptionCount, - optionFormatter: props.optionFormatter, - onChange: handleChange, - onConfirm: handleConfirm, - onCancel: () => showPopup.value = false - }; - }); - - return () => ( - - - - ); - } -}); diff --git a/packages/mobile-ui-vue/components/time-picker-input/src/time-picker-input.props.ts b/packages/mobile-ui-vue/components/time-picker-input/src/time-picker-input.props.ts deleted file mode 100644 index 776df6db0f0..00000000000 --- a/packages/mobile-ui-vue/components/time-picker-input/src/time-picker-input.props.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { ExtractPropTypes } from 'vue'; -import { buttonEditProps } from '@/components/button-edit'; -import { timePickerProps } from '@/components/time-picker'; - -export const TIME_PICKER_INPUT_NAME = 'FmTimePickerInput'; - -export const timePickerInputProps = { - ...buttonEditProps, - ...timePickerProps, - - round: { type: Boolean, default: false } -}; - -export type TimePickerInputProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/time-picker-panel/index.ts b/packages/mobile-ui-vue/components/time-picker-panel/index.ts new file mode 100644 index 00000000000..a731b780417 --- /dev/null +++ b/packages/mobile-ui-vue/components/time-picker-panel/index.ts @@ -0,0 +1,9 @@ +import { withInstall } from '@components/common'; +import TimePickerPanelInstallless from './src/time-picker-panel.component'; + +export * from './src/time-picker-panel.props'; + +const TimePickerPanel = withInstall(TimePickerPanelInstallless); + +export { TimePickerPanel }; +export default TimePickerPanel; diff --git a/packages/mobile-ui-vue/components/time-picker/src/composition/index.ts b/packages/mobile-ui-vue/components/time-picker-panel/src/composition/index.ts similarity index 100% rename from packages/mobile-ui-vue/components/time-picker/src/composition/index.ts rename to packages/mobile-ui-vue/components/time-picker-panel/src/composition/index.ts diff --git a/packages/mobile-ui-vue/components/time-picker/src/composition/use-time-columns.ts b/packages/mobile-ui-vue/components/time-picker-panel/src/composition/use-time-columns.ts similarity index 90% rename from packages/mobile-ui-vue/components/time-picker/src/composition/use-time-columns.ts rename to packages/mobile-ui-vue/components/time-picker-panel/src/composition/use-time-columns.ts index 9d36e3e0ae8..ee2745dfe2c 100644 --- a/packages/mobile-ui-vue/components/time-picker/src/composition/use-time-columns.ts +++ b/packages/mobile-ui-vue/components/time-picker-panel/src/composition/use-time-columns.ts @@ -1,7 +1,7 @@ import { computed, watch, ref } from 'vue'; -import { Columns, Column, PickerChange } from '@components/picker'; +import { Columns, Column, PickerChange } from '@components/picker-panel'; import { formatTime, getTimeRecord, } from "@components/common"; -import { TimePickerProps, TimePickerTypeMap } from "../time-picker.props"; +import { TimePickerPanelProps, TimePickerPanelTypeMap } from "../time-picker-panel.props"; enum TimeColumn { Hours = 'hours', @@ -9,7 +9,7 @@ enum TimeColumn { Seconds= 'seconds', } -export const useTimeColumns = (props: TimePickerProps) => { +export const useTimeColumns = (props: TimePickerPanelProps) => { const textField = 'text'; const valueField = 'value'; @@ -28,7 +28,7 @@ export const useTimeColumns = (props: TimePickerProps) => { return column; }; - const innerValue = ref([]); + const innerValue = ref([]); const formatValue = (value: string)=>{ const { hours, minutes, seconds } = getTimeRecord(value); @@ -104,7 +104,7 @@ export const useTimeColumns = (props: TimePickerProps) => { }; const columnsMap = computed(() => { - const type = props.type === TimePickerTypeMap.Time ? TimePickerTypeMap.HoursMinutesSeconds : props.type; + const type = props.type === TimePickerPanelTypeMap.Time ? TimePickerPanelTypeMap.HoursMinutesSeconds : props.type; return type.split('-'); }); @@ -122,12 +122,13 @@ export const useTimeColumns = (props: TimePickerProps) => { case TimeColumn.Minutes: return minutesColumn; case TimeColumn.Seconds: + default: return secondsColumn; } }); }); - const getTimeValue = (changes?: PickerChange)=>{ + const getTimeValue = (changes?: PickerChange)=>{ const times = [...innerValue.value]; if(changes) { const { index, value } = changes; diff --git a/packages/mobile-ui-vue/components/time-picker-panel/src/time-picker-panel.component.tsx b/packages/mobile-ui-vue/components/time-picker-panel/src/time-picker-panel.component.tsx new file mode 100644 index 00000000000..296dbe40df1 --- /dev/null +++ b/packages/mobile-ui-vue/components/time-picker-panel/src/time-picker-panel.component.tsx @@ -0,0 +1,49 @@ +import { defineComponent } from 'vue'; +import { PickerPanel, PickerChange } from '@components/picker-panel'; +import { useBem } from '@components/common'; +import { useTimeColumns } from './composition'; +import { timePickerPanelProps, TIME_PICKER_PANEL_NAME } from './time-picker-panel.props'; + +export default defineComponent({ + name: TIME_PICKER_PANEL_NAME, + inheritAttrs: false, + props: timePickerPanelProps, + emits: ['change', 'confirm', 'cancel'], + setup(props, context) { + const { emit, expose } = context; + + const { timeColumns, innerValue, textField, valueField, getTimeValue } = useTimeColumns(props); + + expose({ getTextValue: getTimeValue }); + + const handleChange = (changes: PickerChange)=>{ + emit('change', getTimeValue(changes)); + }; + + const handleConfirm = ()=>{ + emit('confirm', getTimeValue()); + }; + + const handleCanCel = ()=>{ + emit('cancel'); + }; + + const { bem } = useBem(TIME_PICKER_PANEL_NAME); + + return () => ( + + ); + } +}); diff --git a/packages/mobile-ui-vue/components/time-picker-panel/src/time-picker-panel.props.ts b/packages/mobile-ui-vue/components/time-picker-panel/src/time-picker-panel.props.ts new file mode 100644 index 00000000000..4789cb0b248 --- /dev/null +++ b/packages/mobile-ui-vue/components/time-picker-panel/src/time-picker-panel.props.ts @@ -0,0 +1,34 @@ +import { ExtractPropTypes, PropType } from 'vue'; + +export const TIME_PICKER_PANEL_NAME = 'FmTimePickerPanel'; + +export const enum TimePickerPanelTypeMap { + Hours = 'hours', + HoursMinutes = 'hours-minutes', + HoursMinutesSeconds = 'hours-minutes-seconds', + Time= 'time', +} + +export type TimePickerPanelType = `${TimePickerPanelTypeMap}`; + +export const timePickerPanelProps = { + title: { type: String, default: '' }, + + type: { type: String as PropType, default: TimePickerPanelTypeMap.Time }, + + modelValue: { type: String, default: '' }, + + format: { type: String, default: 'HH:mm:ss' }, + + maxTime: { type: String, default: undefined }, + + minTime: { type: String, default: undefined }, + + optionFormatter: { type: Function as PropType<(type: string, value: string) => string>, default: undefined }, + + visiableOptionCount: { type: Number, default: 5 }, + + showToolbar: { type: Boolean, default: true } +}; + +export type TimePickerPanelProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/time-picker-panel/src/time-picker-panel.scss b/packages/mobile-ui-vue/components/time-picker-panel/src/time-picker-panel.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/mobile-ui-vue/components/time-picker/index.ts b/packages/mobile-ui-vue/components/time-picker/index.ts index ac81c241a58..c7d881edc93 100644 --- a/packages/mobile-ui-vue/components/time-picker/index.ts +++ b/packages/mobile-ui-vue/components/time-picker/index.ts @@ -1,8 +1,6 @@ import { withInstall } from '@components/common'; import TimePickerInstallless from './src/time-picker.component'; -export * from './src/time-picker.props'; - const TimePicker = withInstall(TimePickerInstallless); export { TimePicker }; diff --git a/packages/mobile-ui-vue/components/time-picker/src/time-picker.component.tsx b/packages/mobile-ui-vue/components/time-picker/src/time-picker.component.tsx index 259f9c82ccd..30370f3623e 100644 --- a/packages/mobile-ui-vue/components/time-picker/src/time-picker.component.tsx +++ b/packages/mobile-ui-vue/components/time-picker/src/time-picker.component.tsx @@ -1,65 +1,45 @@ -/** - * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { defineComponent, SetupContext } from 'vue'; -import { Picker, PickerChange } from '@components/picker'; +import { computed, defineComponent } from 'vue'; import { useBem } from '@components/common'; -import { useTimeColumns } from './composition'; -import { timePickerProps, TimePickerProps, TIME_PICKER_NAME } from './time-picker.props'; +import { TimePickerPanel } from '@/components/time-picker-panel'; +import ButtonEdit from '@/components/button-edit'; +import { usePickerInputState } from '@/components/picker'; +import { timePickerProps, TIME_PICKER_NAME } from './time-picker.props'; export default defineComponent({ name: TIME_PICKER_NAME, - inheritAttrs: false, props: timePickerProps, - emits: ['change', 'confirm', 'cancel'], - setup(props: TimePickerProps, context: SetupContext) { - const { emit, expose } = context; - - const { timeColumns, innerValue, textField, valueField, getTimeValue } = useTimeColumns(props); - - expose({ getTextValue: getTimeValue }); - - const handleChange = (changes: PickerChange)=>{ - emit('change', getTimeValue(changes)); - }; - - const handleConfirm = ()=>{ - emit('confirm', getTimeValue()); - }; - - const handleCanCel = ()=>{ - emit('cancel'); - }; + emits: ['change', 'confirm', 'update:modelValue'], + setup(props, context) { const { bem } = useBem(TIME_PICKER_NAME); + const { buttonEditProps, inputValue, showPopup, componentRef, handleChange, handleConfirm } = usePickerInputState(props, context); + + const pickerProps = computed(() => { + return { + ref: componentRef, + title: props.title, + type: props.type, + format: props.format, + maxTime: props.maxTime, + minTime: props.minTime, + visiableOptionCount: props.visiableOptionCount, + optionFormatter: props.optionFormatter, + onChange: handleChange, + onConfirm: handleConfirm, + onCancel: () => showPopup.value = false + }; + }); + return () => ( - + + + ); } }); diff --git a/packages/mobile-ui-vue/components/time-picker/src/time-picker.props.ts b/packages/mobile-ui-vue/components/time-picker/src/time-picker.props.ts index 19ac8be075e..05eba02a190 100644 --- a/packages/mobile-ui-vue/components/time-picker/src/time-picker.props.ts +++ b/packages/mobile-ui-vue/components/time-picker/src/time-picker.props.ts @@ -1,34 +1,14 @@ -import { ExtractPropTypes, PropType } from 'vue'; +import { ExtractPropTypes } from 'vue'; +import { buttonEditProps } from '@/components/button-edit'; +import { timePickerPanelProps } from '@/components/time-picker-panel'; -export const TIME_PICKER_NAME = 'fm-time-picker'; - -export const enum TimePickerTypeMap { - Hours = 'hours', - HoursMinutes = 'hours-minutes', - HoursMinutesSeconds = 'hours-minutes-seconds', - Time= 'time', -} - -export type TimePickerType = `${TimePickerTypeMap}`; +export const TIME_PICKER_NAME = 'FmTimePicker'; export const timePickerProps = { - title: { type: String, default: '' }, - - type: { type: String as PropType, default: TimePickerTypeMap.Time }, - - modelValue: { type: String, default: '' }, - - format: { type: String, default: 'HH:mm:ss' }, - - maxTime: { type: String, default: undefined }, - - minTime: { type: String, default: undefined }, - - optionFormatter: { type: Function as PropType<(type: string, value: string) => string>, default: undefined }, - - visiableOptionCount: { type: Number, default: 5 }, + ...buttonEditProps, + ...timePickerPanelProps, - showToolbar: { type: Boolean, default: true } + round: { type: Boolean, default: false } }; -export type TimePickerProps = ExtractPropTypes; +export type TimePickerInputProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/demos/date-picker/basic.vue b/packages/mobile-ui-vue/demos/date-picker/basic.vue index 75a8b98d453..e7443d19a2e 100644 --- a/packages/mobile-ui-vue/demos/date-picker/basic.vue +++ b/packages/mobile-ui-vue/demos/date-picker/basic.vue @@ -1,3 +1,7 @@ + + diff --git a/packages/mobile-ui-vue/demos/date-picker/formatter.vue b/packages/mobile-ui-vue/demos/date-picker/formatter.vue index d9a8edf1650..602e3cdbb12 100644 --- a/packages/mobile-ui-vue/demos/date-picker/formatter.vue +++ b/packages/mobile-ui-vue/demos/date-picker/formatter.vue @@ -1,7 +1,9 @@ diff --git a/packages/mobile-ui-vue/demos/date-picker/min-max.vue b/packages/mobile-ui-vue/demos/date-picker/min-max.vue index 1cd4296bbed..eca028f83bc 100644 --- a/packages/mobile-ui-vue/demos/date-picker/min-max.vue +++ b/packages/mobile-ui-vue/demos/date-picker/min-max.vue @@ -1,7 +1,11 @@ + + diff --git a/packages/mobile-ui-vue/demos/date-picker/type.vue b/packages/mobile-ui-vue/demos/date-picker/type.vue index 3dff39088f7..816250c2e7e 100644 --- a/packages/mobile-ui-vue/demos/date-picker/type.vue +++ b/packages/mobile-ui-vue/demos/date-picker/type.vue @@ -1,3 +1,7 @@ + + diff --git a/packages/mobile-ui-vue/demos/date-time-picker/basic.vue b/packages/mobile-ui-vue/demos/date-time-picker/basic.vue index d42b6eaca62..7f456c2d958 100644 --- a/packages/mobile-ui-vue/demos/date-time-picker/basic.vue +++ b/packages/mobile-ui-vue/demos/date-time-picker/basic.vue @@ -1,3 +1,6 @@ + diff --git a/packages/mobile-ui-vue/demos/date-time-picker/formatter.vue b/packages/mobile-ui-vue/demos/date-time-picker/formatter.vue index d9a8edf1650..fcdb453ab0b 100644 --- a/packages/mobile-ui-vue/demos/date-time-picker/formatter.vue +++ b/packages/mobile-ui-vue/demos/date-time-picker/formatter.vue @@ -1,7 +1,9 @@ diff --git a/packages/mobile-ui-vue/demos/date-time-picker/max&min.vue b/packages/mobile-ui-vue/demos/date-time-picker/max&min.vue index 6ad65b1e2a9..c852fe0e863 100644 --- a/packages/mobile-ui-vue/demos/date-time-picker/max&min.vue +++ b/packages/mobile-ui-vue/demos/date-time-picker/max&min.vue @@ -1,7 +1,9 @@ diff --git a/packages/mobile-ui-vue/demos/date-time-picker/type.vue b/packages/mobile-ui-vue/demos/date-time-picker/type.vue index 3dff39088f7..8a638483dd7 100644 --- a/packages/mobile-ui-vue/demos/date-time-picker/type.vue +++ b/packages/mobile-ui-vue/demos/date-time-picker/type.vue @@ -1,3 +1,6 @@ + diff --git a/packages/mobile-ui-vue/demos/filter/base.vue b/packages/mobile-ui-vue/demos/filter/base.vue index 5f4ca5067b1..90ca050edd4 100644 --- a/packages/mobile-ui-vue/demos/filter/base.vue +++ b/packages/mobile-ui-vue/demos/filter/base.vue @@ -18,7 +18,9 @@ const searchValue = ref('小'); const filterData = reactive({ Code: 'code', - Name: 'name' + Name: 'name', + Number: 1, + NumberRange: { start: 1, end: 10 }, }); const fieldConfigs = [ diff --git a/packages/mobile-ui-vue/demos/form/control-type.vue b/packages/mobile-ui-vue/demos/form/control-type.vue index adb7c168863..35232bfbbfc 100644 --- a/packages/mobile-ui-vue/demos/form/control-type.vue +++ b/packages/mobile-ui-vue/demos/form/control-type.vue @@ -20,25 +20,25 @@ > - + > - + > - + > diff --git a/packages/mobile-ui-vue/demos/picker/basic.vue b/packages/mobile-ui-vue/demos/picker/basic.vue index 63056453093..03aea00f56f 100644 --- a/packages/mobile-ui-vue/demos/picker/basic.vue +++ b/packages/mobile-ui-vue/demos/picker/basic.vue @@ -1,7 +1,9 @@ diff --git a/packages/mobile-ui-vue/demos/picker/input.vue b/packages/mobile-ui-vue/demos/picker/input.vue index 17deb9ba97f..e1d0d0b4bd5 100644 --- a/packages/mobile-ui-vue/demos/picker/input.vue +++ b/packages/mobile-ui-vue/demos/picker/input.vue @@ -1,12 +1,14 @@ diff --git a/packages/mobile-ui-vue/demos/time-picker/formatter.vue b/packages/mobile-ui-vue/demos/time-picker/formatter.vue index 6f16c973820..fc44f9ca82d 100644 --- a/packages/mobile-ui-vue/demos/time-picker/formatter.vue +++ b/packages/mobile-ui-vue/demos/time-picker/formatter.vue @@ -1,7 +1,9 @@ diff --git a/packages/mobile-ui-vue/demos/time-picker/min-max.vue b/packages/mobile-ui-vue/demos/time-picker/min-max.vue index 261f1e59550..505e11fbd1d 100644 --- a/packages/mobile-ui-vue/demos/time-picker/min-max.vue +++ b/packages/mobile-ui-vue/demos/time-picker/min-max.vue @@ -1,7 +1,10 @@ + diff --git a/packages/mobile-ui-vue/demos/time-picker/type.vue b/packages/mobile-ui-vue/demos/time-picker/type.vue index 86bf083722c..844acfb294c 100644 --- a/packages/mobile-ui-vue/demos/time-picker/type.vue +++ b/packages/mobile-ui-vue/demos/time-picker/type.vue @@ -1,3 +1,7 @@ + + -- Gitee From 3a0607c7439cd187c246347d4829e2c6fe1a6018 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Sat, 5 Apr 2025 15:45:41 +0800 Subject: [PATCH 152/153] =?UTF-8?q?feature:=20=E8=B0=83=E9=80=9A=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E7=AB=AF6=E4=B8=AA=E6=A0=B8=E5=BF=83=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E6=8E=A7=E4=BB=B6=E5=9F=BA=E7=A1=80=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E7=AE=80=E5=8D=95=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=9A=84=E5=BD=95=E5=85=A5=E5=92=8C=E5=B1=95=E7=A4=BA=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component-converters/datebox-converter.ts | 10 +++++++++- .../metadata/form/converters/converter-factory.ts | 2 +- .../form/normalizers/form-item-normalizer.ts | 1 + packages/mobile-render/src/views/page/page.vue | 2 +- .../src/schema/date-picker-input.schema.json | 7 +++++-- .../date-picker-input/src/schema/schema-mapper.ts | 1 + .../src/schema/datetime-picker-input.schema.json | 3 +-- .../src/schema/schema-mapper.ts | 1 + packages/mobile-ui-vue/components/index.ts | 6 ++++++ .../input-group/src/schema/input-group.schema.json | 3 +-- .../mobile-ui-vue/components/number-input/index.ts | 2 +- .../number-input/src/number-input.component.tsx | 12 +++++++++--- .../number-input/src/schema/number-input.schema.json | 3 +-- .../number-input/src/schema/schema-mapper.ts | 3 +-- .../picker-input/src/schema/picker-input.schema.json | 1 + .../picker-input/src/schema/schema-mapper.ts | 3 ++- .../components/switch/src/schema/switch.schema.json | 8 +------- .../components/textarea/src/schema/schema-mapper.ts | 3 +-- .../textarea/src/schema/textarea.schema.json | 6 +++--- .../components/textarea/src/textarea.component.tsx | 11 ++++++++--- 20 files changed, 55 insertions(+), 33 deletions(-) diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/datebox-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/datebox-converter.ts index f9fc549982f..d3d4b2e53e4 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/datebox-converter.ts +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/datebox-converter.ts @@ -14,10 +14,11 @@ class DateBoxConverter extends InputConverter { super.convert(input); const editorType = this.getEditorType(originInput.showType); + const displayFormat = this.getDisplayFormat(originInput.format); input.editor = Object.assign(input.editor, { type: editorType, title: undefined, - displayFormat: originInput.format, + displayFormat: displayFormat, maxDate: originInput.maxValue, minDate: originInput.minValue }); @@ -33,6 +34,13 @@ class DateBoxConverter extends InputConverter { return 'date-picker'; } } + + /** + * 获取显示格式 + */ + private getDisplayFormat(oldFormat: string): string { + return oldFormat.replace('dd', 'DD'); + } } export { DateBoxConverter }; diff --git a/packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts b/packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts index b7f82f815f5..0aa6e367360 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts +++ b/packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts @@ -69,7 +69,7 @@ class ConverterFactory { this.cmpConverterCtors.set('ListView', ListViewConverter); this.cmpConverterCtors.set('TextBox', TextBoxConverter); - this.cmpConverterCtors.set('MultiTextbox', MultiTextBoxConverter); + this.cmpConverterCtors.set('MultiTextBox', MultiTextBoxConverter); this.cmpConverterCtors.set('NumericBox', NumericBoxConverter); this.cmpConverterCtors.set('SwitchField', SwitchFieldConverter); this.cmpConverterCtors.set('DateBox', DateBoxConverter); diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/form-item-normalizer.ts b/packages/mobile-render/src/services/metadata/form/normalizers/form-item-normalizer.ts index 5618197f299..e4db3a7a3ab 100644 --- a/packages/mobile-render/src/services/metadata/form/normalizers/form-item-normalizer.ts +++ b/packages/mobile-render/src/services/metadata/form/normalizers/form-item-normalizer.ts @@ -12,6 +12,7 @@ class FormItemNormalizer extends ComponentNormalizer { public normalize(component: any, componentSchema: any, viewModelId: string) { super.normalize(component, componentSchema, viewModelId); component.binding.direction = 'TwoWay'; + component.editor.binding = component.binding; this.normalizeEditor(component.editor, viewModelId); } diff --git a/packages/mobile-render/src/views/page/page.vue b/packages/mobile-render/src/views/page/page.vue index 54897741441..ab1878056a2 100644 --- a/packages/mobile-render/src/views/page/page.vue +++ b/packages/mobile-render/src/views/page/page.vue @@ -1,5 +1,5 @@ diff --git a/packages/mobile-ui-vue/demos/date-picker/formatter.vue b/packages/mobile-ui-vue/demos/date-picker/formatter.vue index 602e3cdbb12..7d37a997b2a 100644 --- a/packages/mobile-ui-vue/demos/date-picker/formatter.vue +++ b/packages/mobile-ui-vue/demos/date-picker/formatter.vue @@ -2,7 +2,7 @@ diff --git a/packages/mobile-ui-vue/demos/date-picker/type.vue b/packages/mobile-ui-vue/demos/date-picker/type.vue index 816250c2e7e..6a453c35487 100644 --- a/packages/mobile-ui-vue/demos/date-picker/type.vue +++ b/packages/mobile-ui-vue/demos/date-picker/type.vue @@ -3,5 +3,5 @@ diff --git a/packages/mobile-ui-vue/demos/date-time-picker/basic.vue b/packages/mobile-ui-vue/demos/date-time-picker/basic.vue index 7f456c2d958..58ba9b637e7 100644 --- a/packages/mobile-ui-vue/demos/date-time-picker/basic.vue +++ b/packages/mobile-ui-vue/demos/date-time-picker/basic.vue @@ -2,5 +2,5 @@ diff --git a/packages/mobile-ui-vue/demos/date-time-picker/formatter.vue b/packages/mobile-ui-vue/demos/date-time-picker/formatter.vue index fcdb453ab0b..f0fba9ab5b0 100644 --- a/packages/mobile-ui-vue/demos/date-time-picker/formatter.vue +++ b/packages/mobile-ui-vue/demos/date-time-picker/formatter.vue @@ -2,7 +2,7 @@ diff --git a/packages/mobile-ui-vue/demos/picker/basic.vue b/packages/mobile-ui-vue/demos/picker/basic.vue index 03aea00f56f..1a37e1bea66 100644 --- a/packages/mobile-ui-vue/demos/picker/basic.vue +++ b/packages/mobile-ui-vue/demos/picker/basic.vue @@ -2,7 +2,7 @@ diff --git a/packages/mobile-ui-vue/demos/time-picker/formatter.vue b/packages/mobile-ui-vue/demos/time-picker/formatter.vue index fc44f9ca82d..fb6ca76dff8 100644 --- a/packages/mobile-ui-vue/demos/time-picker/formatter.vue +++ b/packages/mobile-ui-vue/demos/time-picker/formatter.vue @@ -2,7 +2,7 @@ diff --git a/packages/mobile-ui-vue/demos/time-picker/type.vue b/packages/mobile-ui-vue/demos/time-picker/type.vue index 844acfb294c..d7de10908d6 100644 --- a/packages/mobile-ui-vue/demos/time-picker/type.vue +++ b/packages/mobile-ui-vue/demos/time-picker/type.vue @@ -3,5 +3,5 @@ -- Gitee