From 9e1d9a92f7347f83ae8228674f4805c6a258ba64 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Fri, 21 Feb 2025 11:36:04 +0800 Subject: [PATCH 001/287] =?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/287] =?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 c9d90f40c814308f00d53724eebdae06c877473e Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Tue, 25 Feb 2025 11:04:41 +0800 Subject: [PATCH 003/287] =?UTF-8?q?feature:=E6=8F=90=E4=BE=9B=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E8=AE=BE=E8=AE=A1=E6=97=B6=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile-ui-vue/components/button/index.ts | 10 ++ .../src/designer/button.design.component.tsx | 57 +++++++ .../button/src/designer/use-designer-rules.ts | 57 +++++++ .../property-config/button.property-config.ts | 51 ++++++ .../button/src/schema/button.schema.json | 19 ++- .../mobile-ui-vue/components/common/index.ts | 1 + .../common/src/entity/input-base-property.ts | 15 +- .../components/component/index.ts | 10 ++ .../designer/component.design.component.tsx | 41 +++++ .../src/designer/use-designer-rules.ts | 123 ++++++++++++++ .../component.property-config.ts | 63 ++++++++ .../components/content-container/index.ts | 10 ++ .../content-container.design.component.tsx | 38 +++++ .../src/designer/use-designer-rules.ts | 50 ++++++ .../content-container.property-config.ts | 15 ++ .../components/date-picker-input/index.ts | 14 ++ .../src/date-picker-input.props.ts | 8 +- .../designer/date-picker.design.component.tsx | 54 +++++++ .../src/designer/use-designer-rules.ts | 15 ++ .../date-picker.property-config.ts | 74 +++++++++ .../src/schema/schema-mapper.ts | 5 + .../src/schema/schema-resolver.ts | 5 + .../date-picker-input/src/schema/schema.json | 72 +++++++++ .../designer-canvas/src/components/maps.ts | 46 ++++-- .../src/composition/dg-control.ts | 71 +++----- .../src/composition/function/drag-resolve.tsx | 12 +- .../src/composition/function/use-dragula.ts | 6 +- .../designer-canvas/src/composition/types.ts | 6 +- .../src/designer-canvas.component.tsx | 17 +- .../components/designer-toolbox/index.ts | 5 + .../src/toolbox.component.tsx | 153 ++++++++++++++++++ .../designer-toolbox/src/toolbox.css | 75 +++++++++ .../designer-toolbox/src/toolbox.json | 110 +++++++++++++ .../designer-toolbox/src/toolbox.props.ts | 10 ++ .../components/designer-toolbox/src/types.ts | 22 +++ packages/mobile-ui-vue/components/designer.ts | 4 +- .../components/float-container/index.ts | 10 ++ .../float-container.design.component.tsx | 31 ++++ .../src/designer/use-designer-rules.ts | 99 ++++++++++++ .../float-container.property-config.ts | 15 ++ .../components/form-item/index.ts | 9 ++ .../designer/form-item-use-designer-rules.ts | 85 ++++++++++ .../designer/form-item.design.component.tsx | 137 ++++++++++++++++ .../response-form-use-designer-rules.ts | 103 ++++++++++++ .../response-form.design.component.tsx | 46 ++++++ .../form-item/src/form-item.props.ts | 4 +- .../form-group.property-config.ts | 16 ++ .../response-form.property-config.ts | 16 ++ .../mobile-ui-vue/components/form/index.ts | 9 ++ .../components/input-group/index.ts | 10 ++ .../designer/input-group.design.component.tsx | 50 ++++++ .../src/designer/use-designer-rules.ts | 15 ++ .../input-group.property-config.ts | 34 ++++ .../src/schema/input-group.schema.json | 36 ++++- .../components/list-view/index.ts | 32 ++-- .../designer/list-view.design.component.tsx | 40 ++++- .../src/designer/use-designer-rules.ts | 26 ++- .../component.property-config.ts | 51 ++++++ .../list-view.property-config.json | 6 +- .../mobile-ui-vue/components/modal/index.ts | 4 +- .../mobile-ui-vue/components/navbar/index.ts | 6 + .../src/designer/nav.design.component.tsx | 51 ++++++ .../navbar/src/designer/use-designer-rules.ts | 63 ++++++++ .../property-config/navbar.property-config.ts | 31 ++++ .../components/page-body-container/index.ts | 7 +- .../page-body-container.design.component.tsx | 8 +- .../src/designer/use-designer-rules.ts | 26 ++- .../src/page-body-container.props.ts | 4 +- .../page-body-container.property-config.json | 52 ------ .../page-body-container.property-config.ts | 15 ++ .../components/page-container/index.ts | 7 +- .../page-container.design.component.tsx | 8 +- .../src/designer/use-designer-rules.ts | 36 +++-- .../src/page-container.props.ts | 4 +- .../page-container.property-config.json | 52 ------ .../page-container.property-config.ts | 15 ++ .../components/page-footer-container/index.ts | 7 +- ...page-footer-container.design.component.tsx | 8 +- .../src/designer/use-designer-rules.ts | 24 ++- .../src/page-footer-container.props.ts | 4 +- ...page-footer-container.property-config.json | 52 ------ .../page-footer-container.property-config.ts | 15 ++ .../components/page-header-container/index.ts | 7 +- ...page-header-container.design.component.tsx | 8 +- .../src/designer/use-designer-rules.ts | 30 ++-- .../src/page-header-container.props.ts | 4 +- ...page-header-container.property-config.json | 52 ------ .../page-header-container.property-config.ts | 15 ++ .../components/radio-group/index.ts | 14 ++ .../designer/radio-group.design.component.tsx | 63 ++++++++ .../src/designer/use-designer-rules.ts | 15 ++ .../radio-group.property-config.ts | 53 ++++++ .../radio-group/src/radio-group.props.ts | 8 +- .../src/schema/radio-group.schema.json | 85 ++++++++++ .../radio-group/src/schema/schema-mapper.ts | 5 + .../radio-group/src/schema/schema-resolver.ts | 5 + .../components/textarea/index.ts | 14 ++ .../designer/textarea.design.component.tsx | 51 ++++++ .../src/designer/use-designer-rules.ts | 20 +++ .../textarea.property-config.ts | 34 ++++ .../textarea/src/schema/input.schema.json | 75 +++++++++ .../textarea/src/schema/schema-mapper.ts | 5 + .../textarea/src/schema/schema-resolver.ts | 5 + .../components/textarea/src/textarea.props.ts | 8 +- 104 files changed, 2879 insertions(+), 420 deletions(-) create mode 100644 packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/button/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/button/src/property-config/button.property-config.ts create mode 100644 packages/mobile-ui-vue/components/component/src/designer/component.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/component/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/component/src/property-config/component.property-config.ts create mode 100644 packages/mobile-ui-vue/components/content-container/src/designer/content-container.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/content-container/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts create mode 100644 packages/mobile-ui-vue/components/date-picker-input/src/designer/date-picker.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/date-picker-input/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/date-picker-input/src/property-config/date-picker.property-config.ts create mode 100644 packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/date-picker-input/src/schema/schema.json create mode 100644 packages/mobile-ui-vue/components/designer-toolbox/index.ts create mode 100644 packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.component.tsx create mode 100644 packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.css create mode 100644 packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.json create mode 100644 packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.props.ts create mode 100644 packages/mobile-ui-vue/components/designer-toolbox/src/types.ts create mode 100644 packages/mobile-ui-vue/components/float-container/src/designer/float-container.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/float-container/src/property-config/float-container.property-config.ts create mode 100644 packages/mobile-ui-vue/components/form-item/src/designer/form-item-use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/form-item/src/designer/response-form.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/form-item/src/property-config/form-group.property-config.ts create mode 100644 packages/mobile-ui-vue/components/form-item/src/property-config/response-form.property-config.ts create mode 100644 packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/input-group/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts create mode 100644 packages/mobile-ui-vue/components/list-view/src/property-config/component.property-config.ts create mode 100644 packages/mobile-ui-vue/components/navbar/src/designer/nav.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/navbar/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts delete mode 100644 packages/mobile-ui-vue/components/page-body-container/src/property-config/page-body-container.property-config.json create mode 100644 packages/mobile-ui-vue/components/page-body-container/src/property-config/page-body-container.property-config.ts delete mode 100644 packages/mobile-ui-vue/components/page-container/src/property-config/page-container.property-config.json create mode 100644 packages/mobile-ui-vue/components/page-container/src/property-config/page-container.property-config.ts delete mode 100644 packages/mobile-ui-vue/components/page-footer-container/src/property-config/page-footer-container.property-config.json create mode 100644 packages/mobile-ui-vue/components/page-footer-container/src/property-config/page-footer-container.property-config.ts delete mode 100644 packages/mobile-ui-vue/components/page-header-container/src/property-config/page-header-container.property-config.json create mode 100644 packages/mobile-ui-vue/components/page-header-container/src/property-config/page-header-container.property-config.ts create mode 100644 packages/mobile-ui-vue/components/radio-group/src/designer/radio-group.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/radio-group/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts create mode 100644 packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json create mode 100644 packages/mobile-ui-vue/components/radio-group/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/radio-group/src/schema/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/textarea/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts create mode 100644 packages/mobile-ui-vue/components/textarea/src/schema/input.schema.json create mode 100644 packages/mobile-ui-vue/components/textarea/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/textarea/src/schema/schema-resolver.ts diff --git a/packages/mobile-ui-vue/components/button/index.ts b/packages/mobile-ui-vue/components/button/index.ts index f211334c44a..2c5790ae860 100644 --- a/packages/mobile-ui-vue/components/button/index.ts +++ b/packages/mobile-ui-vue/components/button/index.ts @@ -2,6 +2,7 @@ import { Plugin } from 'vue'; import { withInstall, } from '@components/common'; import ButtonInstallless from './src/button.component'; import { propsResolver } from './src/button.props'; +import ButtonDesign from './src/designer/button.design.component'; const BUTTON_REGISTERED_NAME = 'button'; @@ -14,5 +15,14 @@ Button.register = ( propsResolverMap[BUTTON_REGISTERED_NAME] = propsResolver; }; +Button.registerDesigner = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[BUTTON_REGISTERED_NAME] = ButtonDesign; + propsResolverMap[BUTTON_REGISTERED_NAME] = propsResolver; +}; + + export { Button }; export default Button as typeof Button & Plugin; diff --git a/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx b/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx new file mode 100644 index 00000000000..88fa36811c4 --- /dev/null +++ b/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx @@ -0,0 +1,57 @@ +/** + * 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, defineComponent, inject, onMounted, ref, SetupContext } from 'vue'; +import { ButtonProps, buttonProps } from '../button.props'; +import Button from '../..'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; +import { useDesignerRules } from './use-designer-rules'; + +export default defineComponent({ + name: 'FmButtonDesign', + props: buttonProps, + emits: ['click'], + setup(props: ButtonProps, context: SetupContext) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + context.expose(componentInstance.value); + + const schema = componentInstance.value.schema; + + const inputProps = computed(() => ({ + ...props, + })); + + return () => { + return ( + schema.text ? + + : + + ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/button/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/button/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..57b56ec4c0d --- /dev/null +++ b/packages/mobile-ui-vue/components/button/src/designer/use-designer-rules.ts @@ -0,0 +1,57 @@ +import { ref } from "vue"; +import { ButtonProperty } from "../property-config/button.property-config"; +import { DesignerHostService, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { DraggingResolveContext } from "@/components/designer-canvas/src/composition/types"; + +export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService?: DesignerHostService): UseDesignerRules { + + const triggerBelongedComponentToMoveWhenMoved = ref(false); + + const triggerBelongedComponentToDeleteWhenDeleted = ref(false); + + function canAccepts(draggingContext: DraggingResolveContext): boolean { + + return false; + } + + + function checkCanMoveComponent() { + return true; + } + function checkCanDeleteComponent() { + return true; + } + + function hideNestedPaddingInDesginerView() { + return true; + } + + function getStyles(): string { + return ' '; + } + + function getDesignerClass(): string { + return ' '; + } + + /** + * 获取属性配置 + */ + function getPropsConfig(componentId: string) { + const componentProp = new ButtonProperty(componentId, designerHostService); + const { schema } = designItemContext; + return componentProp.getPropertyConfig(schema); + } + + return { + canAccepts, + triggerBelongedComponentToMoveWhenMoved, + triggerBelongedComponentToDeleteWhenDeleted, + checkCanMoveComponent, + checkCanDeleteComponent, + hideNestedPaddingInDesginerView, + getStyles, + getDesignerClass, + getPropsConfig + }; +} diff --git a/packages/mobile-ui-vue/components/button/src/property-config/button.property-config.ts b/packages/mobile-ui-vue/components/button/src/property-config/button.property-config.ts new file mode 100644 index 00000000000..797c3b7aae6 --- /dev/null +++ b/packages/mobile-ui-vue/components/button/src/property-config/button.property-config.ts @@ -0,0 +1,51 @@ +import { BaseControlProperty } from "@/components/property-panel"; + +export class ButtonProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: any) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + //行为 + this.propertyConfig.categories['behavior'] = this.getBehaviorConfig(propertyData); + + return this.propertyConfig; + } + + private getBehaviorConfig(propertyData) { + return { + description: "基本信息", + title: "行为", + properties: { + visible: { + title: "可见", + type: "boolean", + }, + disabled: { + title: "只读", + type: "boolean", + }, + displayType: { + title: "按钮类型", + type: "string", + }, + block: { + title: "是否占满整行", + type: "boolean", + }, + round: { + title: "启用圆角", + type: "boolean", + }, + text: { + title: "提示文本", + type: "string", + } + } + }; + } + +} 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 index 3109eabb1fb..c97693e7758 100644 --- a/packages/mobile-ui-vue/components/button/src/schema/button.schema.json +++ b/packages/mobile-ui-vue/components/button/src/schema/button.schema.json @@ -17,7 +17,7 @@ "displayType": { "description": "显示类型", "type": "string", - "default": "default" + "default": "primary" }, "icon": { "description": "图标", @@ -30,6 +30,16 @@ "default": false, "isEvent": true }, + "text": { + "description": "", + "type": "string", + "default": "按钮" + }, + "block": { + "description": "", + "type": "boolean", + "default": true + }, "appearance": { "description": "外观", "type": "object", @@ -52,6 +62,11 @@ ], "required": [ "id", - "type" + "type", + "visible", + "round", + "disabled", + "text", + "icon" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/common/index.ts b/packages/mobile-ui-vue/components/common/index.ts index 279f22b74ef..b3b9463aea1 100644 --- a/packages/mobile-ui-vue/components/common/index.ts +++ b/packages/mobile-ui-vue/components/common/index.ts @@ -20,6 +20,7 @@ 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 default { install(app: App): void { diff --git a/packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts b/packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts index fb43a637e9a..e705e141bab 100644 --- a/packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts +++ b/packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts @@ -218,15 +218,18 @@ export class InputBaseProperty extends BaseControlProperty { type: "boolean", visible: false }, - // required: { - // description: "", - // title: "必填", - // type: "boolean" - // }, + required: { + description: "", + title: "必填", + type: "boolean", + visible: false + }, placeholder: { description: "空值时,输入控件内的占位文本", title: "提示文本", - type: "string" + type: "string", + visible: false + } }, properties); diff --git a/packages/mobile-ui-vue/components/component/index.ts b/packages/mobile-ui-vue/components/component/index.ts index cba22460cb6..bed6e3bd70c 100644 --- a/packages/mobile-ui-vue/components/component/index.ts +++ b/packages/mobile-ui-vue/components/component/index.ts @@ -18,6 +18,7 @@ import type { Plugin } from 'vue'; import { withInstall } from '@components/common'; import ComponentInstallless from './src/component.component'; import { propsResolver } from './src/component.props'; +import ComponentDesign from './src/designer/component.design.component'; const COMPONENT_REGISTERED_NAME = 'component'; @@ -30,6 +31,15 @@ Component.register = ( propsResolverMap[COMPONENT_REGISTERED_NAME] = propsResolver; }; +Component.registerDesigner = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[COMPONENT_REGISTERED_NAME] = ComponentDesign; + 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/designer/component.design.component.tsx b/packages/mobile-ui-vue/components/component/src/designer/component.design.component.tsx new file mode 100644 index 00000000000..06b97e5ff2a --- /dev/null +++ b/packages/mobile-ui-vue/components/component/src/designer/component.design.component.tsx @@ -0,0 +1,41 @@ +import { SetupContext, defineComponent, inject, ref, onMounted, computed } from 'vue'; +import { ComponentPropsType, componentProps } from '../component.props'; +import { useDesignerRules } from './use-designer-rules'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas'; + +export default defineComponent({ + name: 'FComponetDesign', + props: componentProps, + emits: [], + setup(props: ComponentPropsType, context) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + const componentClass = computed(() => { + const classObject = { + 'drag-container': true + } as Record; + return classObject; + }); + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + + if (designItemContext.parent?.schema?.type === 'component-ref') { + componentInstance.value.parent = designItemContext.parent?.parent?.componentInstance; + } + }); + + context.expose(componentInstance.value); + + return () => { + return ( +
+ {context.slots.default && context.slots.default()} +
+ ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/component/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/component/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..4759823a140 --- /dev/null +++ b/packages/mobile-ui-vue/components/component/src/designer/use-designer-rules.ts @@ -0,0 +1,123 @@ +import { DesignerHostService, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { ComponentProperty } from "../property-config/component.property-config"; + +export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService?: DesignerHostService): UseDesignerRules { + + /** + * 判断是否可以接收拖拽新增的子级控件 + */ + function canAccepts(): boolean { + return true; + } + + function checkCanDeleteComponent() { + return false; + } + + function checkCanMoveComponent() { + return true; + } + + + function hideNestedPaddingInDesginerView() { + return false; + } + + function getStyles(): string { + return ' '; + } + + /** + * 获取属性配置 + */ + function getPropsConfig(componentId: string) { + const componentProp = new ComponentProperty(componentId, designerHostService); + const { schema } = designItemContext; + return componentProp.getPropertyConfig(schema); + } + + /** + * 删除DataGrid/Form类组件时,将父级Section或者TabPage上的相关按钮一起删除 + */ + function removeAddDeleteBtnOnParentContainer() { + const schema = designItemContext?.schema; + const formSchemaUtils = designerHostService?.formSchemaUtils; + const viewModelId = formSchemaUtils.getViewModelIdByComponentId(schema.id); + + if (schema.componentType !== 'form') { + return; + } + if (!designItemContext.componentInstance?.value.parent) { + return; + } + const parentComponentSchema = designItemContext.componentInstance?.value.parent['schema']; + if (parentComponentSchema?.toolbar?.buttons && parentComponentSchema.toolbar.buttons.length) { + parentComponentSchema.toolbar.buttons.forEach(button => { + const clickEvent = button.onClick; + // 判断三段式结构 + const clickEventPath = clickEvent && clickEvent.split('.'); + if (!clickEventPath || clickEventPath.length < 3) { + return; + } + const targetViewModelId = clickEventPath[clickEventPath.length - 2]; + + // 按钮绑定的命令若是在当前viewModel下,则将按钮标记为待删除 + if (targetViewModelId === viewModelId) { + button.needRemove = true; + } + }); + parentComponentSchema.toolbar.buttons = parentComponentSchema.toolbar.buttons.filter(button => !button.needRemove); + + // 为解决标签页画布无法更新的问题,手动触发update方法 + const parentComponentInstance = designItemContext.componentInstance?.value.parent; + if (parentComponentInstance['parent'] && parentComponentInstance['parent']['updateToolbarItems']) { + parentComponentInstance['parent']['updateToolbarItems'](); + } + } + + } + /** + * 组件删除后事件:移除viewmodel和component + */ + function removeViewModelComponent() { + const designViewModelUtils = designerHostService?.designViewModelUtils; + const formSchemaUtils = designerHostService?.formSchemaUtils; + const schema = designItemContext?.schema; + + if (designViewModelUtils && formSchemaUtils) { + const viewModelId = formSchemaUtils.getViewModelIdByComponentId(schema.id); + designViewModelUtils.deleteViewModelById(viewModelId); + + formSchemaUtils.deleteComponent(schema.id); + } + } + /** + * 组件删除后事件:移除表达式、界面规则、受控规则等全局配置 + */ + function removeGlobalConfigs() { + const designViewModelUtils = designerHostService?.designViewModelUtils; + const formSchemaUtils = designerHostService?.formSchemaUtils; + const schema = designItemContext?.schema; + const viewModelId = formSchemaUtils.getViewModelIdByComponentId(schema.id); + + designViewModelUtils.getDgViewModel(viewModelId).fields.forEach(field => { + + // 若绑定字段配置了表达式,需要删除表达式 + if (formSchemaUtils.getExpressions() && formSchemaUtils.getExpressions().length) { + const expFieldIndex = formSchemaUtils.getExpressions().findIndex(e => e.fieldId === field.id); + if (expFieldIndex > -1) { + formSchemaUtils.getExpressions().splice(expFieldIndex, 1); + } + } + }); + } + /** + * 组件删除后事件 + */ + function onRemoveComponent() { + removeAddDeleteBtnOnParentContainer(); + removeGlobalConfigs(); + removeViewModelComponent(); + } + return { canAccepts, checkCanDeleteComponent, checkCanMoveComponent, hideNestedPaddingInDesginerView, getStyles, getPropsConfig, onRemoveComponent }; +} diff --git a/packages/mobile-ui-vue/components/component/src/property-config/component.property-config.ts b/packages/mobile-ui-vue/components/component/src/property-config/component.property-config.ts new file mode 100644 index 00000000000..cdf986d57bd --- /dev/null +++ b/packages/mobile-ui-vue/components/component/src/property-config/component.property-config.ts @@ -0,0 +1,63 @@ +import { BaseControlProperty } from "@/components/property-panel"; + + +export class ComponentProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: any) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + // 事件 + this.getEventPropConfig(propertyData); + return this.propertyConfig; + } + private getEventPropConfig(propertyData: any) { + const events = [ + { + label: "onBeforeInit", + name: "初始化前事件", + }, + { + label: "onInit", + name: "初始化事件", + }, + { + label: "onLoadData", + name: "加载数据事件", + }, + { + label: "goBack", + name: "原生返回事件", + }, + ]; + const self = this; + const initialData = self.eventsEditorUtils['formProperties'](propertyData, self.viewModelId, events); + const properties = {}; + properties[self.viewModelId] = { + type: 'events-editor', + editor: { + initialData + } + }; + this.propertyConfig.categories['eventsEditor'] = { + title: '事件', + hideTitle: true, + properties, + // 这个属性,标记当属性变更得时候触发重新更新属性 + refreshPanelAfterChanged: true, + tabId: 'commands', + tabName: '交互', + setPropertyRelates(changeObject: any, data: any) { + const parameters = changeObject.propertyValue; + delete propertyData[self.viewModelId]; + if (parameters) { + parameters.setPropertyRelates = this.setPropertyRelates; // 添加自定义方法后,调用此回调方法,用于处理联动属性 + self.eventsEditorUtils.saveRelatedParameters(propertyData, self.viewModelId, parameters['events'], parameters); + } + } + }; + } +} diff --git a/packages/mobile-ui-vue/components/content-container/index.ts b/packages/mobile-ui-vue/components/content-container/index.ts index c1fbc4d9104..c14dc398ca2 100644 --- a/packages/mobile-ui-vue/components/content-container/index.ts +++ b/packages/mobile-ui-vue/components/content-container/index.ts @@ -1,6 +1,7 @@ import { App, Plugin } from 'vue'; import FContentContainer from './src/content-container.component'; import { propsResolver } from './src/content-container.props'; +import ContentContainerDesign from './src/designer/content-container.design.component'; const CONTENT_CONTAINER_REGISTERED_NAME = 'content-container'; @@ -16,6 +17,15 @@ FContentContainer.register = ( propsResolverMap[CONTENT_CONTAINER_REGISTERED_NAME] = propsResolver; }; +FContentContainer.registerDesigner = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[CONTENT_CONTAINER_REGISTERED_NAME] = ContentContainerDesign; + 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/designer/content-container.design.component.tsx b/packages/mobile-ui-vue/components/content-container/src/designer/content-container.design.component.tsx new file mode 100644 index 00000000000..2ec2f1037db --- /dev/null +++ b/packages/mobile-ui-vue/components/content-container/src/designer/content-container.design.component.tsx @@ -0,0 +1,38 @@ +import { SetupContext, computed, defineComponent, inject, onMounted, ref } from 'vue'; +import { ContentContainerPropsType, contentContainerProps } from '../content-container.props'; +import { useDesignerRulesForContentContainer } from './use-designer-rules'; +import { getCustomClass } from '@/components/common'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; + +export default defineComponent({ + name: 'FContentContainerDesign', + props: contentContainerProps, + emits: [], + setup(props: ContentContainerPropsType, context) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useDesignerRulesForContentContainer(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + const containerClass = computed(() => { + const classObject = { + 'drag-container': true + } as Record; + return getCustomClass(classObject, props?.customClass); + }); + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + context.expose(componentInstance.value); + + return () => { + return ( +
+ {context.slots.default && context.slots.default()} +
+ ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/content-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/content-container/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..5164c6e8101 --- /dev/null +++ b/packages/mobile-ui-vue/components/content-container/src/designer/use-designer-rules.ts @@ -0,0 +1,50 @@ +import { ComponentSchema, DesignerItemContext } from "@/components/designer-canvas"; +import { ContentContainerProperty } from "../property-config/content-container.property-config"; +import { DesignerHostService, DraggingResolveContext, UseDesignerRules } from "@/components/designer-canvas/src/composition/types"; + +export function useDesignerRulesForContentContainer(designItemContext: DesignerItemContext, designerHostService?: DesignerHostService): UseDesignerRules { + const schema = designItemContext.schema as ComponentSchema; + + /** + * 判断是否可以接收拖拽新增的子级控件 + */ + function canAccepts(draggingContext: DraggingResolveContext): boolean { + return true; + } + + function getStyles() { + const component = schema; + if (component.componentType) { + return 'display:inherit;flex-direction:inherit;margin-bottom:10px'; + } + return ''; + } + + function checkCanMoveComponent() { + return true; + } + function checkCanDeleteComponent() { + return true; + } + + function hideNestedPaddingInDesginerView() { + return false; + } + /** + * 获取属性配置 + */ + function getPropsConfig(componentId: string) { + const componentProp = new ContentContainerProperty(componentId, designerHostService); + const { schema } = designItemContext; + return componentProp.getPropertyConfig(schema); + } + + return { + canAccepts, + getStyles, + checkCanMoveComponent, + checkCanDeleteComponent, + hideNestedPaddingInDesginerView, + getPropsConfig + }; +} diff --git a/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts b/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts new file mode 100644 index 00000000000..8db40b24dd1 --- /dev/null +++ b/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts @@ -0,0 +1,15 @@ +import { BaseControlProperty } from "@/components/property-panel"; + +export class ContentContainerProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: any) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + + return this.propertyConfig; + } +} diff --git a/packages/mobile-ui-vue/components/date-picker-input/index.ts b/packages/mobile-ui-vue/components/date-picker-input/index.ts index ded2df85a66..ec026ee8f75 100644 --- a/packages/mobile-ui-vue/components/date-picker-input/index.ts +++ b/packages/mobile-ui-vue/components/date-picker-input/index.ts @@ -1,7 +1,21 @@ 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.props.ts b/packages/mobile-ui-vue/components/date-picker-input/src/date-picker-input.props.ts index 7871244aa93..cce31ab4471 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 @@ -1,6 +1,10 @@ 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'; @@ -9,6 +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); 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-input/src/designer/date-picker.design.component.tsx new file mode 100644 index 00000000000..a0aa71bb439 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-picker-input/src/designer/date-picker.design.component.tsx @@ -0,0 +1,54 @@ +/* eslint-disable no-use-before-define */ +/** + * 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, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; + +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; +import { useDesignerRules } from './use-designer-rules'; +import { datePickerInputProps, DatePickerInputProps } from '../date-picker-input.props'; +import DatePickerInput from '../..'; + +export default defineComponent({ + name: 'FmDatePickerInputDesign', + props: datePickerInputProps, + emits: [], + setup(props: DatePickerInputProps, context: SetupContext) { + const elementRef = ref(); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerHostService = inject('designer-host-service'); + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext,designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + context.expose(componentInstance.value); + + const inputProps = computed(() => ({ + ...props, + editable: false, + readonly: true + + })); + + return () => { + return ( + + ); + }; + } +}); 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-input/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..27cf298004d --- /dev/null +++ b/packages/mobile-ui-vue/components/date-picker-input/src/designer/use-designer-rules.ts @@ -0,0 +1,15 @@ +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { DatePickerProperty } from "../property-config/date-picker.property-config"; +export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { + + const schema = designItemContext.schema as ComponentSchema; + + // 构造属性配置方法 + function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { + const datePickerProps = new DatePickerProperty(componentId, designerHostService); + return datePickerProps.getPropertyConfig(schema, componentInstance); + } + + return { getPropsConfig } as UseDesignerRules; + +} \ No newline at end of file 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-input/src/property-config/date-picker.property-config.ts new file mode 100644 index 00000000000..c0551502470 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-picker-input/src/property-config/date-picker.property-config.ts @@ -0,0 +1,74 @@ +import { InputBaseProperty } from "@/components/common/src/entity/input-base-property"; + +export class DatePickerProperty extends InputBaseProperty { + + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + + getEditorProperties(propertyData: any) { + const displayFormatOptions = this.getAllShowType(); + const valueFormatOptions = this.getAllFormat(); + return this.getComponentConfig(propertyData, { type: "year-month-day" }, { + placeholder: { + description: "空值时,输入控件内的占位文本", + title: "提示文本", + type: "string" + }, + showType: { + description: "", + title: "选择类型", + type: "enum", + editor: { + data: displayFormatOptions + } + }, + format: { + description: "", + title: "显示格式", + type: "enum", + editor: { + data: valueFormatOptions + } + } + }, this.setEditorPropertyRelates); + } + + private setEditorPropertyRelates(changeObject: any, propertyData: any) { + if (!changeObject || !propertyData.editor) { + return; + } + switch (changeObject.propertyID) { + case 'showTime': { + + } + } + } + + private getAllShowType() { + return [ + { id: "year", name: "年月日" }, + { id: "datetime", name: "年月日时分" }, + { id: "datehour", name: "年月日时" }, + { id: "year-month", name: "年月" }, + { id: "month-day", name: "月日" } + ]; + } + + /** + * 存储格式枚举项 + */ + getAllFormat(): any[] { + return [ + { id: 'YYYY-MM-dd HH:mm', name: 'YYYY-MM-dd HH:mm' }, + { id: 'MM/dd/YYYY HH:mm', name: 'MM/dd/YYYY HH:mm' }, + { id: 'YYYY年MM月dd日 HH:mm', name: 'YYYY年MM月dd日 HH:mm' }, + { id: 'YYYY-MM-dd HH:mm:ss', name: 'YYYY-MM-dd HH:mm:ss' }, + { id: 'MM/dd/YYYY HH:mm:ss', name: 'MM/dd/YYYY HH:mm:ss' }, + { id: 'YYYY年MM月dd日 HH:mm:ss', name: 'YYYY年MM月dd日 HH:mm:ss' }, + ]; + } + + +} diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..abb57152ea8 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-mapper.ts @@ -0,0 +1,5 @@ +import { MapperFunction, resolveAppearance } from '@/components/dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance] +]); diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..660e1e609e1 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-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/date-picker-input/src/schema/schema.json b/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema.json new file mode 100644 index 00000000000..a98542bf4ee --- /dev/null +++ b/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema.json @@ -0,0 +1,72 @@ +{ + "$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", + "type": "object", + "properties": { + "id": { + "description": "The unique identifier for a Date Picker", + "type": "string" + }, + "type": { + "description": "The type string of Date Picker component", + "type": "string", + "default": "date-picker" + }, + "appearance": { + "description": "", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "binding": { + "description": "", + "type": "object", + "default": {} + }, + "disable": { + "type": "string", + "default": false + }, + "title": { + "description": "", + "type": "string", + "default": "" + }, + "label": { + "description": "", + "type": "string", + "default": "" + }, + "lableWidth": { + "description": "", + "type": "number" + }, + "placeholder": { + "description": "", + "type": "string", + "default": "" + }, + "visible": { + "description": "", + "type": "boolean", + "default": true + } + }, + "required": [ + "id", + "type", + "visible", + "label", + "placeholder", + "appearance" + ] +} \ No newline at end of file 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 1a5e6de142d..474da277cb0 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,15 @@ - +import { ContentContainer, DatePickerInput, FormItem, PageHeaderContainer, RadioGroup } from "@/components"; +import Button from "@/components/button"; +import Component from "@/components/component"; +import FloatContainer from "@/components/float-container"; +import Form from "@/components/form"; +import InputGroup from "@/components/input-group"; +import { ListView } from "@/components/list-view"; +import Navbar from "@/components/navbar"; +import PageBodyContainer from "@/components/page-body-container"; +import PageContainer from "@/components/page-container"; +import PageFooterContainer from "@/components/page-footer-container"; +import Textarea from "@/components/textarea"; const componentMap: Record = {}; const componentPropsConverter: Record = {}; @@ -12,21 +23,24 @@ let hasLoaded = false; function loadDesignerRegister() { if (!hasLoaded) { hasLoaded = true; - // FAvatar.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); - - } -} -/** - * 加载设计时组件 - */ -function loadDesignerRegisterByComponents(components:any[]) { - if (!hasLoaded) { - hasLoaded = true; - components.forEach(component => { - component.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); - }); - + Button.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + PageContainer.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + PageHeaderContainer.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + PageBodyContainer.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + PageFooterContainer.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + Navbar.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + Component.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + ListView.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + Form.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + InputGroup.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + FloatContainer.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + ContentContainer.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + FormItem.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + DatePickerInput.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + Textarea.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + RadioGroup.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + } } -export { componentMap, componentPropsConverter, componentPropertyConfigConverter, loadDesignerRegister, loadDesignerRegisterByComponents }; +export { componentMap, componentPropsConverter, componentPropertyConfigConverter, loadDesignerRegister }; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts index 3e00a135b84..e3d215a7141 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts @@ -1,12 +1,24 @@ -export const DgControl = { - 'button': { type: 'button', name: '按钮', icon: 'Button' }, - - 'response-toolbar': { type: 'response-toolbar', name: '工具栏', icon: 'ButtonGroup' }, +export const DgControl = { + 'module': { type: 'Module', name: '模块', icon: 'Module' }, - 'response-toolbar-item': { type: 'response-toolbar-item', name: '按钮', icon: 'Button' }, + 'component': { type: 'component', name: '组件', icon: 'Component' }, 'content-container': { type: 'content-container', name: '容器', icon: 'ContentContainer' }, + 'page-container': { type: 'page-container', name: '页面容器', icon: 'ContentContainer' }, + + 'page-header-container': { type: 'page-header-container', name: '页头容器', icon: 'ContentContainer' }, + + 'page-body-container': { type: 'page-body-container', name: '页面主体容器', icon: 'ContentContainer' }, + + 'page-footer-container': { type: 'page-footer-container', name: '页尾容器', icon: 'ContentContainer' }, + + 'float-container': { type: 'float-container', name: '浮动容器', icon: 'ContentContainer' }, + + 'list-view': { type: 'list-view', name: '列表', icon: 'ListView' }, + + 'button': { type: 'button', name: '按钮', icon: 'Button' }, + 'input-group': { type: 'input-group', name: '文本', icon: 'TextBox' }, 'textarea': { type: 'textarea', name: '多行文本', icon: 'MultiTextBox' }, @@ -27,53 +39,8 @@ export const DgControl = { 'combo-list': { type: 'combo-list', name: '下拉列表', icon: 'EnumField' }, - 'response-form': { type: 'response-form', name: '卡片面板', icon: 'Form' }, - - 'response-layout': { type: 'response-layout', name: '布局容器', icon: 'ResponseLayout3' }, - - 'response-layout-item': { type: 'response-layout-item', name: '布局', icon: 'ResponseLayout1' }, - - 'tree-grid': { type: 'tree-grid', name: '树表格', icon: 'TreeGrid' }, - - 'tree-grid-column': { type: 'tree-grid-column', name: '树表格列' }, - - 'data-grid': { type: 'data-grid', name: '表格', icon: 'DataGrid' }, - - 'data-grid-column': { type: 'data-grid-column', name: '表格列' }, - - 'module': { type: 'Module', name: '模块', icon: 'Module' }, - - 'component': { type: 'component', name: '组件', icon: 'Component' }, - - 'tabs': { type: 'tabs', name: '标签页', icon: 'Tab' }, - - 'tab-page': { type: 'tab-page', name: '标签页项', dependentParentControl: 'Tab' }, - - 'tab-toolbar-item': { type: 'tab-toolbar-item', name: '标签页工具栏按钮', icon: 'Button' }, - - 'time-picker': { type: 'time-picker', name: '时间选择', icon: 'TimePicker' }, - - 'section': { type: 'section', name: '分组面板', icon: 'Section' }, - - 'section-toolbar': { type: 'section-toolbar', name: '分组面板工具栏' }, - - 'section-toolbar-item': { type: 'section-toolbar-item', name: '分组面板按钮' }, - - 'splitter': { type: 'splitter', name: '分栏面板', icon: 'Splitter' }, - - 'splitter-pane': { type: 'splitter-pane', name: '分栏面板项', dependentParentControl: 'Splitter' }, - - 'component-ref': { type: 'component-ref', name: '组件引用节点' }, - - 'uploader': { type: 'uploader', name: '附件上传', icon: 'FileUpload' }, - - 'page-header': { type: 'page-header', name: '页头', icon: 'Header' }, - - 'page-footer': { type: 'page-footer', name: '页脚', icon: 'ModalFooter' }, - - 'tab-toolbar': { type: 'tab-toolbar', name: '标签页工具栏', icon: 'TabToolbar' }, + 'form': { type: 'form', name: '卡片面板', icon: 'Form' }, - 'fieldset': { type: 'fieldset', name: '分组', icon: 'fieldset' }, + 'navigation-bar': { type: 'navigation-bar', name: '导航栏', icon: 'NavBar' }, - 'query-solution': { type: 'query-solution', name: '筛选方案', icon: 'QueryScheme'} }; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/drag-resolve.tsx b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/drag-resolve.tsx index 8bdd337b123..491c53d94b1 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/drag-resolve.tsx +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/drag-resolve.tsx @@ -1,11 +1,9 @@ import { ModalFunctions } from "../../../../modal/src/composition/type"; import { ComponentBindingSourceContext, DesignerHostService, DesignerHTMLElement, DraggingResolveContext } from "../types"; -// import EntityBindingSelectorComponent from '../../../../entity-binding-selector/entity-binding-selector.component'; -// import { FBindingSelectorContainer as BindingSelectorComponent } from "@/components/binding-selector"; import { DesignViewModelField, FormVariable } from "../../../../common/entity/entity-schema"; import { merge } from "lodash-es"; -import { DesignerComponentInstance } from "../../types"; import { DgControl } from "../dg-control"; +import { DesignerComponentInstance } from "@/components"; export function dragResolveService(designerHostService: DesignerHostService) { /** 弹窗实例 */ @@ -64,7 +62,8 @@ export function dragResolveService(designerHostService: DesignerHostService) { */ function renderEntityComponent() { const { componentType } = componentResolveContext; - // return () => (<> ); + const FEntityBindingSelector = designerHostService.uiProviderService.getUiComponent('FEntityBindingSelector'); + return () => (<> ); } /** * 弹出实体绑定窗口 @@ -153,7 +152,10 @@ export function dragResolveService(designerHostService: DesignerHostService) { componentSchema: { editor: { type: componentResolveContext.componentType } } }; const bindingSettings = { enable: false }; - // return () => (<> ); + + const FBindingSelectorContainer = designerHostService.uiProviderService.getUiComponent('FBindingSelectorContainer'); + + return () => (<> ); } /** * 弹出绑定字段的窗口 diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-dragula.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-dragula.ts index a7be4974f63..1b8b01052bc 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-dragula.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-dragula.ts @@ -349,6 +349,10 @@ export function useDragula(designerHostService: DesignerHostService): UseDragula } - return { attachComponents, attachToolbox, initializeDragula }; + function getDragulaInstance() { + return dragulaInstance; + } + + return { attachComponents, initializeDragula,getDragulaInstance }; } diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/types.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/types.ts index e256c20caa3..a3dc5bbfad2 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/types.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/types.ts @@ -12,12 +12,13 @@ export interface DesignerHTMLElement extends HTMLElement { schema: ComponentSchema; } + export interface UseDragula { attachComponents: (element: HTMLElement, component: ComponentSchema) => void; - attachToolbox: () => void; - initializeDragula: (containerElement: DesignerHTMLElement) => void; + + getDragulaInstance: () => any; } export interface DesignerHostService { eventsEditorUtils: any; @@ -27,6 +28,7 @@ export interface DesignerHostService { controlCreatorUtils: any; metadataService?: any; formStateMachineUtils: any; + uiProviderService?: any; [key: string]: any; } /** 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 569b057e421..5ac3463fd7a 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 @@ -8,8 +8,9 @@ import { DesignerHostService, UseDragula } from './composition/types'; import FDesignerItem from './components/designer-item.component'; import './composition/class/designer-canvas.css'; import './composition/class/control.css'; -import { loadDesignerRegister, loadDesignerRegisterByComponents } from './components/maps'; -import { F_MODAL_SERVICE_TOKEN } from '../../modal'; +import { loadDesignerRegister } from './components/maps'; +import { FM_MODAL_SERVICE_TOKEN } from '../../modal'; +import { FM_UI_PROVIDER_SERVICE_TOKEN } from '@/components'; export default defineComponent({ name: 'FDesignerCanvas', @@ -35,17 +36,15 @@ export default defineComponent({ metadataService: inject('Meatdata_Http_Service_Token'), schemaService: inject('schemaService'), useFormCommand: inject('useFormCommand'), - modalService: inject(F_MODAL_SERVICE_TOKEN), - formStateMachineUtils: inject('useFormStateMachine') + modalService: inject(FM_MODAL_SERVICE_TOKEN), + formStateMachineUtils: inject('useFormStateMachine'), + uiProviderService: inject(FM_UI_PROVIDER_SERVICE_TOKEN), + }; provide('designer-host-service', designerHostService); const useDragulaComposition = useDragula(designerHostService); - if(props.components){ - loadDesignerRegisterByComponents(props.components); - }else{ - loadDesignerRegister(); - } + loadDesignerRegister(); provide('canvas-dragula', useDragulaComposition); provide('design-item-context', { diff --git a/packages/mobile-ui-vue/components/designer-toolbox/index.ts b/packages/mobile-ui-vue/components/designer-toolbox/index.ts new file mode 100644 index 00000000000..6616581e20b --- /dev/null +++ b/packages/mobile-ui-vue/components/designer-toolbox/index.ts @@ -0,0 +1,5 @@ +import FDesignerToolbox from './src/toolbox.component'; + +export * from './src/types'; + +export { FDesignerToolbox }; diff --git a/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.component.tsx b/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.component.tsx new file mode 100644 index 00000000000..b28fc46df04 --- /dev/null +++ b/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.component.tsx @@ -0,0 +1,153 @@ +import { defineComponent, ref, watch } from 'vue'; +import { ToolboxPropsType, toolboxProps } from './toolbox.props'; +import { ToolboxCategory, ToolboxItem } from './types'; + +import toolboxItems from './toolbox.json'; +import './toolbox.css'; + +export default defineComponent({ + name: 'FDesignerToolbox', + props: toolboxProps, + emits: [], + setup(props: ToolboxPropsType) { + const controlCategoryList = props.toolboxItems ? ref(props.toolboxItems as ToolboxCategory[]) : ref(toolboxItems); + const dragularCompostion = ref(props.dragula); + + function onClickCardHeader(payload: MouseEvent, category: any) { + category.isHide = !category.isHide; + } + + function getCardHeaderIconClass(category: any) { + const classObject = { + 'f-icon': true, + 'f-icon-arrow-60-down': !category.isHide, + 'f-icon-arrow-e': category.isHide + } as Record; + return classObject; + } + + function renderCategoryCardHeader(category: ToolboxCategory) { + return ( +
onClickCardHeader(payload, category)}> +
+
+
+
+ +
+
+ {category.name} +
+
+
+
+
+ ); + } + + function getControlTileClass(toolboxItem: ToolboxItem) { + const classObject = { + 'd-none': toolboxItem.dependentParent || toolboxItem.hideInControlBox, + controlPanel: true, + 'drag-copy': true, + 'no-drag': toolboxItem.disable, + 'updating': toolboxItem.updating + } as Record; + return classObject; + } + + function getToolboxItemClass(toolboxItem: ToolboxItem) { + const classObject = { + farrisControlIcon: true, + 'fd-i-Family': true + } as Record; + const toolboxItemTypicalClassName = `fd_pc-${toolboxItem.icon || toolboxItem.type}`; + classObject[toolboxItemTypicalClassName] = true; + return classObject; + } + + function renderControlTile(toolboxItem: ToolboxItem, category: ToolboxCategory) { + return ( + + ); + } + + function renderCategoryCardBody(category: ToolboxCategory) { + return ( +
+ {category.items.map((toolboxItem: any) => renderControlTile(toolboxItem, category))} +
+ ); + } + + function renderCategoryCard(category: ToolboxCategory) { + return ( + !category.hideInControlBox && ( +
+ {renderCategoryCardHeader(category)} + {renderCategoryCardBody(category)} +
+ ) + ); + } + + /** + * 将工具箱各容器添加到dragula的拖拽列表中 + */ + function attachToolboxToDragulaContainer(dragulaInstance: any) { + if (!dragulaInstance) { + return; + } + const controlPanels = document.getElementsByClassName('controlCategory'); + if (!controlPanels) { + return; + } + + dragulaInstance.containers = dragulaInstance.containers.filter( + (element: HTMLElement) => !element.className.includes('controlCategory') + ); + + Array.from(controlPanels).forEach((panelElement) => { + dragulaInstance.containers.push(panelElement); + }); + + } + + watch( + () => props.dragula, + (newValue: any) => { + dragularCompostion.value = newValue; + if (dragularCompostion.value?.getDragulaInstance) { + attachToolboxToDragulaContainer(dragularCompostion.value?.getDragulaInstance()); + } + } + ); + + return () => { + return ( +
+
+ {controlCategoryList.value.map((category: any) => { + return renderCategoryCard(category); + })} +
+
+ ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.css b/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.css new file mode 100644 index 00000000000..bdc92e87307 --- /dev/null +++ b/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.css @@ -0,0 +1,75 @@ +.controlBox { + font-size: 13px !important; +} + +.controlBox .farris-panel { + border: none; +} + +.controlBox .farris-panel .card-header { + padding: 10px 0px !important; + background-color: #fcfdff !important; +} + +.controlBox .farris-panel .card-header .col-form-label { + font-size: 13px; + margin-bottom: 0px; + color: #3f4764; + opacity: 0.65; +} + +.controlBox .farris-panel .card-header .col-form-label .f-icon { + font-size: 10.8px; + color: #3f4764; +} + +.controlBox .farris-panel .card-body { + display: flex; + flex-wrap: wrap; + background: #fcfdff !important; +} + +.controlPanel:nth-child(-n + 3) { + margin-top: 0 !important; +} + +.controlPanel .farrisControlIcon { + font-size: 27px; +} + +.controlPanel { + font-size: 13px; + cursor: grab; + display: flex; + background: #fff; + align-items: center; + width: 33.333%; + background-color: #fcfdff; + border: 1px solid #edf1f5; + height: 76px !important; + text-align: center; + margin: -1px 0 0 -1px !important; + color: #6080ad; + /* overflow: hidden; */ + text-overflow: ellipsis; + word-break: keep-all; + -webkit-user-select: none; + user-select: none; +} + +.controlPanel.updating { + color: #707070; +} + +.controlPanel > div { + margin: auto; + overflow: hidden; +} + +.gu-mirror.undroppable.controlPanel { + cursor: no-drop; +} + +.controlBox .farris-panel .card-header .col-form-label .icon-panel .f-icon { + font-size: 16px; +} diff --git a/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.json b/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.json new file mode 100644 index 00000000000..3f3386d8a1d --- /dev/null +++ b/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.json @@ -0,0 +1,110 @@ +[ + { + "type": "input", + "name": "输入类控件", + "items": [ + { + "id": "TextBox", + "type": "input-group", + "name": "文本", + "category": "input" + }, + { + "id": "MultiTextBox", + "type": "textarea", + "name": "多行文本", + "category": "input" + }, + { + "id": "DateBox", + "type": "date-picker", + "name": "日期", + "category": "input" + }, + { + "id": "EnumField", + "type": "combo-list", + "name": "下拉列表", + "category": "input" + }, + { + "id": "NumericBox", + "type": "number-spinner", + "name": "数值", + "category": "input" + }, + { + "id": "CheckBox", + "type": "check-box", + "name": "复选框", + "category": "input" + }, + { + "id": "CheckBoxGroup", + "type": "check-group", + "name": "复选框组", + "category": "input" + }, + { + "id": "RadioGroup", + "type": "radio-group", + "name": "单选组", + "category": "input" + }, + { + "id": "SwitchField", + "type": "switch", + "name": "开关", + "category": "input" + }, + { + "id": "LookupEdit", + "type": "lookup", + "name": "帮助", + "category": "input" + } + ] + }, + { + "type": "dataCollection", + "name": "数据集合类控件", + "items": [ + { + "id": "ResponseForm", + "type": "form", + "name": "卡片面板", + "category": "dataCollection" + }, + { + "id": "DataGrid", + "type": "data-grid", + "name": "表格", + "category": "dataCollection" + } + ] + }, + { + "type": "container", + "name": "容器类控件", + "items": [ + { + "id": "Tab", + "type": "tabs", + "name": "标签页区域", + "category": "container" + } + ] + }, + { + "type": "business", + "name": "业务类控件", + "items": [ + { + "id": "QuerySolution", + "type": "query-solution", + "name": "筛选方案", + "category": "container" + } + ] + } +] \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.props.ts b/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.props.ts new file mode 100644 index 00000000000..ddf9559cc14 --- /dev/null +++ b/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.props.ts @@ -0,0 +1,10 @@ +import { ExtractPropTypes } from 'vue'; + +export const toolboxProps = { + id: { type: String, default: '' }, + dragula: { type: Object }, + toolboxItems: { type: Object } + +}; + +export type ToolboxPropsType = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/designer-toolbox/src/types.ts b/packages/mobile-ui-vue/components/designer-toolbox/src/types.ts new file mode 100644 index 00000000000..52436075af5 --- /dev/null +++ b/packages/mobile-ui-vue/components/designer-toolbox/src/types.ts @@ -0,0 +1,22 @@ +export interface ToolboxItem { + id: string; + type: string; + name: string; + category: string; + icon?: string; + feature?: any; + dependentParent?: boolean; + hideInControlBox?: boolean; + disable?: boolean; + fieldType?: string; + templateCategory?: string; + updating?: boolean; +} + +export interface ToolboxCategory { + type: string; + name: string; + items: ToolboxItem[]; + hideInControlBox?: boolean; + isHide?: boolean; +}; diff --git a/packages/mobile-ui-vue/components/designer.ts b/packages/mobile-ui-vue/components/designer.ts index 3aaf39102fc..6118ec98be8 100644 --- a/packages/mobile-ui-vue/components/designer.ts +++ b/packages/mobile-ui-vue/components/designer.ts @@ -1,3 +1,5 @@ export * from './designer-canvas'; export * from './dynamic-resolver'; - +export { FDesignerToolbox } from './designer-toolbox'; +export { default as FModal, FModalService, FM_MODAL_SERVICE_TOKEN } from './modal'; +export { FM_UI_PROVIDER_SERVICE_TOKEN } from './common'; diff --git a/packages/mobile-ui-vue/components/float-container/index.ts b/packages/mobile-ui-vue/components/float-container/index.ts index 47454ca63a9..3b6178781c2 100644 --- a/packages/mobile-ui-vue/components/float-container/index.ts +++ b/packages/mobile-ui-vue/components/float-container/index.ts @@ -2,6 +2,7 @@ import { Plugin } from 'vue'; import { withInstall } from '@components/common'; import { propsResolver } from './src/float-container.props'; import FloatContainerInstallless from './src/float-container.component'; +import FloatContainerDesign from './src/designer/float-container.design.component'; const FLOAT_CONTAINER_REGISTERED_NAME = 'float-container'; @@ -15,6 +16,15 @@ FloatContainer.register = ( propsResolverMap[FLOAT_CONTAINER_REGISTERED_NAME] = propsResolver; }; +FloatContainer.registerDesigner = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[FLOAT_CONTAINER_REGISTERED_NAME] = FloatContainerDesign; + 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/designer/float-container.design.component.tsx b/packages/mobile-ui-vue/components/float-container/src/designer/float-container.design.component.tsx new file mode 100644 index 00000000000..959f7cde474 --- /dev/null +++ b/packages/mobile-ui-vue/components/float-container/src/designer/float-container.design.component.tsx @@ -0,0 +1,31 @@ +import { SetupContext, defineComponent, inject, onMounted, ref } from 'vue'; +import { FloatContainerProps, floatContainerProps } from '../float-container.props'; +import { useDesignerRules } from './use-designer-rules'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; + +export default defineComponent({ + name: 'FmFloatContainerDesign', + props: floatContainerProps, + emits: [], + setup(props: FloatContainerProps, context: SetupContext) { + const elementRef = ref(); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerHostService = inject('designer-host-service'); + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + context.expose(componentInstance.value); + + return () => { + return ( +
+ {context.slots.default?.()} +
+ ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..6f2d9115c56 --- /dev/null +++ b/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts @@ -0,0 +1,99 @@ +import { ref } from "vue"; +import { ComponentSchema, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { DraggingResolveContext } from "@/components/designer-canvas/src/composition/types"; +import { FloatContainerProperty } from "../property-config/float-container.property-config"; + +export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { + + const triggerBelongedComponentToMoveWhenMoved = ref(false); + + const triggerBelongedComponentToDeleteWhenDeleted = ref(false); + + const hideNestedPadding = true; + + const schema = ref(designItemContext.schema) + + function canAccepts(draggingContext: DraggingResolveContext): boolean { + const acceptableControlTypes = [ + 'navbar', + 'content-container', + 'html-template', + ]; + const uniqueControlTypes = [ + 'navbar', + ]; + const { sourceType, parentComponentInstance } = draggingContext; + if (!acceptableControlTypes.includes(sourceType)) { + return false; + } + const shouldBeUnique = uniqueControlTypes.includes(sourceType); + if (shouldBeUnique) { + const parentComponent = parentComponentInstance?.parent?.value; + const contents: any[] = parentComponent?.contents || []; + const hasSameTypeControl = !!contents.find((content) => content.type === sourceType); + if (hasSameTypeControl) { + return false; + } + } + return true; + } + + function checkCanMoveComponent() { + return false; + } + function checkCanDeleteComponent() { + return true; + } + + function hideNestedPaddingInDesginerView() { + return hideNestedPadding; + } + + function getDesignerClass(): string { + return ' position-absolute z-index-99 '; + } + + function getStyles(): string { + let style = '' + if (schema.value.position) { + style += Object.keys(schema.value.position).map(key => { + return `${key}: ${schema.value.position[key]}px;` + }).join('') + } + if (schema.value.padding) { + style += Object.keys(schema.value.padding).map(key => { + return `padding-${key}: ${schema.padding[key]}px;` + }).join('') + } + if (schema.value.margin) { + style += Object.keys(schema.value.margin).map(key => { + return `margin-${key}: ${schema.value.margin[key]}px;` + }).join('') + } + return style + } + + + /** + * 获取属性配置 + */ + function getPropsConfig(componentId: string) { + const componentProp = new FloatContainerProperty(componentId, designerHostService); + const { schema } = designItemContext; + return componentProp.getPropertyConfig(schema); + } + + + + return { + canAccepts, + triggerBelongedComponentToMoveWhenMoved, + triggerBelongedComponentToDeleteWhenDeleted, + checkCanMoveComponent, + checkCanDeleteComponent, + hideNestedPaddingInDesginerView, + getDesignerClass, + getStyles, + getPropsConfig + }; +} diff --git a/packages/mobile-ui-vue/components/float-container/src/property-config/float-container.property-config.ts b/packages/mobile-ui-vue/components/float-container/src/property-config/float-container.property-config.ts new file mode 100644 index 00000000000..3ad2a788fe1 --- /dev/null +++ b/packages/mobile-ui-vue/components/float-container/src/property-config/float-container.property-config.ts @@ -0,0 +1,15 @@ +import { BaseControlProperty } from "@/components/property-panel"; + +export class FloatContainerProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: any) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + + return this.propertyConfig; + } +} diff --git a/packages/mobile-ui-vue/components/form-item/index.ts b/packages/mobile-ui-vue/components/form-item/index.ts index af7481fd11f..c52eef2821f 100644 --- a/packages/mobile-ui-vue/components/form-item/index.ts +++ b/packages/mobile-ui-vue/components/form-item/index.ts @@ -1,6 +1,7 @@ import { withInstall } from '@components/common'; import { propsResolver } from './src/form-item.props'; import FormItemInstallless from './src/form-item.component'; +import FormItemDesign from './src/designer/form-item.design.component'; const FORM_REGISTERED_NAME = 'form-item'; @@ -14,6 +15,14 @@ FormItem.register = ( propsResolverMap[FORM_REGISTERED_NAME] = propsResolver; }; +FormItem.registerDesigner = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[FORM_REGISTERED_NAME] = FormItemDesign; + 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/designer/form-item-use-designer-rules.ts b/packages/mobile-ui-vue/components/form-item/src/designer/form-item-use-designer-rules.ts new file mode 100644 index 00000000000..305fcbdbd85 --- /dev/null +++ b/packages/mobile-ui-vue/components/form-item/src/designer/form-item-use-designer-rules.ts @@ -0,0 +1,85 @@ +import { DesignerItemContext, DesignerHostService, UseDesignerRules, DesignerComponentInstance, ComponentSchema } from "@/components/designer-canvas"; +import { FormGroupProperty } from "../property-config/form-group.property-config"; + +export function useDesignerRulesForFormItem(designItemContext: DesignerItemContext, designerHostService?: DesignerHostService): UseDesignerRules { + const schema = designItemContext.schema as ComponentSchema; + + function checkCanMoveComponent() { + return true; + } + function checkCanDeleteComponent() { + return true; + } + + function canAccepts() { + return false; + } + + function hideNestedPaddingInDesginerView() { + return true; + } + /** + * 若控件有绑定信息,删除控件时需要同步移除viewmodel中的记录 + */ + function removeBindingFromViewModel(bindingFieldId: string) { + const designViewModelUtils = designerHostService?.designViewModelUtils; + const formSchemaUtils = designerHostService?.formSchemaUtils; + const belongedComponentId = designItemContext?.componentInstance.value?.belongedComponentId; + if (!belongedComponentId || !designViewModelUtils || !formSchemaUtils) { + return; + } + const belongedviewModelId = formSchemaUtils.getViewModelIdByComponentId(belongedComponentId); + const dgViewModel = designViewModelUtils.getDgViewModel(belongedviewModelId); + + if (dgViewModel) { + dgViewModel.removeField([bindingFieldId]); + } + } + /** + * 若控件配置了表达式,删除控件时需要同步移除表达式 + */ + function removeExpression(bindingFieldId: string) { + const formSchemaUtils = designerHostService?.formSchemaUtils; + + if (formSchemaUtils.getExpressions().length) { + const expFieldIndex = formSchemaUtils.getExpressions().findIndex(e => e.fieldId === bindingFieldId); + if (expFieldIndex > -1) { + formSchemaUtils.getExpressions().splice(expFieldIndex, 1); + } + + } + } + + function getDesignerClass(): string { + return ' fm-input-wrapper '; + } + + /** + * 控件删除后事件 + */ + function onRemoveComponent() { + const { schema } = designItemContext; + const bindingFieldId = schema.binding && schema.binding.field; + if (bindingFieldId) { + removeBindingFromViewModel(bindingFieldId); + removeExpression(bindingFieldId); + } + } + + // 构造属性配置方法 + function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { + const inputGroupProps = new FormGroupProperty(componentId, designerHostService); + return inputGroupProps.getPropertyConfig(schema, componentInstance); + } + + + return { + canAccepts, + checkCanDeleteComponent, + checkCanMoveComponent, + hideNestedPaddingInDesginerView, + onRemoveComponent, + getDesignerClass, + getPropsConfig + }; +} diff --git a/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx b/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx new file mode 100644 index 00000000000..251d704b9ea --- /dev/null +++ b/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx @@ -0,0 +1,137 @@ +/** + * 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, defineComponent, inject, onMounted, ref, SetupContext, watch } from 'vue'; +import { useBem } from '@components/common'; +import FmCell from '@components/cell'; +import { FORM_ITEM_NAME, FormItemProps, formItemProps } from '../form-item.props'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; +import { propertyConfigSchemaMap } from '@/components/dynamic-resolver'; +import { useDesignerRulesForFormItem } from './form-item-use-designer-rules'; +import { useTypeResolverDesign } from '@/components/dynamic-form/src/composition/use-type-resolver-design'; + +export default defineComponent({ + name: 'FmFormItemDesign', + props: formItemProps, + + setup(props: FormItemProps, context: SetupContext) { + const { slots, expose } = context; + + const label = ref(props.label); + const labelAlign = ref(props.labelAlign); + const shouldShowRequired = ref(props.required); + const { bem } = useBem(FORM_ITEM_NAME); + const editor = ref(props.editor); + const { resolveEditorProps, resolveEditorType } = useTypeResolverDesign(); + + const elementRef = ref(); + const editorRef = ref(); + + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerHostService = inject('designer-host-service'); + const designerRulesComposition = useDesignerRulesForFormItem(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + + const renderLabel = () => { + if (slots.label) { + return [slots.label()]; + } + return ; + }; + + const contentClass = computed(() => { + let contentAlign = props.contentAlign || 'right'; + if (labelAlign.value === 'top') { + contentAlign = 'left'; + } + return { + [bem('content')]: true, + [bem('content', contentAlign)]: true + }; + }); + const renderContent = () => { + const renderConditionEditor = computed(() => { + const editorType = editor.value.type || 'input-group'; + const Component = resolveEditorType(editorType); + const editorProps = resolveEditorProps(editorType, editor.value); + return () => ; + }); + + + return
{renderConditionEditor.value()}
; + }; + + + const formItemClass = computed(() => { + const direction = labelAlign.value === 'top' ? 'vertical' : 'horizontal'; + return { + [bem()]: true, + [bem('', direction)]: true + }; + }); + + const labelClass = computed(() => { + const labelClasses = [bem('label'), bem('label', labelAlign.value)]; + if (shouldShowRequired.value === true) { + labelClasses.push(bem('label', 'required')); + } + return labelClasses.join(' '); + }); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + + componentInstance.value.getPropConfig = (...args) => { + let propertyConfigSchema = propertyConfigSchemaMap[props.editor.type]; + if (propertyConfigSchema && Object.keys(propertyConfigSchema).length === 0 && editorRef && editorRef.value && editorRef.value?.getPropConfig) { + propertyConfigSchema = editorRef.value.getPropConfig(...args, componentInstance.value); + } + return propertyConfigSchema; + + }; + }); + + watch([ + () => props.label, + ], + ([newLabel])=>{ + label.value = newLabel; + } + + ) + + context.expose(componentInstance.value); + + return () => { + const innerSlots = { + title: renderLabel, + default: renderContent, + leftIcon: slots.leftIcon, + rightIcon: slots.rightIcon, + extra: slots.extra + }; + + return ( + + + ); + }; + + } +}); diff --git a/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts b/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts new file mode 100644 index 00000000000..bb3a52d2f72 --- /dev/null +++ b/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts @@ -0,0 +1,103 @@ +import { ComponentSchema, DesignerComponentInstance, DesignerHostService, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { DraggingResolveContext } from "@/components/designer-canvas/src/composition/types"; +import { getSchemaByType } from "@/components/dynamic-resolver"; +import { ref } from "vue"; +import { ResponseFormProperty } from "../property-config/response-form.property-config"; + +export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService?: DesignerHostService): UseDesignerRules { + const schema = designItemContext.schema as ComponentSchema; + + const triggerBelongedComponentToMoveWhenMoved = ref(false); + + const triggerBelongedComponentToDeleteWhenDeleted = ref(false); + + const hideNestedPadding = true; + + const isInFixedContextRules = true; + + function canAccepts(draggingContext: DraggingResolveContext): boolean { + + return true; + } + + + function checkCanMoveComponent() { + return true + } + function checkCanDeleteComponent() { + return true; + } + + function hideNestedPaddingInDesginerView() { + return hideNestedPadding; + } + + + function onResolveNewComponentSchema(resolveContext: DraggingResolveContext, componentSchema: ComponentSchema): ComponentSchema { + const { label } = resolveContext; + let formGroupElementSchema; + // 控件若有绑定信息,则根据绑定信息创建控件 + if (resolveContext.bindingSourceContext?.entityFieldNode) { + const controlCreatorUtils = designerHostService?.controlCreatorUtils; + formGroupElementSchema = controlCreatorUtils.setFormFieldProperty(resolveContext.bindingSourceContext?.entityFieldNode, componentSchema.type); + } else { + formGroupElementSchema = getSchemaByType('form-item') as ComponentSchema; + formGroupElementSchema.editor = componentSchema; + formGroupElementSchema.label = label; + } + + syncFieldToViewModel(resolveContext, componentSchema.type); + + return formGroupElementSchema; + } + + + + /** + * 添加输入类控件后,将绑定信息同步到视图模型 + */ + function syncFieldToViewModel(resolveContext: DraggingResolveContext, editorType: string) { + const { bindingSourceContext, parentComponentInstance } = resolveContext; + if (bindingSourceContext?.entityFieldNode && parentComponentInstance) { + const designViewModelUtils = designerHostService?.designViewModelUtils; + const formSchemaUtils = designerHostService?.formSchemaUtils; + const viewModelId = formSchemaUtils.getViewModelIdByComponentId(parentComponentInstance.belongedComponentId); + + const dgViewModel = designViewModelUtils.getDgViewModel(viewModelId); + dgViewModel.removeField([bindingSourceContext.entityFieldNode.id]); + dgViewModel.addField(bindingSourceContext.designViewModelField); + if (editorType) { + dgViewModel.changeField(bindingSourceContext.entityFieldNode.id, { editor: { $type: editorType } }); + } + } + + } + + function getStyles(): string { + return ' '; + } + + function getDesignerClass(): string { + return ' '; + } + + // 构造属性配置方法 + function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { + const inputGroupProps = new ResponseFormProperty(componentId, designerHostService); + return inputGroupProps.getPropertyConfig(schema, componentInstance); + } + + + return { + canAccepts, + triggerBelongedComponentToMoveWhenMoved, + triggerBelongedComponentToDeleteWhenDeleted, + checkCanMoveComponent, + checkCanDeleteComponent, + hideNestedPaddingInDesginerView, + getStyles, + getDesignerClass, + onResolveNewComponentSchema, + getPropsConfig + }; +} diff --git a/packages/mobile-ui-vue/components/form-item/src/designer/response-form.design.component.tsx b/packages/mobile-ui-vue/components/form-item/src/designer/response-form.design.component.tsx new file mode 100644 index 00000000000..47b8f94a399 --- /dev/null +++ b/packages/mobile-ui-vue/components/form-item/src/designer/response-form.design.component.tsx @@ -0,0 +1,46 @@ +import { computed, defineComponent, inject, onMounted, ref } from 'vue'; +import { useDesignerRules } from './response-form-use-designer-rules'; +import { FormProps, formProps } from '../form.props'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; + +export default defineComponent({ + name: 'FResponseFormDesign', + props: formProps, + emits: [], + setup(props: FormProps, context) { + const elementRef = ref(); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerHostService = inject('designer-host-service'); + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + context.expose(componentInstance.value); + + const responseFormClass = computed(() => { + const customClassArray = []; + const classObject = { + 'drag-container': true + } as Record; + customClassArray.reduce((result: Record, classString: string) => { + result[classString] = true; + return result; + }, classObject); + return classObject; + }); + + + return () => { + return ( + +
+ {context.slots.default && context.slots.default()} +
+ + ); + }; + } +}); 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 a50759b8f7a..2952c339967 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 @@ -35,7 +35,9 @@ export const formItemProps = { showErrorMessage: { type: Boolean, default: undefined }, /** 错误信息位置 */ - errorMessageAlign: { type: String as PropType, deafult: undefined } + errorMessageAlign: { type: String as PropType, deafult: undefined }, + + editor: { type: Object as PropType, default: {} }, }; diff --git a/packages/mobile-ui-vue/components/form-item/src/property-config/form-group.property-config.ts b/packages/mobile-ui-vue/components/form-item/src/property-config/form-group.property-config.ts new file mode 100644 index 00000000000..46c7790226c --- /dev/null +++ b/packages/mobile-ui-vue/components/form-item/src/property-config/form-group.property-config.ts @@ -0,0 +1,16 @@ +import { DesignerComponentInstance } from "@/components/designer-canvas"; +import { BaseControlProperty } from "@/components/property-panel"; + +export class FormGroupProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: any, componentInstance: DesignerComponentInstance) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + + return this.propertyConfig; + } +} diff --git a/packages/mobile-ui-vue/components/form-item/src/property-config/response-form.property-config.ts b/packages/mobile-ui-vue/components/form-item/src/property-config/response-form.property-config.ts new file mode 100644 index 00000000000..d035881f762 --- /dev/null +++ b/packages/mobile-ui-vue/components/form-item/src/property-config/response-form.property-config.ts @@ -0,0 +1,16 @@ +import { DesignerComponentInstance } from "@/components/designer-canvas"; +import { BaseControlProperty } from "@/components/property-panel"; + +export class ResponseFormProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: any, componentInstance: DesignerComponentInstance) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + + return this.propertyConfig; + } +} diff --git a/packages/mobile-ui-vue/components/form/index.ts b/packages/mobile-ui-vue/components/form/index.ts index c62036c1587..f7cb3ad778c 100644 --- a/packages/mobile-ui-vue/components/form/index.ts +++ b/packages/mobile-ui-vue/components/form/index.ts @@ -18,6 +18,7 @@ import { Plugin } from 'vue'; import { withInstall } from '@components/common'; import { propsResolver } from '@components/form-item/src/form.props'; import FormInstallless from '@components/form-item/src/form.component'; +import FormInstalllessDesign from '../form-item/src/designer/response-form.design.component'; const FORM_REGISTERED_NAME = 'form'; @@ -31,6 +32,14 @@ Form.register = ( propsResolverMap[FORM_REGISTERED_NAME] = propsResolver; }; +Form.registerDesigner = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[FORM_REGISTERED_NAME] = FormInstalllessDesign; + propsResolverMap[FORM_REGISTERED_NAME] = propsResolver; +}; + export * from '@components/form-item/src/form.props'; export { Form }; export default Form as typeof Form & Plugin; diff --git a/packages/mobile-ui-vue/components/input-group/index.ts b/packages/mobile-ui-vue/components/input-group/index.ts index 6217bc10ace..30385677fe3 100644 --- a/packages/mobile-ui-vue/components/input-group/index.ts +++ b/packages/mobile-ui-vue/components/input-group/index.ts @@ -1,6 +1,7 @@ import { withInstall } from '@components/common'; import { propsResolver } from './src/input-group.props'; import InputGroupInstallless from './src/input-group.component'; +import InputGroupDesign from './src/designer/input-group.design.component'; const INPUT_GROUP_REGISTERED_NAME = 'input-group'; @@ -13,6 +14,15 @@ InputGroup.register = ( componentMap[INPUT_GROUP_REGISTERED_NAME] = InputGroup; propsResolverMap[INPUT_GROUP_REGISTERED_NAME] = propsResolver; }; + +InputGroup.registerDesigner = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[INPUT_GROUP_REGISTERED_NAME] = InputGroupDesign; + propsResolverMap[INPUT_GROUP_REGISTERED_NAME] = propsResolver; +}; + export * from './src/input-group.props'; export * from './src/types'; export { InputGroup }; diff --git a/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx b/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx new file mode 100644 index 00000000000..10ef1a9b3f7 --- /dev/null +++ b/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx @@ -0,0 +1,50 @@ +/* eslint-disable no-use-before-define */ +/** + * 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, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; +import { InputGroup, InputProps, inputProps } from '../..'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; +import { useInputGroupDesignerRules } from './use-designer-rules'; + +export default defineComponent({ + name: 'FmInputGroupDesign', + props: inputProps, + emits: [] as (string[] & ThisType) | undefined, + setup(props: InputProps, context: SetupContext) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useInputGroupDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + const inputGroupProps = computed(() => ({ + ...props, + editable: false + })); + + context.expose(componentInstance.value); + + return () => { + return ( + + ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/input-group/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/input-group/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..c6684e06dd7 --- /dev/null +++ b/packages/mobile-ui-vue/components/input-group/src/designer/use-designer-rules.ts @@ -0,0 +1,15 @@ +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { InputGroupProperty } from "../property-config/input-group.property-config"; +export function useInputGroupDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { + + const schema = designItemContext.schema as ComponentSchema; + + // 构造属性配置方法 + function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { + const inputGroupProps = new InputGroupProperty(componentId, designerHostService); + return inputGroupProps.getPropertyConfig(schema, componentInstance); + } + + return { getPropsConfig } as UseDesignerRules; + +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts b/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts new file mode 100644 index 00000000000..34037ac64d8 --- /dev/null +++ b/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts @@ -0,0 +1,34 @@ +import { InputBaseProperty } from "@/components/common/src/entity/input-base-property"; + +export class InputGroupProperty extends InputBaseProperty { + + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + + getEditorProperties(propertyData: any) { + const self = this; + const editorProperties = self.getComponentConfig(propertyData, { type: "radio-group" }, { + placeholder: { + description: "空值时,输入控件内的占位文本", + title: "提示文本", + type: "string" + } + }); + editorProperties['setPropertyRelates'] = function (changeObject) { + if (!changeObject) { + return; + } + switch (changeObject.propertyID) { + case 'data': { + + break; + } + } + }; + return editorProperties; + } + + +} 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 4801efdefbc..03a53f1db63 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 @@ -36,6 +36,38 @@ "description": "值变化事件", "type": "string", "default": "" + }, + "disable": { + "type": "string", + "default": false + }, + "readonly": { + "type": "string", + "default": false + }, + "title": { + "description": "", + "type": "string", + "default": "" + }, + "label": { + "description": "", + "type": "string", + "default": "" + }, + "lableWidth": { + "description": "", + "type": "number" + }, + "placeholder": { + "description": "", + "type": "string", + "default": "" + }, + "visible": { + "description": "", + "type": "boolean", + "default": true } }, "events": [ @@ -43,6 +75,8 @@ ], "required": [ "id", - "type" + "type", + "appearance", + "binding" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/list-view/index.ts b/packages/mobile-ui-vue/components/list-view/index.ts index 5e571fa8982..acf70aef1b2 100644 --- a/packages/mobile-ui-vue/components/list-view/index.ts +++ b/packages/mobile-ui-vue/components/list-view/index.ts @@ -1,23 +1,29 @@ import { withInstall } from '@components/common'; import ListViewInstallless from './src/list-view.component'; -import ListViewDesignInstallless from './src/designer/list-view.design.component'; +import ListViewDesign from './src/designer/list-view.design.component'; import { propsResolver } from './src/list-view.props'; const LIST_VIEW_REGISTER_NAME = 'list-view'; const ListView = withInstall(ListViewInstallless); -const ListViewDesign = withInstall(ListViewDesignInstallless); export * from './src/list-view.props'; -export { ListView, ListViewDesign }; +ListView.register = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[LIST_VIEW_REGISTER_NAME] = ListView; + propsResolverMap[LIST_VIEW_REGISTER_NAME] = propsResolver; +} -export default { - register(componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void { - componentMap[LIST_VIEW_REGISTER_NAME] = ListView; - propsResolverMap[LIST_VIEW_REGISTER_NAME] = propsResolver; - }, - registerDesigner(componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void { - componentMap[LIST_VIEW_REGISTER_NAME] = ListViewDesign; - propsResolverMap[LIST_VIEW_REGISTER_NAME] = propsResolver; - } -}; +ListView.registerDesigner = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[LIST_VIEW_REGISTER_NAME] = ListViewDesign; + propsResolverMap[LIST_VIEW_REGISTER_NAME] = propsResolver; +} + + +export { ListView }; +export default ListView ; diff --git a/packages/mobile-ui-vue/components/list-view/src/designer/list-view.design.component.tsx b/packages/mobile-ui-vue/components/list-view/src/designer/list-view.design.component.tsx index a8d0e4a15db..613a425325f 100644 --- a/packages/mobile-ui-vue/components/list-view/src/designer/list-view.design.component.tsx +++ b/packages/mobile-ui-vue/components/list-view/src/designer/list-view.design.component.tsx @@ -1,9 +1,9 @@ import { SetupContext, defineComponent, inject, onMounted, ref, computed } from 'vue'; -import { ListViewProps, listViewProps } from '../list-view.props'; +import { LIST_VIEW_NAME, ListViewProps, listViewProps } from '../list-view.props'; import { useDesignerRules } from './use-designer-rules'; -import { DesignerItemContext } from '../../../designer-canvas/src/types'; -import { useDesignerComponent } from '../../../designer-canvas/src/composition/function/use-designer-component'; -import ListView from '../list-view.component'; +import List from '@/components/list'; +import { useBem } from '@/components/common'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas'; export default defineComponent({ name: 'FmListViewDesign', @@ -11,8 +11,9 @@ export default defineComponent({ emits: [], setup(props: ListViewProps, context: SetupContext) { const elementRef = ref(); - const designItemContext = inject('design-item-context'); - const designerRulesComposition = useDesignerRules(designItemContext.schema, designItemContext.parent?.schema); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); onMounted(() => { @@ -26,10 +27,33 @@ export default defineComponent({ finished: true, })); + const { bem } = useBem(LIST_VIEW_NAME); + + const listViewClass = { + [bem()]: true, + [bem('', 'fill')]: true, + }; + + const listContentClass = { + [bem('content')]: true, + [bem('content', 'split')]: false, + }; + return () => ( -
- +
+
+ +
+
+
+ +
+
+ ); } }); diff --git a/packages/mobile-ui-vue/components/list-view/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/list-view/src/designer/use-designer-rules.ts index 2ea4e7382a8..66f9e80cd93 100644 --- a/packages/mobile-ui-vue/components/list-view/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/list-view/src/designer/use-designer-rules.ts @@ -1,8 +1,9 @@ -import { nextTick, ref } from "vue"; -import { DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../../../designer-canvas/src/composition/types"; -import { ComponentSchema } from "../../../designer-canvas/src/types"; +import { ref } from "vue"; +import { DesignerHostService, DraggingResolveContext, UseDesignerRules } from "../../../designer-canvas/src/composition/types"; +import { ComponentProperty } from "../property-config/component.property-config"; +import { DesignerItemContext } from "@/components/designer-canvas"; -export function useDesignerRules(schema: ComponentSchema, parentSchema?: ComponentSchema): UseDesignerRules { +export function useDesignerRules(designItemContext: DesignerItemContext,designerHostService?: DesignerHostService): UseDesignerRules { const triggerBelongedComponentToMoveWhenMoved = ref(false); @@ -30,12 +31,20 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone } function getStyles(): string { - if (schema.fill) { - return 'flex: 1'; - } - return ''; + return 'flex: 1'; + + } + + /** + * 获取属性配置 + */ + function getPropsConfig(componentId: string) { + const componentProp = new ComponentProperty(componentId, designerHostService); + const { schema } = designItemContext; + return componentProp.getPropertyConfig(schema); } + return { canAccepts, triggerBelongedComponentToMoveWhenMoved, @@ -44,5 +53,6 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone checkCanDeleteComponent, hideNestedPaddingInDesginerView, getStyles, + getPropsConfig }; } diff --git a/packages/mobile-ui-vue/components/list-view/src/property-config/component.property-config.ts b/packages/mobile-ui-vue/components/list-view/src/property-config/component.property-config.ts new file mode 100644 index 00000000000..b1ea32df738 --- /dev/null +++ b/packages/mobile-ui-vue/components/list-view/src/property-config/component.property-config.ts @@ -0,0 +1,51 @@ +import { BaseControlProperty } from "@/components/property-panel"; + + +export class ComponentProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: any) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + // 事件 + this.getEventPropConfig(propertyData); + return this.propertyConfig; + } + private getEventPropConfig(propertyData: any) { + const events = [ + { + label: "listClick", + name: "行点击事件", + } + ]; + const self = this; + const initialData = self.eventsEditorUtils['formProperties'](propertyData, self.viewModelId, events); + const properties = {}; + properties[self.viewModelId] = { + type: 'events-editor', + editor: { + initialData + } + }; + this.propertyConfig.categories['eventsEditor'] = { + title: '事件', + hideTitle: true, + properties, + // 这个属性,标记当属性变更得时候触发重新更新属性 + refreshPanelAfterChanged: true, + tabId: 'commands', + tabName: '交互', + setPropertyRelates(changeObject: any, data: any) { + const parameters = changeObject.propertyValue; + delete propertyData[self.viewModelId]; + if (parameters) { + parameters.setPropertyRelates = this.setPropertyRelates; // 添加自定义方法后,调用此回调方法,用于处理联动属性 + self.eventsEditorUtils.saveRelatedParameters(propertyData, self.viewModelId, parameters['events'], parameters); + } + } + }; + } +} diff --git a/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.json b/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.json index 49292d31b76..75c9494bb38 100644 --- a/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.json +++ b/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.json @@ -16,11 +16,7 @@ "type": { "description": "组件类型", "title": "控件类型", - "type": "select", - "editor": { - "type": "container", - "enum": [] - } + "type": "string" } } }, diff --git a/packages/mobile-ui-vue/components/modal/index.ts b/packages/mobile-ui-vue/components/modal/index.ts index cea142d232b..ad48a036b87 100644 --- a/packages/mobile-ui-vue/components/modal/index.ts +++ b/packages/mobile-ui-vue/components/modal/index.ts @@ -19,12 +19,12 @@ import FModalService from './src/composition/modal.service'; export * from './src/modal.props'; -export const F_MODAL_SERVICE_TOKEN = Symbol('FModalService'); +export const FM_MODAL_SERVICE_TOKEN = Symbol('FModalService'); FModal.install = (app: App) => { app.component(FModal.name as string, FModal); const modalInstance = new FModalService(app); - app.provide(F_MODAL_SERVICE_TOKEN, modalInstance); + app.provide(FM_MODAL_SERVICE_TOKEN, modalInstance); app.provide('FModalService', modalInstance); }; diff --git a/packages/mobile-ui-vue/components/navbar/index.ts b/packages/mobile-ui-vue/components/navbar/index.ts index 2e20484d4c5..9860ea71a68 100644 --- a/packages/mobile-ui-vue/components/navbar/index.ts +++ b/packages/mobile-ui-vue/components/navbar/index.ts @@ -1,6 +1,7 @@ import { withInstall } from '@components/common'; import { propsResolver } from './src/navbar.props'; import NavbarInstallless from './src/navbar.component'; +import NavbarDesign from './src/designer/nav.design.component'; const NAVBAR_REGISTERED_NAME = 'navigation-bar'; @@ -10,5 +11,10 @@ Navbar.register = (componentMap: Record, propsResolverMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { + componentMap[NAVBAR_REGISTERED_NAME] = NavbarDesign; + propsResolverMap[NAVBAR_REGISTERED_NAME] = propsResolver; +}; export { Navbar }; export default Navbar; diff --git a/packages/mobile-ui-vue/components/navbar/src/designer/nav.design.component.tsx b/packages/mobile-ui-vue/components/navbar/src/designer/nav.design.component.tsx new file mode 100644 index 00000000000..81d1d0cd355 --- /dev/null +++ b/packages/mobile-ui-vue/components/navbar/src/designer/nav.design.component.tsx @@ -0,0 +1,51 @@ +/* eslint-disable no-use-before-define */ +/** + * 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, defineComponent, inject, onMounted, ref, SetupContext } from 'vue'; + +import Navbar from '../..'; +import { navbarProps, NavbarProps } from '../navbar.props'; +import { useDesignerRules } from './use-designer-rules'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; + +export default defineComponent({ + name: 'FNavDesign', + props: navbarProps, + emits: ['nav'] as (string[] & ThisType) | undefined, + setup(props: NavbarProps, context: SetupContext) { + const elementRef = ref(); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerHostService = inject('designer-host-service'); + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext,designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + context.expose(componentInstance.value); + + const navbarProps = computed(() => ({ + ...props, + })); + + return () => { + return ( + + ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/navbar/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/navbar/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..00566e382cc --- /dev/null +++ b/packages/mobile-ui-vue/components/navbar/src/designer/use-designer-rules.ts @@ -0,0 +1,63 @@ +import { DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { DraggingResolveContext } from "@/components/designer-canvas/src/composition/types"; +import { nextTick, ref } from "vue"; +import { NavBarProperty } from "../property-config/navbar.property-config"; + +export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { + + const triggerBelongedComponentToMoveWhenMoved = ref(false); + + const triggerBelongedComponentToDeleteWhenDeleted = ref(false); + + const hideNestedPadding = true; + + const isInFixedContextRules = true; + + function canAccepts(draggingContext: DraggingResolveContext): boolean { + + return false; + } + + + function checkCanMoveComponent() { + return true; + } + function checkCanDeleteComponent() { + return true; + } + + function hideNestedPaddingInDesginerView() { + return true; + } + + function getStyles(): string { + // return 'border-radius: 12px'; + return ' '; + } + + function getDesignerClass(): string { + return ' '; + } + + /** + * 获取属性配置 + */ + function getPropsConfig(componentId: string) { + const componentProp = new NavBarProperty(componentId, designerHostService); + const { schema } = designItemContext; + return componentProp.getPropertyConfig(schema); + } + + + return { + canAccepts, + triggerBelongedComponentToMoveWhenMoved, + triggerBelongedComponentToDeleteWhenDeleted, + checkCanMoveComponent, + checkCanDeleteComponent, + hideNestedPaddingInDesginerView, + getStyles, + getDesignerClass, + getPropsConfig + }; +} diff --git a/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts b/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts new file mode 100644 index 00000000000..ca841d84dc6 --- /dev/null +++ b/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts @@ -0,0 +1,31 @@ +import { BaseControlProperty } from "@/components/property-panel"; + +export class NavBarProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: any) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + //行为 + this.propertyConfig.categories['behavior'] = this.getBehaviorConfig(propertyData); + + return this.propertyConfig; + } + + private getBehaviorConfig(propertyData) { + return { + description: "基本信息", + title: "行为", + properties: { + title: { + title: "标题", + type: "string", + } + } + }; + } + +} 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 c6cfd478abb..7d141367928 100644 --- a/packages/mobile-ui-vue/components/page-body-container/index.ts +++ b/packages/mobile-ui-vue/components/page-body-container/index.ts @@ -16,7 +16,7 @@ */ import { withInstall } from '@components/common'; import PageBodyContainerInstallless from './src/page-body-container.component'; -import PageBodyContainerDesignInstallless from './src/designer/page-body-container.design.component'; +import PageBodyContainerDesign from './src/designer/page-body-container.design.component'; import { propsResolver } from './src/page-body-container.props'; const PAGE_BODY_CONTAINER_REGISTER_NAME = 'page-body-container'; @@ -27,13 +27,12 @@ PageBodyContainer.register = (componentMap: Record, propsResolverMa propsResolverMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = propsResolver; }; -const PageBodyContainerDesign = withInstall(PageBodyContainerDesignInstallless); -PageBodyContainerDesign.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void => { +PageBodyContainer.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 { PageBodyContainer }; export default PageBodyContainer; diff --git a/packages/mobile-ui-vue/components/page-body-container/src/designer/page-body-container.design.component.tsx b/packages/mobile-ui-vue/components/page-body-container/src/designer/page-body-container.design.component.tsx index a34c85bccae..8662cedfd43 100644 --- a/packages/mobile-ui-vue/components/page-body-container/src/designer/page-body-container.design.component.tsx +++ b/packages/mobile-ui-vue/components/page-body-container/src/designer/page-body-container.design.component.tsx @@ -1,8 +1,7 @@ import { SetupContext, defineComponent, inject, onMounted, ref } from 'vue'; import { PageBodyContainerProps, pageBodyContainerProps } from '../page-body-container.props'; import { useDesignerRules } from './use-designer-rules'; -import { DesignerItemContext } from '../../../designer-canvas/src/types'; -import { useDesignerComponent } from '../../../designer-canvas/src/composition/function/use-designer-component'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; export default defineComponent({ name: 'FmPageBodyContainerDesign', @@ -10,8 +9,9 @@ export default defineComponent({ emits: [], setup(props: PageBodyContainerProps, context: SetupContext) { const elementRef = ref(); - const designItemContext = inject('design-item-context'); - const designerRulesComposition = useDesignerRules(designItemContext.schema, designItemContext.parent?.schema); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); onMounted(() => { diff --git a/packages/mobile-ui-vue/components/page-body-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/page-body-container/src/designer/use-designer-rules.ts index 8cfec6e7f99..f5fd184a249 100644 --- a/packages/mobile-ui-vue/components/page-body-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/page-body-container/src/designer/use-designer-rules.ts @@ -1,9 +1,10 @@ import { nextTick, ref } from "vue"; -import { DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../../../designer-canvas/src/composition/types"; -import { ComponentSchema } from "../../../designer-canvas/src/types"; import { PAGE_BODY_CONTAINER_NAME } from '../page-body-container.props'; +import { DesignerHostService, DraggingResolveContext, UseDesignerRules } from "@/components/designer-canvas/src/composition/types"; +import { DesignerItemContext } from "@/components/designer-canvas"; +import { PageBodyContainerProperty } from "../property-config/page-body-container.property-config"; -export function useDesignerRules(schema: ComponentSchema, parentSchema?: ComponentSchema): UseDesignerRules { +export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService?: DesignerHostService): UseDesignerRules { const triggerBelongedComponentToMoveWhenMoved = ref(false); @@ -21,8 +22,8 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone 'float-container', 'navbar', ]; - const { controlType } = draggingContext; - if (unAcceptableControlTypes.includes(controlType)) { + const { componentType } = draggingContext; + if (unAcceptableControlTypes.includes(componentType)) { return false; } return true; @@ -30,10 +31,10 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone function checkCanMoveComponent() { - return !isInFixedContextRules; + return true; } function checkCanDeleteComponent() { - return !isInFixedContextRules; + return true; } function hideNestedPaddingInDesginerView() { @@ -44,6 +45,16 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone return PAGE_BODY_CONTAINER_NAME; } + /** + * 获取属性配置 + */ + function getPropsConfig(componentId: string) { + const componentProp = new PageBodyContainerProperty(componentId, designerHostService); + const { schema } = designItemContext; + return componentProp.getPropertyConfig(schema); + } + + return { canAccepts, triggerBelongedComponentToMoveWhenMoved, @@ -52,5 +63,6 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone checkCanDeleteComponent, hideNestedPaddingInDesginerView, getDesignerClass, + getPropsConfig }; } diff --git a/packages/mobile-ui-vue/components/page-body-container/src/page-body-container.props.ts b/packages/mobile-ui-vue/components/page-body-container/src/page-body-container.props.ts index bcca60bfc7b..4a4089bf75c 100644 --- a/packages/mobile-ui-vue/components/page-body-container/src/page-body-container.props.ts +++ b/packages/mobile-ui-vue/components/page-body-container/src/page-body-container.props.ts @@ -2,7 +2,6 @@ import { ExtractPropTypes } from 'vue'; import { createPropsResolver } from '../../dynamic-resolver'; import { schemaMapper } from './schema/schema-mapper'; import pageBodyContainerSchema from './schema/page-body-container.schema.json'; -import pageBodyContainerPropertyConfig from './property-config/page-body-container.property-config.json'; import { schemaResolver } from './schema/schema-resolver'; export const PAGE_BODY_CONTAINER_NAME = 'fm-page-body-container'; @@ -17,6 +16,5 @@ export const propsResolver = createPropsResolver( pageBodyContainerProps, pageBodyContainerSchema, schemaMapper, - schemaResolver, - pageBodyContainerPropertyConfig, + schemaResolver ); diff --git a/packages/mobile-ui-vue/components/page-body-container/src/property-config/page-body-container.property-config.json b/packages/mobile-ui-vue/components/page-body-container/src/property-config/page-body-container.property-config.json deleted file mode 100644 index e7b0c65f4e6..00000000000 --- a/packages/mobile-ui-vue/components/page-body-container/src/property-config/page-body-container.property-config.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "title": "page-body-container", - "description": "A Farris Container Component", - "type": "object", - "categories": { - "basic": { - "description": "Basic Infomation", - "title": "基本信息", - "properties": { - "id": { - "description": "组件标识", - "title": "标识", - "type": "string", - "readonly": true - }, - "type": { - "description": "组件类型", - "title": "控件类型", - "type": "select", - "editor": { - "type": "container", - "enum": [] - } - } - } - }, - "behavior": { - "description": "", - "title": "行为", - "properties": { - "visible": { - "description": "运行时组件是否可见", - "type": "boolean", - "title": "是否可见", - "editor": { - "type": "combo-list", - "data": [ - { - "value": true, - "name": "是" - }, - { - "value": false, - "name": "否" - } - ] - } - } - } - } - } -} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/page-body-container/src/property-config/page-body-container.property-config.ts b/packages/mobile-ui-vue/components/page-body-container/src/property-config/page-body-container.property-config.ts new file mode 100644 index 00000000000..077bd5883ae --- /dev/null +++ b/packages/mobile-ui-vue/components/page-body-container/src/property-config/page-body-container.property-config.ts @@ -0,0 +1,15 @@ +import { BaseControlProperty } from "@/components/property-panel"; + +export class PageBodyContainerProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: any) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + + return this.propertyConfig; + } +} diff --git a/packages/mobile-ui-vue/components/page-container/index.ts b/packages/mobile-ui-vue/components/page-container/index.ts index 00d8d010d3f..4438af465e2 100644 --- a/packages/mobile-ui-vue/components/page-container/index.ts +++ b/packages/mobile-ui-vue/components/page-container/index.ts @@ -16,7 +16,7 @@ */ import { withInstall } from '@components/common'; import PageContainerInstallless from './src/page-container.component'; -import PageContainerDesignInstallless from './src/designer/page-container.design.component'; +import PageContainerDesign from './src/designer/page-container.design.component'; import { propsResolver } from './src/page-container.props'; const PAGE_CONTAINER_REGISTERED_NAME = 'page-container'; @@ -29,8 +29,7 @@ PageContainer.register = ( propsResolverMap[PAGE_CONTAINER_REGISTERED_NAME] = propsResolver; }; -const PageContainerDesign = withInstall(PageContainerDesignInstallless); -PageContainerDesign.registerDesigner = ( +PageContainer.registerDesigner = ( componentMap: Record, propsResolverMap: Record, configResolverMap: Record ): void => { componentMap[PAGE_CONTAINER_REGISTERED_NAME] = PageContainerDesign; @@ -38,5 +37,5 @@ PageContainerDesign.registerDesigner = ( }; export * from './src/page-container.props'; -export { PageContainer, PageContainerDesign }; +export { PageContainer }; export default PageContainer; diff --git a/packages/mobile-ui-vue/components/page-container/src/designer/page-container.design.component.tsx b/packages/mobile-ui-vue/components/page-container/src/designer/page-container.design.component.tsx index 5751301030d..f265911ef32 100644 --- a/packages/mobile-ui-vue/components/page-container/src/designer/page-container.design.component.tsx +++ b/packages/mobile-ui-vue/components/page-container/src/designer/page-container.design.component.tsx @@ -1,8 +1,7 @@ import { SetupContext, defineComponent, inject, onMounted, ref } from 'vue'; import { PageContainerProps, pageContainerProps } from '../page-container.props'; import { useDesignerRules } from './use-designer-rules'; -import { DesignerItemContext } from '../../../designer-canvas/src/types'; -import { useDesignerComponent } from '../../../designer-canvas/src/composition/function/use-designer-component'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; export default defineComponent({ name: 'FmPageContainerDesign', @@ -10,8 +9,9 @@ export default defineComponent({ emits: [], setup(props: PageContainerProps, context: SetupContext) { const elementRef = ref(); - const designItemContext = inject('design-item-context'); - const designerRulesComposition = useDesignerRules(designItemContext.schema, designItemContext.parent?.schema); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); onMounted(() => { diff --git a/packages/mobile-ui-vue/components/page-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/page-container/src/designer/use-designer-rules.ts index 4b6ed1d438f..dd317403bcc 100644 --- a/packages/mobile-ui-vue/components/page-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/page-container/src/designer/use-designer-rules.ts @@ -1,9 +1,10 @@ -import { nextTick, ref } from "vue"; -import { DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../../../designer-canvas/src/composition/types"; -import { ComponentSchema } from "../../../designer-canvas/src/types"; +import { ref } from "vue"; import { PAGE_CONTAINER_NAME } from '../page-container.props'; +import { DesignerHostService, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { DraggingResolveContext } from "@/components/designer-canvas/src/composition/types"; +import { PageContainerProperty } from "../property-config/page-container.property-config"; -export function useDesignerRules(schema: ComponentSchema, parentSchema?: ComponentSchema): UseDesignerRules { +export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService?: DesignerHostService): UseDesignerRules { const triggerBelongedComponentToMoveWhenMoved = ref(false); @@ -25,15 +26,15 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone 'page-footer-container', 'page-body-container', ]; - const { controlType, parentComponentInstance } = draggingContext; - if (!acceptableControlTypes.includes(controlType)) { + const { componentType, parentComponentInstance } = draggingContext; + if (!acceptableControlTypes.includes(componentType)) { return false; } - const shouldBeUnique = uniqueControlTypes.includes(controlType); + const shouldBeUnique = uniqueControlTypes.includes(componentType); if (shouldBeUnique) { - const parentComponent = parentComponentInstance?.value; + const parentComponent = parentComponentInstance; const contents: any[] = parentComponent?.contents || []; - const hasSameTypeControl = !!contents.find((content) => content.type === controlType); + const hasSameTypeControl = !!contents.find((content) => content.type === componentType); if (hasSameTypeControl) { return false; } @@ -43,7 +44,7 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone function checkCanMoveComponent() { - return !isInFixedContextRules; + return true; } function checkCanDeleteComponent() { return !isInFixedContextRules; @@ -54,13 +55,25 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone } function getStyles(): string { - return 'border-radius: 12px'; + // return 'border-radius: 12px'; + return ' '; } function getDesignerClass(): string { return PAGE_CONTAINER_NAME; } + + /** + * 获取属性配置 + */ + function getPropsConfig(componentId: string) { + const componentProp = new PageContainerProperty(componentId, designerHostService); + const { schema } = designItemContext; + return componentProp.getPropertyConfig(schema); + } + + return { canAccepts, triggerBelongedComponentToMoveWhenMoved, @@ -70,5 +83,6 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone hideNestedPaddingInDesginerView, getStyles, getDesignerClass, + getPropsConfig }; } diff --git a/packages/mobile-ui-vue/components/page-container/src/page-container.props.ts b/packages/mobile-ui-vue/components/page-container/src/page-container.props.ts index e981a24e019..c7a084830eb 100644 --- a/packages/mobile-ui-vue/components/page-container/src/page-container.props.ts +++ b/packages/mobile-ui-vue/components/page-container/src/page-container.props.ts @@ -2,7 +2,6 @@ import { ExtractPropTypes } from 'vue'; import { createPropsResolver } from '../../dynamic-resolver'; import { schemaMapper } from './schema/schema-mapper'; import pageContainerSchema from './schema/page-container.schema.json'; -import pageContainerPropertyConfig from './property-config/page-container.property-config.json'; import { schemaResolver } from './schema/schema-resolver'; export const PAGE_CONTAINER_NAME = 'fm-page-container'; @@ -17,6 +16,5 @@ export const propsResolver = createPropsResolver( pageContainerProps, pageContainerSchema, schemaMapper, - schemaResolver, - pageContainerPropertyConfig, + schemaResolver ); diff --git a/packages/mobile-ui-vue/components/page-container/src/property-config/page-container.property-config.json b/packages/mobile-ui-vue/components/page-container/src/property-config/page-container.property-config.json deleted file mode 100644 index 7bc1352b999..00000000000 --- a/packages/mobile-ui-vue/components/page-container/src/property-config/page-container.property-config.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "title": "page-container", - "description": "A Farris Container Component", - "type": "object", - "categories": { - "basic": { - "description": "Basic Infomation", - "title": "基本信息", - "properties": { - "id": { - "description": "组件标识", - "title": "标识", - "type": "string", - "readonly": true - }, - "type": { - "description": "组件类型", - "title": "控件类型", - "type": "select", - "editor": { - "type": "container", - "enum": [] - } - } - } - }, - "behavior": { - "description": "", - "title": "行为", - "properties": { - "visible": { - "description": "运行时组件是否可见", - "type": "boolean", - "title": "是否可见", - "editor": { - "type": "combo-list", - "data": [ - { - "value": true, - "name": "是" - }, - { - "value": false, - "name": "否" - } - ] - } - } - } - } - } -} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/page-container/src/property-config/page-container.property-config.ts b/packages/mobile-ui-vue/components/page-container/src/property-config/page-container.property-config.ts new file mode 100644 index 00000000000..9771ba1d932 --- /dev/null +++ b/packages/mobile-ui-vue/components/page-container/src/property-config/page-container.property-config.ts @@ -0,0 +1,15 @@ +import { BaseControlProperty } from "@/components/property-panel"; + +export class PageContainerProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: any) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + + return this.propertyConfig; + } +} 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 1f3f9fcbbc2..e8cec7710ae 100644 --- a/packages/mobile-ui-vue/components/page-footer-container/index.ts +++ b/packages/mobile-ui-vue/components/page-footer-container/index.ts @@ -16,7 +16,7 @@ */ import { withInstall } from '@components/common'; import PageFooterContainerInstallless from './src/page-footer-container.component'; -import PageFooterContainerDesignInstallless from './src/designer/page-footer-container.design.component'; +import PageFooterContainerDesign from './src/designer/page-footer-container.design.component'; import { propsResolver } from './src/page-footer-container.props'; const COMPONENT_TYPE = 'page-footer-container'; @@ -30,8 +30,7 @@ PageFooterContainer.register = ( propsResolverMap[COMPONENT_TYPE] = propsResolver; }; -const PageFooterContainerDesign = withInstall(PageFooterContainerDesignInstallless); -PageFooterContainerDesign.registerDesigner = ( +PageFooterContainer.registerDesigner = ( componentMap: Record, propsResolverMap: Record, configResolverMap: Record ): void => { @@ -40,5 +39,5 @@ PageFooterContainerDesign.registerDesigner = ( }; export * from './src/page-footer-container.props'; -export { PageFooterContainer, PageFooterContainerDesign }; +export { PageFooterContainer }; export default PageFooterContainer; diff --git a/packages/mobile-ui-vue/components/page-footer-container/src/designer/page-footer-container.design.component.tsx b/packages/mobile-ui-vue/components/page-footer-container/src/designer/page-footer-container.design.component.tsx index b91bd86138b..8a2a1978665 100644 --- a/packages/mobile-ui-vue/components/page-footer-container/src/designer/page-footer-container.design.component.tsx +++ b/packages/mobile-ui-vue/components/page-footer-container/src/designer/page-footer-container.design.component.tsx @@ -1,8 +1,7 @@ import { SetupContext, defineComponent, inject, onMounted, ref } from 'vue'; import { PageFooterContainerProps, pageFooterContainerProps } from '../page-footer-container.props'; import { useDesignerRules } from './use-designer-rules'; -import { DesignerItemContext } from '../../../designer-canvas/src/types'; -import { useDesignerComponent } from '../../../designer-canvas/src/composition/function/use-designer-component'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; export default defineComponent({ name: 'FmPageFooterContainerDesign', @@ -10,8 +9,9 @@ export default defineComponent({ emits: [], setup(props: PageFooterContainerProps, context: SetupContext) { const elementRef = ref(); - const designItemContext = inject('design-item-context'); - const designerRulesComposition = useDesignerRules(designItemContext.schema, designItemContext.parent?.schema); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); onMounted(() => { diff --git a/packages/mobile-ui-vue/components/page-footer-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/page-footer-container/src/designer/use-designer-rules.ts index 646004bdb6d..d3d813ebed1 100644 --- a/packages/mobile-ui-vue/components/page-footer-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/page-footer-container/src/designer/use-designer-rules.ts @@ -1,9 +1,10 @@ import { ref } from "vue"; -import { DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../../../designer-canvas/src/composition/types"; -import { ComponentSchema } from "../../../designer-canvas/src/types"; import { PAGE_FOOTER_CONTAINER_NAME } from '../page-footer-container.props'; +import { DesignerHostService, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { DraggingResolveContext } from "@/components/designer-canvas/src/composition/types"; +import { PageFooterContainerProperty } from "../property-config/page-footer-container.property-config"; -export function useDesignerRules(schema: ComponentSchema, parentSchema?: ComponentSchema): UseDesignerRules { +export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService?: DesignerHostService): UseDesignerRules { const triggerBelongedComponentToMoveWhenMoved = ref(false); @@ -18,8 +19,8 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone 'content-container', 'html-template', ]; - const { controlType } = draggingContext; - if (!acceptableControlTypes.includes(controlType)) { + const { componentType } = draggingContext; + if (!acceptableControlTypes.includes(componentType)) { return false; } return true; @@ -27,7 +28,7 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone function checkCanMoveComponent() { - return false; + return true; } function checkCanDeleteComponent() { return true; @@ -41,6 +42,16 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone return PAGE_FOOTER_CONTAINER_NAME; } + /** + * 获取属性配置 + */ + function getPropsConfig(componentId: string) { + const componentProp = new PageFooterContainerProperty(componentId, designerHostService); + const { schema } = designItemContext; + return componentProp.getPropertyConfig(schema); + } + + return { canAccepts, triggerBelongedComponentToMoveWhenMoved, @@ -49,5 +60,6 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone checkCanDeleteComponent, hideNestedPaddingInDesginerView, getDesignerClass, + getPropsConfig }; } diff --git a/packages/mobile-ui-vue/components/page-footer-container/src/page-footer-container.props.ts b/packages/mobile-ui-vue/components/page-footer-container/src/page-footer-container.props.ts index 6ed1c2031fc..79bc601420a 100644 --- a/packages/mobile-ui-vue/components/page-footer-container/src/page-footer-container.props.ts +++ b/packages/mobile-ui-vue/components/page-footer-container/src/page-footer-container.props.ts @@ -2,7 +2,6 @@ import { ExtractPropTypes } from 'vue'; import { createPropsResolver } from '../../dynamic-resolver'; import { schemaMapper } from './schema/schema-mapper'; import pageFooterContainerSchema from './schema/page-footer-container.schema.json'; -import pageFooterContainerPropertyConfig from './property-config/page-footer-container.property-config.json'; import { schemaResolver } from './schema/schema-resolver'; export const PAGE_FOOTER_CONTAINER_NAME = 'fm-page-footer-container'; @@ -17,6 +16,5 @@ export const propsResolver = createPropsResolver( pageFooterContainerProps, pageFooterContainerSchema, schemaMapper, - schemaResolver, - pageFooterContainerPropertyConfig, + schemaResolver ); diff --git a/packages/mobile-ui-vue/components/page-footer-container/src/property-config/page-footer-container.property-config.json b/packages/mobile-ui-vue/components/page-footer-container/src/property-config/page-footer-container.property-config.json deleted file mode 100644 index a1a581a9ef8..00000000000 --- a/packages/mobile-ui-vue/components/page-footer-container/src/property-config/page-footer-container.property-config.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "title": "page-footer-container", - "description": "A Farris Container Component", - "type": "object", - "categories": { - "basic": { - "description": "Basic Infomation", - "title": "基本信息", - "properties": { - "id": { - "description": "组件标识", - "title": "标识", - "type": "string", - "readonly": true - }, - "type": { - "description": "组件类型", - "title": "控件类型", - "type": "select", - "editor": { - "type": "container", - "enum": [] - } - } - } - }, - "behavior": { - "description": "", - "title": "行为", - "properties": { - "visible": { - "description": "运行时组件是否可见", - "type": "boolean", - "title": "是否可见", - "editor": { - "type": "combo-list", - "data": [ - { - "value": true, - "name": "是" - }, - { - "value": false, - "name": "否" - } - ] - } - } - } - } - } -} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/page-footer-container/src/property-config/page-footer-container.property-config.ts b/packages/mobile-ui-vue/components/page-footer-container/src/property-config/page-footer-container.property-config.ts new file mode 100644 index 00000000000..066b9d66ca2 --- /dev/null +++ b/packages/mobile-ui-vue/components/page-footer-container/src/property-config/page-footer-container.property-config.ts @@ -0,0 +1,15 @@ +import { BaseControlProperty } from "@/components/property-panel"; + +export class PageFooterContainerProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: any) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + + return this.propertyConfig; + } +} 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 92ddae7dab1..1a36319a7ec 100644 --- a/packages/mobile-ui-vue/components/page-header-container/index.ts +++ b/packages/mobile-ui-vue/components/page-header-container/index.ts @@ -16,7 +16,7 @@ */ import { withInstall } from '@components/common'; import PageHeaderContainerInstallless from './src/page-header-container.component'; -import PageHeaderContainerDesignInstallless from './src/designer/page-header-container.design.component'; +import PageHeaderContainerDesign from './src/designer/page-header-container.design.component'; import { propsResolver } from './src/page-header-container.props'; const PAGE_HEADER_CONTAINER_REGISTERED_NAME = 'page-header-container'; @@ -30,8 +30,7 @@ PageHeaderContainer.register = ( propsResolverMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = propsResolver; }; -const PageHeaderContainerDesign = withInstall(PageHeaderContainerDesignInstallless); -PageHeaderContainerDesign.registerDesigner = ( +PageHeaderContainer.registerDesigner = ( componentMap: Record, propsResolverMap: Record, configResolverMap: Record ): void => { componentMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = PageHeaderContainerDesign; @@ -39,5 +38,5 @@ PageHeaderContainerDesign.registerDesigner = ( }; export * from './src/page-header-container.props'; -export { PageHeaderContainer, PageHeaderContainerDesign }; +export { PageHeaderContainer }; export default PageHeaderContainer; diff --git a/packages/mobile-ui-vue/components/page-header-container/src/designer/page-header-container.design.component.tsx b/packages/mobile-ui-vue/components/page-header-container/src/designer/page-header-container.design.component.tsx index 9237dcb1f83..b43faef2fb8 100644 --- a/packages/mobile-ui-vue/components/page-header-container/src/designer/page-header-container.design.component.tsx +++ b/packages/mobile-ui-vue/components/page-header-container/src/designer/page-header-container.design.component.tsx @@ -1,8 +1,7 @@ import { SetupContext, defineComponent, inject, onMounted, ref } from 'vue'; import { PageHeaderContainerProps, pageHeaderContainerProps } from '../page-header-container.props'; import { useDesignerRules } from './use-designer-rules'; -import { DesignerItemContext } from '../../../designer-canvas/src/types'; -import { useDesignerComponent } from '../../../designer-canvas/src/composition/function/use-designer-component'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; export default defineComponent({ name: 'FmPageHeaderContainerDesign', @@ -10,8 +9,9 @@ export default defineComponent({ emits: [], setup(props: PageHeaderContainerProps, context: SetupContext) { const elementRef = ref(); - const designItemContext = inject('design-item-context'); - const designerRulesComposition = useDesignerRules(designItemContext.schema, designItemContext.parent?.schema); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerHostService = inject('designer-host-service'); + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); onMounted(() => { diff --git a/packages/mobile-ui-vue/components/page-header-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/page-header-container/src/designer/use-designer-rules.ts index 66ae6778195..9833f1936a9 100644 --- a/packages/mobile-ui-vue/components/page-header-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/page-header-container/src/designer/use-designer-rules.ts @@ -1,9 +1,10 @@ import { ref } from "vue"; -import { DraggingResolveContext, UseDesignerRules } from "../../../designer-canvas/src/composition/types"; -import { ComponentSchema } from "../../../designer-canvas/src/types"; import { PAGE_HEADER_CONTAINER_NAME } from '../page-header-container.props'; +import { ComponentSchema, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { DraggingResolveContext } from "@/components/designer-canvas/src/composition/types"; +import { PageHeaderContainerProperty } from "../property-config/page-header-container.property-config"; -export function useDesignerRules(schema: ComponentSchema, parentSchema?: ComponentSchema): UseDesignerRules { +export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { const triggerBelongedComponentToMoveWhenMoved = ref(false); @@ -20,15 +21,15 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone const uniqueControlTypes = [ 'navbar', ]; - const { controlType, parentComponentInstance } = draggingContext; - if (!acceptableControlTypes.includes(controlType)) { + const { sourceType, parentComponentInstance } = draggingContext; + if (!acceptableControlTypes.includes(sourceType)) { return false; } - const shouldBeUnique = uniqueControlTypes.includes(controlType); + const shouldBeUnique = uniqueControlTypes.includes(sourceType); if (shouldBeUnique) { - const parentComponent = parentComponentInstance?.value; + const parentComponent = parentComponentInstance?.parent?.value; const contents: any[] = parentComponent?.contents || []; - const hasSameTypeControl = !!contents.find((content) => content.type === controlType); + const hasSameTypeControl = !!contents.find((content) => content.type === sourceType); if (hasSameTypeControl) { return false; } @@ -37,7 +38,7 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone } function checkCanMoveComponent() { - return false; + return true; } function checkCanDeleteComponent() { return true; @@ -50,6 +51,16 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone function getDesignerClass(): string { return PAGE_HEADER_CONTAINER_NAME; } + + /** + * 获取属性配置 + */ + function getPropsConfig(componentId: string) { + const componentProp = new PageHeaderContainerProperty(componentId, designerHostService); + const { schema } = designItemContext; + return componentProp.getPropertyConfig(schema); + } + return { canAccepts, @@ -59,5 +70,6 @@ export function useDesignerRules(schema: ComponentSchema, parentSchema?: Compone checkCanDeleteComponent, hideNestedPaddingInDesginerView, getDesignerClass, + getPropsConfig }; } diff --git a/packages/mobile-ui-vue/components/page-header-container/src/page-header-container.props.ts b/packages/mobile-ui-vue/components/page-header-container/src/page-header-container.props.ts index 1e8413a3f85..15901f23a8d 100644 --- a/packages/mobile-ui-vue/components/page-header-container/src/page-header-container.props.ts +++ b/packages/mobile-ui-vue/components/page-header-container/src/page-header-container.props.ts @@ -2,7 +2,6 @@ import { ExtractPropTypes } from 'vue'; import { createPropsResolver } from '../../dynamic-resolver'; import { schemaMapper } from './schema/schema-mapper'; import pageHeaderContainerSchema from './schema/page-header-container.schema.json'; -import pageHeaderContainerPropertyConfig from './property-config/page-header-container.property-config.json'; import { schemaResolver } from './schema/schema-resolver'; export const PAGE_HEADER_CONTAINER_NAME = 'fm-page-header-container'; @@ -17,6 +16,5 @@ export const propsResolver = createPropsResolver( pageHeaderContainerProps, pageHeaderContainerSchema, schemaMapper, - schemaResolver, - pageHeaderContainerPropertyConfig, + schemaResolver ); diff --git a/packages/mobile-ui-vue/components/page-header-container/src/property-config/page-header-container.property-config.json b/packages/mobile-ui-vue/components/page-header-container/src/property-config/page-header-container.property-config.json deleted file mode 100644 index 9abbd5182e4..00000000000 --- a/packages/mobile-ui-vue/components/page-header-container/src/property-config/page-header-container.property-config.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "title": "page-header-container", - "description": "A Farris Container Component", - "type": "object", - "categories": { - "basic": { - "description": "Basic Infomation", - "title": "基本信息", - "properties": { - "id": { - "description": "组件标识", - "title": "标识", - "type": "string", - "readonly": true - }, - "type": { - "description": "组件类型", - "title": "控件类型", - "type": "select", - "editor": { - "type": "container", - "enum": [] - } - } - } - }, - "behavior": { - "description": "", - "title": "行为", - "properties": { - "visible": { - "description": "运行时组件是否可见", - "type": "boolean", - "title": "是否可见", - "editor": { - "type": "combo-list", - "data": [ - { - "value": true, - "name": "是" - }, - { - "value": false, - "name": "否" - } - ] - } - } - } - } - } -} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/page-header-container/src/property-config/page-header-container.property-config.ts b/packages/mobile-ui-vue/components/page-header-container/src/property-config/page-header-container.property-config.ts new file mode 100644 index 00000000000..9100e1f3740 --- /dev/null +++ b/packages/mobile-ui-vue/components/page-header-container/src/property-config/page-header-container.property-config.ts @@ -0,0 +1,15 @@ +import { BaseControlProperty } from "@/components/property-panel"; + +export class PageHeaderContainerProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: any) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + + return this.propertyConfig; + } +} diff --git a/packages/mobile-ui-vue/components/radio-group/index.ts b/packages/mobile-ui-vue/components/radio-group/index.ts index 70b9fbc5090..4c196194195 100644 --- a/packages/mobile-ui-vue/components/radio-group/index.ts +++ b/packages/mobile-ui-vue/components/radio-group/index.ts @@ -1,9 +1,23 @@ import { withInstall } from '@components/common'; import RadioGroupInstallless from './src/radio-group.component'; +import { propsResolver } from './src/radio-group.props'; +import RadioGroupDesign from './src/designer/radio-group.design.component'; export * from './src/radio-group.props'; +const RADIO_GROUP_REGISTERED_NAME = 'radio-group'; + const RadioGroup = withInstall(RadioGroupInstallless); +RadioGroup.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { + componentMap[RADIO_GROUP_REGISTERED_NAME] = RadioGroup; + propsResolverMap[RADIO_GROUP_REGISTERED_NAME] = propsResolver; +}; +RadioGroup.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record) => { + componentMap[RADIO_GROUP_REGISTERED_NAME] = RadioGroupDesign; + propsResolverMap[RADIO_GROUP_REGISTERED_NAME] = propsResolver; +}; + + export { RadioGroup }; export default RadioGroup; diff --git a/packages/mobile-ui-vue/components/radio-group/src/designer/radio-group.design.component.tsx b/packages/mobile-ui-vue/components/radio-group/src/designer/radio-group.design.component.tsx new file mode 100644 index 00000000000..ab423e6c767 --- /dev/null +++ b/packages/mobile-ui-vue/components/radio-group/src/designer/radio-group.design.component.tsx @@ -0,0 +1,63 @@ +/* eslint-disable no-use-before-define */ +/** + * 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, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; +import RadioGroup, { RadioGroupProps, radioGroupProps } from '../..'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas'; +import { useRadioGroupDesignerRules } from './use-designer-rules'; +; + +export default defineComponent({ + name: 'FmRadioGroupDesign', + props: radioGroupProps, + emits: [] as (string[] & ThisType) | undefined, + setup(props: RadioGroupProps, context: SetupContext) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useRadioGroupDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + const inputGroupProps = computed(() => ({ + ...props, + editable: false, + // options:[{ + // disabled: false, + // readonly: false, + // value: '1', + // text: '选项1' + // },{ + // disabled: false, + // readonly: false, + // value: '1', + // text: '选项1' + // }], + // direction:'horizontal' + })); + + context.expose(componentInstance.value); + + return () => { + return ( + + ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/radio-group/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/radio-group/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..e16b11842f6 --- /dev/null +++ b/packages/mobile-ui-vue/components/radio-group/src/designer/use-designer-rules.ts @@ -0,0 +1,15 @@ +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { RadioGroupProperty } from "../property-config/radio-group.property-config"; +export function useRadioGroupDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { + + const schema = designItemContext.schema as ComponentSchema; + + // 构造属性配置方法 + function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { + const radioGroupProps = new RadioGroupProperty(componentId, designerHostService); + return radioGroupProps.getPropertyConfig(schema, componentInstance); + } + + return { getPropsConfig } as UseDesignerRules; + +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts b/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts new file mode 100644 index 00000000000..d1b24caa387 --- /dev/null +++ b/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts @@ -0,0 +1,53 @@ +import { InputBaseProperty } from "@/components/common/src/entity/input-base-property"; + +export class RadioGroupProperty extends InputBaseProperty { + + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + + getEditorProperties(propertyData: any) { + const self = this; + const editorProperties = self.getComponentConfig(propertyData, { type: "radio-group" }, { + placeholder: { + description: "空值时,输入控件内的占位文本", + title: "提示文本", + type: "string" + }, + direction: { + description: "", + title: "排列方向", + type: "enum", + editor: { + type: "combo-list", + textField: "value", + valueField: "key", + data: [{ "key": "horizontal", "value": "横向" }, { "key": "vertical", "value": "纵向" }] + } + }, + options: { + description: "", + title: "数据", + type: "array", + $converter: "/converter/enum-data.converter", + ...self.getItemCollectionEditor(propertyData, propertyData.editor.valueField, propertyData.editor.textField), + // 这个属性,标记当属性变更得时候触发重新更新属性 + refreshPanelAfterChanged: true, + } + }); + editorProperties['setPropertyRelates'] = function (changeObject) { + if (!changeObject) { + return; + } + switch (changeObject.propertyID) { + case 'data': { + + break; + } + } + }; + return editorProperties; + } + +} diff --git a/packages/mobile-ui-vue/components/radio-group/src/radio-group.props.ts b/packages/mobile-ui-vue/components/radio-group/src/radio-group.props.ts index 2e9da96c198..f246ce170f2 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/radio-group.props.ts +++ b/packages/mobile-ui-vue/components/radio-group/src/radio-group.props.ts @@ -1,6 +1,10 @@ import { ExtractPropTypes, PropType } from 'vue'; import {CheckerShape, CheckerShapeMap } from '@components/checker'; import { CheckboxGroupContext, checkboxGroupProps } from '@components/checkbox-group'; +import { createPropsResolver } from '@/components/dynamic-resolver'; +import inputSchema from './schema/radio-group.schema.json'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; export const RADIO_GROUP_NAME = 'fm-radio-group'; @@ -10,7 +14,7 @@ export const radioGroupProps = { shape: { type: String as PropType, default: CheckerShapeMap.Round }, modelValue: { type: [String, Number] , default: '' } -}; +} as Record; export type RadioGroupProps = ExtractPropTypes; @@ -19,3 +23,5 @@ type Merge = { }; export type RadioGroupContext = Merge void }>; + +export const propsResolver = createPropsResolver(radioGroupProps, inputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json b/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json new file mode 100644 index 00000000000..c24da46e4b0 --- /dev/null +++ b/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json @@ -0,0 +1,85 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/radio-group.schema.json", + "title": "radio-group", + "description": "A Farris Input Component", + "type": "object", + "properties": { + "id": { + "description": "The unique identifier for a Input Group", + "type": "string" + }, + "type": { + "description": "The type string of Input Group component", + "type": "string", + "default": "radio-group" + }, + "appearance": { + "description": "", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "binding": { + "description": "", + "type": "object", + "default": {} + }, + "disable": { + "type": "string", + "default": false + }, + "readonly": { + "type": "string", + "default": false + }, + "title": { + "description": "", + "type": "string", + "default": "" + }, + "label": { + "description": "", + "type": "string", + "default": "" + }, + "lableWidth": { + "description": "", + "type": "number" + }, + "visible": { + "description": "", + "type": "boolean", + "default": true + }, + "options": { + "description": "", + "type": "array", + "default": [] + }, + "direction": { + "description": "", + "type": "string", + "default": "horizontal" + } + }, + "required": [ + "type", + "options", + "direction" + ], + "ignore": [ + "id", + "type", + "appearance", + "binding", + "visible" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/radio-group/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/radio-group/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..abb57152ea8 --- /dev/null +++ b/packages/mobile-ui-vue/components/radio-group/src/schema/schema-mapper.ts @@ -0,0 +1,5 @@ +import { MapperFunction, resolveAppearance } from '@/components/dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance] +]); diff --git a/packages/mobile-ui-vue/components/radio-group/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/radio-group/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..660e1e609e1 --- /dev/null +++ b/packages/mobile-ui-vue/components/radio-group/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/textarea/index.ts b/packages/mobile-ui-vue/components/textarea/index.ts index 0926050f7e5..b41ca39b337 100644 --- a/packages/mobile-ui-vue/components/textarea/index.ts +++ b/packages/mobile-ui-vue/components/textarea/index.ts @@ -1,9 +1,23 @@ import { withInstall } from '@components/common'; import TextareaInstallless from './src/textarea.component'; +import TextareaDesign from './src/designer/textarea.design.component'; +import { propsResolver } from './src/textarea.props'; export * from './src/textarea.props'; +const TEXTAREA_REGISTERED_NAME = 'textarea'; + const Textarea = withInstall(TextareaInstallless); +Textarea.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { + componentMap[TEXTAREA_REGISTERED_NAME] = Textarea; + propsResolverMap[TEXTAREA_REGISTERED_NAME] = propsResolver; +}; +Textarea.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record) => { + componentMap[TEXTAREA_REGISTERED_NAME] = TextareaDesign; + propsResolverMap[TEXTAREA_REGISTERED_NAME] = propsResolver; +}; + + export { Textarea }; export default Textarea; diff --git a/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx b/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx new file mode 100644 index 00000000000..9302b3507b3 --- /dev/null +++ b/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx @@ -0,0 +1,51 @@ +/* eslint-disable no-use-before-define */ +/** + * 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, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';import { TEXTAREA_NAME, textareaProps, TextareaProps } from '../textarea.props'; +import { useTextareaDesignerRules } from './use-designer-rules'; +import Textarea from '../..'; + + +export default defineComponent({ + name: 'FmTextareaDesign', + props: textareaProps, + emits: [] as (string[] & ThisType) | undefined, + setup(props: TextareaProps, context: SetupContext) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useTextareaDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + const inputGroupProps = computed(() => ({ + ...props, + editable: false + })); + + context.expose(componentInstance.value); + + return () => { + return ( + + ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/textarea/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/textarea/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..76cd82b5e68 --- /dev/null +++ b/packages/mobile-ui-vue/components/textarea/src/designer/use-designer-rules.ts @@ -0,0 +1,20 @@ +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { TextareaProperty } from "../property-config/textarea.property-config"; +export function useTextareaDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { + + const schema = designItemContext.schema as ComponentSchema; + + /** + * 构造属性配置方法 + * @param componentId + * @param componentInstance + * @returns + */ + function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { + const inputGroupProps = new TextareaProperty(componentId, designerHostService); + return inputGroupProps.getPropertyConfig(schema, componentInstance); + } + + return { getPropsConfig } as UseDesignerRules; + +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts b/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts new file mode 100644 index 00000000000..7269a0228aa --- /dev/null +++ b/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts @@ -0,0 +1,34 @@ +import { InputBaseProperty } from "@/components/common/src/entity/input-base-property"; + +export class TextareaProperty extends InputBaseProperty { + + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + getEditorProperties(propertyData: any) { + return this.getComponentConfig(propertyData, { type: "textarea" }, { + placeholder: { + description: "空值时,输入控件内的占位文本", + title: "提示文本", + type: "string" + }, + rows: { + description: "", + title: "文本区域可见的行数", + type: "number", + editor: { + min: 0, + nullable:true + } + }, + showWordLimit: { + description: "", + title: "展示输入文本数量", + type: "boolean" + } + }); + } + + +} diff --git a/packages/mobile-ui-vue/components/textarea/src/schema/input.schema.json b/packages/mobile-ui-vue/components/textarea/src/schema/input.schema.json new file mode 100644 index 00000000000..1425b3ede9c --- /dev/null +++ b/packages/mobile-ui-vue/components/textarea/src/schema/input.schema.json @@ -0,0 +1,75 @@ +{ + "$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", + "type": "object", + "properties": { + "id": { + "description": "The unique identifier for a Input Group", + "type": "string" + }, + "type": { + "description": "The type string of Input Group component", + "type": "string", + "default": "textarea" + }, + "appearance": { + "description": "", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "binding": { + "description": "", + "type": "object", + "default": {} + }, + "disable": { + "type": "string", + "default": false + }, + "readonly": { + "type": "string", + "default": false + }, + "title": { + "description": "", + "type": "string", + "default": "" + }, + "label": { + "description": "", + "type": "string", + "default": "" + }, + "lableWidth": { + "description": "", + "type": "number" + }, + "placeholder": { + "description": "", + "type": "string", + "default": "" + }, + "visible": { + "description": "", + "type": "boolean", + "default": true + } + }, + "required": [ + "id", + "type", + "appearance", + "binding", + "visible" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/textarea/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/textarea/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..abb57152ea8 --- /dev/null +++ b/packages/mobile-ui-vue/components/textarea/src/schema/schema-mapper.ts @@ -0,0 +1,5 @@ +import { MapperFunction, resolveAppearance } from '@/components/dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance] +]); diff --git a/packages/mobile-ui-vue/components/textarea/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/textarea/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..660e1e609e1 --- /dev/null +++ b/packages/mobile-ui-vue/components/textarea/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/textarea/src/textarea.props.ts b/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts index 7f06a76323c..9472bad5408 100644 --- a/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts +++ b/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts @@ -1,5 +1,9 @@ import { ExtractPropTypes } from 'vue'; import { inputCommonProps } from '@/components/input-group'; +import { createPropsResolver } from '@/components/dynamic-resolver'; +import textareaSchema from './schema/input.schema.json'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; export const TEXTAREA_NAME = 'FmTextarea'; @@ -15,6 +19,8 @@ export const textareaProps = { minHeight: { type: Number, default: undefined }, showWordLimit: { type: Boolean, default: undefined } -}; +} as Record; export type TextareaProps = ExtractPropTypes; + +export const propsResolver = createPropsResolver(textareaProps, textareaSchema, schemaMapper, schemaResolver); -- Gitee From a089cfc990589576cdf2447ecdf504f4a47bd1e0 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Tue, 25 Feb 2025 16:39:14 +0800 Subject: [PATCH 004/287] =?UTF-8?q?chore:=20=E7=A7=BB=E5=8A=A8=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=BA=93=E4=BB=A3=E7=A0=81=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/designer/button.design.component.tsx | 3 +- .../property-config/button.property-config.ts | 2 +- .../date-picker.property-config.ts | 13 +----- .../src/designer/use-designer-rules.ts | 29 +++++++++----- .../response-form-use-designer-rules.ts | 40 +++++++++---------- .../property-config/navbar.property-config.ts | 2 +- 6 files changed, 41 insertions(+), 48 deletions(-) diff --git a/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx b/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx index 88fa36811c4..2e886c10725 100644 --- a/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx +++ b/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx @@ -1,3 +1,4 @@ +/* eslint-disable no-use-before-define */ /** * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. * @@ -36,7 +37,7 @@ export default defineComponent({ context.expose(componentInstance.value); - const schema = componentInstance.value.schema; + const{ schema } = componentInstance.value; const inputProps = computed(() => ({ ...props, diff --git a/packages/mobile-ui-vue/components/button/src/property-config/button.property-config.ts b/packages/mobile-ui-vue/components/button/src/property-config/button.property-config.ts index 797c3b7aae6..cf3fd87a769 100644 --- a/packages/mobile-ui-vue/components/button/src/property-config/button.property-config.ts +++ b/packages/mobile-ui-vue/components/button/src/property-config/button.property-config.ts @@ -9,7 +9,7 @@ export class ButtonProperty extends BaseControlProperty { this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); // 外观 this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); - //行为 + // 行为 this.propertyConfig.categories['behavior'] = this.getBehaviorConfig(propertyData); return this.propertyConfig; 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-input/src/property-config/date-picker.property-config.ts index c0551502470..4f7ea85b3a5 100644 --- 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-input/src/property-config/date-picker.property-config.ts @@ -32,18 +32,7 @@ export class DatePickerProperty extends InputBaseProperty { data: valueFormatOptions } } - }, this.setEditorPropertyRelates); - } - - private setEditorPropertyRelates(changeObject: any, propertyData: any) { - if (!changeObject || !propertyData.editor) { - return; - } - switch (changeObject.propertyID) { - case 'showTime': { - - } - } + }); } private getAllShowType() { diff --git a/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts index 6f2d9115c56..e036eeb86b9 100644 --- a/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts @@ -1,3 +1,19 @@ +/* eslint-disable no-use-before-define */ +/** + * 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 { ref } from "vue"; import { ComponentSchema, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; import { DraggingResolveContext } from "@/components/designer-canvas/src/composition/types"; @@ -5,10 +21,6 @@ import { FloatContainerProperty } from "../property-config/float-container.prope export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { - const triggerBelongedComponentToMoveWhenMoved = ref(false); - - const triggerBelongedComponentToDeleteWhenDeleted = ref(false); - const hideNestedPadding = true; const schema = ref(designItemContext.schema) @@ -62,7 +74,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe } if (schema.value.padding) { style += Object.keys(schema.value.padding).map(key => { - return `padding-${key}: ${schema.padding[key]}px;` + return `padding-${key}: ${schema.value.padding[key]}px;` }).join('') } if (schema.value.margin) { @@ -72,8 +84,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe } return style } - - + /** * 获取属性配置 */ @@ -83,12 +94,8 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe return componentProp.getPropertyConfig(schema); } - - return { canAccepts, - triggerBelongedComponentToMoveWhenMoved, - triggerBelongedComponentToDeleteWhenDeleted, checkCanMoveComponent, checkCanDeleteComponent, hideNestedPaddingInDesginerView, diff --git a/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts b/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts index bb3a52d2f72..66a89f6d3b0 100644 --- a/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts @@ -32,27 +32,6 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe return hideNestedPadding; } - - function onResolveNewComponentSchema(resolveContext: DraggingResolveContext, componentSchema: ComponentSchema): ComponentSchema { - const { label } = resolveContext; - let formGroupElementSchema; - // 控件若有绑定信息,则根据绑定信息创建控件 - if (resolveContext.bindingSourceContext?.entityFieldNode) { - const controlCreatorUtils = designerHostService?.controlCreatorUtils; - formGroupElementSchema = controlCreatorUtils.setFormFieldProperty(resolveContext.bindingSourceContext?.entityFieldNode, componentSchema.type); - } else { - formGroupElementSchema = getSchemaByType('form-item') as ComponentSchema; - formGroupElementSchema.editor = componentSchema; - formGroupElementSchema.label = label; - } - - syncFieldToViewModel(resolveContext, componentSchema.type); - - return formGroupElementSchema; - } - - - /** * 添加输入类控件后,将绑定信息同步到视图模型 */ @@ -73,6 +52,24 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe } + function onResolveNewComponentSchema(resolveContext: DraggingResolveContext, componentSchema: ComponentSchema): ComponentSchema { + const { label } = resolveContext; + let formGroupElementSchema; + // 控件若有绑定信息,则根据绑定信息创建控件 + if (resolveContext.bindingSourceContext?.entityFieldNode) { + const controlCreatorUtils = designerHostService?.controlCreatorUtils; + formGroupElementSchema = controlCreatorUtils.setFormFieldProperty(resolveContext.bindingSourceContext?.entityFieldNode, componentSchema.type); + } else { + formGroupElementSchema = getSchemaByType('form-item') as ComponentSchema; + formGroupElementSchema.editor = componentSchema; + formGroupElementSchema.label = label; + } + + syncFieldToViewModel(resolveContext, componentSchema.type); + + return formGroupElementSchema; + } + function getStyles(): string { return ' '; } @@ -87,7 +84,6 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe return inputGroupProps.getPropertyConfig(schema, componentInstance); } - return { canAccepts, triggerBelongedComponentToMoveWhenMoved, diff --git a/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts b/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts index ca841d84dc6..e6a0c287c42 100644 --- a/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts +++ b/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts @@ -9,7 +9,7 @@ export class NavBarProperty extends BaseControlProperty { this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); // 外观 this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); - //行为 + // 行为 this.propertyConfig.categories['behavior'] = this.getBehaviorConfig(propertyData); return this.propertyConfig; -- Gitee From 6bf79732562d284a492b7f27f076cca493f94b96 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Wed, 26 Feb 2025 19:02:07 +0800 Subject: [PATCH 005/287] =?UTF-8?q?chore:=20=E7=A7=BB=E5=8A=A8=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E6=8E=A7=E4=BB=B6=E8=AE=BE=E8=AE=A1=E6=97=B6=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../property-config/button.property-config.ts | 16 +- .../button/src/schema/button.schema.json | 16 +- .../components/checkbox-group/index.ts | 15 ++ .../src/checkbox-group.props.ts | 9 +- .../checkbox-group.design.component.tsx | 74 +++++++++ .../src/designer/use-designer-rules.ts | 15 ++ .../checkbox-group.property-config.ts | 48 ++++++ .../src/schema/checkbox-group.schema.json | 78 +++++++++ .../src/schema/schema-mapper.ts | 7 + .../src/schema/schema-resolver.ts | 5 + .../designer/date-picker.design.component.tsx | 4 +- .../src/property-config/date-format.ts | 79 +++++++++ .../date-picker.property-config.ts | 49 ++---- .../src/schema/schema-mapper.ts | 3 +- .../date-picker-input/src/schema/schema.json | 24 +-- .../designer-canvas/src/components/maps.ts | 9 +- .../src/composition/dg-control.ts | 2 + .../designer-toolbox/src/toolbox.json | 153 ++++++++++++------ .../components/dynamic-resolver/index.ts | 2 + .../src/common/data-resolver.ts | 52 ++++++ .../designer/form-item.design.component.tsx | 11 +- .../src/schema/form-item.schema.json | 8 +- .../designer/input-group.design.component.tsx | 12 +- .../src/schema/input-group.schema.json | 7 +- .../components/picker-input/index.ts | 14 ++ .../enum-field-input.design.component.tsx | 74 +++++++++ .../src/designer/use-designer-rules.ts | 15 ++ .../picker-input/src/picker-input.props.ts | 8 +- .../enum-field-input.property-config.ts | 47 ++++++ .../src/schema/enum-field-input.schema.json | 83 ++++++++++ .../picker-input/src/schema/schema-mapper.ts | 7 + .../src/schema/schema-resolver.ts | 5 + .../designer/radio-group.design.component.tsx | 39 +++-- .../radio-group.property-config.ts | 7 +- .../src/schema/radio-group.schema.json | 11 +- .../radio-group/src/schema/schema-mapper.ts | 5 +- .../mobile-ui-vue/components/switch/index.ts | 23 +++ .../src/designer/switch.design.component.tsx | 51 ++++++ .../switch/src/designer/use-designer-rules.ts | 15 ++ .../property-config/switch.property-config.ts | 55 +++++++ .../switch/src/schema/schema-mapper.ts | 9 ++ .../switch/src/schema/schema-resolver.ts | 5 + .../switch/src/schema/switch.schema.json | 95 +++++++++++ .../components/switch/src/switch.props.ts | 11 ++ .../designer/textarea.design.component.tsx | 3 +- .../textarea.property-config.ts | 7 +- .../textarea/src/schema/input.schema.json | 28 ++-- .../textarea/src/schema/schema-mapper.ts | 4 +- 48 files changed, 1151 insertions(+), 168 deletions(-) create mode 100644 packages/mobile-ui-vue/components/checkbox-group/src/designer/checkbox-group.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/checkbox-group/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts create mode 100644 packages/mobile-ui-vue/components/checkbox-group/src/schema/checkbox-group.schema.json create mode 100644 packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/date-picker-input/src/property-config/date-format.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/common/data-resolver.ts create mode 100644 packages/mobile-ui-vue/components/picker-input/src/designer/enum-field-input.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/picker-input/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/picker-input/src/property-config/enum-field-input.property-config.ts create mode 100644 packages/mobile-ui-vue/components/picker-input/src/schema/enum-field-input.schema.json create mode 100644 packages/mobile-ui-vue/components/picker-input/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/picker-input/src/schema/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/switch/src/designer/switch.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/switch/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/switch/src/property-config/switch.property-config.ts create mode 100644 packages/mobile-ui-vue/components/switch/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/switch/src/schema/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/switch/src/schema/switch.schema.json diff --git a/packages/mobile-ui-vue/components/button/src/property-config/button.property-config.ts b/packages/mobile-ui-vue/components/button/src/property-config/button.property-config.ts index cf3fd87a769..81df157ea73 100644 --- a/packages/mobile-ui-vue/components/button/src/property-config/button.property-config.ts +++ b/packages/mobile-ui-vue/components/button/src/property-config/button.property-config.ts @@ -23,6 +23,7 @@ export class ButtonProperty extends BaseControlProperty { visible: { title: "可见", type: "boolean", + visible:false }, disabled: { title: "只读", @@ -30,7 +31,20 @@ export class ButtonProperty extends BaseControlProperty { }, displayType: { title: "按钮类型", - type: "string", + type: 'select', + editor: { + type: 'combo-list', + textField: 'name', + valueField: 'value', + editable: false, + data: [{ value:'primary' , name: '主要按钮' }, + { value:'secondary' , name: '次要按钮' }, + { value:'success' , name: '成功按钮' }, + { value:'warning' , name: '警告按钮' }, + { value:'danger' , name: '危险按钮' }, + { value:'info' , name: '提示按钮' }, + ] + } }, block: { title: "是否占满整行", 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 index c97693e7758..686c10702c5 100644 --- a/packages/mobile-ui-vue/components/button/src/schema/button.schema.json +++ b/packages/mobile-ui-vue/components/button/src/schema/button.schema.json @@ -27,7 +27,7 @@ "round": { "description": "是否为圆形", "type": "boolean", - "default": false, + "default": true, "isEvent": true }, "text": { @@ -40,6 +40,16 @@ "type": "boolean", "default": true }, + "visible": { + "description": "", + "type": "boolean", + "default": true + }, + "disabled": { + "description": "", + "type": "boolean", + "default": false + }, "appearance": { "description": "外观", "type": "object", @@ -65,8 +75,8 @@ "type", "visible", "round", - "disabled", "text", - "icon" + "icon", + "displayType" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/checkbox-group/index.ts b/packages/mobile-ui-vue/components/checkbox-group/index.ts index c4b3c3a134d..98107fb53f8 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/index.ts +++ b/packages/mobile-ui-vue/components/checkbox-group/index.ts @@ -1,9 +1,24 @@ import { withInstall } from '@components/common'; import CheckboxGroupInstallless from './src/checkbox-group.component'; +import { propsResolver } from './src/checkbox-group.props'; +import CheckBoxGroupDesign from './src/designer/checkbox-group.design.component'; export * from './src/composition'; export * from './src/checkbox-group.props'; + + +const CHECH_GROUP_REGISTERED_NAME = 'check-group'; + const CheckboxGroup = withInstall(CheckboxGroupInstallless); +CheckboxGroup.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { + componentMap[CHECH_GROUP_REGISTERED_NAME] = CheckboxGroup; + propsResolverMap[CHECH_GROUP_REGISTERED_NAME] = propsResolver; +}; +CheckboxGroup.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record) => { + componentMap[CHECH_GROUP_REGISTERED_NAME] = CheckBoxGroupDesign; + propsResolverMap[CHECH_GROUP_REGISTERED_NAME] = propsResolver; +}; + export { CheckboxGroup }; export default CheckboxGroup; diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.props.ts b/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.props.ts index 0e6996410e4..2a9cf19699d 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.props.ts +++ b/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.props.ts @@ -1,5 +1,9 @@ import { ExtractPropTypes, PropType } from 'vue'; import { CheckerShape, CheckerShapeMap, CheckerType, CheckerTypeMap } from '@components/checker'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; +import inputSchema from './schema/checkbox-group.schema.json'; +import { createPropsResolver } from '@/components/dynamic-resolver'; export type CheckboxItem = { disabled: boolean; @@ -36,7 +40,7 @@ export const checkboxGroupProps = { textField: { type: String, default: 'text' }, showDisabledItem: { type: Boolean, default: true }, -}; +} as Record; export type CheckboxGroupProps = ExtractPropTypes; @@ -45,3 +49,6 @@ export type CheckboxGroupContext = { getChecked: (name: any) => boolean; updateChecked: (value: string | number, checked: boolean) => void; }; + +export const propsResolver = createPropsResolver(checkboxGroupProps, inputSchema, schemaMapper, schemaResolver); + diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/designer/checkbox-group.design.component.tsx b/packages/mobile-ui-vue/components/checkbox-group/src/designer/checkbox-group.design.component.tsx new file mode 100644 index 00000000000..23b094b47ee --- /dev/null +++ b/packages/mobile-ui-vue/components/checkbox-group/src/designer/checkbox-group.design.component.tsx @@ -0,0 +1,74 @@ +/* eslint-disable no-use-before-define */ +/** + * 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, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; +import { CheckboxGroup, checkboxGroupProps, CheckboxGroupProps } from '../..'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas'; +import { useCheckBoxGroupProperty } from './use-designer-rules';; + +export default defineComponent({ + name: 'FmEnumFieldInputDesign', + props: checkboxGroupProps, + emits: [] as (string[] & ThisType) | undefined, + setup(props: CheckboxGroupProps, context: SetupContext) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useCheckBoxGroupProperty(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + /** + * 解决在设计时,数据为空数组,界面不显示内容的问题 + */ + const realEnumData = computed(() => { + if (!props.options || props.options.length === 0) { + const result = [] as any; + [ + { value: 'example1', name: '示例一' }, + { value: 'example2', name: '示例二' } + ].map(item => { + const tempData = {}; + tempData[props.valueField] = item['value']; + tempData[props.textField] = item['name']; + result.push(tempData); + }); + return result; + } + return props.options; + }); + + const inputGroupProps = computed(() => ({ + ...props, + editable: false, + readonly: true, + modelValue:null, + options:realEnumData.value, + type:null + })); + + context.expose(componentInstance.value); + + return () => { + return ( + + ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/checkbox-group/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..4ced3151e4b --- /dev/null +++ b/packages/mobile-ui-vue/components/checkbox-group/src/designer/use-designer-rules.ts @@ -0,0 +1,15 @@ +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { CheckBoxGroupProperty } from "../property-config/checkbox-group.property-config"; +export function useCheckBoxGroupProperty(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { + + const schema = designItemContext.schema as ComponentSchema; + + // 构造属性配置方法 + function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { + const radioGroupProps = new CheckBoxGroupProperty(componentId, designerHostService); + return radioGroupProps.getPropertyConfig(schema, componentInstance); + } + + return { getPropsConfig } as UseDesignerRules; + +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts b/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts new file mode 100644 index 00000000000..12eba097050 --- /dev/null +++ b/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts @@ -0,0 +1,48 @@ +import { InputBaseProperty } from "@/components/common/src/entity/input-base-property"; + +export class CheckBoxGroupProperty extends InputBaseProperty { + + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + + getEditorProperties(propertyData: any) { + const self = this; + const editorProperties = self.getComponentConfig(propertyData, { type: "radio-group" }, { + direction: { + description: "", + title: "排列方向", + type: "enum", + editor: { + type: "combo-list", + textField: "value", + valueField: "key", + data: [{ "key": "horizontal", "value": "横向" }, { "key": "vertical", "value": "纵向" }] + } + }, + data: { + description: "", + title: "数据", + type: "array", + $converter: "/converter/enum-data.converter", + ...self.getItemCollectionEditor(propertyData, propertyData.editor.valueField, propertyData.editor.textField), + // 这个属性,标记当属性变更得时候触发重新更新属性 + refreshPanelAfterChanged: true, + } + }); + editorProperties['setPropertyRelates'] = function (changeObject) { + if (!changeObject) { + return; + } + switch (changeObject.propertyID) { + case 'data': { + + break; + } + } + }; + return editorProperties; + } + +} diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/schema/checkbox-group.schema.json b/packages/mobile-ui-vue/components/checkbox-group/src/schema/checkbox-group.schema.json new file mode 100644 index 00000000000..7cbd3c17fe8 --- /dev/null +++ b/packages/mobile-ui-vue/components/checkbox-group/src/schema/checkbox-group.schema.json @@ -0,0 +1,78 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/check-group.schema.json", + "title": "check-group", + "description": "A Farris Input Component", + "type": "object", + "properties": { + "id": { + "description": "The unique identifier for a Input Group", + "type": "string" + }, + "type": { + "description": "The type string of Input Group component", + "type": "string", + "default": "check-group" + }, + "appearance": { + "description": "", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "binding": { + "description": "", + "type": "object", + "default": {} + }, + "readonly": { + "type": "string", + "default": false + }, + "title": { + "description": "", + "type": "string", + "default": "" + }, + "label": { + "description": "", + "type": "string", + "default": "" + }, + "lableWidth": { + "description": "", + "type": "number" + }, + "visible": { + "description": "", + "type": "boolean", + "default": true + }, + "data": { + "description": "", + "type": "array", + "default": [] + }, + "direction": { + "description": "", + "type": "string", + "default": "horizontal" + } + }, + "required": [ + "type" + ], + "ignore": [ + "id", + "appearance", + "binding", + "visible" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..d8ccde7885d --- /dev/null +++ b/packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-mapper.ts @@ -0,0 +1,7 @@ +import { MapperFunction, resolveAppearance, resolveData } from '@/components/dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance], + ['data', resolveData], +]); + diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..660e1e609e1 --- /dev/null +++ b/packages/mobile-ui-vue/components/checkbox-group/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/date-picker-input/src/designer/date-picker.design.component.tsx b/packages/mobile-ui-vue/components/date-picker-input/src/designer/date-picker.design.component.tsx index a0aa71bb439..6ebdca0fc0f 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-input/src/designer/date-picker.design.component.tsx @@ -41,8 +41,8 @@ export default defineComponent({ const inputProps = computed(() => ({ ...props, editable: false, - readonly: true - + readonly: true, + modelValue:null })); return () => { 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-input/src/property-config/date-format.ts new file mode 100644 index 00000000000..7a962b1db6a --- /dev/null +++ b/packages/mobile-ui-vue/components/date-picker-input/src/property-config/date-format.ts @@ -0,0 +1,79 @@ +export function DATE_FORMATS() { + + let languageCode = 'zh-CHS'; + if (window && window.top && window.top.localStorage && window.top.localStorage.languageCode) { + ({ languageCode } = window.top.localStorage); + } + + const timeFormats = [ + { id: 'yyyy-MM-dd HH:mm:ss', name: 'yyyy-MM-dd HH:mm:ss' }, + { id: 'yyyy/MM/dd HH:mm:ss', name: 'yyyy/MM/dd HH:mm:ss' }, + { id: 'yyyyMMddHHmmss', name: 'yyyyMMddHHmmss' }, + { id: 'yyyy-MM-dd HH:mm', name: 'yyyy-MM-dd HH:mm' }, + { id: 'yyyy/MM/dd HH:mm', name: 'yyyy/MM/dd HH:mm' }, + { id: 'yyyyMMddHHmm', name: 'yyyyMMddHHmm' } + ]; + const yMdFormats = [ + { id: 'yyyy-MM-dd', name: 'yyyy-MM-dd' }, + { id: 'yyyy/MM/dd', name: 'yyyy/MM/dd' }, + { id: 'yyyyMMdd', name: 'yyyyMMdd' }, + { id: 'MM/dd/yyyy', name: 'MM/dd/yyyy' } + ]; + const yMFormats = [ + { id: 'yyyy-MM', name: 'yyyy-MM' }, + { id: 'yyyy/MM', name: 'yyyy/MM' }, + { id: 'yyyyMM', name: 'yyyyMM' } + ]; + + const mdFormats = [ + { id: 'MM/dd', name: 'MM/dd' }, + { id: 'MMdd', name: 'MMdd' }, + { id: 'MM-dd', name: 'MM-dd' } + ]; + + const yFormats = [ + { id: 'yyyy', name: 'yyyy' } + ]; + + // 区分语言 + if (languageCode === 'zh-CHS') { + timeFormats.push( + { id: 'yyyy年MM月dd日 HH时mm分ss秒', name: 'yyyy年MM月dd日 HH时mm分ss秒' }, + { id: 'yyyy年MM月dd日 HH时mm分', name: 'yyyy年MM月dd日 HH时mm分' } + ); + yMdFormats.push( + { id: 'yyyy年MM月dd日', name: 'yyyy年MM月dd日' } + ); + yMFormats.push( + { id: 'yyyy年MM月', name: 'yyyy年MM月' } + ); + mdFormats.push( + { id: 'MM月dd日', name: 'MM月dd日' } + ); + yFormats.push( + { id: 'yyyy年', name: 'yyyy年' } + ); + } + if (languageCode === 'zh-CHT') { + timeFormats.push( + { id: 'yyyy年MM月dd日 HH時mm分ss秒', name: 'yyyy年MM月dd日 HH時mm分ss秒' }, + { id: 'yyyy年MM月dd日 HH時mm分', name: 'yyyy年MM月dd日 HH時mm分' } + ); + yMdFormats.push( + { id: 'yyyy年MM月dd日', name: 'yyyy年MM月dd日' } + ); + yMFormats.push( + { id: 'yyyy年MM月', name: 'yyyy年MM月' } + ); + mdFormats.push( + { id: 'MM月dd日', name: 'MM月dd日' } + ); + yFormats.push( + { id: 'yyyy年', name: 'yyyy年' } + ); + } + + + return { timeFormats, yMFormats, yMdFormats, mdFormats, yFormats }; + +} 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-input/src/property-config/date-picker.property-config.ts index 4f7ea85b3a5..0dad89b0fb1 100644 --- 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-input/src/property-config/date-picker.property-config.ts @@ -1,4 +1,5 @@ import { InputBaseProperty } from "@/components/common/src/entity/input-base-property"; +import { DATE_FORMATS } from "./date-format"; export class DatePickerProperty extends InputBaseProperty { @@ -8,56 +9,36 @@ export class DatePickerProperty extends InputBaseProperty { getEditorProperties(propertyData: any) { - const displayFormatOptions = this.getAllShowType(); - const valueFormatOptions = this.getAllFormat(); + const displayFormatOptions = this.getDateFormatOptions(propertyData?.editor); return this.getComponentConfig(propertyData, { type: "year-month-day" }, { placeholder: { description: "空值时,输入控件内的占位文本", title: "提示文本", type: "string" }, - showType: { - description: "", - title: "选择类型", - type: "enum", - editor: { - data: displayFormatOptions - } - }, - format: { + displayFormat: { description: "", title: "显示格式", type: "enum", editor: { - data: valueFormatOptions + data: displayFormatOptions } } }); } - private getAllShowType() { - return [ - { id: "year", name: "年月日" }, - { id: "datetime", name: "年月日时分" }, - { id: "datehour", name: "年月日时" }, - { id: "year-month", name: "年月" }, - { id: "month-day", name: "月日" } - ]; - } + private getDateFormatOptions(editorData: any) { + let formats: any[] = []; + const { timeFormats, yMdFormats, yMFormats, mdFormats, yFormats } = DATE_FORMATS(); - /** - * 存储格式枚举项 - */ - getAllFormat(): any[] { - return [ - { id: 'YYYY-MM-dd HH:mm', name: 'YYYY-MM-dd HH:mm' }, - { id: 'MM/dd/YYYY HH:mm', name: 'MM/dd/YYYY HH:mm' }, - { id: 'YYYY年MM月dd日 HH:mm', name: 'YYYY年MM月dd日 HH:mm' }, - { id: 'YYYY-MM-dd HH:mm:ss', name: 'YYYY-MM-dd HH:mm:ss' }, - { id: 'MM/dd/YYYY HH:mm:ss', name: 'MM/dd/YYYY HH:mm:ss' }, - { id: 'YYYY年MM月dd日 HH:mm:ss', name: 'YYYY年MM月dd日 HH:mm:ss' }, - ]; - } + formats = formats.concat(timeFormats); + formats = formats.concat(yMdFormats); + formats = formats.concat(yMFormats); + formats = formats.concat(yFormats); + formats = formats.concat(mdFormats); + + return formats; + } } diff --git a/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-mapper.ts index abb57152ea8..ea8ec8b6d82 100644 --- a/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/date-picker-input/src/schema/schema-mapper.ts @@ -1,5 +1,6 @@ import { MapperFunction, resolveAppearance } from '@/components/dynamic-resolver'; export const schemaMapper = new Map([ - ['appearance', resolveAppearance] + ['appearance', resolveAppearance], + ['displayFormat','format'] ]); 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/schema.json index a98542bf4ee..1674a23b089 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/schema.json @@ -32,10 +32,6 @@ "type": "object", "default": {} }, - "disable": { - "type": "string", - "default": false - }, "title": { "description": "", "type": "string", @@ -59,14 +55,24 @@ "description": "", "type": "boolean", "default": true + }, + "displayFormat": { + "description": "", + "type": "string", + "default": "YYYY-MM-DD" + }, + "readonly": { + "type": "string", + "default": false } }, "required": [ + "type" + ], + "ignore": [ "id", - "type", - "visible", - "label", - "placeholder", - "appearance" + "appearance", + "binding", + "visible" ] } \ No newline at end of file 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 474da277cb0..8c1e55a382d 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,10 +1,10 @@ -import { ContentContainer, DatePickerInput, FormItem, PageHeaderContainer, RadioGroup } from "@/components"; +import { CheckboxGroup, ContentContainer, DatePickerInput, FormItem, PageHeaderContainer, PickerInput, RadioGroup, Switch } from "@/components"; import Button from "@/components/button"; import Component from "@/components/component"; import FloatContainer from "@/components/float-container"; import Form from "@/components/form"; import InputGroup from "@/components/input-group"; -import { ListView } from "@/components/list-view"; +import ListView from "@/components/list-view"; import Navbar from "@/components/navbar"; import PageBodyContainer from "@/components/page-body-container"; import PageContainer from "@/components/page-container"; @@ -39,7 +39,10 @@ function loadDesignerRegister() { DatePickerInput.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); Textarea.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); RadioGroup.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); - + Switch.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + PickerInput.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + CheckboxGroup.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + } } diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts index e3d215a7141..bc35a129a09 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts @@ -43,4 +43,6 @@ export const DgControl = { 'navigation-bar': { type: 'navigation-bar', name: '导航栏', icon: 'NavBar' }, + 'enum-field': { type: 'enum-field', name: '选择器', icon: 'EnumField' }, + }; diff --git a/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.json b/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.json index 3f3386d8a1d..e160cd632e8 100644 --- a/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.json +++ b/packages/mobile-ui-vue/components/designer-toolbox/src/toolbox.json @@ -1,4 +1,24 @@ [ + { + "type": "basic", + "name": "基础类控件", + "items": [ + { + "id": "Button", + "type": "button", + "name": "按钮", + "category": "basic", + "icon": "button" + }, + { + "id": "ButtonGroup", + "type": "button-group", + "name": "按钮组", + "category": "basic", + "icon": "button-group" + } + ] + }, { "type": "input", "name": "输入类控件", @@ -6,80 +26,71 @@ { "id": "TextBox", "type": "input-group", - "name": "文本", - "category": "input" + "name": "文本框", + "category": "input", + "icon": "input-group" }, { "id": "MultiTextBox", "type": "textarea", "name": "多行文本", - "category": "input" + "category": "input", + "icon": "textarea" }, { "id": "DateBox", "type": "date-picker", - "name": "日期", - "category": "input" + "name": "日期选择", + "category": "input", + "icon": "date-picker" }, { "id": "EnumField", - "type": "combo-list", - "name": "下拉列表", - "category": "input" + "type": "enum-field", + "name": "选择器", + "category": "input", + "icon": "input-group" }, { "id": "NumericBox", "type": "number-spinner", "name": "数值", - "category": "input" + "category": "input", + "icon": "number-spinner" }, { - "id": "CheckBox", - "type": "check-box", - "name": "复选框", - "category": "input" + "id": "RadioGroup", + "type": "radio-group", + "name": "单选组", + "category": "input", + "icon": "radio-group" }, { "id": "CheckBoxGroup", "type": "check-group", "name": "复选框组", - "category": "input" - }, - { - "id": "RadioGroup", - "type": "radio-group", - "name": "单选组", - "category": "input" + "category": "input", + "icon": "check-group" }, { "id": "SwitchField", "type": "switch", "name": "开关", - "category": "input" - }, - { - "id": "LookupEdit", - "type": "lookup", - "name": "帮助", - "category": "input" + "category": "input", + "icon": "switch" } ] }, { - "type": "dataCollection", - "name": "数据集合类控件", + "type": "navigation", + "name": "导航类控件", "items": [ { - "id": "ResponseForm", - "type": "form", - "name": "卡片面板", - "category": "dataCollection" - }, - { - "id": "DataGrid", - "type": "data-grid", - "name": "表格", - "category": "dataCollection" + "id": "NavigationBar", + "type": "navigation-bar", + "name": "导航栏", + "category": "navigation", + "icon": "nav-tab" } ] }, @@ -88,22 +99,66 @@ "name": "容器类控件", "items": [ { - "id": "Tab", - "type": "tabs", - "name": "标签页区域", - "category": "container" + "id": "PageHeaderContainer", + "type": "page-header-container", + "name": "页头容器", + "category": "container", + "icon": "content-container" + }, + { + "id": "PageBodyContainer", + "type": "page-body-container", + "name": "页面主体容器", + "category": "container", + "icon": "content-container" + }, + { + "id": "PageFooterContainer", + "type": "page-footer-container", + "name": "页尾容器", + "category": "container", + "icon": "content-container" + }, + { + "id": "ContentContainer", + "type": "content-container", + "name": "通用容器", + "category": "container", + "icon": "content-container" + }, + { + "id": "FloatContainer", + "type": "float-container", + "name": "浮动容器", + "category": "container", + "icon": "content-container" + }, + { + "id": "Form", + "type": "form", + "name": "字段卡片", + "category": "container", + "icon": "response-form" + }, + { + "id": "Card", + "type": "card", + "name": "卡片", + "category": "container", + "icon": "section" } ] }, { - "type": "business", - "name": "业务类控件", + "type": "display", + "name": "展示类控件", "items": [ { - "id": "QuerySolution", - "type": "query-solution", - "name": "筛选方案", - "category": "container" + "id": "ListView", + "type": "list-view", + "name": "列表", + "category": "display", + "icon": "list-view" } ] } diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/index.ts b/packages/mobile-ui-vue/components/dynamic-resolver/index.ts index 5ee690b0cd7..78edba9a400 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/index.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/index.ts @@ -2,6 +2,7 @@ export * from './src/types'; export * from './src/props-resolver'; export * from './src/common/appearance-resolver'; export * from './src/common/toolbar-resolver'; +export * from './src/common/data-resolver'; export * from './src/binding-resolver'; export * from './src/events-resolver'; export * from './src/selection-item-resolver'; @@ -10,4 +11,5 @@ export * from './src/visible-prop-resolver'; export * from './src/event-handler-resolver'; export * from './src/schema-resolver'; export * from './src/update-columns-resolver'; + export { propertyConfigSchemaMap,getPropertyConfigBySchema } from './src/property-config-resolver'; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/data-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/data-resolver.ts new file mode 100644 index 00000000000..1f3c9c55856 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/data-resolver.ts @@ -0,0 +1,52 @@ + +export function resolveData(key: string, datas: { name: string; value: string }[]) { + const result:{ text: string; value: string }[] = []; + + if(datas && datas.length > 0){ + datas.forEach((data) => { + const newData: { text: string; value: string } = { + text: '', + value: '' + }; + Object.keys(data).map(key => { + if (key === 'name') { + newData['text'] = data[key]; + }else{ + newData[key] = data[key]; + } + }); + + result.push(newData); + }) + } + + return { + options:result + }; +} + +export function resolveDataPicker(key: string, datas: { name: string; value: string }[]) { + const result:{ text: string; value: string }[] = []; + + if(datas && datas.length > 0){ + datas.forEach((data) => { + const newData: { text: string; value: string } = { + text: '', + value: '' + }; + Object.keys(data).map(key => { + if (key === 'name') { + newData['text'] = data[key]; + }else{ + newData[key] = data[key]; + } + }); + + result.push(newData); + }) + } + + return { + columns:result + }; +} diff --git a/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx b/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx index 251d704b9ea..09d05afe132 100644 --- a/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx +++ b/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx @@ -29,7 +29,6 @@ export default defineComponent({ setup(props: FormItemProps, context: SetupContext) { const { slots, expose } = context; - const label = ref(props.label); const labelAlign = ref(props.labelAlign); const shouldShowRequired = ref(props.required); const { bem } = useBem(FORM_ITEM_NAME); @@ -49,7 +48,7 @@ export default defineComponent({ if (slots.label) { return [slots.label()]; } - return ; + return ; }; const contentClass = computed(() => { @@ -104,14 +103,6 @@ export default defineComponent({ }; }); - watch([ - () => props.label, - ], - ([newLabel])=>{ - label.value = newLabel; - } - - ) context.expose(componentInstance.value); 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 cf3da7f92db..e49a2109836 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 @@ -36,11 +36,17 @@ "description": "", "type": "obejct", "default": null + }, + "binding": { + "description": "", + "type": "object", + "default": {} } }, "required": [ "id", - "type" + "type", + "editor" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx b/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx index 10ef1a9b3f7..23cfa3fd840 100644 --- a/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx +++ b/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx @@ -34,16 +34,18 @@ export default defineComponent({ elementRef.value.componentInstance = componentInstance; }); - const inputGroupProps = computed(() => ({ - ...props, - editable: false - })); + const inputGroupProps = { + editable: false, + }; context.expose(componentInstance.value); return () => { return ( - + ); }; } 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 03a53f1db63..260621d8ecf 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 @@ -74,9 +74,12 @@ "onUpdate:modelValue" ], "required": [ + "type" + ], + "ignore": [ "id", - "type", "appearance", - "binding" + "binding", + "visible" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/picker-input/index.ts b/packages/mobile-ui-vue/components/picker-input/index.ts index 1bc59b23dd9..02d38dfc325 100644 --- a/packages/mobile-ui-vue/components/picker-input/index.ts +++ b/packages/mobile-ui-vue/components/picker-input/index.ts @@ -1,10 +1,24 @@ 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/designer/enum-field-input.design.component.tsx b/packages/mobile-ui-vue/components/picker-input/src/designer/enum-field-input.design.component.tsx new file mode 100644 index 00000000000..d2cbcd7b2c0 --- /dev/null +++ b/packages/mobile-ui-vue/components/picker-input/src/designer/enum-field-input.design.component.tsx @@ -0,0 +1,74 @@ +/* eslint-disable no-use-before-define */ +/** + * 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, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; +import { PickerInput, pickerInputProps, PickerInputProps } from '../..'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas'; +import { useEnumFieldDesignerRules } from './use-designer-rules';; + +export default defineComponent({ + name: 'FmEnumFieldInputDesign', + props: pickerInputProps, + emits: [] as (string[] & ThisType) | undefined, + setup(props: PickerInputProps, context: SetupContext) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useEnumFieldDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + /** + * 解决在设计时,数据为空数组,界面不显示内容的问题 + */ + const realEnumData = computed(() => { + if (!props.columns || props.columns.length === 0) { + const result = [] as any; + [ + { value: 'example1', name: '示例一' }, + { value: 'example2', name: '示例二' } + ].map(item => { + const tempData = {}; + tempData[props.valueField] = item['value']; + tempData[props.textField] = item['name']; + result.push(tempData); + }); + return result; + } + return props.columns; + }); + + const inputGroupProps = computed(() => ({ + ...props, + editable: false, + readonly: true, + modelValue:null, + columns:realEnumData.value, + type:null + })); + + context.expose(componentInstance.value); + + 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-input/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..2257102f287 --- /dev/null +++ b/packages/mobile-ui-vue/components/picker-input/src/designer/use-designer-rules.ts @@ -0,0 +1,15 @@ +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { EnumFieldInputProperty } from "../property-config/enum-field-input.property-config"; +export function useEnumFieldDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { + + const schema = designItemContext.schema as ComponentSchema; + + // 构造属性配置方法 + function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { + const radioGroupProps = new EnumFieldInputProperty(componentId, designerHostService); + return radioGroupProps.getPropertyConfig(schema, componentInstance); + } + + return { getPropsConfig } as UseDesignerRules; + +} \ 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 b0344b4a669..20230bd4f50 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 @@ -1,12 +1,18 @@ 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 -}; +} as Record; export type PickerInputProps = ExtractPropTypes; + +export const propsResolver = createPropsResolver(pickerInputProps, inputSchema, schemaMapper, schemaResolver); 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-input/src/property-config/enum-field-input.property-config.ts new file mode 100644 index 00000000000..4c762434707 --- /dev/null +++ b/packages/mobile-ui-vue/components/picker-input/src/property-config/enum-field-input.property-config.ts @@ -0,0 +1,47 @@ +import { InputBaseProperty } from "@/components/common/src/entity/input-base-property"; + +export class EnumFieldInputProperty extends InputBaseProperty { + + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + + getEditorProperties(propertyData: any) { + const self = this; + const editorProperties = self.getComponentConfig(propertyData, { type: "radio-group" }, { + editable: { + description: "", + title: "允许编辑", + type: "boolean" + }, + enableClear: { + description: "", + title: "启用清空", + type: "boolean" + }, + data: { + description: "", + title: "数据", + type: "array", + $converter: "/converter/enum-data.converter", + ...self.getItemCollectionEditor(propertyData, propertyData.editor.valueField, propertyData.editor.textField), + // 这个属性,标记当属性变更得时候触发重新更新属性 + refreshPanelAfterChanged: true, + } + }); + editorProperties['setPropertyRelates'] = function (changeObject) { + if (!changeObject) { + return; + } + switch (changeObject.propertyID) { + case 'data': { + + break; + } + } + }; + return editorProperties; + } + +} 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/enum-field-input.schema.json new file mode 100644 index 00000000000..7cf654531f3 --- /dev/null +++ b/packages/mobile-ui-vue/components/picker-input/src/schema/enum-field-input.schema.json @@ -0,0 +1,83 @@ +{ + "$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", + "type": "object", + "properties": { + "id": { + "description": "The unique identifier for a Input Group", + "type": "string" + }, + "type": { + "description": "The type string of Input Group component", + "type": "string", + "default": "enum-field" + }, + "appearance": { + "description": "", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "binding": { + "description": "", + "type": "object", + "default": {} + }, + "readonly": { + "type": "string", + "default": false + }, + "title": { + "description": "", + "type": "string", + "default": "" + }, + "label": { + "description": "", + "type": "string", + "default": "" + }, + "lableWidth": { + "description": "", + "type": "number" + }, + "visible": { + "description": "", + "type": "boolean", + "default": true + }, + "data": { + "description": "", + "type": "array", + "default": [] + }, + "enableClear": { + "description": "", + "type": "boolean", + "default": false + }, + "editable": { + "description": "", + "type": "boolean", + "default": false + } + }, + "required": [ + "type" + ], + "ignore": [ + "id", + "appearance", + "binding", + "visible" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/picker-input/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/picker-input/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..36cb118f9ce --- /dev/null +++ b/packages/mobile-ui-vue/components/picker-input/src/schema/schema-mapper.ts @@ -0,0 +1,7 @@ +import { MapperFunction, resolveAppearance, resolveDataPicker } from '@/components/dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance], + ['data', resolveDataPicker], +]); + diff --git a/packages/mobile-ui-vue/components/picker-input/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/picker-input/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..660e1e609e1 --- /dev/null +++ b/packages/mobile-ui-vue/components/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/radio-group/src/designer/radio-group.design.component.tsx b/packages/mobile-ui-vue/components/radio-group/src/designer/radio-group.design.component.tsx index ab423e6c767..414ef0c02fb 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/designer/radio-group.design.component.tsx +++ b/packages/mobile-ui-vue/components/radio-group/src/designer/radio-group.design.component.tsx @@ -15,10 +15,9 @@ * limitations under the License. */ import { computed, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; -import RadioGroup, { RadioGroupProps, radioGroupProps } from '../..'; +import { RadioGroup, RadioGroupProps, radioGroupProps } from '../..'; import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas'; import { useRadioGroupDesignerRules } from './use-designer-rules'; -; export default defineComponent({ name: 'FmRadioGroupDesign', @@ -35,21 +34,33 @@ export default defineComponent({ elementRef.value.componentInstance = componentInstance; }); + /** + * 解决在设计时,数据为空数组,界面不显示内容的问题 + */ + const realEnumData = computed(() => { + if (!props.options || props.options.length === 0) { + const result = [] as any; + [ + { value: 'example1', name: '示例一' }, + { value: 'example2', name: '示例二' } + ].map(item => { + const tempData = {}; + tempData[props.valueField] = item['value']; + tempData[props.textField] = item['name']; + result.push(tempData); + }); + return result; + } + return props.options; + }); + const inputGroupProps = computed(() => ({ ...props, editable: false, - // options:[{ - // disabled: false, - // readonly: false, - // value: '1', - // text: '选项1' - // },{ - // disabled: false, - // readonly: false, - // value: '1', - // text: '选项1' - // }], - // direction:'horizontal' + readonly: true, + modelValue:null, + options:realEnumData.value, + type:"default" })); context.expose(componentInstance.value); diff --git a/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts b/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts index d1b24caa387..2af44da90f9 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts +++ b/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts @@ -10,11 +10,6 @@ export class RadioGroupProperty extends InputBaseProperty { getEditorProperties(propertyData: any) { const self = this; const editorProperties = self.getComponentConfig(propertyData, { type: "radio-group" }, { - placeholder: { - description: "空值时,输入控件内的占位文本", - title: "提示文本", - type: "string" - }, direction: { description: "", title: "排列方向", @@ -26,7 +21,7 @@ export class RadioGroupProperty extends InputBaseProperty { data: [{ "key": "horizontal", "value": "横向" }, { "key": "vertical", "value": "纵向" }] } }, - options: { + data: { description: "", title: "数据", type: "array", diff --git a/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json b/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json index c24da46e4b0..316b66fc68f 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json +++ b/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json @@ -32,10 +32,6 @@ "type": "object", "default": {} }, - "disable": { - "type": "string", - "default": false - }, "readonly": { "type": "string", "default": false @@ -59,7 +55,7 @@ "type": "boolean", "default": true }, - "options": { + "data": { "description": "", "type": "array", "default": [] @@ -71,13 +67,10 @@ } }, "required": [ - "type", - "options", - "direction" + "type" ], "ignore": [ "id", - "type", "appearance", "binding", "visible" diff --git a/packages/mobile-ui-vue/components/radio-group/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/radio-group/src/schema/schema-mapper.ts index abb57152ea8..84d9b46a457 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/radio-group/src/schema/schema-mapper.ts @@ -1,5 +1,6 @@ -import { MapperFunction, resolveAppearance } from '@/components/dynamic-resolver'; +import { MapperFunction, resolveAppearance, resolveData } from '@/components/dynamic-resolver'; export const schemaMapper = new Map([ - ['appearance', resolveAppearance] + ['appearance', resolveAppearance], + ['data', resolveData], ]); diff --git a/packages/mobile-ui-vue/components/switch/index.ts b/packages/mobile-ui-vue/components/switch/index.ts index 7c345e8c33f..bd7a3b611a2 100644 --- a/packages/mobile-ui-vue/components/switch/index.ts +++ b/packages/mobile-ui-vue/components/switch/index.ts @@ -1,7 +1,30 @@ import { withInstall } from '@components/common'; import SwitchInstallless from "./src/switch.component"; +import SwitchDesign from './src/designer/switch.design.component'; +import { propsResolver } from './src/switch.props'; + +export * from './src/switch.props'; + + +const SWITCH_REGISTERED_NAME = 'switch'; const Switch = withInstall(SwitchInstallless); +Switch.register = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[SWITCH_REGISTERED_NAME] = Switch; + propsResolverMap[SWITCH_REGISTERED_NAME] = propsResolver; +}; + +Switch.registerDesigner = ( + componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record +) => { + componentMap[SWITCH_REGISTERED_NAME] = SwitchDesign; + propsResolverMap[SWITCH_REGISTERED_NAME] = propsResolver; +}; + export { Switch }; export default Switch; diff --git a/packages/mobile-ui-vue/components/switch/src/designer/switch.design.component.tsx b/packages/mobile-ui-vue/components/switch/src/designer/switch.design.component.tsx new file mode 100644 index 00000000000..c52eea1c84b --- /dev/null +++ b/packages/mobile-ui-vue/components/switch/src/designer/switch.design.component.tsx @@ -0,0 +1,51 @@ +/* eslint-disable no-use-before-define */ +/** + * 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, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; +import { Switch, SwitchProps, switchProps } from '../..'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; +import { useInputGroupDesignerRules } from './use-designer-rules'; + +export default defineComponent({ + name: 'FmSwitchDesign', + props: switchProps, + emits: [] as (string[] & ThisType) | undefined, + setup(props: SwitchProps, context: SetupContext) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useInputGroupDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + const inputGroupProps = computed(() => ({ + ...props, + editable: false, + modelValue:null + })); + + context.expose(componentInstance.value); + + return () => { + return ( + + ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/switch/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/switch/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..7e3baaed1c1 --- /dev/null +++ b/packages/mobile-ui-vue/components/switch/src/designer/use-designer-rules.ts @@ -0,0 +1,15 @@ +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; +import { SwitchProperty } from "../property-config/switch.property-config"; +export function useInputGroupDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { + + const schema = designItemContext.schema as ComponentSchema; + + // 构造属性配置方法 + function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { + const inputGroupProps = new SwitchProperty(componentId, designerHostService); + return inputGroupProps.getPropertyConfig(schema, componentInstance); + } + + return { getPropsConfig } as UseDesignerRules; + +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/switch/src/property-config/switch.property-config.ts b/packages/mobile-ui-vue/components/switch/src/property-config/switch.property-config.ts new file mode 100644 index 00000000000..0aa4d0bd192 --- /dev/null +++ b/packages/mobile-ui-vue/components/switch/src/property-config/switch.property-config.ts @@ -0,0 +1,55 @@ +import { InputBaseProperty } from "@/components/common/src/entity/input-base-property"; + +export class SwitchProperty extends InputBaseProperty { + + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + + getEditorProperties(propertyData: any) { + const self = this; + const editorProperties = self.getComponentConfig(propertyData, { type: "switch" }, { + onBackground: { + description: "", + title: "打开时背景色", + type: "string" + }, + offBackground: { + description: "", + title: "关闭时背景色", + type: "string" + }, + size: { + description: "", + title: "尺寸", + type: "number" + }, + // size:{ + // description: "", + // title: "尺寸", + // type: "enum", + // editor:{ + // data: [ + // { + // id: "small", + // name: "小号" + // }, + // { + // id: "medium", + // name: "中号" + // }, + // { + // id: "large", + // name: "大号" + // } + // ] + // } + // } + }); + + return editorProperties; + } + + +} diff --git a/packages/mobile-ui-vue/components/switch/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/switch/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..df6c8b93d81 --- /dev/null +++ b/packages/mobile-ui-vue/components/switch/src/schema/schema-mapper.ts @@ -0,0 +1,9 @@ +import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance], + ['binding', 'modelValue'], + ['offBackground', 'inactiveColor'], + ['onBackground', 'activeColor'] +]); + diff --git a/packages/mobile-ui-vue/components/switch/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/switch/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..b02bdf93eec --- /dev/null +++ b/packages/mobile-ui-vue/components/switch/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/switch/src/schema/switch.schema.json b/packages/mobile-ui-vue/components/switch/src/schema/switch.schema.json new file mode 100644 index 00000000000..075e96d7a81 --- /dev/null +++ b/packages/mobile-ui-vue/components/switch/src/schema/switch.schema.json @@ -0,0 +1,95 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/switch.schema.json", + "title": "switch", + "description": "", + "type": "object", + "properties": { + "id": { + "description": "", + "type": "string" + }, + "type": { + "description": "", + "type": "string", + "default": "switch" + }, + "appearance": { + "description": "", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "binding": { + "description": "", + "type": "object", + "default": {} + }, + "onUpdate:modelValue": { + "description": "值变化事件", + "type": "string", + "default": "" + }, + "disable": { + "type": "string", + "default": false + }, + "readonly": { + "type": "string", + "default": false + }, + "title": { + "description": "", + "type": "string", + "default": "" + }, + "label": { + "description": "", + "type": "string", + "default": "" + }, + "lableWidth": { + "description": "", + "type": "number" + }, + "visible": { + "description": "", + "type": "boolean", + "default": true + }, + "onBackground": { + "description": "", + "type": "string", + "default": "" + }, + "offBackground": { + "description": "", + "type": "string", + "default": "" + }, + "size": { + "description": "", + "type": "number", + "default": 22 + } + }, + "events": [ + "onUpdate:modelValue" + ], + "required": [ + "type" + ], + "ignore": [ + "id", + "appearance", + "binding", + "visible" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/switch/src/switch.props.ts b/packages/mobile-ui-vue/components/switch/src/switch.props.ts index 74624f834b5..d208781ec45 100644 --- a/packages/mobile-ui-vue/components/switch/src/switch.props.ts +++ b/packages/mobile-ui-vue/components/switch/src/switch.props.ts @@ -13,7 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { createPropsResolver } from '@/components/dynamic-resolver'; import { ExtractPropTypes } from 'vue'; +import switchSchema from './schema/switch.schema.json'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; export const switchProps = { modelValue: { type: Boolean, default: false }, @@ -36,3 +40,10 @@ export const switchProps = { }; export type SwitchProps = ExtractPropTypes; + +export const propsResolver = createPropsResolver( + switchProps, + switchSchema, + schemaMapper, + schemaResolver +); diff --git a/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx b/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx index 9302b3507b3..15ed5219669 100644 --- a/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx +++ b/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx @@ -37,7 +37,8 @@ export default defineComponent({ const inputGroupProps = computed(() => ({ ...props, - editable: false + editable: false, + modelValue:null })); context.expose(componentInstance.value); diff --git a/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts b/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts index 7269a0228aa..3db2084f9a3 100644 --- a/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts +++ b/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts @@ -22,10 +22,15 @@ export class TextareaProperty extends InputBaseProperty { nullable:true } }, - showWordLimit: { + showCount: { description: "", title: "展示输入文本数量", type: "boolean" + }, + maxLength: { + description: "", + title: "文本最大长度", + type: "number" } }); } diff --git a/packages/mobile-ui-vue/components/textarea/src/schema/input.schema.json b/packages/mobile-ui-vue/components/textarea/src/schema/input.schema.json index 1425b3ede9c..577a7d531f6 100644 --- a/packages/mobile-ui-vue/components/textarea/src/schema/input.schema.json +++ b/packages/mobile-ui-vue/components/textarea/src/schema/input.schema.json @@ -32,42 +32,46 @@ "type": "object", "default": {} }, - "disable": { - "type": "string", - "default": false - }, "readonly": { "type": "string", "default": false }, - "title": { + "label": { "description": "", "type": "string", "default": "" }, - "label": { + "placeholder": { "description": "", "type": "string", "default": "" }, - "lableWidth": { + "visible": { "description": "", - "type": "number" + "type": "boolean", + "default": true }, - "placeholder": { + "rows": { "description": "", - "type": "string", + "type": "number", "default": "" }, - "visible": { + "showCount": { "description": "", "type": "boolean", "default": true + }, + "maxLength": { + "description": "", + "type": "number", + "default": 50 } }, "required": [ + "type" + ], + "ignore": [ "id", - "type", "appearance", "binding", "visible" diff --git a/packages/mobile-ui-vue/components/textarea/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/textarea/src/schema/schema-mapper.ts index abb57152ea8..acb5af1fe4f 100644 --- a/packages/mobile-ui-vue/components/textarea/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/textarea/src/schema/schema-mapper.ts @@ -1,5 +1,7 @@ import { MapperFunction, resolveAppearance } from '@/components/dynamic-resolver'; export const schemaMapper = new Map([ - ['appearance', resolveAppearance] + ['appearance', resolveAppearance], + ['showCount','showWordLimit'], + ['maxLength','maxlength'] ]); -- Gitee From fd0ed38c9c60a37de30a90e1239c503aa8228536 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Thu, 27 Feb 2025 15:16:52 +0800 Subject: [PATCH 006/287] =?UTF-8?q?chore:=E7=A7=BB=E5=8A=A8=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E8=AE=BE=E8=AE=A1=E6=97=B6=E7=BB=84=E4=BB=B6=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/designer/button.design.component.tsx | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx b/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx index 2e886c10725..58b8267ebd8 100644 --- a/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx +++ b/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx @@ -30,28 +30,27 @@ export default defineComponent({ const designItemContext = inject('design-item-context') as DesignerItemContext; const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); - + onMounted(() => { elementRef.value.componentInstance = componentInstance; }); context.expose(componentInstance.value); - const{ schema } = componentInstance.value; + const { schema } = componentInstance.value; - const inputProps = computed(() => ({ - ...props, + const buttonProps = computed(() => ({ + round: props.round, + block: props.block, + icon: props.icon, + type: props.type, })); return () => { return ( - schema.text ? - - : - + ); }; } -- Gitee From 9a9916691e7445cf544a0b26be29c79dfbb84e9c Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Mon, 3 Mar 2025 20:38:53 +0800 Subject: [PATCH 007/287] =?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 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 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 058/287] =?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 059/287] =?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 060/287] =?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 061/287] =?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 062/287] =?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 063/287] =?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 064/287] =?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 065/287] =?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 066/287] =?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 067/287] =?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 068/287] =?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 069/287] =?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 070/287] =?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 071/287] =?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 072/287] =?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 073/287] =?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 076/287] =?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 fa26ba51aa318016fbedd374ca13da214c84cf12 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Mon, 17 Mar 2025 20:51:14 +0800 Subject: [PATCH 077/287] =?UTF-8?q?feature:=20=E6=8F=90=E4=BE=9B=E5=A4=9A?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=B1=9E=E6=80=A7=E5=80=BC=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/composition/use-type-resolver.ts | 3 +- .../components/dynamic-form/src/types.ts | 3 +- .../dynamic-view/src/components/maps.ts | 2 + .../components/property-editor/index.ts | 10 +- .../const/const-property.component.tsx | 120 ++++ .../src/components/const/const-property.css | 6 + .../components/const/const-property.props.ts | 29 + .../custom/custom-property.component.tsx | 55 ++ .../src/components/custom/custom-property.css | 6 + .../custom/custom-property.props.ts | 24 + .../state-machine-property.component.tsx | 113 +++ .../state-machine/state-machine-property.css | 53 ++ .../state-machine-property.props.ts | 27 + .../variable/variable-property.component.tsx | 162 +++++ .../components/variable/variable-property.css | 42 ++ .../variable/variable-property.props.ts | 33 + .../property-editor/src/composition/data.ts | 367 +--------- .../property-editor/src/composition/type.ts | 153 ++-- .../src/composition/use-initialized-value.ts | 140 ---- .../src/composition/use-property-type.ts | 144 ++++ .../src/composition/use-property-value.ts | 44 ++ .../src/composition/use-state-machine.ts | 65 ++ .../src/composition/use-update-data.ts | 186 ----- .../src/composition/use-variable.ts | 105 +++ .../src/property-editor.component.tsx | 651 ++---------------- .../property-editor/src/property-editor.css | 178 +---- .../src/property-editor.props.ts | 19 +- .../src/schema/property-editor.schema.json | 33 + .../composition/entity/input-base-property.ts | 14 +- 29 files changed, 1245 insertions(+), 1542 deletions(-) create mode 100644 packages/ui-vue/components/property-editor/src/components/const/const-property.component.tsx create mode 100644 packages/ui-vue/components/property-editor/src/components/const/const-property.css create mode 100644 packages/ui-vue/components/property-editor/src/components/const/const-property.props.ts create mode 100644 packages/ui-vue/components/property-editor/src/components/custom/custom-property.component.tsx create mode 100644 packages/ui-vue/components/property-editor/src/components/custom/custom-property.css create mode 100644 packages/ui-vue/components/property-editor/src/components/custom/custom-property.props.ts create mode 100644 packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.component.tsx create mode 100644 packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.css create mode 100644 packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.props.ts create mode 100644 packages/ui-vue/components/property-editor/src/components/variable/variable-property.component.tsx create mode 100644 packages/ui-vue/components/property-editor/src/components/variable/variable-property.css create mode 100644 packages/ui-vue/components/property-editor/src/components/variable/variable-property.props.ts delete mode 100644 packages/ui-vue/components/property-editor/src/composition/use-initialized-value.ts create mode 100644 packages/ui-vue/components/property-editor/src/composition/use-property-type.ts create mode 100644 packages/ui-vue/components/property-editor/src/composition/use-property-value.ts create mode 100644 packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts delete mode 100644 packages/ui-vue/components/property-editor/src/composition/use-update-data.ts create mode 100644 packages/ui-vue/components/property-editor/src/composition/use-variable.ts diff --git a/packages/ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts b/packages/ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts index b50902acfc5..0a98c5ce927 100644 --- a/packages/ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts +++ b/packages/ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts @@ -95,7 +95,8 @@ export function useTypeResolver(): UseTypeResolver { case 'query-solution-config': case 'solution-preset': return 'onFieldsChanged'; - + case 'property-editor': + return 'onValueChange'; } } diff --git a/packages/ui-vue/components/dynamic-form/src/types.ts b/packages/ui-vue/components/dynamic-form/src/types.ts index e5029eeff4c..555bfffb03a 100644 --- a/packages/ui-vue/components/dynamic-form/src/types.ts +++ b/packages/ui-vue/components/dynamic-form/src/types.ts @@ -2,7 +2,8 @@ export type EditorType = 'button-edit' | 'check-box' | 'check-group' | 'combo-li 'date-picker' | 'date-range' | 'datetime-picker' | 'datetime-range' | 'events-editor' | 'month-picker' | 'month-range' | 'year-picker' | 'year-range' | 'input-group' | 'lookup' | 'number-range' | 'number-spinner' | 'radio-group' | 'text' | 'response-layout-editor-setting' | 'switch' | 'grid-field-editor' | 'field-selector' | 'schema-selector' | 'mapping-editor' | - 'textarea' | 'response-form-layout-setting'|'binding-selector' | 'query-solution-config' | 'solution-preset' | 'item-collection-editor'; + 'textarea' | 'response-form-layout-setting'|'binding-selector' | 'query-solution-config' | 'solution-preset' | 'item-collection-editor' | + 'property-editor'; export interface EditorConfig { /** 编辑器类型 */ diff --git a/packages/ui-vue/components/dynamic-view/src/components/maps.ts b/packages/ui-vue/components/dynamic-view/src/components/maps.ts index 96bb31c94a5..a859da777e2 100644 --- a/packages/ui-vue/components/dynamic-view/src/components/maps.ts +++ b/packages/ui-vue/components/dynamic-view/src/components/maps.ts @@ -60,6 +60,7 @@ import FTreeGrid from '@farris/ui-vue/components/tree-grid'; import FEventParameter from '@farris/ui-vue/components/event-parameter'; // import FExternalContainer from '@farris/ui-vue/components/external-container'; import FFieldset from '@farris/ui-vue/components/fieldset'; +import FPropertyEditor from '@farris/ui-vue/components/property-editor'; const componentMap: Record = {}; const componentPropsConverter: Record = {}; @@ -134,6 +135,7 @@ function loadRegister() { FBindingSelector.register(componentMap, componentPropsConverter, componentPropertyConfigConverter, resolverMap); FEventParameter.register(componentMap, componentPropsConverter, componentPropertyConfigConverter, resolverMap); FFieldset.register(componentMap, componentPropsConverter, componentPropertyConfigConverter, resolverMap); + FPropertyEditor.register(componentMap, componentPropsConverter, componentPropertyConfigConverter, resolverMap); } } diff --git a/packages/ui-vue/components/property-editor/index.ts b/packages/ui-vue/components/property-editor/index.ts index 02947dd5878..4b58d5c871c 100644 --- a/packages/ui-vue/components/property-editor/index.ts +++ b/packages/ui-vue/components/property-editor/index.ts @@ -1,4 +1,4 @@ - + /** * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. * @@ -15,19 +15,19 @@ * limitations under the License. */ import type { App } from 'vue'; -import propertyEditor from './src/property-editor.component'; +import PropertyEditor from './src/property-editor.component'; import { propsResolver } from './src/property-editor.props'; export * from './src/property-editor.props'; -export { propertyEditor }; +export { PropertyEditor }; export default { install(app: App): void { - app.component(propertyEditor.name as string, propertyEditor); + app.component(PropertyEditor.name as string, PropertyEditor); }, register(componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record): void { - componentMap['property-editor'] = propertyEditor; + componentMap['property-editor'] = PropertyEditor; propsResolverMap['property-editor'] = propsResolver; } }; diff --git a/packages/ui-vue/components/property-editor/src/components/const/const-property.component.tsx b/packages/ui-vue/components/property-editor/src/components/const/const-property.component.tsx new file mode 100644 index 00000000000..f224c83079f --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/const/const-property.component.tsx @@ -0,0 +1,120 @@ +/** + * 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 } from 'vue'; +import { ConstPropertyProps, ConstType } from './const-property.props'; +import { FComboList } from '@farris/ui-vue/components/combo-list'; +import { FNumberSpinner } from '@farris/ui-vue/components/number-spinner'; +import './const-property.css'; +import { ConstEnumItem, UsePropertyValue } from '../../composition/type'; + +export default function ( + props: ConstPropertyProps, + context: SetupContext, + usePropertyValueComposition: UsePropertyValue +) { + const readOnly = ref(false); + + /** 静态值类型:number, enum */ + const constType: Ref = ref(props.constType); + /** 静态值的枚举项(静态值类型为enum时使用) */ + const constEnums: Ref = ref(props.constEnums); + + /** 属性值相关方法 */ + const { getPropertyValue, triggerValueChange } = usePropertyValueComposition; + const propertyValue = getPropertyValue('const'); + + /** 控制右侧区域显示的内容 */ + const shouldShowContent = computed(() => (type: string) => { + return type === constType.value; + }); + + /** + * 设置常量的属性值 + */ + function setConstValue(newValue:any) { + triggerValueChange(newValue); + } + + /** + * 数值控件值变化 + * @param value + */ + function onNumberValueChange(value: number) { + setConstValue(value); + } + + /** + * 下拉列表控件值变化 + * @param constEnumItems + * @returns + */ + function onComboListValueChange(constEnumItems: ConstEnumItem[]) { + if (!constEnumItems || constEnumItems.length < 1) { + return; + } + const selectedValue = constEnumItems[0].id; + setConstValue(selectedValue); + } + + /** + * 静态值为number类型,渲染数值控件 + * @returns + */ + function renderNumber() { + return ( + + + ); + } + + /** + * 静态值为enum类型,渲染下拉列表控件 + * @returns + */ + function renderEnum() { + return ( + + + ); + } + + return () => { + return ( +
+ {shouldShowContent.value('number') && renderNumber()} + {shouldShowContent.value('enum') && renderEnum()} +
+ ); + }; + +} + diff --git a/packages/ui-vue/components/property-editor/src/components/const/const-property.css b/packages/ui-vue/components/property-editor/src/components/const/const-property.css new file mode 100644 index 00000000000..4796a723fb2 --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/const/const-property.css @@ -0,0 +1,6 @@ +.f-property-editor-const-container { + float: left; + width: 65%; + margin-left: 3%; + background: #FFFFFF; +} \ No newline at end of file diff --git a/packages/ui-vue/components/property-editor/src/components/const/const-property.props.ts b/packages/ui-vue/components/property-editor/src/components/const/const-property.props.ts new file mode 100644 index 00000000000..8b3dfd1c951 --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/const/const-property.props.ts @@ -0,0 +1,29 @@ + +/** + * 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 { ExtractPropTypes, PropType } from 'vue'; +import { ConstEnumItem } from '../../composition/type'; +export type ConstType = 'number' | 'enum'; + +export const constPropertyProps = { + /** 静态值的类型 */ + constType: { type: String as PropType, default: '' }, + /** 静态值的枚举项(静态值类型为enum时使用) */ + constEnums: { type: Array, default: [] }, +} as Record; + +export type ConstPropertyProps = ExtractPropTypes; + diff --git a/packages/ui-vue/components/property-editor/src/components/custom/custom-property.component.tsx b/packages/ui-vue/components/property-editor/src/components/custom/custom-property.component.tsx new file mode 100644 index 00000000000..a9f1f38873e --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/custom/custom-property.component.tsx @@ -0,0 +1,55 @@ + +/** + * 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 { Ref, ref, SetupContext } from 'vue'; +import { CustomPropertyProps } from './custom-property.props'; +import './custom-property.css'; +import { UsePropertyValue } from '../../composition/type'; +import { JSX } from 'vue/jsx-runtime'; + +export default function ( + props: CustomPropertyProps, + context: SetupContext, + usePropertyValueComposition: UsePropertyValue +): () => JSX.Element { + const readOnly: Ref = ref(false); + /** 属性值相关方法 */ + const { getPropertyValue, triggerValueChange } = usePropertyValueComposition; + const propertyValue: Ref = getPropertyValue('custom'); + + /** + * 文本控件值变化事件 + * @param $event + */ + function onInputValueChange($event: Event) { + const newValue = ($event.target as HTMLInputElement).value; + triggerValueChange(newValue); + } + + return () => { + return ( +
+ + +
+ ); + }; +} diff --git a/packages/ui-vue/components/property-editor/src/components/custom/custom-property.css b/packages/ui-vue/components/property-editor/src/components/custom/custom-property.css new file mode 100644 index 00000000000..ffa645de94e --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/custom/custom-property.css @@ -0,0 +1,6 @@ +.f-property-editor-customize-container { + width: 65%; + float: left; + margin-left: 3%; + background: #FFFFFF; +} \ No newline at end of file diff --git a/packages/ui-vue/components/property-editor/src/components/custom/custom-property.props.ts b/packages/ui-vue/components/property-editor/src/components/custom/custom-property.props.ts new file mode 100644 index 00000000000..3628f1937b1 --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/custom/custom-property.props.ts @@ -0,0 +1,24 @@ + +/** + * 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 { ExtractPropTypes } from 'vue'; + +export const customPropertyProps = { + +} as Record; + +export type CustomPropertyProps = ExtractPropTypes; + diff --git a/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.component.tsx b/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.component.tsx new file mode 100644 index 00000000000..9c80ab4dd7c --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.component.tsx @@ -0,0 +1,113 @@ +/** + * 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 { Ref, ref, SetupContext } from 'vue'; +import { StateMachinePropertyProps } from './state-machine-property.props'; +import { FComboList } from '@farris/ui-vue/components/combo-list'; +import './state-machine-property.css'; +import { useStateMachine } from '../../composition/use-state-machine'; +import { StateMachineItem, UsePropertyValue } from '../../composition/type'; + +export default function ( + props: StateMachinePropertyProps, + context: SetupContext, + usePropertyValueComposition: UsePropertyValue +) { + const readOnly = ref(false); + /** 状态机列表 */ + const stateMachines: Ref = ref(props.stateMachines); + /** 状态机相关方法 */ + const { getStateMachineValue } = useStateMachine(props, context, usePropertyValueComposition); + + /** 属性值相关方法 */ + const { triggerValueChange } = usePropertyValueComposition; + const propertyValue = getStateMachineValue(); + /** 当前状态机内码 */ + const currentStateMachineId = ref(propertyValue.value.field); + /** 状态机前缀,是或否 */ + const status = ref(propertyValue.value.status); + + /** + * 点击状态机前缀(是或否)按钮 + */ + function onButtonClick() { + status.value = !status.value; + propertyValue.value.status = status.value; + triggerValueChange(propertyValue.value); + } + + /** + * 状态机下拉框值变化 + * @param stateMachineItems + * @returns + */ + function onComboListValueChange(stateMachineItems: StateMachineItem[]) { + if (!stateMachineItems || stateMachineItems.length < 1) { + return; + } + const selectedStateMachine = stateMachineItems[0]; + propertyValue.value.field = selectedStateMachine.id; + triggerValueChange(propertyValue.value); + } + + /** + * 渲染是或否按钮 + * @returns + */ + function renderYesNoButton() { + return ( +
+ {status.value ? '是' : '否'} +
+ ); + } + + /** + * 渲染状态机下拉列表 + * @returns + */ + function renderComboList() { + return ( +
+ + +
+ + ); + } + + return () => { + return ( +
+ {renderYesNoButton()} + {renderComboList()} +
+ ); + }; + +} diff --git a/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.css b/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.css new file mode 100644 index 00000000000..70d83cd6adc --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.css @@ -0,0 +1,53 @@ +.f-property-editor-stateMachine-container { + width: 65%; + float: left; + margin-left: 3%; + background: #FFFFFF; + border: 1px solid #D8DCE6; + height: 26px; + border-radius: 3px; + + .f-stateMachine-status { + float: left; + width: 28px; + text-align: center; + background: #FFFFFF; + height: 20px; + margin-top: 2px; + margin-left: 5px; + padding-top: 1px; + background-color: #f4f6ff; + font-size: 13px; + font-family: PingFangSC-Regular; + color: #34495E; + } + + .f-stateMachine-combo-list { + float: right; + width: 75%; + background: #FFFFFF; + border: unset; + + .input-group { + border: unset; + box-shadow: none; + } + + .farris-combo-list .input-group { + border: 0; + box-shadow: none !important; + } + + .farris-combo-list input-group.actived .input-group { + box-shadow: none !important; + } + + .farris-combo-list .f-cmp-inputgroup.actived { + box-shadow: none !important; + } + } +} + +.f-property-editor-stateMachine-container:focus { + box-shadow: blue; +} \ No newline at end of file diff --git a/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.props.ts b/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.props.ts new file mode 100644 index 00000000000..296e5131331 --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.props.ts @@ -0,0 +1,27 @@ + +/** + * 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 { ExtractPropTypes } from 'vue'; +import { StateMachineItem } from '../../composition/type'; + +export const stateMachinePropertyProps = { + /** 状态机列表 */ + stateMachines: { type: Array, default: [] }, + +} as Record; + +export type StateMachinePropertyProps = ExtractPropTypes; + diff --git a/packages/ui-vue/components/property-editor/src/components/variable/variable-property.component.tsx b/packages/ui-vue/components/property-editor/src/components/variable/variable-property.component.tsx new file mode 100644 index 00000000000..ef114433813 --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/variable/variable-property.component.tsx @@ -0,0 +1,162 @@ +/** + * 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 } from 'vue'; +import { VariablePropertyProps } from './variable-property.props'; +import { FComboList } from '@farris/ui-vue/components/combo-list'; +import './variable-property.css' +import { UsePropertyValue, VariableItem, VariableValue } from '../../composition/type'; +import { useVariable } from '../../composition/use-variable'; + +export default function ( + props: VariablePropertyProps, + context: SetupContext, + usePropertyValueComposition: UsePropertyValue +) { + const readOnly = ref(false); + /** 变量列表 */ + const variables: Ref = ref(props.variables); + /** 控件名称,生成新变量时使用 */ + const controlName = ref(props.controlName); + /** 是否显示新增变量按钮 */ + const showAddButton = ref(!!controlName.value); + + /** 变量相关方法 */ + const { generateVariable, getVariableByPath, getVariableValue } = useVariable(props, context, usePropertyValueComposition); + /** 属性值相关方法 */ + const { triggerValueChange } = usePropertyValueComposition; + const propertyValue: Ref = getVariableValue(); + + /** 当前变量内码 */ + const currentVariableId = ref(propertyValue.value.field); + /** 变量下拉列表样式 */ + const comboListClass = computed(() => { + return [{ 'form-control-select-show': showAddButton.value }, + { 'form-control-select-hide': !showAddButton.value }]; + }); + + /** + * 设置变量属性值 + */ + function setVariableValue(variable: VariableValue, isTriggerChange: boolean) { + Object.assign(propertyValue.value, variable); + currentVariableId.value = propertyValue.value.field; + isTriggerChange && triggerValueChange(propertyValue.value); + } + + /** + * 点击新增变量按钮 + */ + function onAddButtonClick() { + // 1、生成一个新变量 + const newVariable = generateVariable(); + + // 2、检查新变量是否已经存在 + const existedVariable = getVariableByPath(newVariable.path); + + // 3、如果变量已经存在,则使用已有变量,否则使用新增变量 + if (existedVariable) { + setVariableValue(existedVariable, true); + } else { + variables.value.push(newVariable); + setVariableValue(newVariable, true); + } + } + + /** + * 显示下拉框前的回调 + */ + const beforeShowVariable = (instance: any) => { + return Promise.resolve(true); + }; + + /** + * 下拉框值变更 + * @param variableItems + */ + function onComboListValueChange(variableItems: VariableItem[]) { + if (!variableItems || variableItems.length < 1) { + return; + } + const variableItem = variableItems[0]; + const newVariable: VariableValue = { + path: variableItem.path, + fullPath: variableItem.fullPath, + field: variableItem.field, + type: "variable" + } + setVariableValue(newVariable, true); + } + + /** + * 清空变量值 + */ + function clearVariable() { + const emptyVariable: VariableValue = { type: 'variable', path: '', field: '', fullPath: '' }; + // 清空变量后,属性值不完整,不需要触发变更 + setVariableValue(emptyVariable, false); + } + + /** + * 渲染变量下拉列表 + * @returns + */ + function renderComboList() { + return ( + + + ); + } + + /** + * 渲染新增变量按钮 + * @returns + */ + function renderAddButton() { + return ( +
+ +
+ ); + } + + return () => { + return ( +
+ {renderComboList()} + {showAddButton.value && renderAddButton()} +
+ ); + }; + +} diff --git a/packages/ui-vue/components/property-editor/src/components/variable/variable-property.css b/packages/ui-vue/components/property-editor/src/components/variable/variable-property.css new file mode 100644 index 00000000000..5e30182cddf --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/variable/variable-property.css @@ -0,0 +1,42 @@ +.f-property-editor-variable-container { + float: left; + width: 65%; + margin-left: 3%; + .f-property-editor-variable-add-button { + margin-left: 2%; + float: left; + } + + .f-variable-button{ + width: calc(2px + .375rem + 1.4286em); + height: calc(2px + .375rem + 1.4286em); + padding: .1875rem; + border-color: transparent !important; + box-shadow: none !important; + background-color:#f0f0f0; + box-shadow: none !important; + transition: color .2s ease-in-out; + border-width: 1px; + border-radius: 3px; + } + + .f-variable-button:focus { + text-decoration: none; + outline: 0; + } + + .form-control-select-hide { + height: 28px; + margin: 0px !important; + width: 100%; + float: left; + } + + .form-control-select-show { + height: 28px; + margin: 0px !important; + width: 80%; + float: left; + } +} + diff --git a/packages/ui-vue/components/property-editor/src/components/variable/variable-property.props.ts b/packages/ui-vue/components/property-editor/src/components/variable/variable-property.props.ts new file mode 100644 index 00000000000..aad22c5712f --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/variable/variable-property.props.ts @@ -0,0 +1,33 @@ + +/** + * 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 { ExtractPropTypes } from 'vue'; +import { VariableItem } from '../../composition/type'; + +export const variablePropertyProps = { + variables: { type: Array, default: [] }, + + controlName: { type: String, default: '' }, + + /** 新增变量名称的前缀 */ + newVariablePrefix: { type: String, default: '' }, + /** 新增变量的类型 */ + newVariableType: { type: String, default: '' }, + +} as Record; + +export type VariablePropertyProps = ExtractPropTypes; + diff --git a/packages/ui-vue/components/property-editor/src/composition/data.ts b/packages/ui-vue/components/property-editor/src/composition/data.ts index 1be17edcf96..04f8fcfaef7 100644 --- a/packages/ui-vue/components/property-editor/src/composition/data.ts +++ b/packages/ui-vue/components/property-editor/src/composition/data.ts @@ -1,374 +1,25 @@ -import { PropertyEditorOptions, ArchiveOfPropertyValue, PropertyEditorValueChanged } from './type'; -import {ref} from 'vue'; +import { PropertyTypeItem } from './type'; -/** 所有值-内部存档&修改ArchiveOfPropertyValue */ -export const archiveOfPropertyValue: any = ref({ - /** 常量值 */ - constValue: { - /** 值类型:常量(const), 变量(variable), 状态机(state), 自定义(custom) */ - type: 'const', - /** 属性值 */ - value: '', - }, - /** 变量值 */ - variableValue: { - type: 'variable', - value: { - category: '', - path: '', - field: '', - fullPath: '' - } - }, - /** 状态值 */ - stateValue: null, - /** 自定义属性值 */ - customValue: { - type: 'custom', - value: '' - }, - expressionValue: { - type: 'expression', - /** 用户点击弹窗内确认按钮后置为true */ - value: '', - }, - stateMachineValue: { - type: 'stateMachine', - value: '', - }, - dataStatesValue: { - type: 'dataStates', - value: '', - } -}); - -/** 左侧状态数组:常量、变量、自定义 */ -export const dropdownStatesInTotal = ref([ +/** 左侧属性类型的枚举数据 */ +export const PROPERTY_TYPE_ENUMS: PropertyTypeItem[] = [ { 'id': 'const', - 'label': '常量' + 'name': '常量' }, { 'id': 'variable', - 'label': '变量' + 'name': '变量' }, { 'id': 'custom', - 'label': '自定义' + 'name': '自定义' }, { 'id': 'stateMachine', - 'label': '状态机' + 'name': '状态机' }, { 'id': 'expression', - 'label': '表达式' - }, - { - 'id': 'dataStates', - 'label': '数据状态' - } -]); - -/** 枚举类型-默认显示const状态 */ -export const option1: PropertyEditorOptions = { - controlName: 'userName', - propertyName: 'readonly', - propertyType: 'enum', - isNewVariable: false, - propertyValue: { - // type: 'dataStates', - // value: undefined - type:'const', - value:'true' - }, - editorOptions: { - types: ['const', 'variable', 'custom', 'expression', 'stateMachine', 'dataStates'], - enums: [{ key: 'true', value: '是' }, { key: 'false', value: '否' }], - variables: [ - { - category: 'remote', - path: 'root-component.isUserNameReadonly', - field: '49311371-fd9f-4019-8611-dce4dcae97fe', - fullPath: 'isUserNameReadonly' - }, - { - category: 'remote', - path: 'isSystem', - field: '49311371-fd9f-4019-8611-dce4dcae99fe', - fullPath: 'isSystem' - } - ], - expressionConfig: { - editor: 'ExpressionEditorComponent', - beforeOpenModal: () => { - return { - editorParams: { - modalTitle: '只读编辑器', - fieldId: 'ca30ad64-c9f6-4660-ad66-38073f6bd0b5', - viewModelId: 'basic-form-viewmodel', - expType: 'readonly' - }, - value: '{\'expr\':\'DefaultFunction.Length(\\\'aaa\\\')>2\',\'sexpr\':\'\'}' - }; - }, - exprValue: { - type: 'expression', - value: { - type: 'expression', - parameters: 'ca30ad64-c9f6', - value: '{\'expr\':\'DefaultFunction.Length(\\\'aaa\\\')>2\',\'sexpr\':\'\'}' - } - }, - }, - stateMachine: [ - { - id: 'canRemove', - name: '删除', - exist: '非' - }, - { - id: 'canCancelApprove', - name: '取消提交审批', - exist: '是' - }, - { - id: 'canApprove', - name: '提交审批', - exist: '是' - }, - { - id: 'editable', - name: '可编辑', - exist: '是' - }, - { - id: 'canEdit', - name: '编辑', - exist: '是' - }, - { - id: 'canRemoveDetail', - name: '删除明细', - exist: '是' - }, - { - id: 'canAdd', - name: '新增', - exist: '是' - }, - { - id: 'canSave', - name: '保存', - exist: '是' - }, - { - id: 'canCancel', - name: '取消', - exist: '是' - }, - { - id: 'canAddDetail', - name: '新增明细', - exist: '是' - } - ], - dataStates: [ - { - textField: '制单', - titleField: '制单', - valueField: 'Billing' - }, - { - textField: '提交审批', - titleField: '提交审批', - valueField: 'SubmitApproval' - }, - { - textField: '审批通过', - titleField: '审批通过', - valueField: 'Approved' - }, - { - textField: '审批不通过', - titleField: '审批不通过', - valueField: 'ApprovalNotPassed' - } - ] - }, - /** 状态机是否有前缀viewModel.stateMachine && */ - hasPrefix: 2 -}; - -/** 枚举类型-默认显示variable状态 */ -const option2: PropertyEditorOptions = { - controlName: 'UserAge', - propertyName: 'readonly', - propertyType: 'enum', - isNewVariable: false, - propertyValue: { - type: 'variable', - value: - { - category: 'remote', - path: 'root-component.isUserAgeReadonly', - field: '49311371-fd9f-4019-8611-dce4dcae97fe', - fullPath: 'isUserAgeReadonly' - }, - }, - editorOptions: { - types: ['variable'], - enums: [{ key: 'true', value: '是' }, { key: 'false', value: '否' }], - variables: [ - { - category: 'remote', - path: 'root-component.isUserAgeReadonly', - field: '49311371-fd9f-4019-8611-dce4dcae97fe', - fullPath: 'isUserAgeReadonly' - }, - ] - } -}; - -/** 枚举类型-默认显示custom状态 */ -const option3: PropertyEditorOptions = { - controlName: 'UserAddress', - propertyName: 'readonly', - propertyType: 'enum', - isNewVariable: false, - propertyValue: { - type: 'custom', - value: '!viewModel.stateMachine["editable"]' - }, - editorOptions: { - types: ['const', 'variable', 'custom'], - enums: [{ key: 'true', value: '是' }, { key: 'false', value: '否' }], - variables: [ - { - category: 'local', - path: 'isSystem', - field: '49311371-fd9f-4019-8611-dce4dcae97fe', - fullPath: 'isSystem' - } - ] + 'name': '表达式' } -}; - -/** string类型- 默认显示const状态 */ -const option4: PropertyEditorOptions = { - controlName: 'UserAddress', - propertyName: 'readonly', - propertyType: 'string', - isNewVariable: false, - propertyValue: { - type: 'const', - value: '!viewmodel.statemachine["editable"]' - }, - editorOptions: { - types: ['const', 'variable', 'custom'], - enums: [{ key: 'true', value: '是' }, { key: 'false', value: '否' }], - variables: - [{ - // 标记来自表单变量或组件变量 - category: 'local', - path: 'isSystem', - field: '49311371-fd9f-4019-8611-dce4dcae97fe', - fullPath: 'isSystem' - } - ] - } -}; - -/** number类型- 默认显示custom状态 */ -const option5: PropertyEditorOptions = { - controlName: 'UserAddress', - propertyName: 'readonly', - propertyType: 'number', - isNewVariable: false, - propertyValue: { - type: 'custom', - value: '!viewModel.stateMachine["editable"]' - }, - editorOptions: { - types: ['const', 'variable', 'custom'], - enums: [{ key: 'true', value: '是' }, { key: 'false', value: '否' }], - variables: - [{ - category: 'local', - path: 'isSystem', - field: '49311371-fd9f-4019-8611-dce4dcae97fe', - fullPath: 'isSystem' - } - ], - - } -}; - -const archiveOfThisPropertyValue: ArchiveOfPropertyValue = { - /** 常量值 */ - constValue: { - /** 值类型:常量(const), 变量(variable), 状态机(state), 自定义(custom) */ - type: 'const', - /** 属性值 */ - value: 'true', - }, - /** 变量值 */ - variableValue: { - type: 'variable', - value: { - category: 'local', - path: 'isUserNameReadonly', - field: '49311371-fd9f-4019-8611-dce4dcae97fe', - fullPath: 'isUserNameReadonly' - } - }, - /** 状态值 */ - stateValue: null, - /** 自定义属性值 */ - customValue: { - type: 'custom', - value: '!viewModel.stateMachine["editable"]' - }, - /** 表达式属性值 */ - expressionValue: { - type: 'expression', - value: false, - }, - /** 状态机属性值 */ - stateMachineValue: { - type: 'stateMachine', - value: '' - }, - /** 数据状态属性值 */ - dataStatesValue: { - type: 'dataStates', - value: '' - } -}; - -const propertyValueChangedEventArgs1: PropertyEditorValueChanged = { - /** 待编辑的属性名 */ - propertyName: 'readonly', - /** 属性类型:enum, string, number, enum */ - propertyType: 'enum', - isNewVariable: false, - propertyValue: archiveOfThisPropertyValue.constValue -}; - -const propertyValueChangedEventArgs2: PropertyEditorValueChanged = { - /** 待编辑的属性名 */ - propertyName: 'readonly', - /** 属性类型:enum, string, number, enum */ - propertyType: 'enum', - isNewVariable: false, - propertyValue: archiveOfThisPropertyValue.variableValue -}; - -const propertyValueChangedEventArgs3: PropertyEditorValueChanged = { - /** 待编辑的属性名 */ - propertyName: 'readonly', - /** 属性类型:enum, string, number, enum */ - propertyType: 'enum', - isNewVariable: false, - propertyValue: archiveOfThisPropertyValue.customValue -}; +]; diff --git a/packages/ui-vue/components/property-editor/src/composition/type.ts b/packages/ui-vue/components/property-editor/src/composition/type.ts index eee7f4b8a2f..fcaaf87689a 100644 --- a/packages/ui-vue/components/property-editor/src/composition/type.ts +++ b/packages/ui-vue/components/property-editor/src/composition/type.ts @@ -1,110 +1,95 @@ +import { Ref } from "vue"; +import { PropertyType } from "../property-editor.props"; + /** - * 枚举选项 + * 属性类型的枚举选项 */ -export interface EnumItem { - /** 枚举项的值 */ - key: any; - /** 枚举项的显示名称 */ - value: string; +export interface PropertyTypeItem { + /** 属性类型:const、variable、custom、stateMachine、expression */ + id: PropertyType; + /** 属性类型的显示名称 */ + name: string; } /** - * 变量选项 + * 常量值的枚举选项 */ -export interface VariableItem { - /** 变量类型,支持状态变量(variable),实体变量(entity) */ - category: string; +export interface ConstEnumItem { + /** 枚举项的键值 */ + id: any; + /** 枚举项的名称 */ + name: string; +} + +/** + * 变量属性值 + */ +export interface VariableValue { + type: 'variable'; + /** 变量唯一标识 */ + field: string; /** 变量绑定路径 */ path: string; - /** 变量唯一标识 */ + /** 包含层级结构的变量路径 */ + fullPath: string; + /** 是否为新增的变量 */ + isNewVariable?: boolean; + /** 新变量的类型 */ + newVariableType?: 'String' | 'Number' | 'Boolean' | 'Date' | 'DateTime' | 'Text' | 'Object' | 'Array'; +} + +/** + * 变量数据的类型 + */ +export interface VariableItem { + /** 变量内码 */ field: string; + /** 变量绑定路径 */ + path: string; /** 包含层级结构的变量路径 */ fullPath: string; } /** - * 属性编辑器的值。 - * 包括:常量、变量、状态机、自定义等类型 + * 状态机属性值 */ -export interface PropertyEditorValue { - /** 值类型:常量(const), 变量(variable), 状态机(stateMachine), 自定义(custom) */ - type: string; - /** 属性值 */ - value: any; +export interface StateMachineValue { + type: 'stateMachine'; + /** 状态机标识 */ + field: string; + /** 状态机前缀状态 */ + status: boolean; } /** - * 属性编辑器可选值配置 + * 状态机数据的类型 */ -export interface EditorOption { - /** 支持的编辑器类型 */ - types: string[]; - /** 枚举类型常量编辑器的枚举列表 */ - enums?: EnumItem[]; - /** 变量编辑器的变量列表 */ - variables?: VariableItem[]; - /** 新增变量的类型 */ - newVariableType?: string; - /** 新增变量名称的前缀 */ - newVariablePrefix?: string; - /** 获取最新变量列表函数 */ - getVariables?: any; - /** 获取最新状态机列表函数 */ - getStates?: any; - /** 状态机编辑器的状态列表 */ - stateMachine?: any; - /** 数据状态列表 */ - dataStates?: any; - expressionConfig?: any; +export interface StateMachineItem { + /** 状态机内码 */ + id: string; + /** 状态机的显示名称 */ + name: string; } -export interface ArchiveOfPropertyValue { - /** 常量值 */ - constValue: PropertyEditorValue; - /** 变量值 */ - variableValue: PropertyEditorValue; - /** 状态值 */ - stateValue: PropertyEditorValue | null; - /** 自定义属性值 */ - customValue: PropertyEditorValue; - /** 表达式值 */ - expressionValue: PropertyEditorValue; - /** 状态机值 */ - stateMachineValue: PropertyEditorValue; - /** 数据状态值 */ - dataStatesValue: PropertyEditorValue; +export interface UsePropertyValue { + triggerValueChange: (newValue: any) => void; + getPropertyValue: (propertyType: PropertyType) => Ref; + } -export interface PropertyEditorValueChanged { - /** 待编辑的属性名 */ - propertyName: string; - /** 属性类型:boolean, string, number, enum */ - propertyType: string; - /** 检测是否产生新变量 */ - isNewVariable: boolean; - /** 属性编辑器的初始值 */ - propertyValue: PropertyEditorValue; - /** 状态机是否有viewModel.stateMachine前缀 */ - hasPrefix?: boolean; +export interface UsePropertyType { + getAllowedPropertyTypeItems: () => Ref; + getCurrentPropertyType: () => Ref; + } -/** - * 属性编辑器配置 - * 用来初始化属性编辑器 - */ -export interface PropertyEditorOptions { - /** 当前选中的控件对应的英文名称,例userName */ - controlName: string; - /** 待编辑的属性名 */ - propertyName: string; - /** 属性类型:boolean, string, number, enum */ - propertyType: string; - /** 检测是否产生新变量 */ - isNewVariable: boolean; - /** 属性编辑器的初始值 */ - propertyValue: PropertyEditorValue; - /** 属性编辑器可选值配置 */ - editorOptions: EditorOption; - /** 状态机是否有前缀viewModel.stateMachine && */ - hasPrefix?: number; +export interface UseStateMachine { + getStateMachineValue: () => Ref; + +} + +export interface UseVariable { + generateVariable: () => VariableValue; + getVariableByPath: (variablePath: string) => VariableValue; + getVariableValue: () => Ref; } diff --git a/packages/ui-vue/components/property-editor/src/composition/use-initialized-value.ts b/packages/ui-vue/components/property-editor/src/composition/use-initialized-value.ts deleted file mode 100644 index c7cd352e2d8..00000000000 --- a/packages/ui-vue/components/property-editor/src/composition/use-initialized-value.ts +++ /dev/null @@ -1,140 +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 { Ref, ref } from 'vue'; -import { cloneDeep } from 'lodash-es'; - -export function useInitializedValue( - importedOriginalData, constEnumValueArray, - currentState, bindStateMachineValue, exists, - searchText, showExpressionComponent -) { - /** 常量-number类型-number-数字输入框 */ - const numberConstValue = ref(0); - /** 数据状态-用户设定绑定值 */ - const dataStatesBindValue = ref(''); - - /** 数据状态-存储所有值的数组 */ - const dataStatesValueArray = ref([]); - - /** 常量-enum类型-用户设定绑定值 */ - const constEnumBindValue = ref(''); - - /** 变量-用户设定的绑定值 */ - const bindVariableValue = ref(''); - - /** - * 常量-枚举:初始设置枚举对应的绑定值和展示数组 - */ - function setEnumConstValue() { - // 存储 常量-enum 的变量值数组 - if (importedOriginalData.value.propertyType === 'enum' && importedOriginalData.value.propertyValue.type === 'const') { - // 当默认显示常量-enum类型时,使用constEnumBindValue来存储comboList中对应的数据,此处value是数组中的key - constEnumBindValue.value = cloneDeep(importedOriginalData.value.propertyValue.value); - constEnumValueArray.value = cloneDeep(importedOriginalData.value.editorOptions.enums); - } - }; - - /** - * 常量-数字 - */ - function setNumberConstValue() { - if (importedOriginalData.value.propertyType === 'number') { - numberConstValue.value = importedOriginalData.value.propertyValue.value; - } - } - - /** 状态机-设置初始绑定值 */ - function setBindStateMachineValue() { - if (currentState.value.id === 'stateMachine') { - bindStateMachineValue = cloneDeep(importedOriginalData.value.propertyValue.value.id); - if (bindStateMachineValue) { - exists.value = cloneDeep(importedOriginalData.value.propertyValue.value.exist); - } else { - exists.value = '否'; - } - } - } - - /** 数据状态-设置初始绑定值 */ - function setBindDataStatesValue() { - if (currentState.value.id === 'dataStates') { - // 数据状态数组 - dataStatesValueArray.value = cloneDeep(importedOriginalData.value.editorOptions.dataStates); - // 数据状态根据propertyValue设置初始值 - if (importedOriginalData.value.propertyValue.value) { - const string = importedOriginalData.value.propertyValue.value; - const result = dataStatesValueArray.value - .filter((element: any) => string.includes(element.value)) - .map((element: any) => element.value) - .join(','); - dataStatesBindValue.value = cloneDeep(result); - } - } - } - /** - * 变量-点击按钮-设置当前绑定的变量值 - */ - function setBindVariableValue() { - if (currentState.value.id === 'variable') { - bindVariableValue.value = importedOriginalData.value.propertyValue.value.path; - } - } - function setBindExpressionValue() { - // 表达式-弹窗组件 - if (currentState.value.id === 'expression') { - showExpressionComponent.value = true; - // 弹窗默认显示值 - const { handleExpressionValue } = importedOriginalData.value.editorOptions.expressionConfig; - if (handleExpressionValue) { - searchText.value = handleExpressionValue().value.value; - } else { - searchText.value = importedOriginalData.value.editorOptions.expressionConfig.expressionValue.value.value; - } - } - } - function setBindCustomValue() { - // 如果为自定义类型,进行subscribe - if (currentState.value.id === 'custom') { - // customValueChange(); - } - } - /** 配置各显示框中的值 */ - function setValue() { - // 常量-enum类型-初始显示值 - setEnumConstValue(); - // 常量-number类型-初始显示值 - setNumberConstValue(); - // 变量-下拉框-初始显示值 - setBindVariableValue(); - // 状态机-下拉框-初始显示值 - setBindStateMachineValue(); - // 数据状态-下拉框-初始显示值 - setBindDataStatesValue(); - // 表达式-帮助-初始显示值 - setBindExpressionValue(); - // 自定义-输入框-初始显示值 - setBindCustomValue(); - } - - return { - numberConstValue, - bindVariableValue, - dataStatesBindValue, - dataStatesValueArray, - constEnumBindValue, - setValue - }; -} diff --git a/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts b/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts new file mode 100644 index 00000000000..b58aae05116 --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts @@ -0,0 +1,144 @@ + + +import { Ref, SetupContext, ref } from "vue"; +import { PropertyEditorProps, PropertyType } from "../property-editor.props"; +import { PROPERTY_TYPE_ENUMS } from "./data"; +import { ConstEnumItem, PropertyTypeItem, UsePropertyType } from "./type"; +import { ConstType } from "../components/const/const-property.props"; + +export function usePropertyType( + props: PropertyEditorProps, + context: SetupContext, +): UsePropertyType { + + const constType: Ref = ref(props.constType); + const constEnums: Ref = ref(props.constEnums); + /** 允许选择的属性类型内码 */ + const propertyTypes: Ref = ref(props.propertyTypes); + /** 允许选择的属性类型数据 */ + const allowedPropertyTypeItems: Ref = ref([]); + /** 当前选择的属性类型 */ + const currentPropertyType: Ref = ref(); + + + /** + * 获取允许选择的属性类型数据 + */ + function getAllowedPropertyTypeItems(): Ref { + const allowedPropertyTypeIds = propertyTypes.value; + allowedPropertyTypeItems.value = PROPERTY_TYPE_ENUMS.filter(propertyTypeItem => allowedPropertyTypeIds.includes(propertyTypeItem.id)); + return allowedPropertyTypeItems; + } + + /** + * 判断是否是状态机(旧的状态机格式) + * @param propertyValue + * @returns + */ + function isStateMachine(propertyValue: any): boolean { + if (typeof (propertyValue) !== 'string') { + return false; + } + const stateMachineRegex = /^(?:(!)?)viewModel\.stateMachine\['([^']+)'\]$/; + const isStateMachine = stateMachineRegex.test(propertyValue); + return isStateMachine; + } + + /** + * 判断是否是常量 + * @param propertyValue + * @returns + */ + function isConst(propertyValue: any): boolean { + const allowedPropertyTypes = propertyTypes.value; + + // 1、常量枚举类型 + const isConstEnum = allowedPropertyTypes.includes('const') && constType.value === 'enum' + && constEnums.value.findIndex(constEnum => constEnum.id === propertyValue) > -1; + + // 2、常量数值类型 + const isConstNumber = allowedPropertyTypes.includes('const') && constType.value === 'number' + && typeof propertyValue === "number"; + + return isConstEnum || isConstNumber; + } + + + /** + * 判断是否是自定义类型 + * @param propertyValue + * @returns + */ + function isCustom(propertyValue: any): boolean { + const allowedPropertyTypes = propertyTypes.value; + + const isCustom = allowedPropertyTypes.includes("custom") && typeof (propertyValue) === 'string'; + return isCustom; + } + + /** + * 从对象结构中提取属性类型 + * @param propertyValue + * @returns + */ + function extractFromObjectType(propertyValue: any): PropertyType | undefined { + const isObject = propertyValue && typeof (propertyValue) === 'object'; + if (!isObject) { + return; + } + return propertyValue.type; + } + + /** + * 从非对象结构中提取属性类型 + * @param propertyValue + * @returns + */ + function extractFromNonObjectType(propertyValue: any): PropertyType | undefined { + // 1、定义属性类型检查器 + const typeCheckers = new Map boolean>([ + ['const', isConst], + ['stateMachine', isStateMachine], + ['custom', isCustom], + ]); + + // 2、遍历检查器,找到匹配的类型 + for (const [propertyType, checker] of typeCheckers.entries()) { + if (checker(propertyValue)) { + return propertyType; + } + } + } + + /** + * 提取属性类型 + * @returns + */ + function extractPropertyType(): PropertyType { + const propertyValue: any = props.modelValue; + // 1、默认为第一个可选的属性类型 + const dfaultPropertyType: PropertyType = propertyTypes.value[0]; + + // 2、属性值为对象结构,属性值的type为属性类型 + const propertyTypefromObject = extractFromObjectType(propertyValue); + + // 2、属性值为非对象结构,属性值的type为属性类型 + const propertyTypefromNonObject = extractFromNonObjectType(propertyValue); + + return propertyTypefromObject || propertyTypefromNonObject || dfaultPropertyType; + } + + /** + * 获取当前选择的属性类型 + * @returns + */ + function getCurrentPropertyType(): Ref { + if (!currentPropertyType.value) { + // 从属性值中提取属性类型 + currentPropertyType.value = extractPropertyType(); + } + return currentPropertyType; + } + + return { getAllowedPropertyTypeItems, getCurrentPropertyType }; +} diff --git a/packages/ui-vue/components/property-editor/src/composition/use-property-value.ts b/packages/ui-vue/components/property-editor/src/composition/use-property-value.ts new file mode 100644 index 00000000000..e52530c6160 --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/composition/use-property-value.ts @@ -0,0 +1,44 @@ +import { Ref, SetupContext, ref } from "vue"; +import { PropertyEditorProps, PropertyType } from "../property-editor.props"; +import { UsePropertyValue } from "./type"; +import { cloneDeep } from "lodash"; + +export function usePropertyValue( + props: PropertyEditorProps, + context: SetupContext, + currentPropertyType: PropertyType +): UsePropertyValue { + const modelValue = ref(props.modelValue); + + /** 存储所有类型的属性值 */ + const propertyValueMap = new Map>(); + propertyValueMap.set(currentPropertyType, ref(cloneDeep(modelValue.value))); + + /** + * 触发属性值改变 + * @param newValue + */ + function triggerValueChange(newValue: any) { + context.emit('valueChange', cloneDeep(newValue)); + } + + /** + * 获取属性值 + * @param propertyType + * @returns + */ + function getPropertyValue(propertyType: PropertyType): Ref { + // 1、从propertyValueMap中获取属性值 + const propertyValue = propertyValueMap.get(propertyType); + if (propertyValue) { + return propertyValue; + } + // 2、propertyValueMap中不存在属性值,则新建 + const newPropertyValue = ref(); + propertyValueMap.set(propertyType, newPropertyValue); + return newPropertyValue; + + } + + return { triggerValueChange, getPropertyValue }; +} diff --git a/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts b/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts new file mode 100644 index 00000000000..8dc2fe63822 --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts @@ -0,0 +1,65 @@ +import { Ref, SetupContext, ref } from "vue"; +import { PropertyEditorProps } from "../property-editor.props"; +import { StateMachineValue, UsePropertyValue, UseStateMachine } from "./type"; + +export function useStateMachine( + props: PropertyEditorProps, + context: SetupContext, + usePropertyValueComposition: UsePropertyValue +): UseStateMachine { + + const stateMachineRegex = /^(?:(!)?)viewModel\.stateMachine\['([^']+)'\]$/; + const { getPropertyValue } = usePropertyValueComposition; + + /** + * 把状态机转为新的格式 + * viewModel.stateMachine['xxx'] -> {type: 'stateMachine',status: false,field: 'xxx'} + */ + function convertStateMachineFormat(oldStateMachineFormat: Ref) { + // 1、字符串类型为旧结构 + const isOldStructure = typeof oldStateMachineFormat.value === 'string'; + if (!isOldStructure) { + return; + } + + // 2、判断是否为状态机 + const matchResult = oldStateMachineFormat.value.match(stateMachineRegex); + if (!matchResult || matchResult.length < 3) { + return; + } + + // 3、转化为新的格式 + const newStateMachineFormat: StateMachineValue = { + type: 'stateMachine', + status: matchResult[1], + field: matchResult[2] + } + + oldStateMachineFormat.value = newStateMachineFormat; + usePropertyValueComposition.triggerValueChange(newStateMachineFormat); + } + + /** + * 获取状态机属性值 + * @returns + */ + function getStateMachineValue() { + // 1、如果存在属性值,则直接返回 + const propertyValue: Ref = getPropertyValue('stateMachine'); + if (propertyValue.value) { + convertStateMachineFormat(propertyValue); + return propertyValue; + } + // 2、如果属性值为空,则新建一个 + propertyValue.value = { + type: 'stateMachine', + field: '', + status: false + } + return propertyValue; + + } + + + return { getStateMachineValue }; +} diff --git a/packages/ui-vue/components/property-editor/src/composition/use-update-data.ts b/packages/ui-vue/components/property-editor/src/composition/use-update-data.ts deleted file mode 100644 index 15ec7d9bc95..00000000000 --- a/packages/ui-vue/components/property-editor/src/composition/use-update-data.ts +++ /dev/null @@ -1,186 +0,0 @@ - -/* eslint-disable no-use-before-define */ -/** - * 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 { PropertyEditorProps, propertyEditorProps } from '../property-editor.props'; -import { SetupContext, ref, Ref } from 'vue'; -import { cloneDeep } from 'lodash-es'; - -export function useUpdate(context: SetupContext, importedOriginalData, constEnumBindValue, constEnumValueArray, - archiveOfPropertyValue, displayArrayState, bindStateMachineValue, exists, dataStatesValueArray, - searchText, readOnly, currentState) { - /** 状态机是否有前缀viewModel.stateMachine && */ - const prefix: Ref = ref(false); - - /** 出参属性PropertyEditorValueChanged */ - const propertyEditorValueChange: any = ref({ - propertyName: '', - /** 属性类型:boolean, string, number, enum */ - propertyType: '', - /** 是否生成新变量*/ - isNewVariable: false, - /** 属性编辑器的初始值 */ - propertyValue: null, - /** 状态机是否有前缀viewModel.stateMachine && */ - hasPrefix: false, - }); - - /** - * 常量-枚举:设置枚举对应的绑定值和展示数组 - */ - function setStateOfEnum() { - if (importedOriginalData.value.propertyValue.type === 'const') { - importedOriginalData.value.propertyValue.value = cloneDeep(archiveOfPropertyValue.value.constValue.value); - constEnumBindValue.value = cloneDeep(archiveOfPropertyValue.value.constValue.value); - constEnumValueArray.value = cloneDeep(importedOriginalData.value.editorOptions.enums); - } - } - - /** 状态机-设置对应的绑定值和生成数组 */ - function setStateOfStateMachine() { - if (importedOriginalData.value.propertyValue.type === 'stateMachine') { - importedOriginalData.value.propertyValue.value = cloneDeep(archiveOfPropertyValue.value.stateMachineValue.value); - displayArrayState.value = cloneDeep(importedOriginalData.value.editorOptions.stateMachine); - if (importedOriginalData.value.propertyValue.value.name) { - bindStateMachineValue = cloneDeep(importedOriginalData.value.propertyValue.value.id); - } - else { - importedOriginalData.value.propertyValue.value = { - id: '', - name: '', - exist: '' - }; - bindStateMachineValue = ''; - exists.value = '否'; - } - } - }; - /** 数据状态-设置对应的绑定值和生成数组 */ - function setValueOfDataStates() { - if (importedOriginalData.value.propertyValue.type === 'dataStates') { - importedOriginalData.value.propertyValue.value = cloneDeep(archiveOfPropertyValue.value.dataStatesValue.value); - dataStatesValueArray.value = cloneDeep(importedOriginalData.value.editorOptions.dataStates); - } - }; - /** 表达式-将表达式绑定值置为空 */ - function setExpressionBindValue() { - searchText.value = ''; - if (archiveOfPropertyValue.value.expressionValue) { - archiveOfPropertyValue.value.expressionValue.value = ''; - } - } - /** 状态机-切换状态-是/否 */ - function changeState() { - if (!readOnly.value) { - exists.value = exists.value === '否' ? '是' : '否'; - importedOriginalData.value.propertyValue.value.exist = exists; - archiveOfPropertyValue.value.stateMachineValue.value.exist = exists; - emitOutPutInterfaceData(); - } - } - - /** 自定义-清空符合状态机的值 */ - function clearCustomBindValue() { - if (propertyEditorValueChange.value.propertyValue.value) { - if (propertyEditorValueChange.value.propertyValue.value.includes('viewModel.stateMachine')) { - archiveOfPropertyValue.value.customValue.value = ''; - } - } - } - - /** 将最终状态和值,赋给propertyEditorValueChange */ - function setOutputData() { - propertyEditorValueChange.value.propertyName = cloneDeep(importedOriginalData.value.propertyName); - propertyEditorValueChange.value.propertyType = cloneDeep(importedOriginalData.value.propertyType); - propertyEditorValueChange.value.propertyValue = cloneDeep(importedOriginalData.value.propertyValue); - propertyEditorValueChange.value.hasPrefix = cloneDeep(prefix); - } - /** - * 出参-传出接口 - */ - function emitOutPutInterfaceData() { - if (!readOnly.value) { - setOutputData(); - // 判定需要出参的情况 - switch (propertyEditorValueChange.value.propertyValue.type) { - case 'const': - // const时的出参判断条件 - if ((propertyEditorValueChange.value.propertyType === 'enum' && propertyEditorValueChange.value.propertyValue.value !== '') - || (propertyEditorValueChange.value.propertyType === 'number' && propertyEditorValueChange.value.propertyValue.value != null) - || (propertyEditorValueChange.value.propertyType === 'string')) { - // 将表达式绑定值置为空 - setExpressionBindValue(); - context.emit('propertyEditorValueChanged', propertyEditorValueChange); - } - break; - case 'variable': - // variable时的出参判断条件 - if (propertyEditorValueChange.value.propertyValue.value.path !== '') { - // 将表达式绑定值置为空 - setExpressionBindValue(); - context.emit('propertyEditorValueChanged', propertyEditorValueChange); - } - break; - case 'custom': - // 将表达式绑定值置为空 - setExpressionBindValue(); - clearCustomBindValue(); - context.emit('propertyEditorValueChanged', propertyEditorValueChange); - break; - case 'expression': - if (searchText.value) { - context.emit('propertyEditorValueChanged', propertyEditorValueChange); - } - break; - case 'stateMachine': - // variable时的出参判断条件 - if (propertyEditorValueChange.value.propertyValue.value.id) { - setExpressionBindValue(); - context.emit('propertyEditorValueChanged', propertyEditorValueChange); - } - break; - case 'dataStates': - // 将表达式绑定值置为空 - if (propertyEditorValueChange.value.propertyValue.value !== '') { - setExpressionBindValue(); - context.emit('propertyEditorValueChanged', propertyEditorValueChange); - break; - } - } - } - } - /** - * 更新数据-左侧区域切换不同模式or各区域值变更后,更新当前数据 - */ - function updateData() { - // 将archiveOfPropertyValue中对应constValue/variableValue/customValue存储的值放入当前值 - importedOriginalData.value.propertyValue = archiveOfPropertyValue.value[`${currentState.value.id}Value`]; - // 出现枚举时,需要绑定 - setStateOfEnum(); - setStateOfStateMachine(); - setValueOfDataStates(); - emitOutPutInterfaceData(); - // 检测当前是否生成了新的变量 - propertyEditorValueChange.value.isNewVariable = false; - } - - return { - updateData, - changeState, - prefix, - propertyEditorValueChange - }; -} diff --git a/packages/ui-vue/components/property-editor/src/composition/use-variable.ts b/packages/ui-vue/components/property-editor/src/composition/use-variable.ts new file mode 100644 index 00000000000..6903c7d8753 --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/composition/use-variable.ts @@ -0,0 +1,105 @@ + + +import { Ref, SetupContext, ref } from "vue"; +import { PropertyEditorProps } from "../property-editor.props"; +import { useGuid } from '@farris/ui-vue/components/common'; +import { UsePropertyValue, UseVariable, VariableValue } from "./type"; + +export function useVariable( + props: PropertyEditorProps, + context: SetupContext, + usePropertyValueComposition: UsePropertyValue +): UseVariable { + + const newVariablePrefix = ref(props.newVariablePrefix); + const newVariableType = ref(props.newVariableType); + + const propertyName = ref(props.id); + const controlName = ref(props.controlName); + const variables = ref(props.variables); + const { getPropertyValue } = usePropertyValueComposition; + + /** + * 把字符串的首字母大写 + * @param originalString + * @returns + */ + function setFirstLetterUpperCase(originalString: string) { + return originalString[0].toUpperCase() + originalString.slice(1); + } + + /** + * 把字符串的首字母小写 + * @param originalString + * @returns + */ + function setFirstLetterLowerCase(originalString: string) { + return originalString[0].toLowerCase() + originalString.slice(1); + } + + /** + * 生成新的变量 + * @returns + */ + function generateVariable(): VariableValue { + // 1、变量名的中间部分 + const splicingNameMiddle = newVariablePrefix.value ? setFirstLetterUpperCase(controlName.value) : + setFirstLetterLowerCase(controlName.value); + + // 2、变量名的右侧内容 + const splicingNameRight = setFirstLetterUpperCase(propertyName.value); + + // 3、拼接成新的变量名 + const newVariablePath = `${newVariablePrefix.value}${splicingNameMiddle}${splicingNameRight}`; + + const { guid } = useGuid(); + const newVariable: VariableValue = { + type: 'variable', + path: newVariablePath, + field: guid(), + fullPath: newVariablePath, + isNewVariable: true, + newVariableType: newVariableType.value + } + return newVariable; + } + + /** + * 根据变量路径获取变量 + * @param variablePath + * @returns + */ + function getVariableByPath(variablePath: string): VariableValue { + const existedVariable = variables.value.find(variable => variable.path === variablePath); + return existedVariable; + } + + /** 判断当前显示的变量是否已被删除,若被删除,则标红处理 */ + function ifHighlightBorder() { + } + + /** + * 获取状态机属性值 + * @returns + */ + function getVariableValue(): Ref { + // 1、如果存在属性值,则直接返回 + const propertyValue: Ref = getPropertyValue('variable'); + if (propertyValue.value) { + return propertyValue; + } + + // 2、如果属性值为空,则新建一个 + propertyValue.value = { + type: 'variable', + field: '', + path: '', + fullPath: '' + } + return propertyValue; + + } + + + return { generateVariable, getVariableByPath, getVariableValue }; +} diff --git a/packages/ui-vue/components/property-editor/src/property-editor.component.tsx b/packages/ui-vue/components/property-editor/src/property-editor.component.tsx index 1c974dd0159..efc8c7fe5b0 100644 --- a/packages/ui-vue/components/property-editor/src/property-editor.component.tsx +++ b/packages/ui-vue/components/property-editor/src/property-editor.component.tsx @@ -1,4 +1,3 @@ - /* eslint-disable no-use-before-define */ /** * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. @@ -15,628 +14,104 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { defineComponent, SetupContext, Ref, ref, onMounted, watch } from 'vue'; -import { PropertyEditorProps, propertyEditorProps } from './property-editor.props'; -import { cloneDeep } from 'lodash-es'; -import { option1, archiveOfPropertyValue, dropdownStatesInTotal } from './composition/data'; -import { FComboList } from '../../../components/combo-list'; -import { FInputGroup } from '../../../components/input-group'; -import { FNumberSpinner } from '../../../components/number-spinner'; -import { useInitializedValue } from './composition/use-initialized-value'; -import { useUpdate } from './composition/use-update-data'; +import { defineComponent, SetupContext, ref, computed } from 'vue'; +import { PropertyEditorProps, propertyEditorProps, PropertyType } from './property-editor.props'; +import { FComboList } from '@farris/ui-vue/components/combo-list'; +import getConstRender from './components/const/const-property.component'; +import getVariableRender from './components/variable/variable-property.component'; +import getStateMachineRender from './components/state-machine/state-machine-property.component'; +import getCustomRender from './components/custom/custom-property.component'; +import { usePropertyValue } from './composition/use-property-value'; +import { usePropertyType } from './composition/use-property-type'; import './property-editor.css'; export default defineComponent({ name: 'FPropertyEditor', props: propertyEditorProps, - emits: ['propertyEditorValueChanged'] as (string[] & ThisType) | undefined, + emits: ['valueChange'] as (string[] & ThisType) | undefined, setup(props: PropertyEditorProps, context: SetupContext) { - /** 初始传入值PropertyEditorOptions*/ - // props.importedOriginalData - const importedOriginalData: any = ref(option1); - - /** 表达式绑定值 */ - const searchText = ref(''); - - /** 左侧状态切换-当前状态 (const-常量;variable-变量;custom-自定义) */ - const currentState: any = ref('const'); - - /** 常量-enum类型-存储所有枚举值的数组 */ - const constEnumValueArray: any = ref([]); - - /** 变量-根据是否显示control名称,确认是否显示button */ - const showAddButton: Ref = ref(false); - - /** 变量-点击button-存储根据命名规则生成的变量名*/ - let newVariable: any; - - /** 变量-点击button-生成代码编辑器中的field部分 */ - const fieldContent: Ref = ref(''); - - /** 变量-点击button-记录上一次点击值 */ - const frontValue: Ref = ref(''); - - /** 变量-下拉框-用户点击增加按钮后的变量数组 */ - const displayArray: any = ref([]); - - // /** 变量-下拉框-绑定值 */ - // let bindVariableValue: any; - - /** 状态机-下拉框 */ - let bindStateMachineValue: any; - - /** 状态机-用户点击下拉框后的变量数组 */ - const displayArrayState = ref([]); - - /** 状态机-文字-是/否 */ - const exists: Ref = ref('是'); - - /** 自定义-string类型-input-用户输入内容绑定 */ - const currentValue: any = ref(''); - - /** 表达式-弹窗 */ - const showExpressionComponent: Ref = ref(false); - - /** 表达式-group */ - const groupIcon = ref(""); - - /** 只读属性 */ - const readOnly: Ref = ref(false); - - const dropdownStates: any = ref([]); - /** 初始化数据 */ - const { numberConstValue, bindVariableValue, dataStatesBindValue, dataStatesValueArray, constEnumBindValue, setValue } = useInitializedValue( - importedOriginalData, constEnumValueArray, - currentState, bindStateMachineValue, exists, - searchText, showExpressionComponent); - /** 更新数据 */ - const { updateData, changeState, prefix, propertyEditorValueChange } = useUpdate( - context, importedOriginalData, constEnumBindValue, constEnumValueArray, - archiveOfPropertyValue, displayArrayState, bindStateMachineValue, exists, - dataStatesValueArray, searchText, readOnly, currentState); - - /** 判断当前显示的变量是否已被删除,若被删除,则标红处理 */ - function ifHighlightBorder() { - // if (currentState.value.id === 'variable' && importedOriginalData.value.propertyValue.type === 'variable') { - // // 更新变量下拉列表 - // const getVariablesFunction = importedOriginalData.value.editorOptions.getVariables; - // if (getVariablesFunction) { - // displayArray.value = getVariablesFunction(); - // } - // if (document.getElementsByClassName('f-page-single-property-editor-component-right-variable')) { - // if (document.getElementsByClassName('f-page-single-property-editor-component-right-variable')[0]) { - // const html = document.getElementsByClassName('f-page-single-property-editor-component-right-variable')[0]; - // if (html.getElementsByClassName('input-group')) { - // if (html.getElementsByClassName('input-group')[0]) { - // const element = html.getElementsByClassName('input-group')[0]; - // // 查看是否该变量已被删除 - // const variableExist = displayArray.value.find(item => item.path === bindVariableValue); - // // if (!variableExist && (bindVariableValue !== '' && bindVariableValue !== undefined)) { - // // element.style?.setProperty('borderColor', 'red'); - // // } - // // else { - // // element.style?.setProperty('borderColor', '#D8DCE6'); - // // } - // } - // } - // } - // } - // } - } - - /** 判断初始支持的状态 */ - function generateDefaultState() { - dropdownStates.value = dropdownStatesInTotal.value.filter(item => - importedOriginalData.value.editorOptions.types.includes(item.id) - ); - } - - /** 属性编辑器左侧初始状态 */ - function setCurrentState() { - // 初始状态: find查询入参中存储的默认状态,与当前存储的3种状态:常量、变量、自定义进行比对; - currentState.value = cloneDeep(dropdownStates.value.find( - item => (item.id === importedOriginalData.value.propertyValue.type))); - } - /** - * 根据入参,判断属性编辑器初始状态,并存储入参到archiveOfPropertyValue的对应状态中 - */ - function defaultStateValue() { - setCurrentState(); - // 判断特例:variable传值为undefined,需设定好path等相关参数 - if (currentState.value.id === 'variable' && importedOriginalData.value.propertyValue.value === undefined) { - importedOriginalData.value.propertyValue = cloneDeep(archiveOfPropertyValue.value.variableValue); - } - // 存储初始值:将默认值存储到archive对应的constValue、variableValue、customValue - archiveOfPropertyValue.value[`${currentState.value.id}Value`] = cloneDeep(importedOriginalData.value.propertyValue); - // 配置各显示框中的值 - setValue(); - } - - /** - * 左侧区域类型转换后,同时切换右侧区域 - */ - function getSelectedState(selectedValue) { - // 确认左侧类型 - currentState.value = cloneDeep(dropdownStates.value.find((item: any) => item.label === selectedValue[0].label)); - // 切换为表达式状态后,显示对应的弹窗组件 - if (currentState.value.id === 'expression') { - if (archiveOfPropertyValue.value.expressionValue.value) { - searchText.value = archiveOfPropertyValue.value.expressionValue.value.value; - } - showExpressionComponent.value = true; - } - // 如果为自定义类型,进行subscribe - if (currentState.value.id === 'custom') { - // TODO 此处的频繁watch是有问题的 - customValueChange(); - } - updateData(); - ifHighlightBorder(); - } - - /** - * 常量-枚举-下拉框:用户切换绑定变量 - */ - function getSelectedFormState(value) { - // 此处value是数组中的key - constEnumBindValue.value = cloneDeep(value.value); - importedOriginalData.value.propertyValue.value = cloneDeep(value.value); - archiveOfPropertyValue.value.constValue.value = cloneDeep(value.value); - updateData(); - } - - /** - * 常量-数字变化 - */ - function numberConstValueChanged($event) { - archiveOfPropertyValue.value.constValue.value = $event; - updateData(); - } - - /** - * 常量-字符串-记录input值 - */ - function getConstInputValue(currentValue) { - archiveOfPropertyValue.value.constValue.value = currentValue; - updateData(); - } - - /** - * 变量-点击button-点击产生新的变量值; - */ - function generateVariables() { - // 根据新变量的命名规则,进行字符串拼接 - const setUpperCaseNameRight = importedOriginalData.value.propertyName; - // 首字母大写 - const splicingNameRight = setUpperCaseNameRight[0].toUpperCase() + setUpperCaseNameRight.substr(1); - const setUpperCaseNameMiddle = importedOriginalData.value.controlName; - // 根据前缀是否存在决定首字母是否小写 - const newVariablePrefix = importedOriginalData.value.editorOptions.newVariablePrefix || ''; - const splicingNameMiddle = newVariablePrefix ? setUpperCaseNameMiddle[0].toUpperCase() + setUpperCaseNameMiddle.substr(1) : - setUpperCaseNameMiddle[0].toLowerCase() + setUpperCaseNameMiddle.substr(1); - newVariable = `${newVariablePrefix}${splicingNameMiddle}${splicingNameRight}`; - saveVariablesChanges(); - ifHighlightBorder(); - } - - /** - * 变量-点击button-是否生成变量、绑定、生成展示数组、更新数据 - */ - function saveVariablesChanges() { - iterateVariableArray(); - if (currentState.value.id === 'variable') { - bindVariableValue.value = importedOriginalData.value.propertyValue.value.path; - } - generateCurrentVariableArray(); - // 当重复前一个绑定值时,不需要更新数据 - if (frontValue.value !== importedOriginalData.value.propertyValue.value.path) { - updateData(); - } - } - - /** - * 变量-点击按钮-遍历数组,确定是否生成新的变量 - */ - function iterateVariableArray() { - let count = 0; - importedOriginalData.value.editorOptions.variables?.forEach(item => { - // 如果遍历一遍后,没有与newVariable相同的值,则表明可以生成新的值; - if (item.path !== newVariable) { - count += 1; - } - else { - // 若遍历到相同的值,则记录这个值,并将这个值设定为当前绑定值 - frontValue.value = importedOriginalData.value.propertyValue.value.path; - importedOriginalData.value.propertyValue.value = cloneDeep(item); - archiveOfPropertyValue.value.variableValue.value = cloneDeep(item); - } - }); - // 如果编辑后所有的path都不与newVariable重复,则生成新变量; - generateNewVariable(count); - } - - /** - * 变量-点击按钮-遍历数组-生成新变量 - */ - function generateNewVariable(count: number) { - // 通过count与原值length的对比,判断是否编辑后所有的path都不与newVariable重复 - if (count === importedOriginalData.value.editorOptions.variables?.length) { - // 生成新变量值 - importedOriginalData.value.propertyValue.value.category = 'local'; - importedOriginalData.value.propertyValue.value.path = newVariable; - importedOriginalData.value.propertyValue.value.field = fieldContent; - importedOriginalData.value.propertyValue.value.fullPath = newVariable; - importedOriginalData.value.propertyValue.value.newVariableType = importedOriginalData.value.editorOptions.newVariableType; - propertyEditorValueChange.value.isNewVariable = true; - // 将新的变量放入变量数组 - importedOriginalData.value.editorOptions.variables.push(cloneDeep(importedOriginalData.value.propertyValue.value)); - archiveOfPropertyValue.value.variableValue.value = cloneDeep(importedOriginalData.value.propertyValue.value); - } - } + const readOnly = ref(false); + + /** 左侧-属性类型相关方法 */ + const { getAllowedPropertyTypeItems, getCurrentPropertyType } = usePropertyType(props, context); + /** 允许选择的属性类型 */ + const allowedPropertyTypeItems = getAllowedPropertyTypeItems(); + /** 当前选择的属性类型 */ + const currentPropertyType = getCurrentPropertyType(); + + /** 右侧-属性值相关方法 */ + const usePropertyValueComposition = usePropertyValue(props, context, currentPropertyType.value); + const { getPropertyValue, triggerValueChange } = usePropertyValueComposition; + /** 渲染右侧内容 */ + const renderConst = getConstRender(props, context, usePropertyValueComposition); + const renderVariable = getVariableRender(props, context, usePropertyValueComposition); + const renderCustom = getCustomRender(props, context, usePropertyValueComposition); + const renderStateMachine = getStateMachineRender(props, context, usePropertyValueComposition); + /** 控制右侧区域显示 */ + const shouldShowRight = computed(() => (selectedPropertyType: PropertyType) => { + return selectedPropertyType === currentPropertyType.value; + }); /** - * 变量-下拉框-点击下拉框中的值-改变当前绑定的变量值 + * 左侧属性类型变化 */ - function changeSelectVariable(value) { - if (!value || !value.selections || value.selections.length < 1) { - return; - } - archiveOfPropertyValue.value.variableValue.value.category = cloneDeep(value.selections[0].category); - archiveOfPropertyValue.value.variableValue.value.path = cloneDeep(value.selections[0].path); - archiveOfPropertyValue.value.variableValue.value.fullPath = cloneDeep(value.selections[0].fullPath); - archiveOfPropertyValue.value.variableValue.value.field = cloneDeep(value.selections[0].field); - bindVariableValue.value = cloneDeep(value.value); - updateData(); - ifHighlightBorder(); - } + function onPropertyTypeChange() { + // 1、获取当前属性值 + const propertyValue = getPropertyValue(currentPropertyType.value); - /** 变量-清空当前值 */ - function clearVariable() { - importedOriginalData.value.propertyValue.value.category = ''; - importedOriginalData.value.propertyValue.value.path = ''; - importedOriginalData.value.propertyValue.value.field = ''; - importedOriginalData.value.propertyValue.value.fullPath = ''; - if (currentState.value.id === 'variable') { - bindVariableValue.value = importedOriginalData.value.propertyValue.value.path; + // 2、如果属性值不为空,触发属性值变更 + if (propertyValue.value) { + triggerValueChange(propertyValue.value); } - updateData(); - ifHighlightBorder(); - } - - /** - * 变量-生成当前的变量数组 - */ - function generateCurrentVariableArray() { - displayArray.value = cloneDeep(importedOriginalData.value.editorOptions.variables); } /** - * 变量-显示变量下拉框前回调 + * 渲染左侧属性类型下拉列表 */ - const beforeShowVariable = (instance: any) => { - const getVariablesFunction = importedOriginalData.value.editorOptions.getVariables; - const result: any = { - showDialog: true - }; - if (getVariablesFunction) { - displayArray.value = getVariablesFunction(); - if (instance) { - instance.data = displayArray; - } - ifHighlightBorder(); - } - return Promise.resolve(true); - }; - - /** 状态机-点击下拉框中的值-改变当前绑定的状态机的值 */ - function changeSelectStateMachine(value) { - const middleArray = { - id: value[0].id, - name: value[0].exist, - exist: value[0].name - }; - archiveOfPropertyValue.value.stateMachineValue.value = cloneDeep(middleArray); - exists.value = importedOriginalData.value.propertyValue.value.exist === '是' ? '是' : '否'; - bindStateMachineValue = cloneDeep(middleArray.id); - updateData(); - } - - /** 状态机-生成当前的状态机数组 */ - function generateCurrentStatesArray() { - displayArrayState.value = cloneDeep(importedOriginalData.value.editorOptions.stateMachine); - exists.value = archiveOfPropertyValue.value.stateMachineValue.value.exist === '是' ? '是' : '否'; - } - - /** - * 自定义-检测自定义值变换并将结果传出 - */ - const textChangeSubject = ref(); - function customValueChange() { - watch(textChangeSubject, (newValue) => { - archiveOfPropertyValue.value.customValue.value = newValue; - updateData(); - }); - } - function getCustomizeValue(changeValue) { - textChangeSubject.value = changeValue; - } - - /** 表达式-弹窗 */ - function showExpression() { - // 修改中 - } - - /** 数据状态-用户切换绑定变量 */ - function getSelectedDataStates(value) { - importedOriginalData.value.propertyValue.value = cloneDeep(value); - archiveOfPropertyValue.value.dataStatesValue.value = cloneDeep(value); - const result = value.map(element => element.valueField).join(','); - dataStatesBindValue.value = cloneDeep(result); - updateData(); - } - - /** 变量 */ - function returnVariableStructure() { + function renderLeftContent() { return ( -
- {/* 如果此组件没有对应的变量名,则展示按钮,双击可添加新变量 */} +
changeSelectVariable(e)} - onClear={clearVariable} - > - - {/* comboList新增模板 */} - {/* < itemTemp let-item let-idx='index'> - - {displayArray.value[idx].fullPath} - */} - {/* 如果此组件有对应的变量名,则展示dropdown组件,可以绑定全局变量及本模块对应变量 */} - {showAddButton.value ? (
- -
) : ''} -
- ); - } - /** 自定义 */ - function returnCustomStructure() { - return ( -
- getCustomizeValue((e.target as HTMLInputElement).value)} - disabled={readOnly.value} > -
- ); - } - /** 表达式 */ - function returnExpressionStructure() { - return ( -
- -
- ); - } - /** 状态机 */ - function returnStateMachineStructure() { - return ( -
- {/* 显示文字 */} -
- {exists.value} -
-
- { changeSelectStateMachine(e); }} - > - - {/* - {{ displayArrayState[idx].name }} - */} -
-
- ); - } - /** 数据状态 */ - function returnDataStatesStructure() { - return ( -
- getSelectedDataStates(e)} - > - -
- ); - } - /** 常量-自定义类型 */ - function returnStringConstStructure() { - return ( - { getConstInputValue(e); }} - disabled={readOnly.value} - placeholder={'输入自定义内容'} - > - ); - } - /** 常量-枚举类型 */ - function returnEnumConstStructure() { - return ( - getSelectedFormState(e)} - > - - ); - } - /** 常量-数字类型 */ - function returnNumberConstStructure() { - return ( - { numberConstValueChanged(value); }} - class='f-page-single-property-editor-component-const-number' > - - ); - } - /** 左侧选择区域:常量、变量、自定义、表达式 */ - function returnLeftController() { - return ( -
- getSelectedState(e)} + onChange={onPropertyTypeChange} >
); } - /** 右侧区域组件 */ - function returnRightController() { + + + /** + * 渲染右侧属性值区域 + */ + function renderRightContent() { + /** 右侧区域渲染方法 */ return ( -
- {/* 对应常量部分 */} - {currentState.value.id === 'const' ? ( -
- {/* 常量-string类型 */} - {importedOriginalData.value.propertyType === 'string' ? returnStringConstStructure() : ''} - {/* 常量-枚举类型 */} - {importedOriginalData.value.propertyType === 'enum' ? returnEnumConstStructure() : ''} - {/* 常量-number类型 */} - {importedOriginalData.value.propertyType === 'number' ? returnNumberConstStructure() : ''} -
- ) : ''} - {/* 对应变量部分 */} - {currentState.value.id === 'variable' ? returnVariableStructure() : ''} - {/* 对应自定义部分 */} - {currentState.value.id === 'custom' ? returnCustomStructure() : ''} - {/* 对应表达式部分 */} - {(currentState.value.id === 'expression' && showExpressionComponent.value) ? returnExpressionStructure() : ''} - {/* 对应状态机部分 */} - {currentState.value.id === 'stateMachine' ? returnStateMachineStructure() : ''} - {/* 对应数据状态部分 */} - {currentState.value.id === 'dataStates' ? returnDataStatesStructure() : ''} +
+ {shouldShowRight.value('const') && renderConst()} + {shouldShowRight.value('variable') && renderVariable()} + {shouldShowRight.value('custom') && renderCustom()} + {shouldShowRight.value('stateMachine') && renderStateMachine()} +
); } - onMounted(() => { - // 如果为只读属性 - // if (isReadonly.value[0] === true) { - // readOnly.value = true; - // showAddButton.value = false; - // } else { - // readOnly.value = false; - // showAddButton.value = true; - // } - // 判断初始支持的状态 - generateDefaultState(); - defaultStateValue(); - generateCurrentVariableArray(); - generateCurrentStatesArray(); - - if (importedOriginalData.value.hasPrefix && importedOriginalData.value.hasPrefix === 2) { - prefix.value = true; - } - if (importedOriginalData.value.controlName !== undefined) { - showAddButton.value = true; - } - }); - - // watch(currentState.value, () => { - // 如果为只读属性 - // if (changes['isReadonly']) { - // if (changes['isReadonly']['currentValue'][0] === true) { - // readOnly = true; - // showAddButton = false; - // } - // else { - // readOnly = false; - // showAddButton = true; - // } - // } - // if (importedOriginalData.value.currentValue.propertyValue && (searchText.value === null || searchText.value.length === 0)) { - // generateDefaultState(); - // defaultStateValue(); - // } - // }); - return () => { return ( - <> -
- {returnLeftController()} - {returnRightController()} -
- +
+ {renderLeftContent()} + {/* 确认好的属性类型后,再显示右侧属性值区域 */} + {renderRightContent()} +
); }; } diff --git a/packages/ui-vue/components/property-editor/src/property-editor.css b/packages/ui-vue/components/property-editor/src/property-editor.css index 4ad46fa988c..cd5079843e5 100644 --- a/packages/ui-vue/components/property-editor/src/property-editor.css +++ b/packages/ui-vue/components/property-editor/src/property-editor.css @@ -1,181 +1,13 @@ -.f-page-single-property-editor-component { +.f-property-editor-container { min-width: 230px; } -.f-page-single-property-editor-component-tag { - display: 1; - font-family: PingFangSC-Regular; - font-size: 13px; - color: rgba(0, 0, 0, 0.50); - letter-spacing: 0; - line-height: 16px; - margin-left: 5%; - margin-top: 2.5%; - margin-bottom: 2.5%; -} - -.f-page-single-property-editor-component-left-controller { - float: left; - /* background: #FFFFFF; */ - height: 28px; - width: 32%; -} - -.f-page-single-property-editor-component-right-const { - float: left; - width: 65%; - margin-left: 3%; - background: #FFFFFF; -} - -.f-page-single-property-editor-component-right-variable { - float: left; - width: 65%; - margin-left: 3%; - /* background: #FFFFFF; */ -} - -.f-page-single-property-editor-template { - width: 100%; - height: 25px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - line-height: 25px; -} - -.form-control-select-1 { - height: 26px; - margin: 0px !important; - width: 100%; - border: 1px solid #D8DCE6; - border-radius: 3px; - border-color: #D8DCE6; -} - -.form-control-select-show { - height: 28px; - margin: 0px !important; - width: 80%; - float: left; - /* border: 1px solid #EEEFF2; - border-radius: 2px; */ -} - -.form-control-select-hide { - height: 28px; - margin: 0px !important; - width: 100%; - float: left; - /* border: 1px solid #EEEFF2; - border-radius: 2px; */ -} - -.selectForm-dropdown { - height: 26px; - width: 100%; - border: 1px solid #D8DCE6; - border-radius: 3px; - border-color: #D8DCE6; -} - -.f-page-single-property-editor-component-variable-button { - margin-left: 2%; - float: left; -} - -.dropdown-all-variables { - display: inline-block; - margin-left: 10px; +.f-property-editor-right { height: 28px; } -.f-page-single-property-editor-component-right-customize { - width: 65%; +.f-property-editor-left { float: left; - margin-left: 3%; - background: #FFFFFF; -} - -.f-page-single-property-editor-component-right-expression { - width: 65%; - float: left; - margin-left: 3%; - /* background: #FFFFFF; */ -} - -.f-page-single-property-editor-component-right-stateMachine { - width: 65%; - float: left; - margin-left: 3%; - background: #FFFFFF; - border: 1px solid #D8DCE6; - height: 26px; - border-radius: 3px; -} - -.f-page-single-property-editor-component-right-dataStates { - float: left; - width: 65%; - margin-left: 3%; - background: #FFFFFF; -} - -.f-page-single-property-editor-component-right-stateMachine:focus { - box-shadow: blue; -} - -:host ::ng-deep div.f-stateMachine-combo>farris-combo-list .input-group { - border: 0; - box-shadow: none !important; -} - -:host ::ng-deep div.f-stateMachine-combo>farris-combo-list input-group.actived .input-group { - box-shadow: none !important; -} - -:host ::ng-deep div.f-stateMachine-combo>farris-combo-list .f-cmp-inputgroup.actived { - box-shadow: none !important; -} - -.f-stateMachine-exist { - float: left; - width: 28px; - text-align: center; - background: #FFFFFF; - height: 20px; - margin-top: 2px; - margin-left: 5px; - padding-top: 1px; - background-color: #f4f6ff; - font-size: 13px; - font-family: PingFangSC-Regular; - color: #34495E; -} - -.f-stateMachine-combo { - float: right; - width: 75%; - background: #FFFFFF; -} - -.f-stateMachine-combo .input-group{ - border: unset; - box-shadow: none; -} - -.f-customize-input-controller { height: 28px; - width: 100%; - border: 1px solid #EEEFF2; - border-radius: 2px; -} - -.f-variable-button{ - width: calc(2px + .375rem + 1.4286em); - height: calc(2px + .375rem + 1.4286em); - padding: .1875rem; - border-color: transparent !important; - box-shadow: none !important; - background-color:#f0f0f0; -} + width: 32%; +} \ No newline at end of file diff --git a/packages/ui-vue/components/property-editor/src/property-editor.props.ts b/packages/ui-vue/components/property-editor/src/property-editor.props.ts index 10b62a8d0fb..1ea95c137a3 100644 --- a/packages/ui-vue/components/property-editor/src/property-editor.props.ts +++ b/packages/ui-vue/components/property-editor/src/property-editor.props.ts @@ -1,4 +1,4 @@ - + /** * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. * @@ -14,14 +14,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ExtractPropTypes, PropType } from 'vue'; +import { ExtractPropTypes } from 'vue'; import { createPropsResolver } from '../../dynamic-resolver/src/props-resolver'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; import propertyEditorSchema from './schema/property-editor.schema.json'; import propertyConfig from './property-config/property-editor.property-config.json'; +import { constPropertyProps } from './components/const/const-property.props'; +import { variablePropertyProps } from './components/variable/variable-property.props'; +import { stateMachinePropertyProps } from './components/state-machine/state-machine-property.props'; +import { customPropertyProps } from './components/custom/custom-property.props'; + +export type PropertyType = 'const' | 'variable' | 'custom' | 'stateMachine' | 'expression'; export const propertyEditorProps = { + ...constPropertyProps, + ...variablePropertyProps, + ...customPropertyProps, + ...stateMachinePropertyProps, + id: { Type: String, default: '' }, + + modelValue: { type: [Number, String, Boolean, Object] }, + /** 属性类型列表 */ + propertyTypes: { type: Array, default: [] }, } as Record; diff --git a/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json b/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json index 31c62155510..0c2cfb59360 100644 --- a/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json +++ b/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json @@ -65,7 +65,40 @@ "description": "", "type": "boolean", "default": true + }, + "propertyTypes": { + "description": "", + "type": "Array", + "default": [] + }, + "constEnums": { + "description": "", + "type": "Array", + "default": [] + }, + "constType": { + "description": "", + "type": "String", + "default": "string" + }, + "variables": { + "description": "", + "type": "Array", + "default": [] + }, + "controlName": { + "description": "", + "type": "string", + "default": "" + }, + "stateMachines": { + "description": "", + "type": "Array", + "default": [] } + + + }, "required": [ "id", diff --git a/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts b/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts index 0b41f267c85..d419e51a4a4 100644 --- a/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts +++ b/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts @@ -313,11 +313,17 @@ export class InputBaseProperty extends BaseControlProperty { readonly: { description: "", title: "只读", - type: "boolean", editor: { - enableClear: true, - editable: true - } + type: "property-editor", + propertyTypes: ['const', 'variable', 'custom', 'stateMachine'], + constType: 'enum', + constEnums: [{ id: true, name: '是' }, { id: false, name: '否' }], + controlName:'', + variables: [ + ], + stateMachines: [ + ] + } }, disabled: { description: "", -- Gitee From 67ce62ab9958e57cf9dbfccaa075b8ed3d39202b Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Mon, 17 Mar 2025 21:20:39 +0800 Subject: [PATCH 078/287] =?UTF-8?q?chore:=20property-editor=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../variable/variable-property.component.tsx | 24 ++++++------------- .../property-editor/src/composition/type.ts | 4 ++-- .../src/composition/use-state-machine.ts | 4 ++-- .../src/composition/use-variable.ts | 4 ++-- .../src/schema/property-editor.schema.json | 13 +++++++--- .../composition/entity/input-base-property.ts | 5 +++- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/packages/ui-vue/components/property-editor/src/components/variable/variable-property.component.tsx b/packages/ui-vue/components/property-editor/src/components/variable/variable-property.component.tsx index ef114433813..6935e43b049 100644 --- a/packages/ui-vue/components/property-editor/src/components/variable/variable-property.component.tsx +++ b/packages/ui-vue/components/property-editor/src/components/variable/variable-property.component.tsx @@ -50,10 +50,10 @@ export default function ( /** * 设置变量属性值 */ - function setVariableValue(variable: VariableValue, isTriggerChange: boolean) { + function setVariableValue(variable: VariableValue) { Object.assign(propertyValue.value, variable); currentVariableId.value = propertyValue.value.field; - isTriggerChange && triggerValueChange(propertyValue.value); + triggerValueChange(propertyValue.value); } /** @@ -68,10 +68,10 @@ export default function ( // 3、如果变量已经存在,则使用已有变量,否则使用新增变量 if (existedVariable) { - setVariableValue(existedVariable, true); + setVariableValue(existedVariable); } else { variables.value.push(newVariable); - setVariableValue(newVariable, true); + setVariableValue(newVariable); } } @@ -95,18 +95,9 @@ export default function ( path: variableItem.path, fullPath: variableItem.fullPath, field: variableItem.field, - type: "variable" + type: "Variable" } - setVariableValue(newVariable, true); - } - - /** - * 清空变量值 - */ - function clearVariable() { - const emptyVariable: VariableValue = { type: 'variable', path: '', field: '', fullPath: '' }; - // 清空变量后,属性值不完整,不需要触发变更 - setVariableValue(emptyVariable, false); + setVariableValue(newVariable); } /** @@ -121,7 +112,7 @@ export default function ( v-model={currentVariableId.value} placeholder={''} viewType={'text'} - enableClear={true} + enableClear={false} valueField='field' textField='fullPath' data={variables.value} @@ -129,7 +120,6 @@ export default function ( readonly={readOnly.value} editable={false} onChange={onComboListValueChange} - onClear={clearVariable} > ); diff --git a/packages/ui-vue/components/property-editor/src/composition/type.ts b/packages/ui-vue/components/property-editor/src/composition/type.ts index fcaaf87689a..4446c344c4f 100644 --- a/packages/ui-vue/components/property-editor/src/composition/type.ts +++ b/packages/ui-vue/components/property-editor/src/composition/type.ts @@ -25,7 +25,7 @@ export interface ConstEnumItem { * 变量属性值 */ export interface VariableValue { - type: 'variable'; + type: 'Variable'; /** 变量唯一标识 */ field: string; /** 变量绑定路径 */ @@ -54,7 +54,7 @@ export interface VariableItem { * 状态机属性值 */ export interface StateMachineValue { - type: 'stateMachine'; + type: 'StateMachine'; /** 状态机标识 */ field: string; /** 状态机前缀状态 */ diff --git a/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts b/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts index 8dc2fe63822..0ca78fe0e75 100644 --- a/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts +++ b/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts @@ -30,7 +30,7 @@ export function useStateMachine( // 3、转化为新的格式 const newStateMachineFormat: StateMachineValue = { - type: 'stateMachine', + type: 'StateMachine', status: matchResult[1], field: matchResult[2] } @@ -52,7 +52,7 @@ export function useStateMachine( } // 2、如果属性值为空,则新建一个 propertyValue.value = { - type: 'stateMachine', + type: 'StateMachine', field: '', status: false } diff --git a/packages/ui-vue/components/property-editor/src/composition/use-variable.ts b/packages/ui-vue/components/property-editor/src/composition/use-variable.ts index 6903c7d8753..abc63ef301f 100644 --- a/packages/ui-vue/components/property-editor/src/composition/use-variable.ts +++ b/packages/ui-vue/components/property-editor/src/composition/use-variable.ts @@ -54,7 +54,7 @@ export function useVariable( const { guid } = useGuid(); const newVariable: VariableValue = { - type: 'variable', + type: 'Variable', path: newVariablePath, field: guid(), fullPath: newVariablePath, @@ -91,7 +91,7 @@ export function useVariable( // 2、如果属性值为空,则新建一个 propertyValue.value = { - type: 'variable', + type: 'Variable', field: '', path: '', fullPath: '' diff --git a/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json b/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json index 0c2cfb59360..050567b93d9 100644 --- a/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json +++ b/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json @@ -91,14 +91,21 @@ "type": "string", "default": "" }, + "newVariablePrefix": { + "description": "", + "type": "string", + "default": "" + }, + "newVariableType": { + "description": "", + "type": "string", + "default": "" + }, "stateMachines": { "description": "", "type": "Array", "default": [] } - - - }, "required": [ "id", diff --git a/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts b/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts index a4c0f47ef3f..435e68207ff 100644 --- a/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts +++ b/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts @@ -308,6 +308,7 @@ export class InputBaseProperty extends BaseControlProperty { type: "input-group", $converter: "/converter/property-editor.converter" }, info); + const controlName = propertyData.type && propertyData.type.toLowerCase().replace(/-/g, '_'); const editorProperties = { readonly: { @@ -318,7 +319,9 @@ export class InputBaseProperty extends BaseControlProperty { propertyTypes: ['const', 'variable', 'custom', 'stateMachine'], constType: 'enum', constEnums: [{ id: true, name: '是' }, { id: false, name: '否' }], - controlName:'', + controlName:controlName, + newVariablePrefix:'is', + newVariableType:'Boolean', variables: [ ], stateMachines: [ -- Gitee From 24d1a9091b4a6db5153fde43400c35b6898e8665 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Mon, 17 Mar 2025 21:26:16 +0800 Subject: [PATCH 079/287] =?UTF-8?q?chore:=20property-editor=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../property-editor/src/schema/property-editor.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json b/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json index 050567b93d9..0afe10b9003 100644 --- a/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json +++ b/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json @@ -79,7 +79,7 @@ "constType": { "description": "", "type": "String", - "default": "string" + "default": "" }, "variables": { "description": "", -- Gitee From 9421ce8571242d6b3aa4e9844d6517f160a6bfcf Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Mon, 17 Mar 2025 22:19:43 +0800 Subject: [PATCH 080/287] =?UTF-8?q?chore:=20property-editor=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/const/const-property.component.tsx | 2 +- .../components/custom/custom-property.component.tsx | 2 +- .../property-editor/src/composition/data.ts | 10 +++++----- .../src/composition/use-property-type.ts | 12 ++++++------ .../src/composition/use-state-machine.ts | 2 +- .../property-editor/src/composition/use-variable.ts | 2 +- .../src/property-editor.component.tsx | 8 ++++---- .../property-editor/src/property-editor.props.ts | 2 +- .../src/composition/entity/input-base-property.ts | 2 +- 9 files changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/ui-vue/components/property-editor/src/components/const/const-property.component.tsx b/packages/ui-vue/components/property-editor/src/components/const/const-property.component.tsx index f224c83079f..d2c3f2d2d59 100644 --- a/packages/ui-vue/components/property-editor/src/components/const/const-property.component.tsx +++ b/packages/ui-vue/components/property-editor/src/components/const/const-property.component.tsx @@ -34,7 +34,7 @@ export default function ( /** 属性值相关方法 */ const { getPropertyValue, triggerValueChange } = usePropertyValueComposition; - const propertyValue = getPropertyValue('const'); + const propertyValue = getPropertyValue('Const'); /** 控制右侧区域显示的内容 */ const shouldShowContent = computed(() => (type: string) => { diff --git a/packages/ui-vue/components/property-editor/src/components/custom/custom-property.component.tsx b/packages/ui-vue/components/property-editor/src/components/custom/custom-property.component.tsx index a9f1f38873e..bbf98dfa192 100644 --- a/packages/ui-vue/components/property-editor/src/components/custom/custom-property.component.tsx +++ b/packages/ui-vue/components/property-editor/src/components/custom/custom-property.component.tsx @@ -28,7 +28,7 @@ export default function ( const readOnly: Ref = ref(false); /** 属性值相关方法 */ const { getPropertyValue, triggerValueChange } = usePropertyValueComposition; - const propertyValue: Ref = getPropertyValue('custom'); + const propertyValue: Ref = getPropertyValue('Custom'); /** * 文本控件值变化事件 diff --git a/packages/ui-vue/components/property-editor/src/composition/data.ts b/packages/ui-vue/components/property-editor/src/composition/data.ts index 04f8fcfaef7..75bc3ad7c19 100644 --- a/packages/ui-vue/components/property-editor/src/composition/data.ts +++ b/packages/ui-vue/components/property-editor/src/composition/data.ts @@ -3,23 +3,23 @@ import { PropertyTypeItem } from './type'; /** 左侧属性类型的枚举数据 */ export const PROPERTY_TYPE_ENUMS: PropertyTypeItem[] = [ { - 'id': 'const', + 'id': 'Const', 'name': '常量' }, { - 'id': 'variable', + 'id': 'Variable', 'name': '变量' }, { - 'id': 'custom', + 'id': 'Custom', 'name': '自定义' }, { - 'id': 'stateMachine', + 'id': 'StateMachine', 'name': '状态机' }, { - 'id': 'expression', + 'id': 'Expression', 'name': '表达式' } ]; diff --git a/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts b/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts index b58aae05116..b7d942d0dc2 100644 --- a/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts +++ b/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts @@ -53,11 +53,11 @@ export function usePropertyType( const allowedPropertyTypes = propertyTypes.value; // 1、常量枚举类型 - const isConstEnum = allowedPropertyTypes.includes('const') && constType.value === 'enum' + const isConstEnum = allowedPropertyTypes.includes('Const') && constType.value === 'enum' && constEnums.value.findIndex(constEnum => constEnum.id === propertyValue) > -1; // 2、常量数值类型 - const isConstNumber = allowedPropertyTypes.includes('const') && constType.value === 'number' + const isConstNumber = allowedPropertyTypes.includes('Const') && constType.value === 'number' && typeof propertyValue === "number"; return isConstEnum || isConstNumber; @@ -72,7 +72,7 @@ export function usePropertyType( function isCustom(propertyValue: any): boolean { const allowedPropertyTypes = propertyTypes.value; - const isCustom = allowedPropertyTypes.includes("custom") && typeof (propertyValue) === 'string'; + const isCustom = allowedPropertyTypes.includes("Custom") && typeof (propertyValue) === 'string'; return isCustom; } @@ -97,9 +97,9 @@ export function usePropertyType( function extractFromNonObjectType(propertyValue: any): PropertyType | undefined { // 1、定义属性类型检查器 const typeCheckers = new Map boolean>([ - ['const', isConst], - ['stateMachine', isStateMachine], - ['custom', isCustom], + ['Const', isConst], + ['StateMachine', isStateMachine], + ['Custom', isCustom], ]); // 2、遍历检查器,找到匹配的类型 diff --git a/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts b/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts index 0ca78fe0e75..9e5e8bafb7e 100644 --- a/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts +++ b/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts @@ -45,7 +45,7 @@ export function useStateMachine( */ function getStateMachineValue() { // 1、如果存在属性值,则直接返回 - const propertyValue: Ref = getPropertyValue('stateMachine'); + const propertyValue: Ref = getPropertyValue('StateMachine'); if (propertyValue.value) { convertStateMachineFormat(propertyValue); return propertyValue; diff --git a/packages/ui-vue/components/property-editor/src/composition/use-variable.ts b/packages/ui-vue/components/property-editor/src/composition/use-variable.ts index abc63ef301f..84cab70df8d 100644 --- a/packages/ui-vue/components/property-editor/src/composition/use-variable.ts +++ b/packages/ui-vue/components/property-editor/src/composition/use-variable.ts @@ -84,7 +84,7 @@ export function useVariable( */ function getVariableValue(): Ref { // 1、如果存在属性值,则直接返回 - const propertyValue: Ref = getPropertyValue('variable'); + const propertyValue: Ref = getPropertyValue('Variable'); if (propertyValue.value) { return propertyValue; } diff --git a/packages/ui-vue/components/property-editor/src/property-editor.component.tsx b/packages/ui-vue/components/property-editor/src/property-editor.component.tsx index efc8c7fe5b0..2c7cf82820d 100644 --- a/packages/ui-vue/components/property-editor/src/property-editor.component.tsx +++ b/packages/ui-vue/components/property-editor/src/property-editor.component.tsx @@ -96,10 +96,10 @@ export default defineComponent({ /** 右侧区域渲染方法 */ return (
- {shouldShowRight.value('const') && renderConst()} - {shouldShowRight.value('variable') && renderVariable()} - {shouldShowRight.value('custom') && renderCustom()} - {shouldShowRight.value('stateMachine') && renderStateMachine()} + {shouldShowRight.value('Const') && renderConst()} + {shouldShowRight.value('Variable') && renderVariable()} + {shouldShowRight.value('Custom') && renderCustom()} + {shouldShowRight.value('StateMachine') && renderStateMachine()}
); diff --git a/packages/ui-vue/components/property-editor/src/property-editor.props.ts b/packages/ui-vue/components/property-editor/src/property-editor.props.ts index 1ea95c137a3..31647b12c95 100644 --- a/packages/ui-vue/components/property-editor/src/property-editor.props.ts +++ b/packages/ui-vue/components/property-editor/src/property-editor.props.ts @@ -25,7 +25,7 @@ import { variablePropertyProps } from './components/variable/variable-property.p import { stateMachinePropertyProps } from './components/state-machine/state-machine-property.props'; import { customPropertyProps } from './components/custom/custom-property.props'; -export type PropertyType = 'const' | 'variable' | 'custom' | 'stateMachine' | 'expression'; +export type PropertyType = 'Const' | 'Variable' | 'Custom' | 'StateMachine' | 'Expression'; export const propertyEditorProps = { ...constPropertyProps, diff --git a/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts b/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts index 435e68207ff..cabb2e63e6e 100644 --- a/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts +++ b/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts @@ -316,7 +316,7 @@ export class InputBaseProperty extends BaseControlProperty { title: "只读", editor: { type: "property-editor", - propertyTypes: ['const', 'variable', 'custom', 'stateMachine'], + propertyTypes: ['Const', 'Variable', 'Custom', 'StateMachine'], constType: 'enum', constEnums: [{ id: true, name: '是' }, { id: false, name: '否' }], controlName:controlName, -- Gitee From 067435ef0e997808681a7c9105160bede32a014a Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Tue, 18 Mar 2025 11:28:01 +0800 Subject: [PATCH 081/287] =?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 082/287] =?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 083/287] =?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 084/287] =?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 085/287] =?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 086/287] =?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 087/287] =?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 088/287] =?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 089/287] =?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 ae0e96d45c86edd2e801aa9e154292b6e838a685 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Wed, 19 Mar 2025 09:23:49 +0800 Subject: [PATCH 090/287] =?UTF-8?q?chore:=20=E6=8F=90=E4=BE=9B=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E8=A1=A8=E5=8D=95=E5=86=85=E5=8F=98=E9=87=8F=E7=9A=84?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/composition/use-form-schema.ts | 21 ++++- .../designer/src/components/types/metadata.ts | 2 + .../const/const-property.component.tsx | 2 +- .../components/const/const-property.props.ts | 2 +- .../custom/custom-property.component.tsx | 2 +- .../expression-property.component.tsx | 77 +++++++++++++++++++ .../expression/expression-property.css | 5 ++ .../expression/expression-property.props.ts | 23 ++++++ .../state-machine-property.component.tsx | 2 +- .../state-machine-property.props.ts | 2 +- .../variable/variable-property.component.tsx | 11 ++- .../variable/variable-property.props.ts | 2 +- .../src/composition/{data.ts => datas.ts} | 2 +- .../src/composition/{type.ts => types.ts} | 5 ++ .../src/composition/use-property-editor.ts | 66 ++++++++++++++++ .../src/composition/use-property-type.ts | 4 +- .../src/composition/use-property-value.ts | 2 +- .../src/composition/use-state-machine.ts | 2 +- .../src/composition/use-variable.ts | 14 +++- .../src/property-editor.component.tsx | 4 +- .../src/schema/property-editor.schema.json | 4 +- .../src/composition/entity/base-property.ts | 50 ++++++++++-- .../composition/entity/input-base-property.ts | 20 +++-- 23 files changed, 294 insertions(+), 30 deletions(-) create mode 100644 packages/ui-vue/components/property-editor/src/components/expression/expression-property.component.tsx create mode 100644 packages/ui-vue/components/property-editor/src/components/expression/expression-property.css create mode 100644 packages/ui-vue/components/property-editor/src/components/expression/expression-property.props.ts rename packages/ui-vue/components/property-editor/src/composition/{data.ts => datas.ts} (90%) rename packages/ui-vue/components/property-editor/src/composition/{type.ts => types.ts} (93%) create mode 100644 packages/ui-vue/components/property-editor/src/composition/use-property-editor.ts diff --git a/packages/designer/src/components/composition/use-form-schema.ts b/packages/designer/src/components/composition/use-form-schema.ts index 0986e1b165e..a5f46eba53c 100644 --- a/packages/designer/src/components/composition/use-form-schema.ts +++ b/packages/designer/src/components/composition/use-form-schema.ts @@ -739,6 +739,23 @@ export function useFormSchema(): UseFormSchema { } } } + + /** + * 根据编号获取变量 + */ + function getVariableByCode(variableCode: string): FormVariable | undefined { + const viewModels = formSchema.module.viewmodels; + if (!viewModels || viewModels.length === 0) { + return; + } + for (const viewModel of viewModels) { + const variable = viewModel.states.find(stateItem => stateItem.code === variableCode); + if (variable) { + return variable; + } + } + } + /** * 获取所有VM下的变量,组装成树结构 * 树表中额外增加statePath属性(命令所在viewModelId.variableCode),用于窗口展开时数据行的回显。 @@ -1302,6 +1319,8 @@ export function useFormSchema(): UseFormSchema { deleteComponent, getControlsInCmpWidthBinding, getVariableById, - updateRemoteVariables + getVariableByCode, + updateRemoteVariables, + getRootViewModelId }; } diff --git a/packages/designer/src/components/types/metadata.ts b/packages/designer/src/components/types/metadata.ts index 6715f37ae3d..32703509242 100644 --- a/packages/designer/src/components/types/metadata.ts +++ b/packages/designer/src/components/types/metadata.ts @@ -218,6 +218,7 @@ export interface UseFormSchema { setFormTemplateRule: (rules: any) => void; getFormTemplateRule: () => any; getLocaleVariablesByViewModelId: (viewModelId: string) => any; + getRootViewModelId: () => string; getRemoteVariables: () => any; getFieldsByViewModelId: (viewModelId: string) => FormSchemaEntityField[] | undefined; getExpressions: () => FormExpression[]; @@ -225,6 +226,7 @@ export interface UseFormSchema { deleteComponent: (componentId: string) => void; getControlsInCmpWidthBinding: (viewModelId: string, fieldId: string) => any; getVariableById: (variableId: string) => FormVariable | undefined; + getVariableByCode: (variableCode: string) => FormVariable | undefined; updateRemoteVariables: (variables: FormSchemaEntityField[]) => void; } diff --git a/packages/ui-vue/components/property-editor/src/components/const/const-property.component.tsx b/packages/ui-vue/components/property-editor/src/components/const/const-property.component.tsx index d2c3f2d2d59..bbf5eebae02 100644 --- a/packages/ui-vue/components/property-editor/src/components/const/const-property.component.tsx +++ b/packages/ui-vue/components/property-editor/src/components/const/const-property.component.tsx @@ -18,7 +18,7 @@ import { ConstPropertyProps, ConstType } from './const-property.props'; import { FComboList } from '@farris/ui-vue/components/combo-list'; import { FNumberSpinner } from '@farris/ui-vue/components/number-spinner'; import './const-property.css'; -import { ConstEnumItem, UsePropertyValue } from '../../composition/type'; +import { ConstEnumItem, UsePropertyValue } from '../../composition/types'; export default function ( props: ConstPropertyProps, diff --git a/packages/ui-vue/components/property-editor/src/components/const/const-property.props.ts b/packages/ui-vue/components/property-editor/src/components/const/const-property.props.ts index 8b3dfd1c951..b83b6bdce93 100644 --- a/packages/ui-vue/components/property-editor/src/components/const/const-property.props.ts +++ b/packages/ui-vue/components/property-editor/src/components/const/const-property.props.ts @@ -15,7 +15,7 @@ * limitations under the License. */ import { ExtractPropTypes, PropType } from 'vue'; -import { ConstEnumItem } from '../../composition/type'; +import { ConstEnumItem } from '../../composition/types'; export type ConstType = 'number' | 'enum'; export const constPropertyProps = { diff --git a/packages/ui-vue/components/property-editor/src/components/custom/custom-property.component.tsx b/packages/ui-vue/components/property-editor/src/components/custom/custom-property.component.tsx index bbf98dfa192..3d433b9b207 100644 --- a/packages/ui-vue/components/property-editor/src/components/custom/custom-property.component.tsx +++ b/packages/ui-vue/components/property-editor/src/components/custom/custom-property.component.tsx @@ -17,7 +17,7 @@ import { Ref, ref, SetupContext } from 'vue'; import { CustomPropertyProps } from './custom-property.props'; import './custom-property.css'; -import { UsePropertyValue } from '../../composition/type'; +import { UsePropertyValue } from '../../composition/types'; import { JSX } from 'vue/jsx-runtime'; export default function ( diff --git a/packages/ui-vue/components/property-editor/src/components/expression/expression-property.component.tsx b/packages/ui-vue/components/property-editor/src/components/expression/expression-property.component.tsx new file mode 100644 index 00000000000..61cd40e5829 --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/expression/expression-property.component.tsx @@ -0,0 +1,77 @@ +/** + * 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 { Ref, ref, SetupContext } from 'vue'; +import { ExpressionPropertyProps } from './expression-property.props'; +import { FInputGroup } from '@farris/ui-vue/components/input-group'; +import './expression-property.css'; +import { UsePropertyValue } from '../../composition/types'; +import { ExpressionEditor } from '@farris/ui-vue/components/expression-editor'; +import { FModalService } from '@farris/ui-vue/components/modal'; + +export default function ( + props: ExpressionPropertyProps, + context: SetupContext, + usePropertyValueComposition: UsePropertyValue +) { + const readOnly = ref(false); + /** 表达式绑定值 */ + const expressionValue = ref(''); + const groupIcon = ref(""); + + /** + * 将表达式绑定值置为空 + */ + function clearExpressionValue() { + + } + + /** + * 弹出表达式编辑器 + */ + function showExpressionEditor() { + const config = { + render: () => { + return + ; + }, + width: 1060, + height: 600, + fitContent: false, + showButtons: false, + showHeader: false, + showFloatingClose: true + } + FModalService.show(config); + } + return () => { + return ( +
+ +
+ ); + }; + +} diff --git a/packages/ui-vue/components/property-editor/src/components/expression/expression-property.css b/packages/ui-vue/components/property-editor/src/components/expression/expression-property.css new file mode 100644 index 00000000000..fa335d0e915 --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/expression/expression-property.css @@ -0,0 +1,5 @@ +.f-property-editor-expression-container { + width: 65%; + float: left; + margin-left: 3%; +} \ No newline at end of file diff --git a/packages/ui-vue/components/property-editor/src/components/expression/expression-property.props.ts b/packages/ui-vue/components/property-editor/src/components/expression/expression-property.props.ts new file mode 100644 index 00000000000..9e54d3102ed --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/components/expression/expression-property.props.ts @@ -0,0 +1,23 @@ + +/** + * 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 { ExtractPropTypes } from 'vue'; + +export const expressionPropertyProps = { + +} as Record; + +export type ExpressionPropertyProps = ExtractPropTypes; diff --git a/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.component.tsx b/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.component.tsx index 9c80ab4dd7c..9db1949e968 100644 --- a/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.component.tsx +++ b/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.component.tsx @@ -18,7 +18,7 @@ import { StateMachinePropertyProps } from './state-machine-property.props'; import { FComboList } from '@farris/ui-vue/components/combo-list'; import './state-machine-property.css'; import { useStateMachine } from '../../composition/use-state-machine'; -import { StateMachineItem, UsePropertyValue } from '../../composition/type'; +import { StateMachineItem, UsePropertyValue } from '../../composition/types'; export default function ( props: StateMachinePropertyProps, diff --git a/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.props.ts b/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.props.ts index 296e5131331..da85d3eaeed 100644 --- a/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.props.ts +++ b/packages/ui-vue/components/property-editor/src/components/state-machine/state-machine-property.props.ts @@ -15,7 +15,7 @@ * limitations under the License. */ import { ExtractPropTypes } from 'vue'; -import { StateMachineItem } from '../../composition/type'; +import { StateMachineItem } from '../../composition/types'; export const stateMachinePropertyProps = { /** 状态机列表 */ diff --git a/packages/ui-vue/components/property-editor/src/components/variable/variable-property.component.tsx b/packages/ui-vue/components/property-editor/src/components/variable/variable-property.component.tsx index 6935e43b049..68973d45e76 100644 --- a/packages/ui-vue/components/property-editor/src/components/variable/variable-property.component.tsx +++ b/packages/ui-vue/components/property-editor/src/components/variable/variable-property.component.tsx @@ -17,7 +17,7 @@ import { computed, Ref, ref, SetupContext } from 'vue'; import { VariablePropertyProps } from './variable-property.props'; import { FComboList } from '@farris/ui-vue/components/combo-list'; import './variable-property.css' -import { UsePropertyValue, VariableItem, VariableValue } from '../../composition/type'; +import { UsePropertyValue, VariableItem, VariableValue } from '../../composition/types'; import { useVariable } from '../../composition/use-variable'; export default function ( @@ -51,7 +51,13 @@ export default function ( * 设置变量属性值 */ function setVariableValue(variable: VariableValue) { - Object.assign(propertyValue.value, variable); + Object.assign(propertyValue.value, { + field: variable.field, + path: variable.path, + fullPath: variable.fullPath, + isNewVariable: variable.isNewVariable, + newVariableType: variable.isNewVariable && variable.newVariableType + }); currentVariableId.value = propertyValue.value.field; triggerValueChange(propertyValue.value); } @@ -114,6 +120,7 @@ export default function ( viewType={'text'} enableClear={false} valueField='field' + idField='field' textField='fullPath' data={variables.value} beforeOpen={beforeShowVariable} diff --git a/packages/ui-vue/components/property-editor/src/components/variable/variable-property.props.ts b/packages/ui-vue/components/property-editor/src/components/variable/variable-property.props.ts index aad22c5712f..c87614d54ad 100644 --- a/packages/ui-vue/components/property-editor/src/components/variable/variable-property.props.ts +++ b/packages/ui-vue/components/property-editor/src/components/variable/variable-property.props.ts @@ -15,7 +15,7 @@ * limitations under the License. */ import { ExtractPropTypes } from 'vue'; -import { VariableItem } from '../../composition/type'; +import { VariableItem } from '../../composition/types'; export const variablePropertyProps = { variables: { type: Array, default: [] }, diff --git a/packages/ui-vue/components/property-editor/src/composition/data.ts b/packages/ui-vue/components/property-editor/src/composition/datas.ts similarity index 90% rename from packages/ui-vue/components/property-editor/src/composition/data.ts rename to packages/ui-vue/components/property-editor/src/composition/datas.ts index 75bc3ad7c19..d4e69075a60 100644 --- a/packages/ui-vue/components/property-editor/src/composition/data.ts +++ b/packages/ui-vue/components/property-editor/src/composition/datas.ts @@ -1,4 +1,4 @@ -import { PropertyTypeItem } from './type'; +import { PropertyTypeItem } from './types'; /** 左侧属性类型的枚举数据 */ export const PROPERTY_TYPE_ENUMS: PropertyTypeItem[] = [ diff --git a/packages/ui-vue/components/property-editor/src/composition/type.ts b/packages/ui-vue/components/property-editor/src/composition/types.ts similarity index 93% rename from packages/ui-vue/components/property-editor/src/composition/type.ts rename to packages/ui-vue/components/property-editor/src/composition/types.ts index 4446c344c4f..45f401b05f9 100644 --- a/packages/ui-vue/components/property-editor/src/composition/type.ts +++ b/packages/ui-vue/components/property-editor/src/composition/types.ts @@ -93,3 +93,8 @@ export interface UseVariable { getVariableByPath: (variablePath: string) => VariableValue; getVariableValue: () => Ref; } + +export interface UsePropertyEditor { + getVariables: (viewModelId: string) => any[]; + getControlName: (propertyData: any) => string; +} \ No newline at end of file diff --git a/packages/ui-vue/components/property-editor/src/composition/use-property-editor.ts b/packages/ui-vue/components/property-editor/src/composition/use-property-editor.ts new file mode 100644 index 00000000000..035bd7640c9 --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/composition/use-property-editor.ts @@ -0,0 +1,66 @@ +import { FormVariable } from "@farris/ui-vue/components/common"; +import { DesignerHostService } from "@farris/ui-vue/components/designer-canvas"; +import { UsePropertyEditor } from "./types"; + +/** + * PropertyEditor对外提供的接口 + * @param designerHostService + * @returns + */ +export function usePropertyEditor(designerHostService: DesignerHostService): UsePropertyEditor { + const { formSchemaUtils } = designerHostService; + + /** + * 把变量视图模型的变量转化为PropertyEditor的变量格式 + * @param variable + * @returns + */ + function convertToEditorVariable(variable: FormVariable, pathPrefix: string = '') { + return { + category: variable.category, + path: pathPrefix + variable.code, + name: variable.name, + field: variable.id, + fullPath: variable.code + }; + } + + /** + * 获取视图模型上的变量 + * @param viewModelId + * @returns + */ + function getVariablesByViewModelId(viewModelId: string, pathPrefix: string = '') { + const viewModel = formSchemaUtils.getViewModelById(viewModelId); + return viewModel.states.map(state => convertToEditorVariable(state, pathPrefix)); + } + + /** + * 获取PropertyEditor需要的变量数据 + */ + function getVariables(viewModelId: string): any[] { + const rootViewModelId = formSchemaUtils.getRootViewModelId(); + // 1、当前组件的组件变量 + const currentViewModelVariables = getVariablesByViewModelId(viewModelId); + if (viewModelId === rootViewModelId) { + return currentViewModelVariables; + } + + // 2、根组件的组件变量 + const rootViewModelVariables = getVariablesByViewModelId(rootViewModelId, 'root-component.'); + return [...currentViewModelVariables, ...rootViewModelVariables]; + } + + /** + * 获取控件名称 + * @param propertyData + * @returns + */ + function getControlName(propertyData: any): string { + const bindingPath = propertyData && propertyData.binding && propertyData.binding.path; + return bindingPath || ''; + + } + + return { getVariables, getControlName }; +} \ No newline at end of file diff --git a/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts b/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts index b7d942d0dc2..fdf7b5b3c7b 100644 --- a/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts +++ b/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts @@ -2,8 +2,8 @@ import { Ref, SetupContext, ref } from "vue"; import { PropertyEditorProps, PropertyType } from "../property-editor.props"; -import { PROPERTY_TYPE_ENUMS } from "./data"; -import { ConstEnumItem, PropertyTypeItem, UsePropertyType } from "./type"; +import { PROPERTY_TYPE_ENUMS } from "./datas"; +import { ConstEnumItem, PropertyTypeItem, UsePropertyType } from "./types"; import { ConstType } from "../components/const/const-property.props"; export function usePropertyType( diff --git a/packages/ui-vue/components/property-editor/src/composition/use-property-value.ts b/packages/ui-vue/components/property-editor/src/composition/use-property-value.ts index e52530c6160..3ad722aabce 100644 --- a/packages/ui-vue/components/property-editor/src/composition/use-property-value.ts +++ b/packages/ui-vue/components/property-editor/src/composition/use-property-value.ts @@ -1,6 +1,6 @@ import { Ref, SetupContext, ref } from "vue"; import { PropertyEditorProps, PropertyType } from "../property-editor.props"; -import { UsePropertyValue } from "./type"; +import { UsePropertyValue } from "./types"; import { cloneDeep } from "lodash"; export function usePropertyValue( diff --git a/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts b/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts index 9e5e8bafb7e..d96ccaa36db 100644 --- a/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts +++ b/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts @@ -1,6 +1,6 @@ import { Ref, SetupContext, ref } from "vue"; import { PropertyEditorProps } from "../property-editor.props"; -import { StateMachineValue, UsePropertyValue, UseStateMachine } from "./type"; +import { StateMachineValue, UsePropertyValue, UseStateMachine } from "./types"; export function useStateMachine( props: PropertyEditorProps, diff --git a/packages/ui-vue/components/property-editor/src/composition/use-variable.ts b/packages/ui-vue/components/property-editor/src/composition/use-variable.ts index 84cab70df8d..bbdefab21a0 100644 --- a/packages/ui-vue/components/property-editor/src/composition/use-variable.ts +++ b/packages/ui-vue/components/property-editor/src/composition/use-variable.ts @@ -3,7 +3,7 @@ import { Ref, SetupContext, ref } from "vue"; import { PropertyEditorProps } from "../property-editor.props"; import { useGuid } from '@farris/ui-vue/components/common'; -import { UsePropertyValue, UseVariable, VariableValue } from "./type"; +import { UsePropertyValue, UseVariable, VariableValue } from "./types"; export function useVariable( props: PropertyEditorProps, @@ -37,6 +37,15 @@ export function useVariable( return originalString[0].toLowerCase() + originalString.slice(1); } + /** + * 把_和-删除,并且把后面第一个字符转为大写 + * @param originalString + * @returns + */ + function removeAndCapitalize(originalString: string): string { + return originalString.replace(/[-_](.)/g, (match, char) => char.toUpperCase()); + } + /** * 生成新的变量 * @returns @@ -50,7 +59,8 @@ export function useVariable( const splicingNameRight = setFirstLetterUpperCase(propertyName.value); // 3、拼接成新的变量名 - const newVariablePath = `${newVariablePrefix.value}${splicingNameMiddle}${splicingNameRight}`; + let newVariablePath = `${newVariablePrefix.value}${splicingNameMiddle}${splicingNameRight}`; + newVariablePath = removeAndCapitalize(newVariablePath); const { guid } = useGuid(); const newVariable: VariableValue = { diff --git a/packages/ui-vue/components/property-editor/src/property-editor.component.tsx b/packages/ui-vue/components/property-editor/src/property-editor.component.tsx index 2c7cf82820d..de64ebd412d 100644 --- a/packages/ui-vue/components/property-editor/src/property-editor.component.tsx +++ b/packages/ui-vue/components/property-editor/src/property-editor.component.tsx @@ -21,6 +21,7 @@ import getConstRender from './components/const/const-property.component'; import getVariableRender from './components/variable/variable-property.component'; import getStateMachineRender from './components/state-machine/state-machine-property.component'; import getCustomRender from './components/custom/custom-property.component'; +import getExpressionRender from './components/expression/expression-property.component'; import { usePropertyValue } from './composition/use-property-value'; import { usePropertyType } from './composition/use-property-type'; @@ -48,6 +49,7 @@ export default defineComponent({ const renderVariable = getVariableRender(props, context, usePropertyValueComposition); const renderCustom = getCustomRender(props, context, usePropertyValueComposition); const renderStateMachine = getStateMachineRender(props, context, usePropertyValueComposition); + const renderExpression = getExpressionRender(props, context, usePropertyValueComposition); /** 控制右侧区域显示 */ const shouldShowRight = computed(() => (selectedPropertyType: PropertyType) => { return selectedPropertyType === currentPropertyType.value; @@ -100,7 +102,7 @@ export default defineComponent({ {shouldShowRight.value('Variable') && renderVariable()} {shouldShowRight.value('Custom') && renderCustom()} {shouldShowRight.value('StateMachine') && renderStateMachine()} - + {shouldShowRight.value('Expression') && renderExpression()}
); } diff --git a/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json b/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json index 0afe10b9003..65a19971f75 100644 --- a/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json +++ b/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json @@ -108,7 +108,9 @@ } }, "required": [ - "id", "type" + ], + "ignore": [ + "id" ] } \ No newline at end of file diff --git a/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts b/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts index dc43fc281c2..2f22e82553f 100644 --- a/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts +++ b/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts @@ -3,6 +3,7 @@ import { DgControl } from "../../../../designer-canvas/src/composition/dg-contro import { cloneDeep } from "lodash-es"; import { refreshCanvas } from "../../../../designer-canvas/src/composition/update-cancas"; import { canvasChanged } from "../../../../designer-canvas/src/composition/designer-canvas-changed"; +import { PropertyChangeObject } from "./property-entity"; /** * 控件属性基类 @@ -153,11 +154,11 @@ export class BaseControlProperty { } /** - * - * @param propertyId - * @param componentInstance - * @returns - */ + * + * @param propertyId + * @param componentInstance + * @returns + */ public updateElementByParentContainer(propertyId: string, componentInstance: DesignerComponentInstance) { // 1、定位控件父容器 const parentContainer = componentInstance && componentInstance.parent && componentInstance.parent['schema']; @@ -173,4 +174,43 @@ export class BaseControlProperty { refreshCanvas(); } + /** + * 属性编辑器,在编辑过程中会新增变量,此处需要将新增的变量追加到ViewModel中 + * @param changeObject + * @param viewModelId + * @returns + */ + public addNewVariableToViewModel(changeObject: PropertyChangeObject, viewModelId: string) { + const newPropertyValue = changeObject.propertyValue; + // 1、判断当前属性值是否为对象 + const isObject = newPropertyValue && typeof newPropertyValue === 'object'; + if (!isObject) { + return; + } + + // 2、判断是否为新变量 + const isNewVariable = newPropertyValue.type === 'Variable' && newPropertyValue.isNewVariable; + if (!isNewVariable) { + return; + } + + // 3、构造变量结构 + const newVariable = { + id: newPropertyValue.field, + category: 'locale', + code: newPropertyValue.fullPath, + name: newPropertyValue.fullPath, + type: newPropertyValue.newVariableType || 'String' + }; + delete newPropertyValue.newVariableType; + delete newPropertyValue.isNewVariable; + + // 4、把新变量添加到ViewModel中 + const existedVariable = this.formSchemaUtils.getVariableByCode(newVariable.code); + if (!existedVariable) { + const viewModel = this.formSchemaUtils.getViewModelById(viewModelId); + viewModel.states.push(newVariable); + } + } + } diff --git a/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts b/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts index cabb2e63e6e..f13562019c9 100644 --- a/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts +++ b/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts @@ -11,6 +11,7 @@ import { import { useResponseLayoutEditorSetting } from "../../../../response-layout-editor/src/composition/converter/use-response-layout-editor-setting"; import { FormSchemaEntityField$Type, FormSchemaEntityFieldType$Type, FormVariable } from "@farris/ui-vue/components/common"; import { DgControl } from "../../../../designer-canvas"; +import { usePropertyEditor } from "../../../../property-editor/src/composition/use-property-editor"; export class InputBaseProperty extends BaseControlProperty { public responseLayoutEditorFunction: UseResponseLayoutEditorSetting; @@ -308,7 +309,8 @@ export class InputBaseProperty extends BaseControlProperty { type: "input-group", $converter: "/converter/property-editor.converter" }, info); - const controlName = propertyData.type && propertyData.type.toLowerCase().replace(/-/g, '_'); + + const { getVariables, getControlName } = usePropertyEditor(this.designerHostService) const editorProperties = { readonly: { @@ -319,14 +321,13 @@ export class InputBaseProperty extends BaseControlProperty { propertyTypes: ['Const', 'Variable', 'Custom', 'StateMachine'], constType: 'enum', constEnums: [{ id: true, name: '是' }, { id: false, name: '否' }], - controlName:controlName, - newVariablePrefix:'is', - newVariableType:'Boolean', - variables: [ - ], + controlName: getControlName(propertyData), + newVariablePrefix: 'is', + newVariableType: 'Boolean', + variables: getVariables(this.viewModelId), stateMachines: [ ] - } + } }, disabled: { description: "", @@ -349,6 +350,11 @@ export class InputBaseProperty extends BaseControlProperty { // 合并属性,保留原属性值 editorProperties[key] = Object.assign(editorProperties[key] || {}, properties[key]); } + if (!setPropertyRelates) { + setPropertyRelates = (changeObject) => { + this.addNewVariableToViewModel(changeObject, this.viewModelId); + } + } return { ...editorBasic, properties: { ...editorProperties }, setPropertyRelates }; -- Gitee From 94a9bf1ab52214b3bddb22bf7f6e5f99ef2aa858 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Wed, 19 Mar 2025 09:30:46 +0800 Subject: [PATCH 091/287] =?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 092/287] =?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 093/287] =?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 094/287] =?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 095/287] =?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 096/287] =?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 097/287] =?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 098/287] =?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 099/287] =?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 100/287] =?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 101/287] =?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 102/287] =?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 103/287] =?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 104/287] =?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 105/287] =?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 106/287] =?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 107/287] =?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 108/287] =?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 915e2e2aeea217faa2c6a761b36bb5a36757e4a2 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Mon, 24 Mar 2025 09:01:21 +0800 Subject: [PATCH 109/287] =?UTF-8?q?feature:=20property-edotor=E9=9B=86?= =?UTF-8?q?=E6=88=90=E8=A1=A8=E8=BE=BE=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../expression-property.component.tsx | 69 ++++++++----------- .../expression/expression-property.props.ts | 2 +- .../property-editor/src/composition/types.ts | 38 +++++++++- .../src/composition/use-expression.ts | 53 ++++++++++++++ .../src/composition/use-property-editor.ts | 22 +++--- .../src/composition/use-property-type.ts | 2 +- .../src/composition/use-property-value.ts | 24 ++++++- .../src/property-editor.component.tsx | 4 +- .../src/property-editor.props.ts | 2 + .../src/schema/property-editor.schema.json | 7 +- .../src/composition/entity/base-property.ts | 66 ++++++++++++++++++ .../composition/entity/expression-property.ts | 27 +++++++- .../composition/entity/input-base-property.ts | 20 ++++-- 13 files changed, 271 insertions(+), 65 deletions(-) create mode 100644 packages/ui-vue/components/property-editor/src/composition/use-expression.ts diff --git a/packages/ui-vue/components/property-editor/src/components/expression/expression-property.component.tsx b/packages/ui-vue/components/property-editor/src/components/expression/expression-property.component.tsx index 61cd40e5829..b799d0fcc44 100644 --- a/packages/ui-vue/components/property-editor/src/components/expression/expression-property.component.tsx +++ b/packages/ui-vue/components/property-editor/src/components/expression/expression-property.component.tsx @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Ref, ref, SetupContext } from 'vue'; +import { ref, SetupContext } from 'vue'; import { ExpressionPropertyProps } from './expression-property.props'; -import { FInputGroup } from '@farris/ui-vue/components/input-group'; import './expression-property.css'; import { UsePropertyValue } from '../../composition/types'; -import { ExpressionEditor } from '@farris/ui-vue/components/expression-editor'; -import { FModalService } from '@farris/ui-vue/components/modal'; +import { FExpressionTextbox } from '@farris/ui-vue/components/expression-editor'; +import { useExpression } from '../../composition/use-expression'; export default function ( props: ExpressionPropertyProps, @@ -27,49 +26,41 @@ export default function ( usePropertyValueComposition: UsePropertyValue ) { const readOnly = ref(false); - /** 表达式绑定值 */ - const expressionValue = ref(''); - const groupIcon = ref(""); + /** 属性值相关方法 */ + const { triggerValueChange } = usePropertyValueComposition; - /** - * 将表达式绑定值置为空 - */ - function clearExpressionValue() { + /** 表达式相关方法 */ + const { getExpressionValue } = useExpression(props, context, usePropertyValueComposition); + /** 表达式属性值 */ + const expressionValue = getExpressionValue(); + const { expressionInfo } = expressionValue.value; + /** 表达式的规则值 */ + const expressionRule = ref(expressionInfo.value); + /** 表达式的提示信息 */ + const expressionMessage = ref(expressionInfo.message); + /** 表达式编辑器所需的配置 */ + const expressionConfig = ref(props.expressionConfig) - } - - /** - * 弹出表达式编辑器 - */ - function showExpressionEditor() { - const config = { - render: () => { - return - ; - }, - width: 1060, - height: 600, - fitContent: false, - showButtons: false, - showHeader: false, - showFloatingClose: true + function onSubmitModal({ expression, message }) { + if (!expression) { + return; } - FModalService.show(config); + expressionValue.value.expressionInfo.value = expression; + expressionValue.value.expressionInfo.message = message; + triggerValueChange(expressionValue.value); } + return () => { return ( -
    - + + onSubmitModal={onSubmitModal} + >
    ); }; diff --git a/packages/ui-vue/components/property-editor/src/components/expression/expression-property.props.ts b/packages/ui-vue/components/property-editor/src/components/expression/expression-property.props.ts index 9e54d3102ed..0671b5b5790 100644 --- a/packages/ui-vue/components/property-editor/src/components/expression/expression-property.props.ts +++ b/packages/ui-vue/components/property-editor/src/components/expression/expression-property.props.ts @@ -17,7 +17,7 @@ import { ExtractPropTypes } from 'vue'; export const expressionPropertyProps = { - + expressionConfig: { type: Object , default: {} }, } as Record; export type ExpressionPropertyProps = ExtractPropTypes; diff --git a/packages/ui-vue/components/property-editor/src/composition/types.ts b/packages/ui-vue/components/property-editor/src/composition/types.ts index 45f401b05f9..f8b7acb1057 100644 --- a/packages/ui-vue/components/property-editor/src/composition/types.ts +++ b/packages/ui-vue/components/property-editor/src/composition/types.ts @@ -71,10 +71,37 @@ export interface StateMachineItem { name: string; } +/** + * 表达式的信息 + */ +export interface ExpressionInfo { + /** 表达式的规则值 */ + value: string; + /** 表达式的提示信息 */ + message: string; + /** 表达式目标控件的标识 */ + targetId: string; + /** 表达式目标控件的类型 */ + targetType: string; + /** 表达式的类型 */ + expressionType: string; +} + +/** + * 表达式属性值 + */ +export interface ExpressionValue { + type: 'Expression'; + /** 表达式标识 */ + expressionId: string; + /** 表达式信息,用于往expressions节点存储 */ + expressionInfo: ExpressionInfo; +} + export interface UsePropertyValue { triggerValueChange: (newValue: any) => void; getPropertyValue: (propertyType: PropertyType) => Ref; - + isPropertyValueValid: (propertyType: PropertyType, propertyValue: any) => boolean; } export interface UsePropertyType { @@ -95,6 +122,11 @@ export interface UseVariable { } export interface UsePropertyEditor { - getVariables: (viewModelId: string) => any[]; + getVariables: (viewModelId: string) => VariableItem[]; getControlName: (propertyData: any) => string; -} \ No newline at end of file + getStateMachines: () => StateMachineItem[]; +} + +export interface UseExpression { + getExpressionValue: () => Ref; +} diff --git a/packages/ui-vue/components/property-editor/src/composition/use-expression.ts b/packages/ui-vue/components/property-editor/src/composition/use-expression.ts new file mode 100644 index 00000000000..c4dee062f96 --- /dev/null +++ b/packages/ui-vue/components/property-editor/src/composition/use-expression.ts @@ -0,0 +1,53 @@ +import { Ref, SetupContext, ref } from "vue"; +import { PropertyEditorProps } from "../property-editor.props"; +import { ExpressionValue, UseExpression, UsePropertyValue } from "./types"; + +export function useExpression( + props: PropertyEditorProps, + context: SetupContext, + usePropertyValueComposition: UsePropertyValue +): UseExpression { + + const { getPropertyValue } = usePropertyValueComposition; + const expressionType = props.id; + const { expressionConfig } = props; + const { targetId } = expressionConfig && expressionConfig.expressionInfo; + + /** + * 生成表达式内码 + * @returns + */ + function generateExpressionId(): string { + return targetId + '_' + expressionType; + } + + /** + * 生成有个空的表达式值 + * @returns + */ + function generateExpressionValue(): ExpressionValue { + return { + type: 'Expression', + expressionId: generateExpressionId(), + expressionInfo: expressionConfig.expressionInfo + } + } + + /** + * 获取表达式的值 + */ + function getExpressionValue(): Ref { + const propertyValue = getPropertyValue('Expression'); + // 1、表达式为空,生成一个空的表达式值 + if (!propertyValue.value) { + propertyValue.value = generateExpressionValue(); + return propertyValue; + } + + // 2、记录expressionInfo的值 + propertyValue.value.expressionInfo = expressionConfig.expressionInfo; + return propertyValue; + } + + return { getExpressionValue }; +} diff --git a/packages/ui-vue/components/property-editor/src/composition/use-property-editor.ts b/packages/ui-vue/components/property-editor/src/composition/use-property-editor.ts index 035bd7640c9..66043c05fbb 100644 --- a/packages/ui-vue/components/property-editor/src/composition/use-property-editor.ts +++ b/packages/ui-vue/components/property-editor/src/composition/use-property-editor.ts @@ -1,6 +1,6 @@ import { FormVariable } from "@farris/ui-vue/components/common"; import { DesignerHostService } from "@farris/ui-vue/components/designer-canvas"; -import { UsePropertyEditor } from "./types"; +import { StateMachineItem, UsePropertyEditor, VariableItem } from "./types"; /** * PropertyEditor对外提供的接口 @@ -8,18 +8,16 @@ import { UsePropertyEditor } from "./types"; * @returns */ export function usePropertyEditor(designerHostService: DesignerHostService): UsePropertyEditor { - const { formSchemaUtils } = designerHostService; + const { formSchemaUtils, formStateMachineUtils } = designerHostService; /** * 把变量视图模型的变量转化为PropertyEditor的变量格式 * @param variable * @returns */ - function convertToEditorVariable(variable: FormVariable, pathPrefix: string = '') { + function convertToEditorVariable(variable: FormVariable, pathPrefix: string = ''):VariableItem { return { - category: variable.category, path: pathPrefix + variable.code, - name: variable.name, field: variable.id, fullPath: variable.code }; @@ -30,7 +28,7 @@ export function usePropertyEditor(designerHostService: DesignerHostService): Use * @param viewModelId * @returns */ - function getVariablesByViewModelId(viewModelId: string, pathPrefix: string = '') { + function getVariablesByViewModelId(viewModelId: string, pathPrefix: string = ''):VariableItem[] { const viewModel = formSchemaUtils.getViewModelById(viewModelId); return viewModel.states.map(state => convertToEditorVariable(state, pathPrefix)); } @@ -38,7 +36,7 @@ export function usePropertyEditor(designerHostService: DesignerHostService): Use /** * 获取PropertyEditor需要的变量数据 */ - function getVariables(viewModelId: string): any[] { + function getVariables(viewModelId: string): VariableItem[] { const rootViewModelId = formSchemaUtils.getRootViewModelId(); // 1、当前组件的组件变量 const currentViewModelVariables = getVariablesByViewModelId(viewModelId); @@ -62,5 +60,13 @@ export function usePropertyEditor(designerHostService: DesignerHostService): Use } - return { getVariables, getControlName }; + /** + * 获取PropertyEditor需要的状态机数据 + */ + function getStateMachines(): StateMachineItem[] { + const renderStates = formStateMachineUtils && formStateMachineUtils.getRenderStates(); + return renderStates || []; + } + + return { getVariables, getControlName, getStateMachines }; } \ No newline at end of file diff --git a/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts b/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts index fdf7b5b3c7b..402132cce73 100644 --- a/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts +++ b/packages/ui-vue/components/property-editor/src/composition/use-property-type.ts @@ -122,7 +122,7 @@ export function usePropertyType( // 2、属性值为对象结构,属性值的type为属性类型 const propertyTypefromObject = extractFromObjectType(propertyValue); - // 2、属性值为非对象结构,属性值的type为属性类型 + // 3、属性值为非对象结构,属性值的type为属性类型 const propertyTypefromNonObject = extractFromNonObjectType(propertyValue); return propertyTypefromObject || propertyTypefromNonObject || dfaultPropertyType; diff --git a/packages/ui-vue/components/property-editor/src/composition/use-property-value.ts b/packages/ui-vue/components/property-editor/src/composition/use-property-value.ts index 3ad722aabce..904a95e9637 100644 --- a/packages/ui-vue/components/property-editor/src/composition/use-property-value.ts +++ b/packages/ui-vue/components/property-editor/src/composition/use-property-value.ts @@ -1,7 +1,7 @@ import { Ref, SetupContext, ref } from "vue"; import { PropertyEditorProps, PropertyType } from "../property-editor.props"; import { UsePropertyValue } from "./types"; -import { cloneDeep } from "lodash"; +import { cloneDeep } from "lodash-es"; export function usePropertyValue( props: PropertyEditorProps, @@ -40,5 +40,25 @@ export function usePropertyValue( } - return { triggerValueChange, getPropertyValue }; + /** + * 检查属性值是否有效 + * @param propertyType + * @returns + */ + function isPropertyValueValid(propertyType: PropertyType,propertyValue:any): boolean { + switch (propertyType) { + case 'Const': + return propertyValue !== undefined; + case 'Variable': + return propertyValue && propertyValue.field; + case 'Custom': + return propertyValue !== undefined; + case 'Expression': + return propertyValue && propertyValue.expressionInfo && propertyValue.expressionInfo.value; + case 'StateMachine': + return propertyValue && propertyValue.field;; + } + } + + return { triggerValueChange, getPropertyValue, isPropertyValueValid }; } diff --git a/packages/ui-vue/components/property-editor/src/property-editor.component.tsx b/packages/ui-vue/components/property-editor/src/property-editor.component.tsx index de64ebd412d..27411089dba 100644 --- a/packages/ui-vue/components/property-editor/src/property-editor.component.tsx +++ b/packages/ui-vue/components/property-editor/src/property-editor.component.tsx @@ -43,7 +43,7 @@ export default defineComponent({ /** 右侧-属性值相关方法 */ const usePropertyValueComposition = usePropertyValue(props, context, currentPropertyType.value); - const { getPropertyValue, triggerValueChange } = usePropertyValueComposition; + const { getPropertyValue, triggerValueChange, isPropertyValueValid } = usePropertyValueComposition; /** 渲染右侧内容 */ const renderConst = getConstRender(props, context, usePropertyValueComposition); const renderVariable = getVariableRender(props, context, usePropertyValueComposition); @@ -63,7 +63,7 @@ export default defineComponent({ const propertyValue = getPropertyValue(currentPropertyType.value); // 2、如果属性值不为空,触发属性值变更 - if (propertyValue.value) { + if (isPropertyValueValid(currentPropertyType.value,propertyValue.value)) { triggerValueChange(propertyValue.value); } } diff --git a/packages/ui-vue/components/property-editor/src/property-editor.props.ts b/packages/ui-vue/components/property-editor/src/property-editor.props.ts index 31647b12c95..9ba44286bef 100644 --- a/packages/ui-vue/components/property-editor/src/property-editor.props.ts +++ b/packages/ui-vue/components/property-editor/src/property-editor.props.ts @@ -24,6 +24,7 @@ import { constPropertyProps } from './components/const/const-property.props'; import { variablePropertyProps } from './components/variable/variable-property.props'; import { stateMachinePropertyProps } from './components/state-machine/state-machine-property.props'; import { customPropertyProps } from './components/custom/custom-property.props'; +import { expressionPropertyProps } from './components/expression/expression-property.props'; export type PropertyType = 'Const' | 'Variable' | 'Custom' | 'StateMachine' | 'Expression'; @@ -32,6 +33,7 @@ export const propertyEditorProps = { ...variablePropertyProps, ...customPropertyProps, ...stateMachinePropertyProps, + ...expressionPropertyProps, id: { Type: String, default: '' }, modelValue: { type: [Number, String, Boolean, Object] }, diff --git a/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json b/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json index 65a19971f75..f8e390c41fd 100644 --- a/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json +++ b/packages/ui-vue/components/property-editor/src/schema/property-editor.schema.json @@ -105,7 +105,12 @@ "description": "", "type": "Array", "default": [] - } + }, + "expressionConfig": { + "description": "", + "type": "Object", + "default": {} + } }, "required": [ "type" diff --git a/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts b/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts index 3e7bb862a0f..b0d33867694 100644 --- a/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts +++ b/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts @@ -214,4 +214,70 @@ export class BaseControlProperty { } } + /** + * 更新表达式到expressions节点 + * @param changeObject + */ + public updateExpressionValue(changeObject: PropertyChangeObject) { + const newPropertyValue = changeObject.propertyValue; + const newValueType = newPropertyValue && newPropertyValue.type; + + // 1、判断是否需要更新表达式 + const needUpdateExpression = newValueType === 'Expression' && newPropertyValue.expressionInfo; + if (!needUpdateExpression) { + return; + } + + const { expressionId, expressionInfo } = newPropertyValue; + const { targetId, targetType, expressionType, value, message } = expressionInfo; + const module = this.formSchemaUtils.getModule(); + module.expressions ??= []; + const { expressions } = module; + + // 2、获取目标表达式,如果不存在,则创建一个空的目标表达式 + let targetExpression = expressions.find(expression => expression.target === targetId); + if (!targetExpression) { + targetExpression = { target: targetId, rules: [], targetType }; + expressions.push(targetExpression); + } + + // 3、更新表达式 + const expressionItem = targetExpression.rules.find(rule => rule.type === expressionType); + if (expressionItem) { + expressionItem.value = value; + expressionItem.message = message; + } else { + const newExpressionRule = { id: expressionId, type: expressionType, value, message }; + targetExpression.rules.push(newExpressionRule); + } + delete newPropertyValue.expressionInfo; + } + + /** + * 属性类型切换为非表达式后,清除原表达式 + * @param changeObject + * @param propertyData + * @returns + */ + clearExpression(changeObject: PropertyChangeObject, propertyData: any) { + const newPropertyValue = changeObject.propertyValue; + const isExpression = newPropertyValue && newPropertyValue.type === 'Expression'; + // 1、如果为当前属性为表达式,则不需要清空 + if (isExpression) { + return; + } + + // 2、属性值不是表达式后,需要清空表达式 + const expressionType = changeObject.propertyID; + const expressions = this.formSchemaUtils.getExpressions(); + + const targetId = propertyData.binding ? propertyData.binding.field : propertyData.id; + const targetExpression = expressions.find(expression => expression.target === targetId); + if (!targetExpression || !targetExpression.rules) { + return; + } + targetExpression.rules = targetExpression.rules.filter(rule => rule.type !== expressionType); + + } + } diff --git a/packages/ui-vue/components/property-panel/src/composition/entity/expression-property.ts b/packages/ui-vue/components/property-panel/src/composition/entity/expression-property.ts index 99373ddbcae..8b045a7b203 100644 --- a/packages/ui-vue/components/property-panel/src/composition/entity/expression-property.ts +++ b/packages/ui-vue/components/property-panel/src/composition/entity/expression-property.ts @@ -172,7 +172,7 @@ export class ExpressionProperty { const rule = this.getExpressionRule(expressionId, expressionType); const entitiesAndVariables = this.getEntitiesAndVariables(); return { - message: expressionType === 'validate' && rule? rule.message : '', + message: ['validate','required'].includes(expressionType) && rule? rule.message : '', ...entitiesAndVariables }; } @@ -285,6 +285,19 @@ export class ExpressionProperty { }, {}); } + private getExpressionInfo(propertyData: any, targetType: 'Field' | 'Button' | 'Container', expressionType: string){ + const targetId = targetType === 'Field' ? propertyData.binding.field : propertyData.id; + const expressionRule = this.getExpressionRule(targetId, expressionType); + const expressionInfo = { + value: expressionRule && expressionRule.value, + message: expressionRule && expressionRule.message, + targetId, + targetType, + expressionType + } + return expressionInfo + } + getExpressionConfig(propertyData: any, type: 'Field'|'Button'|'Container', expressionTypes: string[] = ['compute', 'dependency', 'validate']) { return { description: "表达式", @@ -294,4 +307,16 @@ export class ExpressionProperty { } }; } + + getExpressionOptions(propertyData: any, targetType: 'Field' | 'Button' | 'Container', expressionType: string) { + const expressionInfo = this.getExpressionInfo(propertyData, targetType, expressionType); + return { + singleExpand: false, + showMessage: expressionType === 'require', + beforeOpen: () => { + return this.onBeforeOpenExpression(propertyData, expressionType, targetType); + }, + expressionInfo + }; + } } diff --git a/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts b/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts index 43669b23014..6fae7d90dd4 100644 --- a/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts +++ b/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts @@ -44,7 +44,7 @@ export class InputBaseProperty extends BaseControlProperty { // 外观 this.propertyConfig.categories['appearance'] = this.getAppearanceProperties(propertyData, componentInstance); // 编辑器 - this.propertyConfig.categories['editor'] = this.getEditorProperties(propertyData); + this.propertyConfig.categories['editor'] = this.getEditorProperties(propertyData); // 表达式编辑器 this.propertyConfig.categories['expressons'] = this.getExpressionConfig(propertyData, 'Field'); // 事件 @@ -328,7 +328,7 @@ export class InputBaseProperty extends BaseControlProperty { $converter: "/converter/property-editor.converter" }, info); - const { getVariables, getControlName } = usePropertyEditor(this.designerHostService) + const { getVariables, getControlName, getStateMachines } = usePropertyEditor(this.designerHostService) const editorProperties = { readonly: { @@ -336,15 +336,15 @@ export class InputBaseProperty extends BaseControlProperty { title: "只读", editor: { type: "property-editor", - propertyTypes: ['Const', 'Variable', 'Custom', 'StateMachine'], + propertyTypes: ['Const', 'Variable', 'Custom', 'StateMachine', 'Expression'], constType: 'enum', constEnums: [{ id: true, name: '是' }, { id: false, name: '否' }], controlName: getControlName(propertyData), newVariablePrefix: 'is', newVariableType: 'Boolean', variables: getVariables(this.viewModelId), - stateMachines: [ - ] + stateMachines: getStateMachines(), + expressionConfig: this.getExpressionOptions(propertyData, 'Field', 'readonly') } }, disabled: { @@ -369,8 +369,10 @@ export class InputBaseProperty extends BaseControlProperty { editorProperties[key] = Object.assign(editorProperties[key] || {}, properties[key]); } if (!setPropertyRelates) { - setPropertyRelates = (changeObject) => { + setPropertyRelates = (changeObject, propertyData) => { this.addNewVariableToViewModel(changeObject, this.viewModelId); + this.updateExpressionValue(changeObject) + this.clearExpression(changeObject, propertyData); } } @@ -612,4 +614,8 @@ export class InputBaseProperty extends BaseControlProperty { getExpressionConfig(propertyData: any, type: 'Field' | 'Button' | 'Container') { return new ExpressionProperty(this.formSchemaUtils).getExpressionConfig(propertyData, type); } -} + + getExpressionOptions(propertyData: any, targetType: 'Field' | 'Button' | 'Container', expressionType: string) { + return new ExpressionProperty(this.formSchemaUtils).getExpressionOptions(propertyData, targetType, expressionType); + } +} \ No newline at end of file -- Gitee From 8241d3658fa4ae8c405ab64db086d14784c6337f Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Mon, 24 Mar 2025 09:05:56 +0800 Subject: [PATCH 110/287] 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 230582ea13f7cd221e330a66f03ccde80e4cf34c Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Mon, 24 Mar 2025 09:07:40 +0800 Subject: [PATCH 111/287] =?UTF-8?q?chore:=20=20=E5=AE=8C=E5=96=84property-?= =?UTF-8?q?editor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/composition/entity/base-property.ts | 44 ++++--------------- 1 file changed, 8 insertions(+), 36 deletions(-) diff --git a/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts b/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts index aa8e906bde1..5424928700d 100644 --- a/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts +++ b/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts @@ -5,6 +5,7 @@ import { refreshCanvas } from "../../../../designer-canvas/src/composition/updat import { canvasChanged } from "../../../../designer-canvas/src/composition/designer-canvas-changed"; import { PropertyChangeObject } from "./property-entity"; import { usePropertyEditor } from "../../../../property-editor/src/composition/use-property-editor"; +import { ExpressionProperty } from "./expression-property"; /** * 控件属性基类 @@ -123,7 +124,7 @@ export class BaseControlProperty { }; } protected getPropertyEditorParams(propertyData, propertyTypes:any = []) { - const { getVariables, getControlName } = usePropertyEditor(this.designerHostService); + const { getVariables, getControlName, getStateMachines } = usePropertyEditor(this.designerHostService); return { type: "property-editor", propertyTypes: propertyTypes && propertyTypes.length > 0 ? propertyTypes : ['Const', 'Variable', 'Custom', 'StateMachine'], @@ -133,41 +134,8 @@ export class BaseControlProperty { newVariablePrefix: 'is', newVariableType: 'Boolean', variables: getVariables(this.viewModelId), - // 先预置数据,待多值编辑器完善后替换 - stateMachines: [ - { - "id": "canRemove", - "name": "删除" - }, - { - "id": "editable", - "name": "可编辑" - }, - { - "id": "canEdit", - "name": "编辑" - }, - { - "id": "canRemoveDetail", - "name": "删除明细" - }, - { - "id": "canAdd", - "name": "新增" - }, - { - "id": "canSave", - "name": "保存" - }, - { - "id": "canCancel", - "name": "取消" - }, - { - "id": "canAddDetail", - "name": "新增明细" - } - ] + stateMachines: getStateMachines(), + expressionConfig: this.getExpressionOptions(propertyData, 'Field', 'readonly') } } protected getVisibleProperty(propertyData, position = '') { @@ -336,4 +304,8 @@ export class BaseControlProperty { } + getExpressionOptions(propertyData: any, targetType: 'Field' | 'Button' | 'Container', expressionType: string) { + return new ExpressionProperty(this.formSchemaUtils).getExpressionOptions(propertyData, targetType, expressionType); + } + } -- Gitee From daf7b5138c2a9dced7c49ab48cd09e865555d7d1 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Mon, 24 Mar 2025 09:38:25 +0800 Subject: [PATCH 112/287] =?UTF-8?q?chore:=20=20=E4=BB=A3=E7=A0=81=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../expression/expression-property.component.tsx | 8 ++++++++ .../src/composition/entity/base-property.ts | 2 +- .../src/composition/entity/input-base-property.ts | 8 -------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/ui-vue/components/property-editor/src/components/expression/expression-property.component.tsx b/packages/ui-vue/components/property-editor/src/components/expression/expression-property.component.tsx index b799d0fcc44..2bd7d6707a5 100644 --- a/packages/ui-vue/components/property-editor/src/components/expression/expression-property.component.tsx +++ b/packages/ui-vue/components/property-editor/src/components/expression/expression-property.component.tsx @@ -49,6 +49,13 @@ export default function ( expressionValue.value.expressionInfo.message = message; triggerValueChange(expressionValue.value); } + function beforeSubmit({ expression, notifyService }) { + if (expression) { + return true; + } + notifyService.warning('请先配置表达式'); + return false; + } return () => { return ( @@ -59,6 +66,7 @@ export default function ( validateMessage={expressionMessage.value} enableClear={false} readonly={readOnly.value} + beforeSubmit={beforeSubmit} onSubmitModal={onSubmitModal} >
    diff --git a/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts b/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts index 5424928700d..54da6089ccc 100644 --- a/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts +++ b/packages/ui-vue/components/property-panel/src/composition/entity/base-property.ts @@ -127,7 +127,7 @@ export class BaseControlProperty { const { getVariables, getControlName, getStateMachines } = usePropertyEditor(this.designerHostService); return { type: "property-editor", - propertyTypes: propertyTypes && propertyTypes.length > 0 ? propertyTypes : ['Const', 'Variable', 'Custom', 'StateMachine'], + propertyTypes: propertyTypes && propertyTypes.length > 0 ? propertyTypes : ['Const', 'Variable', 'Custom', 'StateMachine', 'Expression'], constType: 'enum', constEnums: [{ id: true, name: '是' }, { id: false, name: '否' }], controlName: getControlName(propertyData), diff --git a/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts b/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts index ec547b3a497..c2922c3c8cd 100644 --- a/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts +++ b/packages/ui-vue/components/property-panel/src/composition/entity/input-base-property.ts @@ -41,14 +41,6 @@ export class InputBaseProperty extends BaseControlProperty { } public getGridFieldEdtiorPropConfig(propertyData: any, componentInstance: DesignerComponentInstance) { this.propertyConfig.categories = {}; - // 基本信息 - this.propertyConfig.categories['basic'] = this.getBasicProperties(propertyData, componentInstance); - // 外观 - this.propertyConfig.categories['appearance'] = this.getAppearanceProperties(propertyData, componentInstance); - // 编辑器 - this.propertyConfig.categories['editor'] = this.getEditorProperties(propertyData); - // 表达式编辑器 - this.propertyConfig.categories['expressons'] = this.getExpressionConfig(propertyData, 'Field'); this.getCommonPropertyConfig(propertyData,componentInstance); // 事件 this.propertyConfig.categories['eventsEditor'] = this.getEventPropertyConfig(propertyData, 'gridFieldEditor'); -- Gitee From 314f67503243812091732e958332718da88cfc3b Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Mon, 24 Mar 2025 11:54:21 +0800 Subject: [PATCH 113/287] =?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 114/287] =?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 128/287] =?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 129/287] =?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 135aab66a6b068017c3d27cf4effaa117e4e5430 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Tue, 25 Mar 2025 10:31:37 +0800 Subject: [PATCH 130/287] =?UTF-8?q?chore:=20=E7=BB=B4=E6=8A=A4=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E5=8A=9F=E8=83=BD=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../use-array-and-object-editor.tsx | 4 +- .../composition/use-variable-data.ts | 41 +++++++++++++++++-- .../default-value-column-formatter.tsx | 17 +++++++- .../variable-manager.component.tsx | 8 ++-- 4 files changed, 60 insertions(+), 10 deletions(-) diff --git a/packages/designer/src/components/components/view-model-designer/variable-manager/composition/use-array-and-object-editor.tsx b/packages/designer/src/components/components/view-model-designer/variable-manager/composition/use-array-and-object-editor.tsx index b84fb3fde5d..232db07c30f 100644 --- a/packages/designer/src/components/components/view-model-designer/variable-manager/composition/use-array-and-object-editor.tsx +++ b/packages/designer/src/components/components/view-model-designer/variable-manager/composition/use-array-and-object-editor.tsx @@ -14,7 +14,7 @@ export function useArrayAndObjectEditor() { function renderEditor(value: any): () => JSX.Element { return () => { return ( - + ); }; } @@ -27,6 +27,8 @@ export function useArrayAndObjectEditor() { function showArrayAndObjectEditor(value: any, confirmHandler: (newValue: any) => boolean) { const monacoEditorModal = modalService?.open({ fitContent: false, + enableEsc: true, + draggable: true, width: 840, height: 445, title: '默认值编辑器', diff --git a/packages/designer/src/components/components/view-model-designer/variable-manager/composition/use-variable-data.ts b/packages/designer/src/components/components/view-model-designer/variable-manager/composition/use-variable-data.ts index 093f1b0f39d..1744778736e 100644 --- a/packages/designer/src/components/components/view-model-designer/variable-manager/composition/use-variable-data.ts +++ b/packages/designer/src/components/components/view-model-designer/variable-manager/composition/use-variable-data.ts @@ -4,6 +4,7 @@ import { useVariableDefaultValue } from "./use-variable-default-value"; import { FNotifyService } from "@farris/ui-vue/components"; import { IdService } from "../../method-manager/service/id.service"; import { useViewModelName } from '../../method-manager/composition/use-view-model-name'; +import { cloneDeep } from "lodash-es"; export function useVariableData(gridComponentInstance: Ref) { @@ -138,6 +139,38 @@ export function useVariableData(gridComponentInstance: Ref) { return true; } + function checkBeforeEndEditCell(data: any): boolean { + const currentEditingCell = data && data.cell; + if (!currentEditingCell) { + return true; + } + + const { field, editingData } = currentEditingCell; + const newValue = editingData.trim(); + + // 1、编辑编号和名称列时,需要校验是否为空 + if (field === 'code' || field === 'name') { + if (!newValue) { + return false; + } + } + + // 2、编辑编号列时,需要校验编号是否重复 + if (field === 'code') { + const newVariable = cloneDeep(data.row.raw); + newVariable.code = newValue; + return checkUniqueCode(newVariable); + } + + // 3、编辑默认值列时,打开数组和对象编辑器时,不允许结束编辑 + if (field === 'value') { + const canNotEndEdit = document.getElementById('variable-array-and-object-editor'); + return !canNotEndEdit; + } + + return true; + } + /** * 从视图模型中删除变量 * @param variable @@ -155,7 +188,7 @@ export function useVariableData(gridComponentInstance: Ref) { * @returns */ function deleteVariables() { - const variablesToBeDeleted = gridComponentInstance.value.getSelectedItems(); + let variablesToBeDeleted = gridComponentInstance.value.getSelectedItems(); // 1、要删除的变量不能为空 if (!variablesToBeDeleted || !variablesToBeDeleted.length) { notifyService.info('请勾选要删除的行'); @@ -168,6 +201,7 @@ export function useVariableData(gridComponentInstance: Ref) { } // 3、从视图模型中删除变量 + variablesToBeDeleted = variablesToBeDeleted.filter(variableToBeDeleted => variableToBeDeleted.category === FormVariableCategory.locale); variablesToBeDeleted.forEach(variableToBeDeleted => { variableList.value = variableList.value.filter(variable => variable.id !== variableToBeDeleted.id); deleteVariableFromViewModel(variableToBeDeleted); @@ -207,7 +241,7 @@ export function useVariableData(gridComponentInstance: Ref) { } const variableCode = variable.code && variable.code.trim(); const variableName = variable.name && variable.name.trim(); - + // 2、变量编号、名称、类型不能为空 if (!variableCode || !variableName || !variable.type) { return false; @@ -335,6 +369,7 @@ export function useVariableData(gridComponentInstance: Ref) { deleteVariables, addVariableToDataGrid, updateVariableToViewModel, - refreshRemoteVariables + refreshRemoteVariables, + checkBeforeEndEditCell }; } diff --git a/packages/designer/src/components/components/view-model-designer/variable-manager/formatters/default-value-column-formatter.tsx b/packages/designer/src/components/components/view-model-designer/variable-manager/formatters/default-value-column-formatter.tsx index 0215e637d80..22faed2eb77 100644 --- a/packages/designer/src/components/components/view-model-designer/variable-manager/formatters/default-value-column-formatter.tsx +++ b/packages/designer/src/components/components/view-model-designer/variable-manager/formatters/default-value-column-formatter.tsx @@ -7,11 +7,24 @@ import { JSX } from "vue/jsx-runtime"; */ export default function defaultValueColumnFormatter(visualDataCell: VisualDataCell, visualDataRow: VisualData): () => JSX.Element { const { data } = visualDataCell; - const displayText = data; + + /** + * 格式化单元格数据 + * @returns + */ + function formatCellData(data: any): string { + let displayText = data; + // 1、如果默认值为布尔值,则转换为字符串 + if (typeof displayText === 'boolean') { + displayText = displayText + ""; + } + + return displayText; + } return (
    - {displayText} + {formatCellData(data)}
    ); diff --git a/packages/designer/src/components/components/view-model-designer/variable-manager/variable-manager.component.tsx b/packages/designer/src/components/components/view-model-designer/variable-manager/variable-manager.component.tsx index 923982799a3..9164eebddd8 100644 --- a/packages/designer/src/components/components/view-model-designer/variable-manager/variable-manager.component.tsx +++ b/packages/designer/src/components/components/view-model-designer/variable-manager/variable-manager.component.tsx @@ -32,7 +32,7 @@ export default defineComponent({ /** 变量默认值相关方法 */ const { clearDefaultValueWhenModifyType } = useVariableDefaultValue(); /** 变量数据相关方法 */ - const { variableList, loadVariables, deleteVariables, addVariableToDataGrid, updateVariableToViewModel, refreshRemoteVariables } = useVariableData(gridComponentInstance); + const { variableList, loadVariables, deleteVariables, addVariableToDataGrid, updateVariableToViewModel, refreshRemoteVariables, checkBeforeEndEditCell } = useVariableData(gridComponentInstance); loadVariables(); /** @@ -79,11 +79,11 @@ export default defineComponent({ /** * 单元格结束编辑前事件, 用于检查输入内容是否合法 - * @param cell + * @param data * @returns */ - function onBeforeEndEditCell(cell: any): boolean { - return true; + function onBeforeEndEditCell(data: any): boolean { + return checkBeforeEndEditCell(data); } /** -- Gitee From d7f6e98770420893333aece8a9a951fa0e425364 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Tue, 25 Mar 2025 10:33:49 +0800 Subject: [PATCH 131/287] =?UTF-8?q?chore:=20=E5=B1=8F=E8=94=BD=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E6=A0=B7=E5=BC=8F=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/form-designer/form-designer.component.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/designer/src/components/components/form-designer/form-designer.component.tsx b/packages/designer/src/components/components/form-designer/form-designer.component.tsx index 96bd49bda4f..1950679adc5 100644 --- a/packages/designer/src/components/components/form-designer/form-designer.component.tsx +++ b/packages/designer/src/components/components/form-designer/form-designer.component.tsx @@ -229,8 +229,8 @@ export default defineComponent({ class={formDesignerViewClass.value}>可视化设计器
    onChangeDesignerView('formDesignerCode')} class={formDesignerCodeViewClass.value}>设计时代码
    -
    onChangeDesignerView('customClassEditor')} - class={customClassEditorClass.value}>自定义样式
    + {/*
    onChangeDesignerView('customClassEditor')} + class={customClassEditorClass.value}>自定义样式
    */}
    -- Gitee From e597817d224747ed13d7f3972f776cddd09cb882 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Tue, 25 Mar 2025 10:36:48 +0800 Subject: [PATCH 132/287] =?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 133/287] =?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 134/287] =?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 135/287] =?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 136/287] =?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 137/287] =?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 138/287] =?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 139/287] =?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 140/287] =?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 141/287] =?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 142/287] =?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 163/287] =?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 164/287] =?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 165/287] =?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 166/287] =?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 167/287] =?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 168/287] =?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 169/287] =?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 170/287] =?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 3aefe6f891efad518efd8e167ac3c75d99a40988 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Fri, 28 Mar 2025 09:03:56 +0800 Subject: [PATCH 171/287] =?UTF-8?q?feature:=20=E5=88=9D=E5=A7=8B=E5=8C=96?= =?UTF-8?q?=E9=9A=90=E8=97=8F=E5=8C=BA=E5=9F=9F=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designer-canvas/src/components/maps.ts | 2 + .../src/composition/dg-control.ts | 5 +- .../src/designer-canvas.component.tsx | 13 ++ .../designer-hidden-area.css | 127 ++++++++++++++++++ .../components/designer-hidden-area/index.ts | 31 +++++ .../hidden-component-selector.component.tsx | 78 +++++++++++ .../hidden-component-selector.props.ts | 13 ++ .../hidden-component-template.component.tsx | 44 ++++++ .../hidden-component-container.component.tsx | 107 +++++++++++++++ .../hidden-component.component.tsx | 105 +++++++++++++++ .../hidden-component.props.ts | 16 +++ .../src/composition/drag-resolve.tsx | 85 ++++++++++++ .../src/composition/types.ts | 16 +++ .../src/composition/use-designer-rules.ts | 36 +++++ .../composition/use-hidden-area-dragula.ts | 69 ++++++++++ .../src/composition/use-hidden-component.ts | 52 +++++++ .../src/designer-hidden-area.component.tsx | 55 ++++++++ .../src/designer-hidden-area.props.ts | 8 ++ .../hidden-component.property-config.ts | 16 +++ .../src/schema/hidden-component.schema.json | 32 +++++ .../src/schema/schema-mapper.ts | 4 + .../src/schema/schema-resolver.ts | 6 + packages/ui-vue/components/designer.ts | 1 + 23 files changed, 920 insertions(+), 1 deletion(-) create mode 100644 packages/ui-vue/components/designer-hidden-area/designer-hidden-area.css create mode 100644 packages/ui-vue/components/designer-hidden-area/index.ts create mode 100644 packages/ui-vue/components/designer-hidden-area/src/components/hidden-component-selector/hidden-component-selector.component.tsx create mode 100644 packages/ui-vue/components/designer-hidden-area/src/components/hidden-component-selector/hidden-component-selector.props.ts create mode 100644 packages/ui-vue/components/designer-hidden-area/src/components/hidden-component-template/hidden-component-template.component.tsx create mode 100644 packages/ui-vue/components/designer-hidden-area/src/components/hidden-component/hidden-component-container.component.tsx create mode 100644 packages/ui-vue/components/designer-hidden-area/src/components/hidden-component/hidden-component.component.tsx create mode 100644 packages/ui-vue/components/designer-hidden-area/src/components/hidden-component/hidden-component.props.ts create mode 100644 packages/ui-vue/components/designer-hidden-area/src/composition/drag-resolve.tsx create mode 100644 packages/ui-vue/components/designer-hidden-area/src/composition/types.ts create mode 100644 packages/ui-vue/components/designer-hidden-area/src/composition/use-designer-rules.ts create mode 100644 packages/ui-vue/components/designer-hidden-area/src/composition/use-hidden-area-dragula.ts create mode 100644 packages/ui-vue/components/designer-hidden-area/src/composition/use-hidden-component.ts create mode 100644 packages/ui-vue/components/designer-hidden-area/src/designer-hidden-area.component.tsx create mode 100644 packages/ui-vue/components/designer-hidden-area/src/designer-hidden-area.props.ts create mode 100644 packages/ui-vue/components/designer-hidden-area/src/property-config/hidden-component.property-config.ts create mode 100644 packages/ui-vue/components/designer-hidden-area/src/schema/hidden-component.schema.json create mode 100644 packages/ui-vue/components/designer-hidden-area/src/schema/schema-mapper.ts create mode 100644 packages/ui-vue/components/designer-hidden-area/src/schema/schema-resolver.ts diff --git a/packages/ui-vue/components/designer-canvas/src/components/maps.ts b/packages/ui-vue/components/designer-canvas/src/components/maps.ts index 8124dd0a400..8622f452950 100644 --- a/packages/ui-vue/components/designer-canvas/src/components/maps.ts +++ b/packages/ui-vue/components/designer-canvas/src/components/maps.ts @@ -57,6 +57,7 @@ import FTreeGrid from '@farris/ui-vue/components/tree-grid'; import FFieldset from '@farris/ui-vue/components/fieldset'; import FDrawer from '@farris/ui-vue/components/drawer'; import FHtmlTemplate from '@farris/ui-vue/components/html-template'; +import FDesignerHiddenArea from '@farris/ui-vue/components/designer-hidden-area'; const componentMap: Record = {}; const componentPropsConverter: Record = {}; @@ -130,6 +131,7 @@ function loadDesignerRegister() { FFieldset.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); FDrawer.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); FHtmlTemplate.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + FDesignerHiddenArea.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); } } diff --git a/packages/ui-vue/components/designer-canvas/src/composition/dg-control.ts b/packages/ui-vue/components/designer-canvas/src/composition/dg-control.ts index 853950e6426..816e428eff2 100644 --- a/packages/ui-vue/components/designer-canvas/src/composition/dg-control.ts +++ b/packages/ui-vue/components/designer-canvas/src/composition/dg-control.ts @@ -83,5 +83,8 @@ export const DgControl = { 'external-container': { type: 'external-container', name: '外部容器', icon: 'content-container' }, - 'list-nav': { type: 'list-nav', name: '列表导航' } + 'list-nav': { type: 'list-nav', name: '列表导航' }, + + 'hidden-component': { type: 'hidden-component', name: '隐藏组件' } + }; diff --git a/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx b/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx index f51372a3c5f..d92ebf1a1f7 100644 --- a/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx +++ b/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx @@ -11,6 +11,7 @@ import './composition/class/control.css'; import { loadDesignerRegister } from './components/maps'; import { F_MODAL_SERVICE_TOKEN } from '../../modal'; import { canvasKey, refreshCanvas } from './composition/update-cancas'; +import { FDesignerHiddenArea } from '@farris/ui-vue/components/designer-hidden-area'; export default defineComponent({ name: 'FDesignerCanvas', @@ -99,6 +100,17 @@ export default defineComponent({ setPositionOfButtonGroupInContainer(designerCanvasContainerElementRef.value); }); } + + /** + * 选择HiddenComponent后,触发属性面板更新 + * @param schemaValue + * @param componentInstance + */ + function onSelectHiddenComponent(schemaValue: ComponentSchema, componentInstance) { + const schemaType = schemaValue.type; + context.emit('selectionChange', schemaType, schemaValue, '', componentInstance); + } + onMounted(() => { if (designerCanvasElementRef.value) { useDragulaComposition.initializeDragula(designerCanvasElementRef.value); @@ -123,6 +135,7 @@ export default defineComponent({
    {schema.value && } + {/* {schema.value && } */}
    diff --git a/packages/ui-vue/components/designer-hidden-area/designer-hidden-area.css b/packages/ui-vue/components/designer-hidden-area/designer-hidden-area.css new file mode 100644 index 00000000000..0061975a696 --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/designer-hidden-area.css @@ -0,0 +1,127 @@ +/* 主内容 */ +.f-designer-hidden-area-container { + z-index: 999; +} + +.f-designer-hidden-area-main-content { + display: flex; + height: 400px; + background: #F8FAFC; + border-radius: 10px 10px 0px 0px; + box-shadow: 0px -10px 10px -10px rgba(215, 223, 244, 1); +} + +.f-designer-hidden-area-top-bar-container { + display: flex; + justify-content: flex-end; + margin-right: 30px; +} + +/* 右侧模板 */ +.f-designer-hidden-area-template-container { + background: white; + margin: 10px 10px 10px 0px; + width: 15%; + display: flex; + flex-direction: column; + align-items: center; + border-radius: 6px; +} + +.f-designer-hidden-area-usual-template-text { + width: 65px; + height: 26px; + background: #F0F3F9; + border-radius: 0px 0px 12px 12px; + text-align: center; + color: #8DA3CE; +} + +.f-designer-hidden-area-template-box-container { + width: 140px; + height: 140px; + border: 1px solid #EBEBEB; + border-radius: 4px; + margin-top: 10px; +} + +.f-designer-hidden-area-template-img-container { + width: 138px; + height: 109px; +} + +.f-designer-hidden-area-template-text-container { + height: 28px; + box-shadow: rgb(215, 223, 244) 0px -10px 10px -10px; + background: rgb(248, 250, 251); + display: flex; + align-items: center; + padding-left: 5px; +} + +/* 左侧HiddenComponent */ +.f-designer-hidden-area-component { + display: inline-block; + margin: 10px 0px 0px 10px; +} + +.f-designer-hidden-area-component-container { + display: flex; + margin: 10px; + width: 85%; + border-radius: 6px; +} + +.f-designer-hidden-area-component-list-container { + display: flex; + flex: 1; + border-radius: 6px; + box-shadow: rgba(91, 163, 255, 0.1) 0px 0px 8px 0px; + flex-wrap: wrap; + overflow: auto; +} + +.f-designer-hidden-area-component-white-background { + background-color: white; +} + +.hidden-area-drag-over:not(.no-drop) { + background-color: #f3f8ff !important; + border: 0.8px dashed #388fff !important; +} + +.f-designer-hidden-area-form-box-container { + width: 140px; + height: 140px; + border: 1px solid #EBEBEB; + border-radius: 4px; +} + +.f-designer-hidden-area-form-box-selected { + border: 2px solid #388fff !important; +} + +.f-designer-hidden-area-empty-container { + display: flex; + flex: 1; + box-shadow: rgba(91, 163, 255, 0.1) 0px 0px 8px 0px; + border-radius: 6px; + display: flex; + justify-content: center; + align-items: center; +} + +.f-designer-hidden-area-empty-container-border { + border: 0.8px dashed rgb(143, 157, 176); +} + +.f-designer-hidden-area-empty-drap-text { + width: 140px; + height: 20px; + opacity: 0.55; + font-family: PingFangSC-Regular; + font-size: 14px; + color: #3F4764; + text-align: center; + font-weight: 400; +} \ No newline at end of file diff --git a/packages/ui-vue/components/designer-hidden-area/index.ts b/packages/ui-vue/components/designer-hidden-area/index.ts new file mode 100644 index 00000000000..e7e98c71655 --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/index.ts @@ -0,0 +1,31 @@ +/** + * 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 { App } from 'vue'; +import FDesignerHiddenArea from './src/designer-hidden-area.component'; +import FHiddenComponent from './src/components/hidden-component/hidden-component.component'; +import { propsResolver } from './src/components/hidden-component/hidden-component.props'; + +export { FDesignerHiddenArea }; + +export default { + install(app: App): void { + app.component(FDesignerHiddenArea.name as string, FDesignerHiddenArea); + }, + registerDesigner(componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void { + componentMap['hidden-component'] = FHiddenComponent; + propsResolverMap['hidden-component'] = propsResolver; + } +}; diff --git a/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component-selector/hidden-component-selector.component.tsx b/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component-selector/hidden-component-selector.component.tsx new file mode 100644 index 00000000000..2658935ef9e --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component-selector/hidden-component-selector.component.tsx @@ -0,0 +1,78 @@ +import { computed, defineComponent, Ref, ref } from "vue"; +import { FNotifyService } from "@farris/ui-vue/components/notify"; +import { FSchemaSelector, SchemaItem } from "@farris/ui-vue/components/schema-selector"; +import { FormSchemaRepositorySymbol } from '../../../../common'; +import { hiddenComponentSelectorProps, HiddenComponentSelectorProps } from "./hidden-component-selector.props"; +import { LookupSchemaRepositoryToken } from "@farris/ui-vue/components/lookup"; + +export default defineComponent({ + name: 'FHiddenComponentSelector', + props: hiddenComponentSelectorProps, + emits: ['close', 'submit'], + setup(props: HiddenComponentSelectorProps, context) { + const selectedComponent: Ref = ref(); + const { hiddenComponentType, designerHostService } = props; + const notifyService = new FNotifyService(); + notifyService.globalConfig = { position: 'top-center' }; + + const formBasicInfo = designerHostService.formSchemaUtils.getFormMetadataBasicInfo(); + const editorParams = { formBasicInfo }; + const viewOptions = [ + { id: 'recommend', title: '推荐', type: 'Card', dataSource: 'Recommand', pagination: false }, + { id: 'total', title: '全部', type: 'Card', dataSource: 'Total', pagination: false } + ]; + const injectSymbolToken = computed(() => { + return hiddenComponentType === 'Popup' ? FormSchemaRepositorySymbol : LookupSchemaRepositoryToken; + }) + + /** + * 选择HiddenComponent + * @param $event + */ + function onSelectionChange($event) { + if (hiddenComponentType === 'Help') { + selectedComponent.value = $event[0].data; + } else { + selectedComponent.value = $event[0]; + } + } + + /** + * 校验HiddenComponent + * @returns + */ + async function validate() { + if (!selectedComponent.value) { + notifyService.warning('请选择表单'); + return false; + } + return true; + } + + function onSubmit() { + context.emit('submit', selectedComponent.value); + } + + function onCancel() { + context.emit('close'); + } + + return () => { + return ( + + + ) + } + } + +}) diff --git a/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component-selector/hidden-component-selector.props.ts b/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component-selector/hidden-component-selector.props.ts new file mode 100644 index 00000000000..69af9e460e1 --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component-selector/hidden-component-selector.props.ts @@ -0,0 +1,13 @@ +import { ExtractPropTypes, PropType } from "vue"; +import { HiddenComponentType } from "../../composition/types"; + +export const hiddenComponentSelectorProps = { + id: { type: String, default: '' }, + modelValue: { type: Object }, + designerHostService: { type: String, Object: {} }, + hiddenComponentType: { type: String as PropType, default: 'Popup' }, + +} as Record; + +export type HiddenComponentSelectorProps = ExtractPropTypes; + diff --git a/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component-template/hidden-component-template.component.tsx b/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component-template/hidden-component-template.component.tsx new file mode 100644 index 00000000000..a06b30e34ae --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component-template/hidden-component-template.component.tsx @@ -0,0 +1,44 @@ +import { ref } from "vue"; + +export default function () { + const templates = ref([ + { + code: 'Popup', + name: '弹窗', + imagePath: './image/弹窗.png', + + }, { + code: 'Help', + name: '帮助', + imagePath: './image/帮助.png', + }, + ]); + + function renderTemplate(template: { code: string, name: string, imagePath: string }) { + const { code, name, imagePath } = template; + return ( +
    +
    +
    + +
    +
    +
    {name}
    +
    +
    +
    + ); + } + + return () => { + return ( +
    +
    常用模板
    +
    + {templates.value.map(renderTemplate)} +
    +
    + ) + } +} diff --git a/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component/hidden-component-container.component.tsx b/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component/hidden-component-container.component.tsx new file mode 100644 index 00000000000..0daf3db2824 --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component/hidden-component-container.component.tsx @@ -0,0 +1,107 @@ +import { computed, inject, onMounted, Ref, ref, SetupContext } from "vue"; +import { useHiddenAreaDragula } from "../../composition/use-hidden-area-dragula"; +import { DesignerHiddenAreaProps } from "../../designer-hidden-area.props"; +import { DesignerHostService } from "@farris/ui-vue/components/designer-canvas"; +import FHiddenComponent from './hidden-component.component'; +import useHiddenComponent from "../../composition/use-hidden-component"; +import { HiddenComponentSchema } from "../../composition/types"; + +export default function ( + props: DesignerHiddenAreaProps, + context: SetupContext, +) { + /** HiddenComponent的容器 */ + const componentContainerRef = ref(); + /** 选中组件的内码 */ + const selectedComponentId: Ref = ref(); + const designerHostService = inject('designer-host-service') as DesignerHostService; + const hiddenComponentComposition = useHiddenComponent(designerHostService); + /** 拖拽相关方法 */ + const { initDragula, attachToDragulaContainer } = useHiddenAreaDragula(designerHostService, hiddenComponentComposition); + + const module = designerHostService.formSchemaUtils.getModule(); + module.hiddenComponents ??= []; + const hiddenComponents = ref(module.hiddenComponents); + /** 存在HiddenComponents */ + const hasHiddenComponents = computed(() => { + return hiddenComponents.value.length > 0; + }) + /** HiddenComponent是否选中 */ + const isSelected = computed(() => { + return (hiddenComponentSchema: HiddenComponentSchema) => hiddenComponentSchema.id === selectedComponentId.value; + }) + + /** + * 点击HiddenComponent + * @param selectedComponent + * @param componentInstance + */ + function onClick(selectedComponent: HiddenComponentSchema, componentInstance: any) { + selectedComponentId.value = selectedComponent.id; + context.emit('selectionChange', selectedComponent, componentInstance); + } + + /** + * 删除HiddenComponent + * @param component + */ + function onDelete(hiddenComponentSchema: HiddenComponentSchema) { + hiddenComponentComposition.deleteComponent(hiddenComponentSchema); + } + + onMounted(() => { + initDragula(componentContainerRef.value); + attachToDragulaContainer(); + }) + + /** + * 渲染HiddenComponent + * @returns + */ + function renderComponent(hiddenComponentSchema: HiddenComponentSchema) { + return ( + + + ) + } + + /** + * 渲染HiddenComponent所在的容器 + * @returns + */ + function renderComponentContainer() { + return ( +
    + {hiddenComponents.value.map(renderComponent)} +
    + ) + } + + /** + * 渲染空容器 + * @returns + */ + function renderEmptyContainer() { + return ( +
    +
    + 从右侧拖拽模版到这里 +
    +
    + ) + } + + return () => { + return ( +
    + {hasHiddenComponents.value ? renderComponentContainer() : renderEmptyContainer()} +
    + ) + } + +} diff --git a/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component/hidden-component.component.tsx b/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component/hidden-component.component.tsx new file mode 100644 index 00000000000..dffda2cedcf --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component/hidden-component.component.tsx @@ -0,0 +1,105 @@ +import { computed, defineComponent, inject, onMounted, ref, watch } from "vue"; +import { FNotifyService } from "@farris/ui-vue/components/notify"; +import { DesignerHostService, useDesignerComponent } from "@farris/ui-vue/components/designer-canvas"; +import { hiddenComponentProps, HiddenComponentProps } from "./hidden-component.props"; +import { useDesignerRules } from "../../composition/use-designer-rules"; +import { HiddenComponentSchema } from "../../composition/types"; + +export default defineComponent({ + name: 'FHiddenComponent', + props: hiddenComponentProps, + emits: ['click', 'delete'] as (string[] & ThisType) | undefined, + setup(props: HiddenComponentProps, context) { + const elementRef = ref(); + const notifyService = new FNotifyService(); + notifyService.globalConfig = { position: 'top-center' }; + /** HiddenComponent的Schema */ + const hiddenComponentSchema: HiddenComponentSchema = props.modelValue; + const { name, componentType } = hiddenComponentSchema; + /** 当前组件是否选中 */ + const isSelected = ref(props.isSelected); + + const designerHostService = inject('designer-host-service') as DesignerHostService; + const designerRulesComposition = useDesignerRules(hiddenComponentSchema, designerHostService); + const componentInstance = useDesignerComponent(elementRef, undefined, designerRulesComposition); + + /** 删除按钮的样式 */ + const deleteButtonStyle = computed(() => { + return isSelected.value ? 'display: flex;position:relative' : 'display: none'; + }) + /** 图片路径 */ + const imagePath = computed(() => { + return componentType === 'Popup' ? './image/弹窗.png' : './image/弹窗.png'; + }) + + /** + * 点击HiddenComponent + */ + function onClick() { + context.emit('click', hiddenComponentSchema, componentInstance.value); + } + + /** + * 删除HiddenComponent + */ + function onDelete() { + context.emit('delete', hiddenComponentSchema); + } + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + watch( + () => props.isSelected, + () => { + isSelected.value = props.isSelected; + } + ); + + context.expose(componentInstance.value); + + function renderDeleteButton() { + return ( +
    +
    + +
    +
    + ); + } + + function renderHidenComponent() { + return ( +
    +
    +
    + +
    +
    +
    {name}
    +
    +
    +
    + ); + } + + return () => { + return ( +
    + {renderDeleteButton()} + {renderHidenComponent()} +
    + ); + } + } + +}) diff --git a/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component/hidden-component.props.ts b/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component/hidden-component.props.ts new file mode 100644 index 00000000000..95d7bf5ba84 --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/components/hidden-component/hidden-component.props.ts @@ -0,0 +1,16 @@ +import { ExtractPropTypes } from "vue"; +import { createPropsResolver } from '../../../../dynamic-resolver'; +import { schemaMapper } from '../../schema/schema-mapper'; +import { schemaResolver } from '../../schema/schema-resolver'; +import hiddenComponentSchema from '../../schema/hidden-component.schema.json'; + +export const hiddenComponentProps = { + id: { type: String, default: '' }, + modelValue: { type: Object, default: {} }, + isSelected: { type: Boolean, default: false }, + +} as Record; + +export type HiddenComponentProps = ExtractPropTypes; + +export const propsResolver = createPropsResolver(hiddenComponentProps, hiddenComponentSchema, schemaMapper, schemaResolver); diff --git a/packages/ui-vue/components/designer-hidden-area/src/composition/drag-resolve.tsx b/packages/ui-vue/components/designer-hidden-area/src/composition/drag-resolve.tsx new file mode 100644 index 00000000000..f23f3eeaeaf --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/composition/drag-resolve.tsx @@ -0,0 +1,85 @@ +import { DesignerHostService } from "@farris/ui-vue/components/designer-canvas"; +import { ModalFunctions } from "@farris/ui-vue/components/modal/src/composition/type"; +import FHiddenAreaFormSelector from '../components/hidden-component-selector/hidden-component-selector.component'; +import { DesignerHTMLElement } from "@farris/ui-vue/components/designer-canvas/src/composition/types"; +import { HiddenComponentType, UseHiddenComponent } from "./types"; +import { SchemaItem } from "@farris/ui-vue/components/schema-selector"; + +export function dragResolveService(designerHostService: DesignerHostService, hiddenComponentComposition: UseHiddenComponent) { + let modalEditor: ModalFunctions; + + /** + * 关闭模态框 + */ + function closeModal() { + const closeFunction = modalEditor?.modalRef?.value.close; + if (closeFunction) { + closeFunction(); + } + } + + /** + * 确定选择HiddenComponent + * @param selectedComponent + * @param hiddenComponentType + * @returns + */ + function onSubmit(selectedComponent: SchemaItem, hiddenComponentType: HiddenComponentType) { + hiddenComponentComposition.addComponent(selectedComponent, hiddenComponentType); + closeModal(); + } + + /** + * 渲染HiddenComponent选择器 + * @param hiddenComponentType + * @returns + */ + function renderComponentSelector(hiddenComponentType: HiddenComponentType) { + return () => { + return ( + { onSubmit(selectedComponent, hiddenComponentType) }} + onClose={closeModal} hiddenComponentType={hiddenComponentType}> + ) + } + } + + /** + * 弹出HiddenComponent选择器 + * @param element + * @returns + */ + function showModel(element: DesignerHTMLElement) { + const hiddenComponentType = element.getAttribute('data-code') as HiddenComponentType; + if (!hiddenComponentType) { + console.error('HiddenComponentType is null'); + return; + } + const title = hiddenComponentType === 'Help' ? '选择帮助' : '选择表单'; + modalEditor = designerHostService.modalService.open({ + title: title, + width: 950, + height: 600, + fitContent: false, + showButtons: false, + render: renderComponentSelector(hiddenComponentType), + enableEsc: true, + draggable: true + }); + } + + /** + * 拖拽落下事件 + * @param element + * @param target + * @param source + * @param sibling + * @returns + */ + function onDrop(element: DesignerHTMLElement, target: DesignerHTMLElement, source: DesignerHTMLElement, sibling: DesignerHTMLElement) { + showModel(element); + } + + return { + onDrop + }; +} diff --git a/packages/ui-vue/components/designer-hidden-area/src/composition/types.ts b/packages/ui-vue/components/designer-hidden-area/src/composition/types.ts new file mode 100644 index 00000000000..1bfdd277938 --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/composition/types.ts @@ -0,0 +1,16 @@ +import { SchemaItem } from "@farris/ui-vue/components/schema-selector"; + +export type HiddenComponentType = 'Popup' | 'Help'; + +export interface HiddenComponentSchema { + id: string; + type: 'hidden-component'; + name: string; + componentType: HiddenComponentType; + component: SchemaItem; +} + +export interface UseHiddenComponent { + addComponent: (component: SchemaItem, hiddenComponentType: HiddenComponentType) => void; + deleteComponent: (hiddenComponentSchema: HiddenComponentSchema) => void; +} \ No newline at end of file diff --git a/packages/ui-vue/components/designer-hidden-area/src/composition/use-designer-rules.ts b/packages/ui-vue/components/designer-hidden-area/src/composition/use-designer-rules.ts new file mode 100644 index 00000000000..3a46d3621c6 --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/composition/use-designer-rules.ts @@ -0,0 +1,36 @@ +import { DesignerHostService, UseDesignerRules } from "../../../designer-canvas/src/composition/types"; +import { ComponentSchema } from "../../../designer-canvas/src/types"; +import { HiddenComponentProperty } from "../property-config/hidden-component.property-config"; + +export function useDesignerRules(schema: ComponentSchema, designerHostService: DesignerHostService): UseDesignerRules { + + function canAccepts(): boolean { + return false; + } + + function checkCanDeleteComponent() { + return false; + } + + function checkCanMoveComponent() { + return false; + } + + function hideNestedPaddingInDesginerView() { + return false; + } + function getStyles(): string { + return ''; + } + + /** + * 构造属性配置方法 + * @param componentId + * @returns + */ + function getPropsConfig(componentId: string) { + const properties = new HiddenComponentProperty(componentId, designerHostService); + return properties.getPropertyConfig(schema); + } + return { canAccepts, checkCanDeleteComponent, checkCanMoveComponent, hideNestedPaddingInDesginerView, getStyles, getPropsConfig }; +} diff --git a/packages/ui-vue/components/designer-hidden-area/src/composition/use-hidden-area-dragula.ts b/packages/ui-vue/components/designer-hidden-area/src/composition/use-hidden-area-dragula.ts new file mode 100644 index 00000000000..e6a39e6877e --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/composition/use-hidden-area-dragula.ts @@ -0,0 +1,69 @@ +import dragula from '@farris/designer-dragula'; +import { DesignerHTMLElement } from '../../../designer-canvas/src/composition/types'; +import { dragResolveService } from './drag-resolve'; +import { DesignerHostService } from "@farris/ui-vue/components/designer-canvas"; +import { UseHiddenComponent } from './types'; + +export function useHiddenAreaDragula(designerHostService: DesignerHostService, hiddenComponentComposition: UseHiddenComponent) { + + let dragulaInstance: any; + /** 拖拽所需的服务 */ + const dragResolveUtil = dragResolveService(designerHostService, hiddenComponentComposition); + + const COMPONENT_CONTAINER_CLASS = "f-designer-hidden-area-component-container"; + const TEMPLATE_BOX_CLASS = "f-designer-hidden-area-template-box-container"; + + /** + * 初始化拖拽 + */ + function initDragula(containerElement: DesignerHTMLElement) { + if (dragulaInstance) { + dragulaInstance.destroy(); + } + if (!dragula || !containerElement) { + return; + } + + dragulaInstance = dragula([containerElement], { + direction: 'horizontal', + revertOnSpill: true, + moves(element: DesignerHTMLElement): boolean { + return !element.classList.contains('no-drag'); + }, + getMirrorText(element: DesignerHTMLElement): string { + return element.innerText; + }, + accepts(element: HTMLElement, target: DesignerHTMLElement, source: HTMLElement, sibling: DesignerHTMLElement): boolean { + const canAccept = target.className.includes(COMPONENT_CONTAINER_CLASS); + return canAccept; + } + }).on('over', (element: DesignerHTMLElement, container: DesignerHTMLElement) => { + if (container.className.includes(COMPONENT_CONTAINER_CLASS)) { + container.className += ' hidden-area-drag-over'; + } + }).on('out', (el: DesignerHTMLElement, container: DesignerHTMLElement) => { + container.className = container.className.replace('hidden-area-drag-over', '').replace(' ', ''); + }).on('drop', (element: DesignerHTMLElement, target: DesignerHTMLElement, source: DesignerHTMLElement, sibling: DesignerHTMLElement + ) => dragResolveUtil.onDrop(element, target, source, sibling)); + + } + + /** + * 把右侧模板添加到可拖拽容器中 + * @returns + */ + function attachToDragulaContainer() { + if (!dragulaInstance) { + return; + } + const templateBoxs = document.getElementsByClassName(TEMPLATE_BOX_CLASS); + const formContainer = document.getElementsByClassName(COMPONENT_CONTAINER_CLASS); + dragulaInstance.containers = [...templateBoxs, ...formContainer]; + } + + + return { + initDragula, + attachToDragulaContainer + }; +} diff --git a/packages/ui-vue/components/designer-hidden-area/src/composition/use-hidden-component.ts b/packages/ui-vue/components/designer-hidden-area/src/composition/use-hidden-component.ts new file mode 100644 index 00000000000..a6ddc0f05c1 --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/composition/use-hidden-component.ts @@ -0,0 +1,52 @@ +import { Ref, ref } from "vue"; +import { HiddenComponentSchema, HiddenComponentType, UseHiddenComponent } from "./types"; +import { FNotifyService } from "@farris/ui-vue/components/notify"; +import { DesignerHostService } from "@farris/ui-vue/components/designer-canvas"; +import { useGuid } from "@farris/ui-vue/components/common"; +import { SchemaItem } from "@farris/ui-vue/components/schema-selector"; + +export default function (designerHostService: DesignerHostService): UseHiddenComponent { + + const notifyService = new FNotifyService(); + notifyService.globalConfig = { position: 'top-center' }; + + const module = designerHostService.formSchemaUtils.getModule(); + module.hiddenComponents ??= []; + const hiddenComponents: Ref = ref(module.hiddenComponents); + + /** + * 添加HiddenComponent + * @param component + * @param hiddenComponentType + */ + function addComponent(component: SchemaItem, hiddenComponentType: HiddenComponentType) { + const { uuid } = useGuid(); + const id = `hidden-component-${uuid(4)}`; + const hiddenComponentSchema: HiddenComponentSchema = { + id, + type: 'hidden-component', + name: component.name, + componentType: hiddenComponentType, + component + } + + hiddenComponents.value.push(hiddenComponentSchema); + } + + /** + * 删除HiddenComponent + * @param hiddenComponentSchema + */ + function deleteComponent(hiddenComponentSchema: HiddenComponentSchema) { + const componentIndex = hiddenComponents.value.findIndex(component => component.id === hiddenComponentSchema.id); + if (componentIndex > -1) { + hiddenComponents.value.splice(componentIndex, 1); + } + } + + + return { + addComponent, + deleteComponent, + } +} diff --git a/packages/ui-vue/components/designer-hidden-area/src/designer-hidden-area.component.tsx b/packages/ui-vue/components/designer-hidden-area/src/designer-hidden-area.component.tsx new file mode 100644 index 00000000000..e1a767fdee0 --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/designer-hidden-area.component.tsx @@ -0,0 +1,55 @@ +import { defineComponent, ref, } from 'vue'; +import { DesignerHiddenAreaProps, designerHiddenAreaProps } from './designer-hidden-area.props'; +import getHiddenComponentTemplateRender from './components/hidden-component-template/hidden-component-template.component'; +import getHiddenComponentContainerRender from './components/hidden-component/hidden-component-container.component'; + +import '../designer-hidden-area.css' + +export default defineComponent({ + name: 'FDesignerHiddenArea', + props: designerHiddenAreaProps, + emits: ['selectionChange'] as (string[] & ThisType) | undefined, + setup(props: DesignerHiddenAreaProps, context) { + const showHiddenArea = ref(false); + /** 渲染HiddenComponent的容器 */ + const renderHiddenComponentContainer = getHiddenComponentContainerRender(props, context); + /** 渲染HiddenComponent的模板 */ + const renderHiddenComponentTemplate = getHiddenComponentTemplateRender(); + + /** + * 点击顶部按钮 + */ + function onClickTopBar() { + showHiddenArea.value = !showHiddenArea.value; + } + + function renderTopBar() { + return ( +
    + + + + {showHiddenArea.value ? '隐藏区域' : '收起面板'} + + +
    + ) + } + + return () => { + return ( +
    + {renderTopBar()} + +
    + ); + } + } + +}); + diff --git a/packages/ui-vue/components/designer-hidden-area/src/designer-hidden-area.props.ts b/packages/ui-vue/components/designer-hidden-area/src/designer-hidden-area.props.ts new file mode 100644 index 00000000000..c72f5faeb13 --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/designer-hidden-area.props.ts @@ -0,0 +1,8 @@ +import { ExtractPropTypes } from "vue"; + +export const designerHiddenAreaProps = { + id: { type: String, default: '' }, + modelValue: { type: Object }, +} as Record; + +export type DesignerHiddenAreaProps = ExtractPropTypes; diff --git a/packages/ui-vue/components/designer-hidden-area/src/property-config/hidden-component.property-config.ts b/packages/ui-vue/components/designer-hidden-area/src/property-config/hidden-component.property-config.ts new file mode 100644 index 00000000000..24c4ecd9d37 --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/property-config/hidden-component.property-config.ts @@ -0,0 +1,16 @@ +import { ComponentSchema, DesignerHostService } from "@farris/ui-vue/components/designer-canvas"; +import { BaseControlProperty } from "@farris/ui-vue/components/property-panel"; + +export class HiddenComponentProperty extends BaseControlProperty { + + constructor(componentId: string, designerHostService: DesignerHostService) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: ComponentSchema) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + + return this.propertyConfig; + } + +} diff --git a/packages/ui-vue/components/designer-hidden-area/src/schema/hidden-component.schema.json b/packages/ui-vue/components/designer-hidden-area/src/schema/hidden-component.schema.json new file mode 100644 index 00000000000..0293e5d71b4 --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/schema/hidden-component.schema.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/hidden-component.schema.json", + "title": "hidden-component", + "description": "A Farris Visual Component", + "type": "object", + "properties": { + "id": { + "description": "The unique identifier for a hidden-component", + "type": "string" + }, + "type": { + "description": "The type string of hidden-component", + "type": "string", + "default": "hidden-component" + }, + "componentType": { + "type": "string", + "default": "" + }, + "component": { + "type": "ojbect", + "default": {} + } + }, + "required": [ + "id", + "type", + "componentType", + "component" + ] +} \ No newline at end of file diff --git a/packages/ui-vue/components/designer-hidden-area/src/schema/schema-mapper.ts b/packages/ui-vue/components/designer-hidden-area/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..e7bbde5239e --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/schema/schema-mapper.ts @@ -0,0 +1,4 @@ +import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; + +export const schemaMapper = new Map([ +]); diff --git a/packages/ui-vue/components/designer-hidden-area/src/schema/schema-resolver.ts b/packages/ui-vue/components/designer-hidden-area/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..75fe61bbed0 --- /dev/null +++ b/packages/ui-vue/components/designer-hidden-area/src/schema/schema-resolver.ts @@ -0,0 +1,6 @@ +import { DesignerComponentInstance, DesignerHostService, DgControl } from "../../../designer-canvas"; +import { DynamicResolver } from "../../../dynamic-resolver"; + +export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record, designerHostService?: DesignerHostService): Record { + return schema; +} \ No newline at end of file diff --git a/packages/ui-vue/components/designer.ts b/packages/ui-vue/components/designer.ts index b8aabcb5d13..45ca914df5c 100644 --- a/packages/ui-vue/components/designer.ts +++ b/packages/ui-vue/components/designer.ts @@ -10,4 +10,5 @@ export * from './schema-selector'; export * from './dynamic-resolver'; export * from './field-selector'; export { resolverMap } from './dynamic-view'; +export { FDesignerHiddenArea} from './designer-hidden-area'; -- Gitee From 7c9b3408c47a0f5df496535a1dcd6be67b59eac3 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Fri, 28 Mar 2025 09:11:19 +0800 Subject: [PATCH 172/287] =?UTF-8?q?chore:=20=20=E8=BD=AC=E6=8D=A2=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=9C=BA=E6=A0=BC=E5=BC=8F=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../property-editor/src/composition/use-state-machine.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts b/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts index d96ccaa36db..671f78ca35a 100644 --- a/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts +++ b/packages/ui-vue/components/property-editor/src/composition/use-state-machine.ts @@ -29,9 +29,10 @@ export function useStateMachine( } // 3、转化为新的格式 + const status = matchResult[1] === '!' ? false : true; const newStateMachineFormat: StateMachineValue = { type: 'StateMachine', - status: matchResult[1], + status, field: matchResult[2] } -- Gitee From f0ecf88b128d3d78deb88e1a8c4b69a036e915a7 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Fri, 28 Mar 2025 17:05:54 +0800 Subject: [PATCH 173/287] =?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 174/287] =?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 179/287] =?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 180/287] =?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 181/287] =?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 182/287] =?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 183/287] =?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 184/287] =?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 185/287] =?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 186/287] =?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 187/287] =?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 188/287] =?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 189/287] =?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 From 2f66d86f89c6d6e8c491a14c820dbb5cf805a505 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Sat, 5 Apr 2025 17:20:52 +0800 Subject: [PATCH 191/287] =?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=E5=B1=9E=E6=80=A7=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=9B=E7=A7=BB=E5=8A=A8filter=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=97=A5=E6=9C=9F=E5=92=8C=E6=97=A5=E6=9C=9F?= =?UTF-8?q?=E8=8C=83=E5=9B=B4=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../button-edit/src/button-edit.component.tsx | 2 +- .../button-edit/src/button-edit.props.ts | 2 + .../src/composition/use-button-edit-props.ts | 3 +- .../components/common/src/utils/src/common.ts | 5 ++ .../components/date-picker/index.ts | 2 +- .../date-picker/src/composition/index.ts | 1 + .../date-picker/src/composition/type.ts | 25 ++++++++ .../src/composition/use-date-columns.ts | 35 ++++++----- .../src/date-picker-panel.props.ts | 14 ++--- .../date-picker/src/date-picker.component.tsx | 1 + .../date-time-picker/src/composition/type.ts | 8 +++ .../src/composition/use-date-state.ts | 4 +- .../src/composition/use-date-time-value.ts | 2 +- .../src/composition/use-time-state.ts | 4 +- .../src/date-time-picker-panel.props.ts | 16 ++--- .../filter/src/compositions/type.ts | 1 + .../filter/src/compositions/use-condition.ts | 1 + .../compositions/use-filter-panel-state.ts | 14 ++++- .../compositions/use-render-field-item.tsx | 60 +++++++++++-------- .../filter/src/filter-panel.component.tsx | 5 +- .../components/filter/src/filter-panel.scss | 19 +++--- .../src/composition/use-picker-state.ts | 2 +- .../components/time-picker/index.ts | 2 +- .../time-picker/src/composition/index.ts | 1 + .../time-picker/src/composition/type.ts | 13 ++++ .../src/composition/use-time-columns.ts | 10 +--- .../src/time-picker-panel.props.ts | 11 +--- packages/mobile-ui-vue/demos/filter/base.vue | 20 +++++++ 28 files changed, 180 insertions(+), 103 deletions(-) create mode 100644 packages/mobile-ui-vue/components/date-picker/src/composition/type.ts create mode 100644 packages/mobile-ui-vue/components/date-time-picker/src/composition/type.ts create mode 100644 packages/mobile-ui-vue/components/time-picker/src/composition/type.ts diff --git a/packages/mobile-ui-vue/components/button-edit/src/button-edit.component.tsx b/packages/mobile-ui-vue/components/button-edit/src/button-edit.component.tsx index 1d958cfecce..e1c98d6c4c3 100644 --- a/packages/mobile-ui-vue/components/button-edit/src/button-edit.component.tsx +++ b/packages/mobile-ui-vue/components/button-edit/src/button-edit.component.tsx @@ -71,7 +71,7 @@ export default defineComponent({ readonly: props.readonly, editable: props.editable, class: props.inputClass, - rightIcon: props.readonly || 's-arrow', + rightIcon: props.readonly ? '' : props.rightIcon, textAlign: props.textAlign, showPadding: props.showPadding, formatter: props.formatter, diff --git a/packages/mobile-ui-vue/components/button-edit/src/button-edit.props.ts b/packages/mobile-ui-vue/components/button-edit/src/button-edit.props.ts index d151ece1051..e8f039e3cbf 100644 --- a/packages/mobile-ui-vue/components/button-edit/src/button-edit.props.ts +++ b/packages/mobile-ui-vue/components/button-edit/src/button-edit.props.ts @@ -15,6 +15,8 @@ export const buttonEditProps = { type: { type: String as PropType, default: 'text' }, + rightIcon: { type: String, default: 's-arrow' }, + editable: { type: Boolean, default: false }, inputClass: { type: String, default: undefined }, 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 0db4a07b91c..521f8775c91 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 @@ -17,8 +17,9 @@ export const useButtonEditProps = (props: Omit>(obj: T, key: keyof T): Omit => { + const { [key]: omitted, ...rest } = obj; + return rest as Omit; +}; + export function addUnit(value: string | number) { if (!isDef(value)) { return undefined; diff --git a/packages/mobile-ui-vue/components/date-picker/index.ts b/packages/mobile-ui-vue/components/date-picker/index.ts index 5f3654b577a..639140d32d1 100644 --- a/packages/mobile-ui-vue/components/date-picker/index.ts +++ b/packages/mobile-ui-vue/components/date-picker/index.ts @@ -1,6 +1,6 @@ import { withInstall, withRegister, withRegisterDesigner } from '@components/common'; import DatePickerPanelInstallless from './src/date-picker-panel.component'; -export * from './src/date-picker-panel.props'; +export { DatePickerType, ModelValueType } from './src/composition'; import DatePickerInstallless from './src/date-picker.component'; import DatePickerDesign from './src/designer/date-picker.design.component'; diff --git a/packages/mobile-ui-vue/components/date-picker/src/composition/index.ts b/packages/mobile-ui-vue/components/date-picker/src/composition/index.ts index a16d7300f03..5cef1299185 100644 --- a/packages/mobile-ui-vue/components/date-picker/src/composition/index.ts +++ b/packages/mobile-ui-vue/components/date-picker/src/composition/index.ts @@ -1 +1,2 @@ +export * from './type'; export * from './use-date-columns'; diff --git a/packages/mobile-ui-vue/components/date-picker/src/composition/type.ts b/packages/mobile-ui-vue/components/date-picker/src/composition/type.ts new file mode 100644 index 00000000000..165d19c1c82 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-picker/src/composition/type.ts @@ -0,0 +1,25 @@ +export enum DatePickerType { + Year = 'year', + YearMonth = 'year-month', + YearMonthDay = 'year-month-day', + Date= 'date', +} + +export enum ModelValueType { + Date = 'date', + String = 'string' +}; + +export enum DateColumn { + Year = 'year', + Month = 'month', + Date = 'day' +} + +export type DateRecord = { + year: number; + month: number; + day: number; +}; + +export type ColumnsMap = ('year' | 'month' | 'day')[]; diff --git a/packages/mobile-ui-vue/components/date-picker/src/composition/use-date-columns.ts b/packages/mobile-ui-vue/components/date-picker/src/composition/use-date-columns.ts index 9d20d1fa164..7244939fa67 100644 --- a/packages/mobile-ui-vue/components/date-picker/src/composition/use-date-columns.ts +++ b/packages/mobile-ui-vue/components/date-picker/src/composition/use-date-columns.ts @@ -9,21 +9,8 @@ import { isString, parseDate } from '@components/common'; -import { DatePickerPanelProps, DatePickerPanelTypeMap } from '../date-picker-panel.props'; - -enum DateColumn { - Year = 'year', - Month = 'month', - Date = 'day' -} - -type DateRecord = { - year: number; - month: number; - day: number; -}; - -type ColumnsMap = ('year' | 'month' | 'day')[]; +import { DatePickerPanelProps } from '../date-picker-panel.props'; +import { ColumnsMap, DateColumn, DatePickerType, DateRecord, ModelValueType } from './type'; export const useDateColumns = (props: DatePickerPanelProps) => { const textField = 'text'; @@ -145,7 +132,7 @@ export const useDateColumns = (props: DatePickerPanelProps) => { const columnsMap = computed(() => { const type = - props.type === DatePickerPanelTypeMap.Date ? DatePickerPanelTypeMap.YearMonthDay : props.type; + props.type === DatePickerType.Date ? DatePickerType.YearMonthDay : props.type; return type.split('-') as ColumnsMap; }); @@ -170,6 +157,17 @@ export const useDateColumns = (props: DatePickerPanelProps) => { }); }); + const modelValueType = computed(()=>{ + if(props.modelValueType) { + return props.modelValueType; + } + if(props.type === DatePickerType.Date || props.type === DatePickerType.YearMonthDay) { + return ModelValueType.Date; + } else { + return ModelValueType.String; + } + }); + const getDateValue = (changes?: PickerChange) => { const dates = [...innerValue.value]; if (changes) { @@ -180,10 +178,11 @@ export const useDateColumns = (props: DatePickerPanelProps) => { const result = new Date(year, month - 1, day); - if (props.type === DatePickerPanelTypeMap.Date || props.type === DatePickerPanelTypeMap.YearMonthDay) { + if (modelValueType.value === ModelValueType.Date) { return result; + } else { + return formatDate(result, props.format); } - return formatDate(result, props.format); }; const getTextValue = () => { diff --git a/packages/mobile-ui-vue/components/date-picker/src/date-picker-panel.props.ts b/packages/mobile-ui-vue/components/date-picker/src/date-picker-panel.props.ts index f31162f43a2..96358661511 100644 --- a/packages/mobile-ui-vue/components/date-picker/src/date-picker-panel.props.ts +++ b/packages/mobile-ui-vue/components/date-picker/src/date-picker-panel.props.ts @@ -1,23 +1,17 @@ import { ExtractPropTypes, PropType } from 'vue'; +import { DatePickerType, ModelValueType } from './composition/type'; 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 }, + type: { type: String as PropType, default: DatePickerType.Date }, modelValue: { type: [String, Date], default: '' }, + modelValueType: { type: String as PropType, default: '' }, + format: { type: String, default: 'YYYY-MM-DD' }, maxDate: { type: Date, default: undefined }, 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 114cbec904f..06621edc9f0 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 @@ -22,6 +22,7 @@ export default defineComponent({ format: props.format, maxDate: props.maxDate, minDate: props.minDate, + modelValueType: props.modelValueType, visiableOptionCount: props.visiableOptionCount, optionFormatter: props.optionFormatter, onChange: handleChange, diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/composition/type.ts b/packages/mobile-ui-vue/components/date-time-picker/src/composition/type.ts new file mode 100644 index 00000000000..f949626a6dd --- /dev/null +++ b/packages/mobile-ui-vue/components/date-time-picker/src/composition/type.ts @@ -0,0 +1,8 @@ +import { DatePickerType } from "@/components/date-picker"; +import { TimePickerType } from "@/components/time-picker"; + +export const enum DateTimeType { + DateTime = `${DatePickerType.Date} ${TimePickerType.Time}`, + DateHour = `${DatePickerType.Date} ${TimePickerType.Hours}`, + DateMinute = `${DatePickerType.Date} ${TimePickerType.HoursMinutes}` +} 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/src/composition/use-date-state.ts index 0ebe74e4835..8b52195e7f1 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/src/composition/use-date-state.ts @@ -1,10 +1,10 @@ import { computed, ref } from "vue"; -import { DatePickerType, DatePickerPanelTypeMap } from "@/components/date-picker"; +import { DatePickerType } from "@/components/date-picker"; import { DateTimePickerPanelProps } from "../date-time-picker-panel.props"; export const useDateState = (props: DateTimePickerPanelProps) => { const dateType = computed(() => { - return (props.type.split(" ")[0] as DatePickerType) || DatePickerPanelTypeMap.Date; + return (props.type.split(" ")[0] as DatePickerType) || DatePickerType.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/src/composition/use-date-time-value.ts index 1f70346ee77..f83ad15828a 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/src/composition/use-date-time-value.ts @@ -1,6 +1,6 @@ import { watch } from "vue"; -import { DateTimePickerPanelProps } from "../date-time-picker-panel.props"; import { compareDate, formatDate, isDate, parseDate } from "@components/common"; +import { DateTimePickerPanelProps } from "../date-time-picker-panel.props"; 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/src/composition/use-time-state.ts index 367c9646b42..50da16ec7b8 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/src/composition/use-time-state.ts @@ -1,5 +1,5 @@ import { computed, ref } from "vue"; -import { TimePickerPanelType, TimePickerPanelTypeMap } from "@components/time-picker"; +import { TimePickerType } from "@components/time-picker"; import { DateTimePickerPanelProps } 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: DateTimePickerPanelProps, datePropsCompositi const { dateValue } = datePropsComposition; const timeType = computed(() => { - return (props.type.split(" ")[1] as TimePickerPanelType) || TimePickerPanelTypeMap.Time; + return (props.type.split(" ")[1] as TimePickerType) || TimePickerType.Time; }); const timeFormat = computed(() => { return props.format.split(" ")[1] || 'HH:mm:ss'; diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker-panel.props.ts b/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker-panel.props.ts index c3358f28753..adbd38f4854 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker-panel.props.ts +++ b/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker-panel.props.ts @@ -1,24 +1,18 @@ import { ExtractPropTypes, PropType } from 'vue'; -import { DatePickerPanelTypeMap } from '@/components/date-picker'; -import { TimePickerPanelTypeMap } from '@/components/time-picker'; +import { ModelValueType } from '@/components/date-picker'; +import { DateTimeType } from './composition/type'; 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 }, + type: { type: String as PropType, default: DateTimeType.DateTime }, modelValue: { type: [String, Date], default: '' }, + modelValueType: { type: String as PropType, default: '' }, + format: { type: String, default: 'YYYY-MM-DD HH:mm:ss' }, maxDate: { type: Date, default: undefined }, 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 476a532cb63..d939d43ae2a 100644 --- a/packages/mobile-ui-vue/components/filter/src/compositions/type.ts +++ b/packages/mobile-ui-vue/components/filter/src/compositions/type.ts @@ -3,6 +3,7 @@ import { FilterCondition } from "@/components/common"; export enum ControlType { InputGroup = 'input-group', DatePicker = 'date-picker', + DatePickerRange = 'date-picker-range', DateTimePicker = 'datetime-picker', Number = 'number', NumberRange = 'number-range', 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 index 03b90d3d45b..f820544b866 100644 --- a/packages/mobile-ui-vue/components/filter/src/compositions/use-condition.ts +++ b/packages/mobile-ui-vue/components/filter/src/compositions/use-condition.ts @@ -45,6 +45,7 @@ export const userCondition = () => { conditions.push(condition); break; } + case ControlType.DatePickerRange: case ControlType.NumberRange:{ const { start, end } = value; 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 index 3348291182d..8d669513c4d 100644 --- 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 @@ -1,6 +1,7 @@ import { computed, reactive, watch } from "vue"; import { FilterPanelProps } from "../filter-panel.props"; import { userCondition } from "./use-condition"; +import { omitProperty } from "@/components/common"; export const useFilterPanelState = (props: FilterPanelProps)=>{ const filterData = reactive({}); @@ -15,8 +16,18 @@ export const useFilterPanelState = (props: FilterPanelProps)=>{ return props.modelValue ? props.modelValue[name] : undefined; }; + const fieldConfigs = computed(() => { + return props.configs.map(config=>{ + const { editor } = config; + return { + ...config, + editor: omitProperty(editor, 'type') + }; + }); + }); + const initFilterData = ()=>{ - props.configs.map(config=>{ + fieldConfigs.value.map(config=>{ const { code } = config; filterData[code] = getModelValue(code); }); @@ -39,6 +50,7 @@ export const useFilterPanelState = (props: FilterPanelProps)=>{ return { filterData, filterConditions, + fieldConfigs, resetData, getFilterPanelState }; 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 dcf0685e275..2f02a322b04 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 @@ -3,6 +3,7 @@ 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"; +import DatePicker from "@/components/date-picker"; export const useRenderFieldItem = (filterData: Record, context: SetupContext) => { const { emit } = context; @@ -14,16 +15,6 @@ export const useRenderFieldItem = (filterData: Record, context: Set emit('change', { code, value, data: filterData }); }; - const renderInput = (inputProps = {}) => { - return ( - - ); - }; - const renderInputGroup = (config: FieldConfig) =>{ const { code, editor = {} } = config; const inputProps = { @@ -32,19 +23,19 @@ export const useRenderFieldItem = (filterData: Record, context: Set onChange: (value: any) => handleChange(code, value) }; - return renderInput(inputProps); + return ( + + ); }; const renderNumber = (config: FieldConfig) => { - const { code, editor = {} } = config; - const inputProps = { - ...editor, - type: 'number', - modelValue: getValue(code, filterData), - onChange: (value: any) => handleChange(code, value) - }; + const { editor = {} } = config; - return renderInput(inputProps); + return renderInputGroup({...config, editor: { ...editor, type: 'number' }}); }; const renderNumberRange = (config: FieldConfig) => { @@ -60,26 +51,47 @@ 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); + return ( + + ); + }; + + const renderDatePickerRange = (config: FieldConfig) => { + const { code } = config; + const startCode = `${code}.start`; + const endCode = `${code}.end`; + + return ( +
    + {renderDatePicker({...config, code: startCode})} + + {renderDatePicker({...config, code: endCode})} +
    + ); }; const renderFieldItem = (config: FieldConfig) => { const { controlType } = config; switch (controlType) { case ControlType.DatePicker: - + return renderDatePicker(config); break; - case ControlType.DateTimePicker: - + case ControlType.DatePickerRange: + return renderDatePickerRange(config); break; case ControlType.Number: return renderNumber(config); 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 2b797eee385..bf1002af260 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 @@ -13,14 +13,11 @@ export default defineComponent({ const { bem } = useBem(FILTER_PANEL_NAME); - const { filterData, filterConditions, resetData, getFilterPanelState } = useFilterPanelState(props); + const { filterData, fieldConfigs, filterConditions, resetData, getFilterPanelState } = useFilterPanelState(props); expose({ getFilterPanelState }); /* content */ - const fieldConfigs = computed(() => { - return props.configs; - }); const { renderFieldItem } = useRenderFieldItem(filterData, context); const getFieldSlots = (config: FieldConfig)=>{ return { 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 317bf32379b..ab6a6c2add6 100644 --- a/packages/mobile-ui-vue/components/filter/src/filter-panel.scss +++ b/packages/mobile-ui-vue/components/filter/src/filter-panel.scss @@ -32,16 +32,17 @@ border: 1px solid #999; } } + + .fm-input-group .fm-input-group__body{ + 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; + } } - @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/picker/src/composition/use-picker-state.ts b/packages/mobile-ui-vue/components/picker/src/composition/use-picker-state.ts index 380f3235416..a444eb15cb0 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,6 +1,6 @@ import { SetupContext, onMounted, shallowRef } from 'vue'; import { ButtonEditProps, useButtonEditProps } from '@/components/button-edit'; -import { ColumnItem } from '@/components/picker-panel'; +import { ColumnItem } from '@/components/picker'; export const usePickerInputState = ( props: Omit, diff --git a/packages/mobile-ui-vue/components/time-picker/index.ts b/packages/mobile-ui-vue/components/time-picker/index.ts index 04847b04b70..e40e0e20f06 100644 --- a/packages/mobile-ui-vue/components/time-picker/index.ts +++ b/packages/mobile-ui-vue/components/time-picker/index.ts @@ -2,7 +2,7 @@ import { withInstall } from '@components/common'; import TimePickerInstallless from './src/time-picker.component'; import TimePickerPanelInstallless from './src/time-picker-panel.component'; -export * from './src/time-picker-panel.props'; +export { TimePickerType } from './src/composition'; const TimePickerPanel = withInstall(TimePickerPanelInstallless); const TimePicker = withInstall(TimePickerInstallless); diff --git a/packages/mobile-ui-vue/components/time-picker/src/composition/index.ts b/packages/mobile-ui-vue/components/time-picker/src/composition/index.ts index 0e0b60b69b9..247698b0dbe 100644 --- a/packages/mobile-ui-vue/components/time-picker/src/composition/index.ts +++ b/packages/mobile-ui-vue/components/time-picker/src/composition/index.ts @@ -1 +1,2 @@ +export * from './type'; export * from './use-time-columns'; diff --git a/packages/mobile-ui-vue/components/time-picker/src/composition/type.ts b/packages/mobile-ui-vue/components/time-picker/src/composition/type.ts new file mode 100644 index 00000000000..9cd9a523dfc --- /dev/null +++ b/packages/mobile-ui-vue/components/time-picker/src/composition/type.ts @@ -0,0 +1,13 @@ + +export enum TimePickerType { + Hours = 'hours', + HoursMinutes = 'hours-minutes', + HoursMinutesSeconds = 'hours-minutes-seconds', + Time= 'time', +} + +export enum TimeColumn { + Hours = 'hours', + Minutes = 'minutes', + Seconds= 'seconds', +}; diff --git a/packages/mobile-ui-vue/components/time-picker/src/composition/use-time-columns.ts b/packages/mobile-ui-vue/components/time-picker/src/composition/use-time-columns.ts index 0451215d9e5..e354dc52a41 100644 --- a/packages/mobile-ui-vue/components/time-picker/src/composition/use-time-columns.ts +++ b/packages/mobile-ui-vue/components/time-picker/src/composition/use-time-columns.ts @@ -1,13 +1,9 @@ import { computed, watch, ref } from 'vue'; import { Columns, Column, PickerChange } from '@components/picker'; import { formatTime, getTimeRecord, } from "@components/common"; -import { TimePickerPanelProps, TimePickerPanelTypeMap } from "../time-picker-panel.props"; +import { TimePickerPanelProps } from "../time-picker-panel.props"; +import { TimeColumn, TimePickerType } from './type'; -enum TimeColumn { - Hours = 'hours', - Minutes = 'minutes', - Seconds= 'seconds', -} export const useTimeColumns = (props: TimePickerPanelProps) => { const textField = 'text'; @@ -104,7 +100,7 @@ export const useTimeColumns = (props: TimePickerPanelProps) => { }; const columnsMap = computed(() => { - const type = props.type === TimePickerPanelTypeMap.Time ? TimePickerPanelTypeMap.HoursMinutesSeconds : props.type; + const type = props.type === TimePickerType.Time ? TimePickerType.HoursMinutesSeconds : props.type; return type.split('-'); }); diff --git a/packages/mobile-ui-vue/components/time-picker/src/time-picker-panel.props.ts b/packages/mobile-ui-vue/components/time-picker/src/time-picker-panel.props.ts index 4789cb0b248..2759e6d3160 100644 --- a/packages/mobile-ui-vue/components/time-picker/src/time-picker-panel.props.ts +++ b/packages/mobile-ui-vue/components/time-picker/src/time-picker-panel.props.ts @@ -1,20 +1,13 @@ import { ExtractPropTypes, PropType } from 'vue'; +import { TimePickerType } from './composition/type'; 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 }, + type: { type: String as PropType, default: TimePickerType.Time }, modelValue: { type: String, default: '' }, diff --git a/packages/mobile-ui-vue/demos/filter/base.vue b/packages/mobile-ui-vue/demos/filter/base.vue index 90ca050edd4..66a3c78232c 100644 --- a/packages/mobile-ui-vue/demos/filter/base.vue +++ b/packages/mobile-ui-vue/demos/filter/base.vue @@ -60,6 +60,26 @@ const fieldConfigs = [ required: false, type: 'input-group' } + }, + { + code: 'Date', + name: 'Date', + controlType: ControlType.DatePicker, + editor: { + placeHolder: '', + required: false, + type: 'input-group' + } + }, + { + code: 'DateRange', + name: 'DateRange', + controlType: ControlType.DatePickerRange, + editor: { + placeHolder: '', + required: false, + type: 'input-group' + } } ]; -- Gitee From 8b8c973075415e767c16b69954a0ee52095f0bc0 Mon Sep 17 00:00:00 2001 From: LuPing Zou <“zouluping@inspur.com”> Date: Mon, 7 Apr 2025 11:28:02 +0800 Subject: [PATCH 192/287] =?UTF-8?q?feature:=20=E6=96=B0=E5=A2=9E=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E7=AB=AFCard=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../button-group/src/button-group.scss | 26 +++++-- .../mobile-ui-vue/components/card/index.ts | 22 ++++++ .../components/card/src/card.component.tsx | 69 +++++++++++++++++++ .../components/card/src/card.props.ts | 32 +++++++++ .../components/card/src/card.scss | 43 ++++++++++++ .../card/src/schema/card.schema.json | 42 +++++++++++ .../card/src/schema/schema-mapper.ts | 5 ++ .../card/src/schema/schema-resolver.ts | 5 ++ .../common/src/style/variables.scss | 1 + packages/mobile-ui-vue/components/index.scss | 1 + packages/mobile-ui-vue/components/index.ts | 3 + packages/mobile-ui-vue/demos/card/base.vue | 52 ++++++++++++++ packages/mobile-ui-vue/demos/card/index.vue | 11 +++ packages/mobile-ui-vue/src/menu-data.ts | 6 ++ 14 files changed, 312 insertions(+), 6 deletions(-) create mode 100644 packages/mobile-ui-vue/components/card/index.ts create mode 100644 packages/mobile-ui-vue/components/card/src/card.component.tsx create mode 100644 packages/mobile-ui-vue/components/card/src/card.props.ts create mode 100644 packages/mobile-ui-vue/components/card/src/card.scss create mode 100644 packages/mobile-ui-vue/components/card/src/schema/card.schema.json create mode 100644 packages/mobile-ui-vue/components/card/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/card/src/schema/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/demos/card/base.vue create mode 100644 packages/mobile-ui-vue/demos/card/index.vue 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 index 6a73cfc0a49..dc524668874 100644 --- a/packages/mobile-ui-vue/components/button-group/src/button-group.scss +++ b/packages/mobile-ui-vue/components/button-group/src/button-group.scss @@ -96,12 +96,26 @@ border-top: 0; } - &--horizontal#{&}--mode-text &__item:not(:last-child) { - border-right: var(--fm-button-border-width) solid currentColor !important; - } - - &--vertical#{&}--mode-text &__item:not(:last-child) { - border-bottom: var(--fm-button-border-width) solid currentColor !important; + &--horizontal#{&}--mode-text &__item:not(:last-child)::after, + &--vertical#{&}--mode-text &__item:not(:last-child)::after { + content: ''; + display: block; + position: absolute; + background-color: var(--fm-gray-3); + } + + &--horizontal#{&}--mode-text &__item:not(:last-child)::after { + width: 1px; + right: 0; + top: var(--fm-padding-xs); + bottom: var(--fm-padding-xs); + } + + &--vertical#{&}--mode-text &__item:not(:last-child)::after { + height: 1px; + bottom: 0; + left: var(--fm-padding-xs); + right: var(--fm-padding-xs); } &--fill { diff --git a/packages/mobile-ui-vue/components/card/index.ts b/packages/mobile-ui-vue/components/card/index.ts new file mode 100644 index 00000000000..65abf564a6c --- /dev/null +++ b/packages/mobile-ui-vue/components/card/index.ts @@ -0,0 +1,22 @@ +import { Plugin } from 'vue'; +import { withInstall } from '@components/common'; +import CardInstallless from './src/card.component'; +import { propsResolver } from './src/card.props'; + +const CARD_REGISTERED_NAME = 'card'; + +const Card = withInstall(CardInstallless); + +Card.register = ( + componentMap: Record, + propsResolverMap: Record, + configResolverMap: Record, + resolverMap: Record, +) => { + componentMap[CARD_REGISTERED_NAME] = Card; + propsResolverMap[CARD_REGISTERED_NAME] = propsResolver; +}; + +export * from './src/card.props'; +export { Card }; +export default Card as typeof Card & Plugin; diff --git a/packages/mobile-ui-vue/components/card/src/card.component.tsx b/packages/mobile-ui-vue/components/card/src/card.component.tsx new file mode 100644 index 00000000000..6639d7b7e7d --- /dev/null +++ b/packages/mobile-ui-vue/components/card/src/card.component.tsx @@ -0,0 +1,69 @@ +import { defineComponent, computed } from 'vue'; +import { useBem } from '@components/common'; +import { ButtonGroup } from '@components/button-group'; +import { CARD_NAME, cardProps, CardProps } from './card.props'; + +export default defineComponent({ + name: CARD_NAME, + props: cardProps, + emits: [], + setup(props: CardProps, context) { + const { bem } = useBem(CARD_NAME); + const { slots } = context; + + const toolbarItemCount = computed(() => props.toolbarItems?.length ?? 0); + + const shouldRenderHeader = computed(() => { + const isHeaderEmpty = !slots.header && !props.title; + return props.showHeader && !isHeaderEmpty; + }); + + const shouldRenderFooter = computed(() => { + const isFooterEmpty = !slots.footer && toolbarItemCount.value === 0; + return props.showFooter && !isFooterEmpty; + }); + + function renderHeader() { + if (slots.header) { + return slots.header(); + } + return ( +
    + {props.title} +
    + ); + } + + function renderContent() { + return ( +
    + {slots.content ? slots.content?.() : slots.default?.()} +
    + ); + } + + function renderFooter() { + if (slots.footer) { + return slots.footer(); + } + return ( +
    + +
    + ); + } + + return () => ( +
    + {shouldRenderHeader.value && renderHeader()} + {renderContent()} + {shouldRenderFooter.value && renderFooter()} +
    + ); + + } +}); diff --git a/packages/mobile-ui-vue/components/card/src/card.props.ts b/packages/mobile-ui-vue/components/card/src/card.props.ts new file mode 100644 index 00000000000..76b4b1ef63b --- /dev/null +++ b/packages/mobile-ui-vue/components/card/src/card.props.ts @@ -0,0 +1,32 @@ +import { ExtractPropTypes } from 'vue'; +import { createPropsResolver } from '@components/dynamic-resolver'; +import { ButtonItem } from '@components/button-group'; +import cardSchema from './schema/card.schema.json'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; + +export const CARD_NAME = 'fm-card'; + +export const cardProps = { + + /** 标题 */ + title: { type: String, default: '' }, + + /** 是否显示头部区域 */ + showHeader: { type: Boolean, default: true }, + + /** 是否显示尾部区域 */ + showFooter: { type: Boolean, default: true }, + + /** 按钮工具栏 */ + toolbarItems: { type: Array, default: [] }, +}; + +export const propsResolver = createPropsResolver( + cardProps, + cardSchema, + schemaMapper, + schemaResolver, +); + +export type CardProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/card/src/card.scss b/packages/mobile-ui-vue/components/card/src/card.scss new file mode 100644 index 00000000000..a8106b291a0 --- /dev/null +++ b/packages/mobile-ui-vue/components/card/src/card.scss @@ -0,0 +1,43 @@ +@use '../../common/src/style/mixins/index.scss' as *; + +:root { + --fm-card-background: var(--fm-white); + --fm-card-title-color: var(--fm-gray-7); +} + +.fm-card { + background-color: var(--fm-card-background); + + &__header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 11px 16px 10px; + @include hairline('bottom'); + } + + &__title { + position: relative; + padding-left: var(--fm-padding-md); + color: var(--fm-card-title-color); + font-size: var(--fm-font-size-lg); + line-height: var(--fm-line-height-lg); + font-weight: var(--fm-font-bold-light); + @include ellipsis(); + + &::before { + content: ''; + position: absolute; + left: 0; + top: 50%; + width: 3px; + height: 14px; + margin: -7px 0 0; + background: var(--fm-primary-color); + } + } + + &__footer { + @include hairline('top'); + } +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/card/src/schema/card.schema.json b/packages/mobile-ui-vue/components/card/src/schema/card.schema.json new file mode 100644 index 00000000000..4d1160f7ec4 --- /dev/null +++ b/packages/mobile-ui-vue/components/card/src/schema/card.schema.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/card.schema.json", + "title": "card", + "description": "", + "type": "object", + "properties": { + "id": { + "description": "唯一标识", + "type": "string" + }, + "type": { + "description": "组件类型", + "type": "string", + "default": "card" + }, + "title": { + "description": "显示的标题", + "type": "string", + "default": "" + }, + "showHeader": { + "description": "是否显示头部区域", + "type": "boolean", + "default": true + }, + "showFooter": { + "description": "是否显示尾部区域", + "type": "boolean", + "default": true + }, + "toolbarItems": { + "description": "按钮工具栏", + "type": "array", + "default": [] + } + }, + "required": [ + "id", + "type" + ] +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/card/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/card/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..47415f8117f --- /dev/null +++ b/packages/mobile-ui-vue/components/card/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/card/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/card/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..c1bf8da88a0 --- /dev/null +++ b/packages/mobile-ui-vue/components/card/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/common/src/style/variables.scss b/packages/mobile-ui-vue/components/common/src/style/variables.scss index 8d7e07e4e75..8bca70a58c5 100644 --- a/packages/mobile-ui-vue/components/common/src/style/variables.scss +++ b/packages/mobile-ui-vue/components/common/src/style/variables.scss @@ -73,6 +73,7 @@ --fm-font-bold: 600; --fm-font-size: 16px; --fm-line-height: 1.2; + --fm-line-height-lg: 1.5; --fm-font-size-xs: 10px; --fm-font-size-sm: 12px; diff --git a/packages/mobile-ui-vue/components/index.scss b/packages/mobile-ui-vue/components/index.scss index 5d371b8e9ab..67be30e7903 100644 --- a/packages/mobile-ui-vue/components/index.scss +++ b/packages/mobile-ui-vue/components/index.scss @@ -2,6 +2,7 @@ @use './button/src/button.scss'; @use './button-edit/src/button-edit.scss'; @use './button-group/src/button-group.scss'; +@use './card/src/card.scss'; @use './cell/src/cell.scss'; @use './checkbox-group/src/checkbox-group.scss'; @use './checkbox/src/checkbox.scss'; diff --git a/packages/mobile-ui-vue/components/index.ts b/packages/mobile-ui-vue/components/index.ts index 69d269a6750..e43e6372636 100644 --- a/packages/mobile-ui-vue/components/index.ts +++ b/packages/mobile-ui-vue/components/index.ts @@ -2,6 +2,7 @@ import { App, Plugin } from 'vue'; import Button from './button'; import ButtonEdit from './button-edit'; import ButtonGroup from './button-group'; +import Card from './card'; import Cell from './cell'; import Icon from './icon'; import InputGroup from './input-group'; @@ -59,6 +60,7 @@ const components = [ Button, ButtonEdit, ButtonGroup, + Card, Cell, Checkbox, CheckboxGroup, @@ -122,6 +124,7 @@ export { Button, ButtonEdit, ButtonGroup, + Card, Cell, Checker, Checkbox, diff --git a/packages/mobile-ui-vue/demos/card/base.vue b/packages/mobile-ui-vue/demos/card/base.vue new file mode 100644 index 00000000000..c9fbc6e7416 --- /dev/null +++ b/packages/mobile-ui-vue/demos/card/base.vue @@ -0,0 +1,52 @@ + + + + + diff --git a/packages/mobile-ui-vue/demos/card/index.vue b/packages/mobile-ui-vue/demos/card/index.vue new file mode 100644 index 00000000000..3010a50ba93 --- /dev/null +++ b/packages/mobile-ui-vue/demos/card/index.vue @@ -0,0 +1,11 @@ + + + + + diff --git a/packages/mobile-ui-vue/src/menu-data.ts b/packages/mobile-ui-vue/src/menu-data.ts index 4c6d0b06ee5..1574f8bde9c 100644 --- a/packages/mobile-ui-vue/src/menu-data.ts +++ b/packages/mobile-ui-vue/src/menu-data.ts @@ -192,6 +192,12 @@ export default { url: "/demos/list-view", component: "/list-view", }, + { + title: "卡片", + name: "card", + url: "/demos/card", + component: "/card", + }, { title: "标签栏", name: "tab-bar", -- Gitee From 912eb3a9de2304c93e17a641c7ca6332775dd8cd Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Mon, 7 Apr 2025 19:53:09 +0800 Subject: [PATCH 193/287] =?UTF-8?q?fix:=20time-picker=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui-vue/components/designer-toolbox/src/toolbox.json | 6 ++++++ .../dynamic-form/src/composition/use-type-resolver.ts | 2 ++ packages/ui-vue/components/dynamic-form/src/types.ts | 2 +- .../time-picker/src/components/time.component.tsx | 2 +- .../src/designer/time-picker.design.component.tsx | 3 ++- .../time-picker/src/schema/time-picker.schema.json | 2 +- .../components/time-picker/src/time-picker.component.tsx | 3 +++ .../ui-vue/components/time-picker/src/time-picker.props.ts | 2 +- packages/ui-vue/public/assets/farris-all.css | 4 ++-- 9 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/ui-vue/components/designer-toolbox/src/toolbox.json b/packages/ui-vue/components/designer-toolbox/src/toolbox.json index 9ae7e7cc783..2a5084fb695 100644 --- a/packages/ui-vue/components/designer-toolbox/src/toolbox.json +++ b/packages/ui-vue/components/designer-toolbox/src/toolbox.json @@ -62,6 +62,12 @@ "type": "lookup", "name": "帮助", "category": "input" + }, + { + "id": "TimePicker", + "type": "time-picker", + "name": "时间选择", + "category": "input" } ] }, diff --git a/packages/ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts b/packages/ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts index 786c8b71072..c15f1bee515 100644 --- a/packages/ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts +++ b/packages/ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts @@ -41,6 +41,8 @@ export function useTypeResolver(): UseTypeResolver { return ''; case 'datetime-picker': return ''; + case 'time-picker': + return 'onValueChange'; case 'datetime-range': return ''; case 'month-picker': diff --git a/packages/ui-vue/components/dynamic-form/src/types.ts b/packages/ui-vue/components/dynamic-form/src/types.ts index d10c2663b28..1b973d4f063 100644 --- a/packages/ui-vue/components/dynamic-form/src/types.ts +++ b/packages/ui-vue/components/dynamic-form/src/types.ts @@ -1,5 +1,5 @@ export type EditorType = 'button-edit' | 'check-box' | 'check-group' | 'combo-list' | 'combo-lookup' | 'combo-tree' | - 'date-picker' | 'date-range' | 'datetime-picker' | 'datetime-range' | 'events-editor' | 'month-picker' | 'month-range' | + 'date-picker' | 'date-range' | 'datetime-picker' | 'time-picker' | 'datetime-range' | 'events-editor' | 'month-picker' | 'month-range' | 'year-picker' | 'year-range' | 'input-group' | 'lookup' | 'number-range' | 'number-spinner' | 'radio-group' | 'text' | 'response-layout-editor-setting' | 'switch' | 'grid-field-editor' | 'field-selector' | 'schema-selector' | 'mapping-editor' | 'textarea' | 'response-form-layout-setting' | 'binding-selector' | 'query-solution-config' | 'solution-preset' | 'item-collection-editor' | diff --git a/packages/ui-vue/components/time-picker/src/components/time.component.tsx b/packages/ui-vue/components/time-picker/src/components/time.component.tsx index 008d94819e9..98d876ca017 100644 --- a/packages/ui-vue/components/time-picker/src/components/time.component.tsx +++ b/packages/ui-vue/components/time-picker/src/components/time.component.tsx @@ -425,7 +425,7 @@ export default defineComponent({ } onMounted(() => { - format.value = props.format; + format.value = getRealFormat(props.format, props.use12Hours); use12Hours.value = props.use12Hours; setModelValue(props.modelValue); buildTimes(); diff --git a/packages/ui-vue/components/time-picker/src/designer/time-picker.design.component.tsx b/packages/ui-vue/components/time-picker/src/designer/time-picker.design.component.tsx index 37888ba4763..bacc91a0d2e 100644 --- a/packages/ui-vue/components/time-picker/src/designer/time-picker.design.component.tsx +++ b/packages/ui-vue/components/time-picker/src/designer/time-picker.design.component.tsx @@ -42,7 +42,8 @@ export default defineComponent({ v-model={modelValue.value} buttonContent={groupIcon} enableClear - readonly + editable={false} + placeholder={props.placeholder} onClickButton={() => onClickButton()}> diff --git a/packages/ui-vue/components/time-picker/src/schema/time-picker.schema.json b/packages/ui-vue/components/time-picker/src/schema/time-picker.schema.json index dbcc087e395..d34a7efedae 100644 --- a/packages/ui-vue/components/time-picker/src/schema/time-picker.schema.json +++ b/packages/ui-vue/components/time-picker/src/schema/time-picker.schema.json @@ -51,7 +51,7 @@ "type": "boolean", "default": false }, - "require": { + "required": { "description": "", "type": "boolean", "default": false diff --git a/packages/ui-vue/components/time-picker/src/time-picker.component.tsx b/packages/ui-vue/components/time-picker/src/time-picker.component.tsx index ec6481a37a8..1de119272a0 100644 --- a/packages/ui-vue/components/time-picker/src/time-picker.component.tsx +++ b/packages/ui-vue/components/time-picker/src/time-picker.component.tsx @@ -44,6 +44,7 @@ export default defineComponent({ }); watch(modelValue, (newValue) => { + console.log('time-picker.component--47 \n', 'modelValue:', newValue); context.emit("valueChange", newValue); context.emit("update:modelValue", newValue); }); @@ -59,6 +60,8 @@ export default defineComponent({ buttonContent={groupIcon} placeholder={props.placeholder} enableClear={true} + popupOnClick={true} + preventScroll={true} onClear={onClearHandler} onBlur={onBlurHandler} > diff --git a/packages/ui-vue/components/time-picker/src/time-picker.props.ts b/packages/ui-vue/components/time-picker/src/time-picker.props.ts index da4ba5b249f..8a3edd6db16 100644 --- a/packages/ui-vue/components/time-picker/src/time-picker.props.ts +++ b/packages/ui-vue/components/time-picker/src/time-picker.props.ts @@ -15,7 +15,7 @@ export const timePickerProps = { minuteStep: { type: Number, default: 1 }, secondStep: { type: Number, default: 1 }, popupClassName: { type: String, default: '' }, - placeholder: { type: String, default: '' }, + placeholder: { type: String, default: '请选择时间' }, /** * 默认时间控件下拉面板,展开时的值 */ diff --git a/packages/ui-vue/public/assets/farris-all.css b/packages/ui-vue/public/assets/farris-all.css index bad983f65fa..d82719e9c95 100644 --- a/packages/ui-vue/public/assets/farris-all.css +++ b/packages/ui-vue/public/assets/farris-all.css @@ -1,2 +1,2 @@ -/**2025-03-27 19:27:52**/ -@charset "UTF-8";.rtv-container .toolbar button:active,.rtv-container .toolbar button:focus,[tabindex="-1"]:focus{outline:0!important}body,caption{text-align:left}.f-calendar-month-view td,.f-icon::before,.ngx-pagination .f-icon,progress,sub,sup{vertical-align:baseline}.f-page-header-base>.col,.f-page-header-base>[class*=col-],.f-utils-nogutters>.col,.f-utils-nogutters>[class*=col-]{padding-left:0;padding-right:0}.f-utils-fill-auto{flex-shrink:1;flex-grow:1;flex-basis:0;overflow-x:hidden;overflow-y:auto}.f-cmp-footer-hasgap,.f-page-is-managelist .f-section+.f-section,.f-page-is-managelist .f-struct-wrapper+.f-struct-wrapper>.f-section,.f-section-hasgap{margin:.5rem 0 0}.f-cmp-footer-hasgap::before,.f-page-is-managelist .f-section+.f-section::before,.f-page-is-managelist .f-struct-wrapper+.f-struct-wrapper>.f-section::before,.f-section-hasgap::before{content:"";position:absolute;height:.5rem;background:#EFF2F4;left:0;right:0;top:-.5rem}.f-section-header .f-title,.f-tmpl-for-title-withline{color:var(--f-text-01);display:inline-flex;align-items:center;line-height:1.375rem;position:relative;overflow:hidden;padding:0 0 0 .75rem}article,aside,figcaption,figure,footer,header,hgroup,legend,main,nav,section{display:block}label,output{display:inline-block}.f-section-header .f-title>*,.f-tmpl-for-title-withline>*{margin:0 .625rem 0 0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn,dl,ol,ol ol,ol ul,ul,ul ol,ul ul{margin-bottom:0}dd,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem}.rtv-container.rtv-container-week .header-cell>span,dd{margin-left:0}.f-section-header .f-title .f-title-text,.f-tmpl-for-title-withline .f-title-text{font-size:.9375rem;line-height:1.375rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.f-section-header .f-title .f-title-subtitle,.f-tmpl-for-title-withline .f-title-subtitle{font-size:.8125rem;color:var(--f-text-08);line-height:1.375rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.f-section-header .f-title::before,.f-tmpl-for-title-withline::before{content:"";width:.25rem;height:1rem;background:var(--f-theme-03);border-radius:2px;position:absolute;top:50%;left:0;margin-top:-.5rem}dl,h1,h2,h3,h4,h5,h6,ol,p,pre,ul{margin-top:0}:root{--f-theme-01:#0E6DED;--f-theme-02:linear-gradient(135deg, #0E6DED 0%, #1B75EF 100%);--f-theme-03:#2A87FF;--f-theme-04:linear-gradient(135deg, #2A87FF 0%, #328BFF 100%);--f-theme-05:#529DFF;--f-theme-06:linear-gradient(135deg, #529DFF 0%, #559FFF 100%);--f-theme-07:linear-gradient(214deg, #3F65FF 0%, #4D9AFF 100%);--f-theme-08:#6388FF;--f-theme-09:linear-gradient(46deg, #2E77FF 0%, #2A87FF 100%);--f-theme-10:#2A62AB;--f-theme-11:linear-gradient(135deg, #2A87FF 0%, #328BFF 100%);--f-theme-12:linear-gradient(135deg, #2A87FF 0%, #328BFF 100%);--f-theme-13:linear-gradient(135deg, rgba(42, 135, 255, 0.1) 0%, rgba(50, 139, 255, 0.1) 100%);--f-theme-more-02:#2E77FF;--f-aid-01:#95BEF1;--f-aid-02:#DBE9FF;--f-aid-03:#E8F2FF;--f-aid-04:#EFF5FF;--f-aid-05:#CFEDFF;--f-aid-06:#EFF2F4;--f-aid-07:linear-gradient(195deg, #FFFBEB 0%, #EFF8F8 100%);--f-aid-08:#F0F6FF;--f-aid-09:#F7FAFF;--f-aid-10:#95C3FF;--f-ornament-01:linear-gradient(135deg, #FC8249 0%, #FE9539 100%);--f-ornament-02:linear-gradient(135deg, #1FC8DC 0%, #41D2BD 100%);--f-ornament-03:linear-gradient(135deg, #4190FF 0%, #657CFF 100%);--f-ornament-04:linear-gradient(135deg, #8B82FF 0%, #A082FF 100%);--f-ornament-05:linear-gradient(135deg, #4EC87A 0%, #52D389 100%);--f-ornament-01-start:#FC8249;--f-ornament-02-start:#1FC8DC;--f-ornament-03-start:#4190FF;--f-ornament-04-start:#8B82FF;--f-ornament-05-start:#4EC87A;--f-neutral-00:#fff;--f-neutral-00-rgb:255,255,255;--f-neutral-01:#303C53;--f-neutral-02:#AEB5C6;--f-neutral-03:#CCD1DD;--f-neutral-04:#D9DEE7;--f-neutral-05:#DEE4ED;--f-neutral-06:#E6E9F0;--f-neutral-07:#E9ECF3;--f-neutral-08:#E8EBF2;--f-neutral-09:#F1F3F7;--f-neutral-10:#F5F6F9;--f-neutral-11:#F7F8FB;--f-neutral-12:#FFFFFF;--f-neutral-13:#E4E7EF;--f-neutral-14:#FAFAFC;--f-neutral-15:#1F2329;--f-neutral-15-rgb:31,35,41;--f-neutral-16:#013364;--f-neutral-17:#031233;--f-neutral-18:rgba(255, 255, 255, 0.7);--f-neutral-19:rgba(255, 255, 255, 0.85);--f-neutral-20:#ffffff;--f-neutral-21:#334052;--f-text-00:#fff;--f-text-01:#000;--f-text-02:#2D2F33;--f-text-03:#424347;--f-text-04:#5A5E66;--f-text-05:#6080AD;--f-text-06:#747B8B;--f-text-07:#848C9A;--f-text-08:#A8ADB8;--f-text-09:#B4BCCC;--f-text-10:#C7CFDD;--f-text-11:#ffffff;--f-text-12:#C7D4EE;--f-text-13:rgba(255, 255, 255, 0.85);--f-semantic-info-01:#4D9AFF;--f-semantic-info-02:#AED1FF;--f-semantic-info-03:#EEF5FF;--f-semantic-info-04:linear-gradient(135deg, #657CFF 0%, #4190FF 100%);--f-semantic-submit-01:#62CBCD;--f-semantic-submit-02:#A7E0E1;--f-semantic-submit-03:#F3FBFB;--f-semantic-submit-04:linear-gradient(135deg, #12BFD3 0%, #41D5B9 100%);--f-semantic-success-01:#6CC77F;--f-semantic-success-02:#B5E3BF;--f-semantic-success-03:#F0FAF4;--f-semantic-success-04:linear-gradient(135deg, #3CA78D 0%, #7BCA8B 100%);--f-semantic-warning-01:#F5A144;--f-semantic-warning-02:#FAD0A1;--f-semantic-warning-03:#FEF5EC;--f-semantic-warning-04:linear-gradient(135deg, #FC8249 0%, #FE9539 100%);--f-semantic-warning-06:#F7B500;--f-semantic-danger-01:#F46160;--f-semantic-danger-02:#F9B0AF;--f-semantic-danger-03:#FDEFEF;--f-semantic-danger-04:linear-gradient(135deg, #E55875 0%, #FF7878 100%)}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}.popover,body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei","Helvetica Neue",Helvetica,Arial,sans-serif}body{margin:0;font-size:.8125rem;font-weight:400;line-height:1.4286;color:var(--f-text-02);background-color:#fff}.text-monospace,code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}p{margin-bottom:1rem}abbr[data-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{padding:0}li{list-style:none}dt{font-weight:700}blockquote,figure{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--f-theme-03);text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:var(--f-theme-05);text-decoration:none}a:not([href]):not([tabindex]),a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-size:1em}pre{margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:var(--f-text-08);caption-side:bottom}th{text-align:inherit}label{margin-bottom:.3125rem}button{border-radius:0}button:focus{outline:dotted 1px;outline:-webkit-focus-ring-color auto 5px}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}.display-1,.display-2,.display-3,.display-4{line-height:1.2}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:400;color:inherit}.blockquote,hr{margin-bottom:1rem}.display-1,.display-2,.display-3,.display-4,.lead{font-weight:300}.h1,h1{font-size:1.625rem}.h2,h2{font-size:1.5rem}.h3,h3{font-size:1.375rem}.h4,h4{font-size:1.25rem}.accordion .card .card-header .panel-item-title,.farris-panel .card .card-header .panel-item-title,.h5,h5{font-size:1rem;line-height:1.375rem}.h5,h5{font-size:1rem}.btn-lg,.h6,h6{font-size:.875rem}.lead{font-size:1.015625rem}.display-1{font-size:6rem}.display-2{font-size:5.5rem}.display-3{font-size:4.5rem}.display-4{font-size:3.5rem}hr{box-sizing:content-box;height:0;overflow:visible;margin-top:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-inline,.list-unstyled{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{font-size:1.015625rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"— "}.clearfix::after,.custom-control-label::after,.custom-control-label::before{content:""}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:var(--f-theme-03)!important}.bg-secondary{background-color:#6c757d!important}.bg-success{background-color:var(--f-semantic-success-01)!important}.bg-info{background-color:var(--f-semantic-info-01)!important}.bg-warning{background-color:var(--f-semantic-warning-01)!important}.bg-danger{background-color:#dc3545!important}.bg-light{background-color:#f8f9fa!important}.bg-dark{background-color:#343a40!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid var(--f-neutral-06)!important}.border-top{border-top:1px solid var(--f-neutral-06)!important}.border-right{border-right:1px solid var(--f-neutral-06)!important}.border-bottom{border-bottom:1px solid var(--f-neutral-06)!important}.border-left{border-left:1px solid var(--f-neutral-06)!important}.border-0{border:0!important}.rounded-right,.rounded-top{border-top-right-radius:6px!important}.rounded-bottom,.rounded-right{border-bottom-right-radius:6px!important}.rounded-left,.rounded-top{border-top-left-radius:6px!important}.rounded-bottom,.rounded-left{border-bottom-left-radius:6px!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:var(--f-theme-03)!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:var(--f-semantic-success-01)!important}.border-info{border-color:var(--f-semantic-info-01)!important}.border-warning{border-color:var(--f-semantic-warning-01)!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded{border-radius:6px!important}.rounded-circle{border-radius:50%!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width:888px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media (min-width:1690px){.d-el-none{display:none!important}.d-el-inline{display:inline!important}.d-el-inline-block{display:inline-block!important}.d-el-block{display:block!important}.d-el-table{display:table!important}.d-el-table-row{display:table-row!important}.d-el-table-cell{display:table-cell!important}.d-el-flex{display:flex!important}.d-el-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.flex-row{flex-direction:row!important}.f-utils-flex-column,.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.f-button-edit-nowrap .input-group,.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex-grow:1!important;flex-shrink:1!important;flex-basis:auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width:576px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex-grow:1!important;flex-shrink:1!important;flex-basis:auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width:768px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex-grow:1!important;flex-shrink:1!important;flex-basis:auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width:888px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex-grow:1!important;flex-shrink:1!important;flex-basis:auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:888px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.fixed-bottom,.fixed-top{position:fixed;z-index:1030;left:0;right:0}.fixed-top{top:0}.fixed-bottom{bottom:0}@supports (position:sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.f-max-width-auto,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link .farris-title-auto{max-width:none!important}.mh-100{max-height:100%!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:888px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex-grow:1!important;flex-shrink:1!important;flex-basis:auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}@media (min-width:1690px){.flex-el-row{flex-direction:row!important}.flex-el-column{flex-direction:column!important}.flex-el-row-reverse{flex-direction:row-reverse!important}.flex-el-column-reverse{flex-direction:column-reverse!important}.flex-el-wrap{flex-wrap:wrap!important}.flex-el-nowrap{flex-wrap:nowrap!important}.flex-el-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-el-fill{flex-grow:1!important;flex-shrink:1!important;flex-basis:auto!important}.flex-el-grow-0{flex-grow:0!important}.flex-el-grow-1{flex-grow:1!important}.flex-el-shrink-0{flex-shrink:0!important}.flex-el-shrink-1{flex-shrink:1!important}.justify-content-el-start{justify-content:flex-start!important}.justify-content-el-end{justify-content:flex-end!important}.justify-content-el-center{justify-content:center!important}.justify-content-el-between{justify-content:space-between!important}.justify-content-el-around{justify-content:space-around!important}.align-items-el-start{align-items:flex-start!important}.align-items-el-end{align-items:flex-end!important}.align-items-el-center{align-items:center!important}.align-items-el-baseline{align-items:baseline!important}.align-items-el-stretch{align-items:stretch!important}.align-content-el-start{align-content:flex-start!important}.align-content-el-end{align-content:flex-end!important}.align-content-el-center{align-content:center!important}.align-content-el-between{align-content:space-between!important}.align-content-el-around{align-content:space-around!important}.align-content-el-stretch{align-content:stretch!important}.align-self-el-auto{align-self:auto!important}.align-self-el-start{align-self:flex-start!important}.align-self-el-end{align-self:flex-end!important}.align-self-el-center{align-self:center!important}.align-self-el-baseline{align-self:baseline!important}.align-self-el-stretch{align-self:stretch!important}.float-el-left{float:left!important}.float-el-right{float:right!important}.float-el-none{float:none!important}.m-el-0{margin:0!important}.mt-el-0,.my-el-0{margin-top:0!important}.mr-el-0,.mx-el-0{margin-right:0!important}.mb-el-0,.my-el-0{margin-bottom:0!important}.ml-el-0,.mx-el-0{margin-left:0!important}.m-el-1{margin:.25rem!important}.mt-el-1,.my-el-1{margin-top:.25rem!important}.mr-el-1,.mx-el-1{margin-right:.25rem!important}.mb-el-1,.my-el-1{margin-bottom:.25rem!important}.ml-el-1,.mx-el-1{margin-left:.25rem!important}.m-el-2{margin:.5rem!important}.mt-el-2,.my-el-2{margin-top:.5rem!important}.mr-el-2,.mx-el-2{margin-right:.5rem!important}.mb-el-2,.my-el-2{margin-bottom:.5rem!important}.ml-el-2,.mx-el-2{margin-left:.5rem!important}.m-el-3{margin:1rem!important}.mt-el-3,.my-el-3{margin-top:1rem!important}.mr-el-3,.mx-el-3{margin-right:1rem!important}.mb-el-3,.my-el-3{margin-bottom:1rem!important}.ml-el-3,.mx-el-3{margin-left:1rem!important}.m-el-4{margin:1.5rem!important}.mt-el-4,.my-el-4{margin-top:1.5rem!important}.mr-el-4,.mx-el-4{margin-right:1.5rem!important}.mb-el-4,.my-el-4{margin-bottom:1.5rem!important}.ml-el-4,.mx-el-4{margin-left:1.5rem!important}.m-el-5{margin:3rem!important}.mt-el-5,.my-el-5{margin-top:3rem!important}.mr-el-5,.mx-el-5{margin-right:3rem!important}.mb-el-5,.my-el-5{margin-bottom:3rem!important}.ml-el-5,.mx-el-5{margin-left:3rem!important}.p-el-0{padding:0!important}.pt-el-0,.py-el-0{padding-top:0!important}.pr-el-0,.px-el-0{padding-right:0!important}.pb-el-0,.py-el-0{padding-bottom:0!important}.pl-el-0,.px-el-0{padding-left:0!important}.p-el-1{padding:.25rem!important}.pt-el-1,.py-el-1{padding-top:.25rem!important}.pr-el-1,.px-el-1{padding-right:.25rem!important}.pb-el-1,.py-el-1{padding-bottom:.25rem!important}.pl-el-1,.px-el-1{padding-left:.25rem!important}.p-el-2{padding:.5rem!important}.pt-el-2,.py-el-2{padding-top:.5rem!important}.pr-el-2,.px-el-2{padding-right:.5rem!important}.pb-el-2,.py-el-2{padding-bottom:.5rem!important}.pl-el-2,.px-el-2{padding-left:.5rem!important}.p-el-3{padding:1rem!important}.pt-el-3,.py-el-3{padding-top:1rem!important}.pr-el-3,.px-el-3{padding-right:1rem!important}.pb-el-3,.py-el-3{padding-bottom:1rem!important}.pl-el-3,.px-el-3{padding-left:1rem!important}.p-el-4{padding:1.5rem!important}.pt-el-4,.py-el-4{padding-top:1.5rem!important}.pr-el-4,.px-el-4{padding-right:1.5rem!important}.pb-el-4,.py-el-4{padding-bottom:1.5rem!important}.pl-el-4,.px-el-4{padding-left:1.5rem!important}.p-el-5{padding:3rem!important}.pt-el-5,.py-el-5{padding-top:3rem!important}.pr-el-5,.px-el-5{padding-right:3rem!important}.pb-el-5,.py-el-5{padding-bottom:3rem!important}.pl-el-5,.px-el-5{padding-left:3rem!important}.m-el-auto{margin:auto!important}.mt-el-auto,.my-el-auto{margin-top:auto!important}.mr-el-auto,.mx-el-auto{margin-right:auto!important}.mb-el-auto,.my-el-auto{margin-bottom:auto!important}.ml-el-auto,.mx-el-auto{margin-left:auto!important}}.f-cmp-pt,.f-cmp-py{padding-top:.875rem!important}.f-cmp-pb,.f-cmp-py{padding-bottom:.875rem!important}.f-cmp-mr,.f-cmp-mx{margin-right:.875rem!important}.f-cmp-ml,.f-cmp-mx{margin-left:.875rem!important}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:888px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:var(--f-theme-03)!important}.text-secondary{color:#6c757d!important}.text-success{color:var(--f-semantic-success-01)!important}.text-warning{color:var(--f-semantic-warning-01)!important}.text-danger{color:#dc3545!important}.text-light{color:#f8f9fa!important}.text-dark{color:#343a40!important}.text-body{color:var(--f-text-02)!important}.text-muted{color:var(--f-text-08)!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.visible{visibility:visible!important}.invisible{visibility:hidden!important}body{background:#f0f3f6}input::-ms-clear{display:none}input::-webkit-contacts-auto-fill-button{visibility:hidden;display:none!important;pointer-events:none;position:absolute;right:0}.f-utils-fill-flex-column,.f-utils-flex-column,.f-utils-flex-row,.f-utils-flex-row-wrap{display:flex!important;overflow:hidden}.h1,h1{line-height:2.125rem}.h2,h2{line-height:2}.h3,h3{line-height:1.875rem}.h4,h4{line-height:1.75rem}.btn-link,.dropdown-item,.h6,h6{line-height:1.25rem}.text-dark{color:var(--f-text-01)}.text-danger{color:var(--f-semantic-danger-01)!important}.text-info{color:var(--f-theme-05)!important}::-webkit-scrollbar{width:7px;height:7px;background-color:var(--f-neutral-14)}::-webkit-scrollbar-track{border-radius:0;background-color:var(--f-neutral-14);border:none;background-clip:padding-box}::-webkit-scrollbar-thumb{background-color:var(--f-neutral-03);border:none;background-clip:content-box;opacity:.6;border-radius:7px}::-webkit-scrollbar-thumb:hover{background:var(--f-text-06)}.f-cmp-mt{margin-top:.875rem!important}.f-cmp-mb{margin-bottom:.875rem!important}.f-cmp-mx-minus{margin-left:-.875rem!important;margin-right:-.875rem!important}.f-cmp-px{padding-left:.875rem!important;padding-right:.875rem!important}.f-cmp-p{padding:.875rem!important}.f-cmp-gutter{border-bottom:10px solid #EFF2F4}.f-split-border-b{border-bottom:1px solid var(--f-neutral-08)}.f-common-px{padding-left:.875rem;padding-right:.875rem}.f-col-h1,.f-col-h10,.f-col-h11,.f-col-h12,.f-col-h2,.f-col-h3,.f-col-h4,.f-col-h5,.f-col-h6,.f-col-h7,.f-col-h8,.f-col-h9,.f-col-w1,.f-col-w10,.f-col-w11,.f-col-w12,.f-col-w2,.f-col-w3,.f-col-w4,.f-col-w5,.f-col-w6,.f-col-w7,.f-col-w8,.f-col-w9{padding-right:14px;padding-left:14px}.f-common-py{padding-top:.875rem;padding-bottom:.875rem}.f-common-py-form{padding-top:.875rem;padding-bottom:.5rem}.f-utils-absolute-all{top:0;bottom:0;position:absolute;right:0;left:0}.accordion .card .card-header,.f-col-h1,.f-col-h10,.f-col-h11,.f-col-h12,.f-col-h2,.f-col-h3,.f-col-h4,.f-col-h5,.f-col-h6,.f-col-h7,.f-col-h8,.f-col-h9,.f-col-w1,.f-col-w10,.f-col-w11,.f-col-w12,.f-col-w2,.f-col-w3,.f-col-w4,.f-col-w5,.f-col-w6,.f-col-w7,.f-col-w8,.f-col-w9,.farris-panel .card .card-header,.rtv-container .toolbar .btns .btn-group button i.f-icon{position:relative}.f-utils-fill-flex-column{flex-shrink:1;flex-grow:1;flex-basis:0;flex-direction:column!important}.f-utils-flex-row{flex-direction:row!important;flex-wrap:nowrap}.f-utils-flex-row-wrap{flex-direction:row!important;flex-wrap:wrap!important}.f-utils-fill-flex-row,.f-utils-fill-flex-row-wrap{flex-shrink:1;display:flex!important;overflow:hidden}.f-utils-fill-flex-row{flex-grow:1;flex-basis:0;flex-direction:row!important;flex-wrap:nowrap!important}.f-utils-fill-flex-row-wrap{flex-grow:1;flex-basis:0;flex-direction:row!important;flex-wrap:wrap!important}.f-utils-fill{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.f-utils-overflow-xhya{overflow-x:hidden!important;overflow-y:auto!important}.f-utils-overflow-xayh{overflow-y:hidden!important;overflow-x:auto!important}.f-utils-overflow-xaya{overflow:auto!important}.f-utils-overflow-hidden{overflow:hidden!important}.f-utils-overflow-auto{overflow:auto!important}.f-utils-hcenter-vcenter{display:flex;align-items:center;justify-content:center}.f-overflow-y-auto{overflow-y:auto!important}.f-overflow-y-hidden{overflow-y:hidden!important}.f-overflow-x-auto{overflow-x:auto!important}.f-overflow-x-hidden{overflow-x:hidden!important}@media (min-width:576px){.f-overflow-sm-y-auto{overflow-y:auto!important}.f-overflow-sm-y-hidden{overflow-y:hidden!important}.f-overflow-sm-x-auto{overflow-x:auto!important}.f-overflow-sm-x-hidden{overflow-x:hidden!important}}@media (min-width:768px){.f-overflow-md-y-auto{overflow-y:auto!important}.f-overflow-md-y-hidden{overflow-y:hidden!important}.f-overflow-md-x-auto{overflow-x:auto!important}.f-overflow-md-x-hidden{overflow-x:hidden!important}}@media (min-width:888px){.f-overflow-lg-y-auto{overflow-y:auto!important}.f-overflow-lg-y-hidden{overflow-y:hidden!important}.f-overflow-lg-x-auto{overflow-x:auto!important}.f-overflow-lg-x-hidden{overflow-x:hidden!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}.f-overflow-xl-y-auto{overflow-y:auto!important}.f-overflow-xl-y-hidden{overflow-y:hidden!important}.f-overflow-xl-x-auto{overflow-x:auto!important}.f-overflow-xl-x-hidden{overflow-x:hidden!important}}@media (min-width:1690px){.text-el-left{text-align:left!important}.text-el-right{text-align:right!important}.text-el-center{text-align:center!important}.f-overflow-el-y-auto{overflow-y:auto!important}.f-overflow-el-y-hidden{overflow-y:hidden!important}.f-overflow-el-x-auto{overflow-x:auto!important}.f-overflow-el-x-hidden{overflow-x:hidden!important}}.farris-overflow-y-auto{overflow-x:hidden!important;overflow-y:auto!important}.farris-overflow-y-hidden{overflow-x:hidden!important;overflow-y:hidden!important}.farris-overflow-hidden{overflow:hidden!important}.f-col-w1{min-height:1px;width:8.3333333333%}.f-col-w2{min-height:1px;width:16.6666666667%}.f-col-w3{min-height:1px;width:25%}.f-col-w4{min-height:1px;width:33.3333333333%}.f-col-w5{min-height:1px;width:41.6666666667%}.f-col-w6{min-height:1px;width:50%}.f-col-w7{min-height:1px;width:58.3333333333%}.f-col-w8{min-height:1px;width:66.6666666667%}.f-col-w9{min-height:1px;width:75%}.f-col-w10{min-height:1px;width:83.3333333333%}.f-col-w11{min-height:1px;width:91.6666666667%}.f-col-w12{min-height:1px;width:100%}.f-col-h1{min-height:1px;height:8.3333333333%}.f-col-h2{min-height:1px;height:16.6666666667%}.f-col-h3{min-height:1px;height:25%}.f-col-h4{min-height:1px;height:33.3333333333%}.f-col-h5{min-height:1px;height:41.6666666667%}.f-col-h6{min-height:1px;height:50%}.f-col-h7{min-height:1px;height:58.3333333333%}.f-col-h8{min-height:1px;height:66.6666666667%}.f-col-h9{min-height:1px;height:75%}.f-col-h10{min-height:1px;height:83.3333333333%}.f-col-h11{min-height:1px;height:91.6666666667%}.f-col-h12{min-height:1px;height:100%}.f-utils-text-break{white-space:normal!important;word-break:break-all!important}.f-text-emphasize{color:var(--f-text-01)!important}.f-text-light{color:var(--f-text-04)!important}.f-text-lighter{color:var(--f-text-08)!important}.f-text-mute{color:var(--f-text-09)!important}.f-text-two-line{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;max-height:2.5rem}.f-min-width-auto{min-width:auto!important}.win11Scroll{overflow:overlay;scroll-behavior:smooth}.win11Scroll::-webkit-scrollbar{width:14px;height:14px;border-radius:7px}.win11Scroll::-webkit-scrollbar-thumb{display:none;background-clip:padding-box;border:6px solid transparent;border-radius:14px}.win11Scroll::-webkit-scrollbar-thumb:hover{border:4px solid transparent}.win11Scroll::-webkit-scrollbar-button:single-button{height:14px}.win11Scroll:hover::-webkit-scrollbar-thumb{display:block}.win11Scroll.show::-webkit-scrollbar-thumb{display:block}.win11Scroll::-webkit-scrollbar-corner{background:rgba(0,0,0,0)}.win11Scroll::-webkit-scrollbar-track{background-color:transparent}.win11Scroll.nobtn::-webkit-scrollbar:vertical{background:0 0}.win11Scroll.nobtn::-webkit-scrollbar:horizontal{background:0 0}.win11Scroll.nobtn::-webkit-scrollbar-button:single-button{height:0;width:0}.accordion,.farris-panel{border:1px solid var(--f-neutral-13)}.accordion .card,.farris-panel .card{border-top:0;background:var(--f-neutral-00);border-color:var(--f-neutral-13)}.accordion .card .card-header,.farris-panel .card .card-header{border-width:0;background-color:var(--f-neutral-00);color:var(--f-text-02);padding:.5265rem .875rem}.accordion .card .card-header:hover,.accordion .card.f-state-hover,.farris-panel .card .card-header:hover,.farris-panel .card.f-state-hover{color:var(--f-theme-05);border-color:var(--f-neutral-13);background-color:var(--f-neutral-00)}.accordion .card .card-body,.farris-panel .card .card-body{padding:.9375rem}.accordion .card.f-state-disabled .card-header,.farris-panel .card.f-state-disabled .card-header{color:var(--f-text-07);background-color:var(--f-neutral-00);border-color:var(--f-neutral-02)}.accordion .card.f-state-disabled .f-icon,.farris-panel .card.f-state-disabled .f-icon{display:none}.accordion .card.f-state-disabled .accordion-title,.farris-panel .card.f-state-disabled .accordion-title{color:var(--f-text-07)}.accordion .card.f-state-selected .card-header,.farris-panel .card.f-state-selected .card-header{color:var(--f-theme-01);background-color:var(--f-neutral-00);border-color:var(--f-neutral-13)}.accordion .accordion-title,.farris-panel .accordion-title{color:var(--f-text-02)}.accordion .f-accordion-collapse,.accordion .f-accordion-expand,.farris-panel .f-accordion-collapse,.farris-panel .f-accordion-expand{margin-top:-.3125rem;color:var(--f-neutral-01);font-size:1.25rem;width:1.25rem;height:1.25rem;vertical-align:middle}.accordion .f-accordion-collapse::before,.farris-panel .f-accordion-collapse::before{font-family:FarrisIcons;content:"\e013"}.accordion .f-accordion-expand::before,.f-btn-collapse-expand::after,.farris-panel .f-accordion-expand::before{font-family:FarrisIcons;content:"\e015"}.accordion .card-header,.farris-panel .card-header{cursor:pointer}.accordion .panel-item-title,.farris-panel .panel-item-title{float:left}.accordion .panel-item-tool,.farris-panel .panel-item-tool{float:right}.accordion .panel-item-clear,.farris-panel .panel-item-clear{clear:both}.accordion .f-state-disabled,.farris-panel .f-state-disabled{pointer-events:none}.accordion .card,.farris-panel .card{border-left:0;border-right:0}.accordion .active,.farris-panel .active{height:initial;transition:height .35s ease}.accordion .inactive,.farris-panel .inactive{height:0;overflow:hidden;transition:height .35s ease}.farris-panel .card:not(:first-of-type) .card-header:first-child,.farris-panel .card:not(:first-of-type):not(:last-of-type){border-radius:0}.farris-panel .card:first-of-type{border-bottom-right-radius:0;border-bottom-left-radius:0}.farris-panel .card:last-of-type{border-bottom:0;border-top-left-radius:0;border-top-right-radius:0}.f-cmp-panel-pt-card-subgrid .card,.farris-panel-dividing-line .card{border-width:0}.f-cmp-panel-pt-card-subgrid .card .card-header,.farris-panel-dividing-line .card .card-header{border-width:0 0 1px;background:var(--f-neutral-00);border-color:var(--f-neutral-13)}.f-cmp-panel-pt-card-subgrid .card.f-state-selected .card-header,.farris-panel-dividing-line .card.f-state-selected .card-header{background-color:var(--f-neutral-00);border-color:var(--f-neutral-13);color:var(--f-theme-01)}.f-cmp-panel-pt-card-subgrid{margin:0}.f-cmp-panel-has-form .card .card-body{padding:0}.accordion .card .card-header .f-icon,.farris-panel .card .card-header .f-icon{color:var(--f-text-02)}.accordion .card .card-header:hover .f-icon,.farris-panel .card .card-header:hover .f-icon{color:var(--f-theme-05)}.accordion .card.f-state-selected .card-header .f-icon,.farris-panel .card.f-state-selected .card-header .f-icon{color:var(--f-theme-01)}.rtv-container{width:100%;height:100%;display:flex;flex-direction:column;background:#fff}.rtv-container .room-subject{border-radius:2px}.rtv-container .room-subject dt{font-size:13px;text-overflow:ellipsis;overflow:hidden}.rtv-container .room-subject_category{padding:0 4px;border-radius:4px;margin-right:8px;font-size:12px;display:inline-block;line-height:20px;background:var(--f-aid-02);border:1px solid var(--f-theme-01)}.rtv-container .room-subject dd.other-info{margin:0;line-height:18px;color:var(--f-text-07);text-overflow:ellipsis;overflow:hidden;padding-top:3px}.rtv-container .text-center{align-items:center;justify-content:center}.rtv-container .toolbar{height:50px;width:100%;border-bottom:1px solid var(--f-neutral-07);display:flex;align-items:center;padding-left:20px}.rtv-container .toolbar .view-type{width:131px;height:32px;line-height:32px;background:var(--f-aid-04);border-radius:32px;display:flex;align-items:center}.rtv-container .toolbar .view-type .btn-day,.rtv-container .toolbar .view-type .btn-week{width:64px;height:30px;border-radius:32px;background:0 0;border:0;font-weight:400;cursor:pointer}.rtv-container .toolbar .view-type .btn-active{background:rgba(255,255,255,.75);box-shadow:0 4px 18px 0 rgba(2,75,193,.2);color:var(--f-theme-03);cursor:default}.rtv-container .toolbar .line{height:20px;width:20px;display:inline-block;border-right:1px solid var(--f-neutral-06);margin-right:20px}.rtv-container .toolbar .btns{display:flex;width:112px;margin-right:20px}.rtv-container .toolbar .btns button{height:26px;background:#FFF;border:1px solid #e8ebf2;box-shadow:0 2px 6px 0 rgba(31,35,41,.06);border-radius:6px;outline:0;cursor:pointer}.rtv-container .toolbar .btns .btn-today{width:50px;margin-right:5px}.rtv-container .toolbar .btns .btn-group{width:53px;flex-grow:1;display:flex}.rtv-container .toolbar .btns .btn-group button{width:26px}.rtv-container .toolbar .btns .btn-group button i.f-icon{left:-2px;top:2px}.rtv-container .toolbar .btns .btn-prev{border-radius:6px 0 0 6px}.rtv-container .toolbar .btns .btn-next{border-radius:0 6px 6px 0}.rtv-container .main{flex-grow:1;display:flex;flex-direction:column;overflow:hidden}.rtv-container .main .fixed-left{position:sticky!important;left:0;z-index:9;flex:none!important;width:300px}.rtv-container .main .roomname{align-items:center;justify-content:start;background-color:#fff!important}.rtv-container .main .header{height:40px;overflow:hidden;border-bottom:1px solid #E6E9F0}.rtv-container .main .body .room-cell,.rtv-container .main .header-cell{height:100%;border-right:1px solid var(--f-neutral-06);border-bottom:1px solid var(--f-neutral-06);display:flex}.rtv-container .main .header-row{display:flex;flex-direction:row;width:2700px;height:100%}.rtv-container .main .header-cell>span.time{margin-left:-20px;font-size:14px;color:var(--f-text-04);font-weight:500}.rtv-container .main .time-cell{width:100px;align-items:center}.rtv-container .main .body{flex-grow:1;height:100%}.rtv-container .main .body .room-row{min-height:62px;display:flex;flex-direction:row;width:2700px}.rtv-container .main .body .room-cell{position:relative}.rtv-container .main .body .room-cell .item-content{width:100px;position:absolute;left:0;flex-wrap:nowrap;display:flex;flex-direction:column;line-height:20px;justify-content:center;z-index:1;word-break:normal;white-space:nowrap;overflow:hidden;height:calc(100% - 4px);cursor:pointer}.rtv-container .main .body .room-cell .item-content:hover{box-shadow:2px 2px 7px #bebebe}.rtv-container .main .body .room-cell .item-content .item-content-wrap{border-radius:6px;background:var(--f-aid-02);width:100%;height:100%}.rtv-container .main .body .room-cell .item-content .item-content-wrap.gray{background-color:#f0f0f0}.rtv-container .main .body .room-cell .item-content .item-content-wrap.gray .room-subject_category{border:1px solid #ccc;background:#F2F3F5;color:#878d99}.rtv-container .main .body .room-cell .item-content .item-content-wrap.blue{background:#dae9ff}.rtv-container .main .body .room-cell .item-content .item-content-wrap.blue .room-subject_category{border:1px solid #9bf;background:#9bf;color:#fff}.rtv-container .main .body .room-cell .item-content .item-content-wrap.orange{background:#ffedda}.rtv-container .main .body .room-cell .item-content .item-content-wrap.orange .room-subject_category{border:1px solid #ff772e;background:#ff772e;color:#fff5ea}.rtv-container .main .body .room-cell .item-content .item-content-wrap.mintgreen{background:#daffe0}.rtv-container .main .body .room-cell .item-content .item-content-wrap.mintgreen .room-subject_category{border:1px solid #42fc57;background:#42fc57;color:#449e00}.rtv-container .main .body .room-cell .item-content .item-content-wrap.red{background:#ffdada}.rtv-container .main .body .room-cell .item-content .item-content-wrap.red .room-subject_category{border:1px solid #ff8383;background:#ffa4a4;color:#ae0000}.rtv-container .main .body .room-cell .item-content .item-content-wrap.pink{background:#f6daff}.rtv-container .main .body .room-cell .item-content .item-content-wrap.pink .room-subject_category{border:1px solid #f867d6;background:#f867d6;color:#ffe2ef}.rtv-container .main .body .room-cell .item-content .item-content-wrap.bluegreen{background:#dafffe}.rtv-container .main .body .room-cell .item-content .item-content-wrap.bluegreen .room-subject_category{border:1px solid #2ac3ac;background:#2ac3ac;color:#efffe5}.rtv-container .main .body .room-cell .item-content .selected{outline:var(--f-theme-05) solid 2px;outline-offset:-2px;border-radius:6px}.rtv-container.rtv-container-week .header-cell,.rtv-container.rtv-container-week .room-cell{flex:1}.rtv-container.rtv-container-week .header-row,.rtv-container.rtv-container-week .room-row{width:auto!important}.rtv-container.rtv-container-week .time-cell{line-height:20px;width:150px}.rtv-container.rtv-container-week .time-cell .week-day-subject{cursor:pointer;transition:all .1s ease}.rtv-container.rtv-container-week .time-cell .week-day-subject:hover{background-color:var(--f-aid-02)}.rtv-container.rtv-container-week .time-cell li.selected{border:1px solid var(--f-theme-01);border-radius:4px;background:var(--f-aid-02)}.rtv-container.rtv-container-week .time-cell .rtv-week-day{text-align:center;border-radius:10px;width:20px;margin:0 5px;font-size:13px}.rtv-container.rtv-container-week .time-cell .rtv-week-day.active{background-image:linear-gradient(135deg,var(--f-aid-10) 0,var(--f-theme-05) 100%);color:#fff}.rtv-container.rtv-container-week .time-cell .rtv-week-day-item:before{content:"●";margin-right:3px;top:-2px;position:relative}.reserve-detail-container{display:flex;flex-direction:column;background:#FFF;box-shadow:0 4px 12px 2px rgba(31,35,41,.1);border-radius:16px;width:368px;height:436px;transition:all .12s ease}.reserve-detail-container .detail-header{height:185px;background-image:linear-gradient(116deg,var(--f-aid-10) 0,var(--f-theme-05) 100%);border-radius:16px 16px 0 0}.reserve-detail-container .detail-header.gray{color:#fff;background-image:linear-gradient(116deg,#bcbebf 0,#909293 100%)}.reserve-detail-container .detail-header.blue{color:#fff;background-image:linear-gradient(116deg,#09F 0,#0AF 100%)}.reserve-detail-container .detail-header.orange{color:#fff;background-image:linear-gradient(116deg,#ffc78c 0,#ffab58 100%)}.reserve-detail-container .detail-header.mintgreen{color:#fff;background-image:linear-gradient(116deg,#72cc89 0,#00a804 100%)}.reserve-detail-container .detail-header.red{color:#fff;background-image:linear-gradient(116deg,#ff9797 0,#ff3939 100%)}.reserve-detail-container .detail-header.pink{color:#fff;background-image:linear-gradient(116deg,#f1b9fb 0,#d458ff 100%)}.reserve-detail-container .detail-header.bluegreen{color:#fff;background-image:linear-gradient(116deg,#59ddc9 0,#1694c5 100%)}.reserve-detail-container .detail-header .detail-toolbar{height:44px;justify-content:flex-end;align-items:center;padding-right:15px;display:flex}.reserve-detail-container .detail-header .detail-toolbar span.f-icon{font-size:14px;cursor:pointer;width:32px;height:32px;text-align:center;line-height:32px;border-radius:6px}.reserve-detail-container .detail-header .detail-toolbar span.f-icon:hover{background:rgba(255,255,255,.2)}.reserve-detail-container .detail-header .detail-title{flex:1;padding:0 24px;overflow:hidden}.reserve-detail-container .detail-header .detail-title .detail-place{font-size:16px}.reserve-detail-container .detail-header .detail-title div.title-content{margin:6px 0 16px;font-size:20px;line-height:28px}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge{height:18px;border-radius:4px;display:inline-block;font-size:12px;text-align:center;line-height:18px;padding:0 5px}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge.gray{border:1px solid #ccc;background:#F2F3F5;color:#878d99}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge.blue{border:1px solid #9bf;background:#9bf;color:#fff}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge.pink{border:1px solid #f867d6;background:#f867d6;color:#ffe2ef}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge.red{border:1px solid #ff8383;background:#ffa4a4;color:#ae0000}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge.mintgreen{border:1px solid #42fc57;background:#42fc57;color:#449e00}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge.orange{border:1px solid #ff772e;background:#ff772e;color:#fff5ea}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge.bluegreen{border:1px solid #48fce0;background:#5efee6;color:#00b8bd}.reserve-detail-container .detail-header .detail-title .detail-timer{height:30px;font-size:14px;line-height:30px}.reserve-detail-container .detail-info-content{flex:1;padding:2px 2px 10px;color:#666;border-radius:0 0 16px 16px}.reserve-detail-container .detail-info-content ul{list-style:none;margin:0;padding:16px;font-size:14px}.reserve-detail-container .detail-info-content ul li{line-height:28px;display:flex;flex-direction:row}.f-calendar-day-view-header-primary,.reserve-detail-container .detail-info-content ul li span.detail-content{flex:1}.reserve-detail-container .detail-info-content ul li span.detail-subtitle{width:70px;display:inline-block}.shading-border-top{border-top:1px solid #fff!important}.f-avatar{position:relative;cursor:pointer;overflow:hidden}.f-avatar.f-avatar-readonly{cursor:default}.f-avatar.f-avatar-circle{border-radius:100%;overflow:hidden}.f-avatar.f-avatar-square{border-radius:0}.f-avatar .f-avatar-defult,.f-avatar .f-avatar-image{display:inline-block;width:100%;height:100%}.f-avatar .f-avatar-icon{display:none;position:absolute;left:0;right:0;top:0;bottom:0;align-items:center;justify-content:center;background:rgba(0,0,0,.3)}.f-avatar .f-avatar-icon .f-icon{font-size:24px;color:#fff}.f-avatar.f-avatar-circle .f-avatar-icon{border-radius:100%}.f-avatar.f-avatar-square .f-avatar-icon{border-radius:0}.f-avatar .f-avatar-upload-loading{position:absolute;left:0;top:0;display:inline-block;width:100%;height:100%;background-color:rgba(0,0,0,.15)}.f-avatar .f-avatar-upload-loading .loading-inner{position:absolute;width:100%;left:0;top:50%;margin-top:-25px;height:50px;line-height:50px;text-align:center;font-size:16px;color:#fff}.f-avatar:hover .f-avatar-icon{display:flex}.btn{display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:1px solid transparent;padding:.1875rem .875rem;font-size:.8125rem;line-height:1.4286;border-radius:6px;transition:none}@media screen and (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:focus,.btn:hover{text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn.disabled,.btn:disabled{opacity:1;box-shadow:none}.btn:not(:disabled):not(.disabled){cursor:pointer}.btn:not(:disabled):not(.disabled).active,.btn:not(:disabled):not(.disabled).active:focus,.btn:not(:disabled):not(.disabled):active,.btn:not(:disabled):not(.disabled):active:focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:var(--f-text-00);background:var(--f-theme-04);border-color:var(--f-theme-03);box-shadow:0 4px 10px 0 rgba(var(--f-theme-03),.2);position:relative;z-index:20}.btn-primary:hover,.btn-primary:not(:disabled):not(.disabled).focus,.btn-primary:not(:disabled):not(.disabled):focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-primary:hover{color:var(--f-text-00);background:linear-gradient(135deg,#529DFF 0,#559FFF 100%);border-color:var(--f-theme-05)}.btn-primary.disabled,.btn-primary:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:var(--f-text-00);background:var(--f-theme-02);border-color:var(--f-theme-01);box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-secondary,.btn-secondary:hover,.btn-secondary:not(:disabled):not(.disabled).focus,.btn-secondary:not(:disabled):not(.disabled):focus{box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-secondary{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-08)}.btn-secondary:hover{color:var(--f-theme-05);background:var(--f-neutral-12);border-color:var(--f-theme-05)}.btn-secondary.disabled,.btn-secondary:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:var(--f-theme-01);background:var(--f-neutral-12);border-color:var(--f-theme-01);box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-danger,.btn-danger:hover{color:var(--f-semantic-danger-01);box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-danger{background:var(--f-neutral-00);border-color:#F9B0AF}.btn-danger:hover{background:rgba(var(--f-semantic-danger-01),.06);border-color:var(--f-semantic-danger-01)}.btn-danger:not(:disabled):not(.disabled).focus,.btn-danger:not(:disabled):not(.disabled):focus{box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-danger.disabled,.btn-danger:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:var(--f-semantic-danger-01);background:rgba(var(--f-semantic-danger-01),.1);border-color:var(--f-semantic-danger-01);box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-success,.btn-success:hover,.btn-success:not(:disabled):not(.disabled).focus,.btn-success:not(:disabled):not(.disabled):focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-success,.btn-success:hover{color:var(--f-text-00);background:var(--f-semantic-success-01);border-color:var(--f-semantic-success-01)}.btn-success.disabled,.btn-success:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:var(--f-text-00);background:var(--f-semantic-success-01);border-color:var(--f-semantic-success-01);box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-warning,.btn-warning:hover{color:var(--f-text-00);background:var(--f-semantic-warning-01);border-color:var(--f-semantic-warning-01);box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-warning:not(:disabled):not(.disabled).focus,.btn-warning:not(:disabled):not(.disabled):focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-warning.disabled,.btn-warning:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-dark,.btn-dark:hover,.btn-dark:not(:disabled):not(.disabled).focus,.btn-dark:not(:disabled):not(.disabled):focus,.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:var(--f-text-00);background:var(--f-semantic-warning-01);border-color:var(--f-semantic-warning-01)}.btn-dark{color:var(--f-text-00);background:#343a40;border-color:#343a40}.btn-dark:hover{color:var(--f-text-00);background:#23272b;border-color:#23272b}.btn-dark.disabled,.btn-dark:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:var(--f-text-00);background:#1d2124;border-color:#171a1d;box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-light,.btn-light:hover{color:#212529;box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-light{background:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{background:#e2e6ea;border-color:#dae0e5}.btn-light:not(:disabled):not(.disabled).focus,.btn-light:not(:disabled):not(.disabled):focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-light.disabled,.btn-light:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-info,.btn-info:hover,.btn-info:not(:disabled):not(.disabled).focus,.btn-info:not(:disabled):not(.disabled):focus,.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background:#dae0e5;border-color:#d3d9df}.btn-info{background:var(--f-theme-03);border-color:var(--f-theme-03)}.btn-info:hover{color:var(--f-text-00);background:linear-gradient(135deg,#529DFF 0,#559FFF 100%);border-color:var(--f-theme-05)}.btn-info.disabled,.btn-info:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:var(--f-text-00);background:var(--f-theme-02);border-color:var(--f-theme-02);box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-link,.btn-link:hover{background-color:transparent}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-link{font-weight:400;color:var(--f-theme-03);padding:0;border:0}.btn-lg,.btn-sm{line-height:1.4286;border-radius:6px}.btn-link:hover{color:var(--f-theme-05);text-decoration:none;border-color:transparent}.btn-link.focus,.btn-link:focus{text-decoration:none;border-color:transparent;color:var(--f-theme-01);box-shadow:none}.btn-link.active,.btn-link:active{box-shadow:none!important;color:var(--f-theme-01)}.btn-link.disabled,.btn-link:disabled{color:var(--f-text-07);pointer-events:none}.btn-link+.btn-link{margin-right:.875rem}.btn-lg{padding:.25rem 1.125rem}.btn-sm{padding:.125rem .5rem;font-size:.75rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.btn-warning{color:var(--f-text-00)}.btn-outline-danger.disabled,.btn-outline-danger:disabled,.btn-outline-dark.disabled,.btn-outline-dark:disabled,.btn-outline-info.disabled,.btn-outline-info:disabled,.btn-outline-light.disabled,.btn-outline-light:disabled,.btn-outline-link.disabled,.btn-outline-link:disabled,.btn-outline-primary.disabled,.btn-outline-primary:disabled,.btn-outline-secondary.disabled,.btn-outline-secondary:disabled,.btn-outline-success.disabled,.btn-outline-success:disabled,.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:var(--f-text-07);border-color:var(--f-neutral-05);background:0 0}.btn-info{color:var(--f-text-00)}.f-cursor-pointer{cursor:pointer!important}.f-btn-collapse-expand{color:var(--f-text-03);background-color:transparent;box-shadow:none}.f-btn-collapse-expand:hover{color:var(--f-theme-05)}.f-btn-collapse-expand:active{color:var(--f-theme-01)}.f-btn-collapse-expand:active,.f-btn-collapse-expand:focus{box-shadow:none!important}.f-btn-collapse-expand::after{width:1em;height:1em;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-size:1rem;font-style:normal;font-variant:normal;font-weight:400;line-height:1;speak:none;text-transform:none;display:inline-block;vertical-align:middle;margin-left:.25rem}.f-btn-collapse-expand.f-state-expand::after{content:"\e013"}.f-toolbar .f-btn-collapse-expand{padding-right:0}.f-pretend-link{color:var(--f-theme-03)!important;cursor:pointer;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}.f-pretend-link:hover{color:var(--f-theme-05);text-decoration:none}.btn.btn-px{padding-left:2.25rem;padding-right:2.25rem}.f-btn-ml{margin-left:.5rem!important}.f-btn-link-ml,.f-btn-link-mr{margin-left:.875rem!important}.f-btn-mr{margin-right:.625rem!important}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex-grow:0;flex-shrink:1;flex-basis:auto}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group-sm>.btn{padding:.125rem .5rem;font-size:.75rem;line-height:1.4286;border-radius:6px}.btn-group-lg>.btn{padding:.25rem 1.125rem;font-size:.875rem;line-height:1.4286;border-radius:6px}.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropright-top .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropup-left .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before,.dropleft-up .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-lg+.dropdown-toggle-split{padding-right:.84375rem;padding-left:.84375rem}.btn-group.show .dropdown-toggle{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-group.show .dropdown-toggle.btn-link{box-shadow:none}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.f-btn-group .f-btn-group-links .btn-link{margin-left:.375rem;margin-right:.375rem}.f-btn-group .f-btn-group-links .btn-link:first-child{margin-left:0}.f-btn-group .f-btn-group-links .btn-link:last-child{margin-right:.1875rem}.f-btn-group .f-btn-group-links .btn-icontext{color:var(--f-theme-03);padding:0 3px;margin:0 0 0 .375rem}.f-btn-group .f-btn-group-links .btn-icontext .f-icon{margin:0}.f-btn-group .f-btn-group-links .btn-icontext:last-child{margin-right:0}.f-btn-group .f-btn-group-dropdown{padding:0 3px;margin-left:.375rem}.f-btn-group .f-btn-group-dropdown .f-btn-dropdown{display:inline-block;border:none;outline:0;background:var(--f-aid-04);color:var(--f-theme-03);width:1rem;height:1rem;line-height:1rem;text-align:center;border-radius:100%;padding:0}.f-btn-group .f-btn-group-dropdown .f-btn-dropdown:hover{cursor:pointer;color:var(--f-theme-03);background:var(--f-aid-03)}.f-btn-group .f-btn-group-dropdown .f-btn-dropdown:focus{color:var(--f-text-00);background:var(--f-theme-02)}.f-btn-group .f-btn-group-dropdown .f-btn-dropdown .f-icon{font-size:.75rem}.f-btn-group .f-btn-group-dropdown .dropdown-menu{min-width:5rem}.f-btn-group-dropdown-menu{z-index:1300!important}.f-btn-group-dropdown-menu .dropdown-item .dropdown-item-icon{margin:0 8px 0 0}.f-button-edit .farris-tags.form-control{padding:0}.f-button-edit .farris-tag-input-box,.f-button-edit .farris-tag-item{line-height:17px!important;margin:2px 6px 2px 0!important}.f-button-edit .farris-tag-input-box .form-control{height:inherit!important;padding:1px 0!important}.f-button-edit-nowrap .farris-tags{overflow:hidden}.f-button-edit-nowrap .farris-tags-item-container{display:flex;flex-wrap:nowrap;overflow:hidden}.f-button-edit .input-group:not(.f-state-disabled,.f-state-readonly) .form-control,.f-cmp-number-spinner:not(.f-state-disabled,.f-state-readonly,.number-range) .form-control{border-top-right-radius:0;border-bottom-right-radius:0}.fv-calculator-standard-main{background-color:#f1f1f1;margin:0 auto;box-shadow:0 0 15px #4d4d4d}.fv-calculator-standard-main ul{list-style:none;margin:0;padding:0}.fv-calculator-standard-main li{float:left;text-align:center;cursor:pointer}.fv-calculator-standard-main li img{height:14px}.fv-calculator-standard-main .fv-calculator-title{padding:5px 0;height:30px;line-height:30px;font-size:18px;margin-left:10px}.fv-calculator-standard-main .fv-calculator-result{height:140px;text-align:right;width:100%}.fv-calculator-standard-main .fv-calculator-result-out{margin:0 5px;height:48px;overflow:hidden}.fv-calculator-standard-main .fv-calculator-second{font-size:42px;font-weight:700;overflow-y:auto;white-space:nowrap;text-align:right}.fv-calculator-standard-main .fv-calculator-pre{color:#A7A7A7;padding:0 20px;font-size:16px;height:24px;width:100%;overflow:hidden;position:relative;z-index:99}.fv-calculator-standard-main .fv-calculator-pre .fv-calculator-pre-left{width:16px;text-align:center;line-height:20px;height:24px;position:absolute;z-index:101;left:0;top:0;font-weight:600;cursor:pointer;background:#f1f1f1}.fv-calculator-standard-main .fv-calculator-pre .fv-calculator-pre-right{width:16px;text-align:center;line-height:20px;height:24px;position:absolute;z-index:101;right:0;top:0;font-weight:600;cursor:pointer;background:#f1f1f1}.fv-calculator-pre .fv-calculator-pre-content{text-align:right;height:24px;line-height:24px;white-space:nowrap;overflow-y:auto;overflow-x:hidden}.fv-calculator-pre-left:hover,.fv-calculator-pre-right:hover{color:#1853d1;background:#9b9b9b}.fv-calculator-standard-main .fv-calculator-type{height:auto;text-align:left;font-weight:700;margin:10px 0 20px 10px;font-size:22px}.fv-calculator-standard-main .fv-calculator-type-bar{height:90px;width:100px;position:absolute;top:110px;background-color:#E6E6E6}.fv-calculator-standard-main .fv-calculator-type-bar li{float:left;width:100px;text-align:center;line-height:30px}.fv-calculator-standard-main .active{background-color:#CFCFCF}.fv-calculator-standard-main .fv-calculator-number{font-weight:700;border:1px solid #fff!important;background:#fff!important}.fv-calculator-standard-main .fv-calculator-number:hover{border:1px solid #f1f1f1!important;background:#c6c6c6!important}.fv-calculator-standard-main .fv-calculator-operator:hover{border:1px solid #f1f1f1!important;background:#82bceb!important;color:#fff}.fv-calculator-standard-main .fv-calculator-letter{font-size:16px}.fv-calculator-standard-main{width:500px;height:460px}#fv-calculator-num-symbol{height:270px;font-size:20px;display:flex;flex-wrap:wrap;justify-content:center}#fv-calculator-num-symbol li{line-height:48px;width:23%;margin:5px 0 0 5px;background:#dedede;border:1px solid #dedede;list-style-type:none}#fv-calculator-num-symbol li:hover{background:#c6c6c6;border:1px solid #f1f1f1}.f-calendar-day-view-item,.f-calendar-day-view-item-lower,.f-calendar-day-view-item-upper,.f-calendar-day-view-item-upper:first-child,.f-calendar-day-view-item:first-child{border-top:1px solid transparent}.f-calendar-day-view{background-color:#fff;display:flex;flex-direction:column;min-width:860px;height:530px}.f-calendar-day-view-header{display:flex;border-bottom:1px solid #e9e9e9}.f-calendar-day-view-header-corner{width:44px;height:24px}.f-calendar-day-view-header-columns{display:flex}.f-calendar-day-view-header-cell{display:flex;flex:1;padding:4px 4px 8px;font-size:14px;color:rgba(0,0,0,.75);line-height:22px;font-weight:500}.f-calendar-day-view-header-cell .f-calendar-day-view-date{border-radius:20px;width:24px;height:24px;text-align:center;margin-right:4px}.f-calendar-day-view-header-cell .f-calendar-day-view-current{background:#0093f5;color:#fff}.f-calendar-day-view-content{display:flex;flex:1;overflow-y:scroll}.f-calendar-day-view-content-side{width:44px}.f-calendar-day-view-item{height:22px;display:flex;border-bottom:1px solid #e9e9e9}.f-calendar-day-view-item-upper{border-bottom:1px solid transparent}.f-calendar-day-view-item-lower{border-bottom:1px solid #e9e9e9}.f-calendar-day-view-item-cell{flex:1;height:22px;border-left:1px solid transparent;border-right:1px solid #e9e9e9}.f-calendar-day-view-item-cell:first-child{border-left:1px solid #e9e9e9;border-right:1px solid #e9e9e9}.f-calendar-day-view-item-cell:last-child{border-left:1px solid transparent;border-right:1px solid transparent}.f-calendar-header{display:flex;background-color:#fff}.f-calendar-header>.f-calendar-title{font-weight:600;font-size:24px;line-height:32px;margin:14px 0;padding:0 14px;border-right:1px solid #e9e9e9;width:144px}.f-calendar-header>.f-calendar-navigator{flex:1;display:flex}.f-calendar-header .f-calendar-view-switch{margin:16px 14px;position:relative}.f-calendar-header .f-calendar-view-switch-panel{background-color:#eff5ff;width:200px;height:28px;border-radius:28px;display:flex;font-weight:500}.f-calendar-header .f-calendar-view-switch-panel>span{flex:1;line-height:28px;text-align:center}.f-calendar-header .f-calendar-view-switch>.f-calendar-view-switch-active-view{height:24px;width:62px;position:absolute;background:#fff;box-shadow:0 4px 18px 0 rgba(2,75,193,.2);border-radius:24px;line-height:24px;text-align:center;color:#0091da;font-weight:500;transition:.3s ease-out all}.f-calendar-header>.f-calendar-navigator>.f-calendar-navigator-today{background:#fff;border:1px solid #e8ebf2;box-shadow:0 2px 6px 0 rgba(31,35,41,.06);border-radius:6px;font-size:13px;color:#2d2f33;font-weight:400;margin:auto 6px auto 14px}.f-calendar-header>.f-calendar-navigator>.f-calendar-navigator-button-group{box-shadow:0 2px 6px 0 rgba(31,35,41,.06);border-radius:6px;font-size:13px;color:#2d2f33;font-weight:400;margin:auto 14px auto 0}.f-calendar-header>.f-calendar-navigator>.f-calendar-navigator-button-group>.f-calendar-navigator-previous{background:#fff;border:1px solid #e8ebf2;border-right-color:transparent;border-radius:6px 0 0 6px;padding:.1875rem .375rem}.f-calendar-header>.f-calendar-navigator>.f-calendar-navigator-button-group>.f-calendar-navigator-next{background:#fff;border:1px solid #e8ebf2;border-radius:0 6px 6px 0;padding:.1875rem .375rem}.f-calendar-month-view{min-width:860px;display:flex}.f-calendar-month-view table{display:table!important;margin:initial!important;flex:1;table-layout:fixed;width:-moz-fit-content;width:fit-content}.f-calendar-month-view tr{border-top:initial!important;transition:initial!important}.f-calendar-month-view th{border:initial!important;background-color:initial!important;font-size:14px!important;color:rgba(0,0,0,.75);line-height:22px;font-weight:500!important}.f-calendar-month-view{background-color:#fff}.f-calendar-month-view td{border:1px solid #e9e9e9!important;padding:4px!important;height:100px}.f-calendar-week-view-header,.f-calendar-week-view-item{display:flex;border-bottom:1px solid #e9e9e9}.f-calendar-month-view .f-calendar-month-view-title{display:flex}.f-calendar-month-view .f-calendar-month-view-title>.f-calendar-month-view-date{border-radius:20px;width:24px;height:24px;line-height:24px;text-align:center;font-size:14px}.f-calendar-month-view .f-calendar-month-view-title>.f-calendar-month-view-date-month{flex:1;border-radius:20px;width:24px;height:24px;line-height:24px;text-align:right;font-size:14px}.f-calendar-month-view .f-calendar-month-view-current{background:#0093f5;color:#fff}.f-calendar-month-view .f-calendar-month-view-event-item{background-color:#ebf3ff;font-size:12px;color:#0e6ded;line-height:18px;margin:2px 0;padding:2px 4px}.f-calendar-week-view{background-color:#fff;display:flex;flex-direction:column;min-width:860px;height:530px}.f-calendar-week-view-header-corner{width:44px;height:24px}.f-calendar-week-view-header-primary{flex:1}.f-calendar-week-view-header-columns{display:flex}.f-calendar-week-view-header-cell{flex:1;padding:4px 4px 8px;display:flex;font-size:14px;color:rgba(0,0,0,.75);line-height:22px;font-weight:500}.f-calendar-week-view-header-cell .f-calendar-week-view-date{border-radius:20px;width:24px;height:24px;text-align:center;margin-right:4px}.f-calendar-week-view-header-cell .f-calendar-week-view-current{background:#0093f5;color:#fff}.f-calendar-week-view-content{display:flex;flex:1;overflow-y:scroll}.f-calendar-week-view-content-side{width:44px}.f-calendar-content-primary{flex:1}.f-calendar-side{margin-top:-11px}.f-calendar-side-row{height:22px;padding-right:4px;text-align:end}.f-calendar-side-row-number{height:22px;line-height:22px}.f-calendar-week-view-item{height:22px;border-top:1px solid transparent}.f-calendar-week-view-item:first-child{border-top:1px solid #e9e9e9}.f-calendar-week-view-item-lower,.f-calendar-week-view-item-upper,.f-calendar-week-view-item-upper:first-child{border-top:1px solid transparent}.f-calendar-week-view-item-upper{border-bottom:1px solid transparent}.f-calendar-week-view-item-lower{border-bottom:1px solid #e9e9e9}.f-calendar-week-view-item-cell{flex:1;height:22px;border-left:1px solid transparent;border-right:1px solid #e9e9e9}.f-calendar-week-view-item-cell:first-child{border-left:1px solid #e9e9e9;border-right:1px solid #e9e9e9}.f-calendar-week-view-item-cell:last-child{border-left:1px solid transparent;border-right:1px solid transparent}.f-calendar-event{background:#ebf3ff;border-radius:2px;margin:2px;font-size:12px;color:#0e6ded;padding:2px 4px}.custom-control-label,.f-radio-tag{margin-bottom:0;position:relative}.f-capsule-container{color:#6080AD;position:relative;display:inline-block;box-sizing:content-box;padding:0;margin:0;cursor:pointer;white-space:nowrap;min-width:2.5rem;height:1.8rem;overflow:hidden}.f-capsule-container.primary .f-capsule-board{background-color:#eff5ff}.f-capsule-container.secondary .f-capsule-board{background-color:#f2f4f8}.f-capsule-container .f-capsule-pane{display:flex;height:100%;min-height:100%;justify-content:flex-start;align-items:center;top:0;position:relative}.f-capsule-container .f-capsule-pane .f-capsule-item{opacity:1;display:inline-block;font-size:12px;line-height:1.8rem;padding-left:24px;padding-right:24px;z-index:2}.f-capsule-container .f-capsule-pane .f-capsule-item.f-capsule-active-item{font-weight:700}.f-capsule-container.primary .f-capsule-pane .f-capsule-item.f-capsule-active-item{color:#2a87ff}.f-capsule-container .f-capsule-pane .f-capsule-item>i{margin-right:2px;font-size:12px}.f-capsule-container .f-capsule-board{background-color:#f2f4f8;border-radius:1.8rem;height:1.8rem;position:absolute;top:0;z-index:0}.f-capsule{height:calc(100% - 4px);border-radius:1.8rem;position:absolute;background:#fff;left:2px;top:2px;opacity:1;display:inline-block;font-size:12px;padding-left:22px;padding-right:22px;z-index:1}.custom-checkbox .custom-control-input:checked~.custom-control-label::after,.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:none}.custom-control{position:relative;display:block;min-height:1.1607375rem;padding-left:0}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;clip:rect(0,0,0,0);overflow:hidden;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:var(--f-theme-03);background-color:var(--f-neutral-00);box-shadow:none}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 4px 2px rgba(99,136,255,.12);color:var(--f-theme-03)}.custom-control-input:active~.custom-control-label::before{color:var(--f-text-00);background-color:var(--f-theme-03);box-shadow:none}.custom-checkbox .custom-control-input:checked~.custom-control-label::before,.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before,.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before,.custom-control-input:disabled~.custom-control-label::before,.custom-control-label::before,.custom-radio .custom-control-input:checked~.custom-control-label::before,.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:var(--f-neutral-00)}.custom-control-input:disabled~.custom-control-label{color:var(--f-neutral-06)}.custom-control-label::before{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;box-shadow:0 0 0;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.custom-control-label::after{position:absolute;top:.08036875rem;left:-1.5rem;width:1rem;height:1rem;background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-control-label::before,.f-icon{width:1em;-moz-osx-font-smoothing:grayscale;font-variant:normal;speak:none;font-family:FarrisIcons;-webkit-font-smoothing:antialiased;font-weight:400;font-style:normal;text-transform:none}.custom-checkbox .custom-control-label::before{top:1px;border-radius:0}@media screen and (prefers-reduced-motion:reduce){.custom-control-label::before{transition:none}}.custom-control.custom-checkbox,.custom-control.custom-radio{padding-right:.8125rem;margin-bottom:.25rem}.custom-control .custom-control-label::before{color:var(--f-neutral-02)}.custom-control .custom-control-label:hover{cursor:pointer}.custom-control .custom-control-input:disabled~.custom-control-label:hover,.custom-control .custom-control-input[readonly]~.custom-control-label:hover{cursor:default}.custom-control .custom-control-label:hover::before{color:var(--f-theme-05)}.custom-control .custom-control-input:checked~.custom-control-label::before{color:var(--f-theme-03)}.custom-control .custom-control-input[readonly]~.custom-control-label{color:var(--f-text-02)}.custom-control .custom-control-input[readonly]~.custom-control-label::before{color:var(--f-neutral-06)}.custom-control .custom-control-input:disabled~.custom-control-label{color:var(--f-text-02)}.custom-control .custom-control-input:disabled~.custom-control-label::before{color:var(--f-neutral-06)}.custom-control .custom-control-input[disabled]:checked~.custom-control-label::before,.custom-control .custom-control-input[readonly]:checked~.custom-control-label::before{color:rgba(var(--f-theme-03),.2)}.custom-control-label{padding-left:1.5rem;color:var(--f-text-02);display:inline}.custom-control-label::before{height:1em;display:inline-block;vertical-align:middle;color:var(--f-neutral-02);font-size:14px;line-height:1;top:3px;left:0;position:absolute}.custom-control-label::after{display:none}.custom-checkbox .custom-control-label::before{content:"\e304"}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{box-shadow:none;font-family:FarrisIcons;content:"\e306";color:var(--f-theme-03)}.custom-checkbox .custom-control-input:checked~.custom-control-label::before,.custom-radio .custom-control-input:checked~.custom-control-label::before{content:"";background-repeat:no-repeat;background-size:contain;background-position:center center;box-shadow:0 2px 6px 0 rgba(var(--f-theme-03),.2)}.custom-checkbox .custom-control-input[disabled]:checked~.custom-control-label::before,.custom-checkbox .custom-control-input[readonly]:checked~.custom-control-label::before,.custom-radio .custom-control-input[disabled]:checked~.custom-control-label::before,.custom-radio .custom-control-input[readonly]:checked~.custom-control-label::before{box-shadow:none;opacity:.4}.custom-checkbox .custom-control-input:checked~.custom-control-label::before{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjE0cHgiIGhlaWdodD0iMTRweCIgdmlld0JveD0iMCAwIDE0IDE0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgIDx0aXRsZT7nvJbnu4QgMjc8L3RpdGxlPg0KICAgIDxkZWZzPg0KICAgICAgICA8bGluZWFyR3JhZGllbnQgeDE9Ijg3LjE4OTcwNjUlIiB5MT0iMCUiIHgyPSIxOC4yNDA0NDkyJSIgeTI9IjEwMCUiIGlkPSJsaW5lYXJHcmFkaWVudC0xIj4NCiAgICAgICAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiMzRjY1RkYiIG9mZnNldD0iMCUiPjwvc3RvcD4NCiAgICAgICAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiM0RDlBRkYiIG9mZnNldD0iMTAwJSI+PC9zdG9wPg0KICAgICAgICA8L2xpbmVhckdyYWRpZW50Pg0KICAgIDwvZGVmcz4NCiAgICA8ZyBpZD0i5paw54mIIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4NCiAgICAgICAgPGcgaWQ9Iue8lue7hC0yNyI+DQogICAgICAgICAgICA8cmVjdCBpZD0i55+p5b2i5aSH5Lu9LTE0IiBmaWxsPSJ1cmwoI2xpbmVhckdyYWRpZW50LTEpIiB4PSIwIiB5PSIwIiB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHJ4PSIzIj48L3JlY3Q+DQogICAgICAgICAgICA8cGF0aCBkPSJNMTAuNjkwOTE2NCw0LjEzNjA2NjY0IEwxMS4zNTMzNzY5LDQuNzU0MDk0OTIgQzExLjQzNDE0MzMsNC44Mjk0NDQyNCAxMS40Mzg1MzQ3LDQuOTU2MDAxMDcgMTEuMzYzMTg1NCw1LjAzNjc2NzUxIEMxMS4zNjMwNjY2LDUuMDM2ODk0ODYgMTEuMzYyOTQ3Niw1LjAzNzAyMjA2IDExLjM2MjgyODUsNS4wMzcxNDkxMSBMNi42MTYzOTg1OSwxMC4wOTgyNDI1IEM2LjU0MDgzODUyLDEwLjE3ODgxMTggNi40MTQyNzA2NSwxMC4xODI4NzI2IDYuMzMzNzAxMzQsMTAuMTA3MzEyNSBDNi4zMzE3ODIyMSwxMC4xMDU1MTI3IDYuMzI5ODk4NzgsMTAuMTAzNjc1MiA2LjMyODA1MjE1LDEwLjEwMTgwMSBMMy4xNDA3NDAxNiw2Ljg2NzAxODkyIEMzLjA2MzIxNDc1LDYuNzg4MzM4ODggMy4wNjQxNTA3NSw2LjY2MTcwOTM0IDMuMTQyODMwNzksNi41ODQxODM5MyBDMy4xNDI5NTUxMSw2LjU4NDA2MTQzIDMuMTQzMDc5Niw2LjU4MzkzOTA5IDMuMTQzMjA0MjQsNi41ODM4MTY5MiBMMy43OTAxMjUxOCw1Ljk0OTcxODg4IEMzLjg2ODg2OTM1LDUuODcyNTM1NTQgMy45OTUyMjY2Myw1Ljg3MzY0MzM2IDQuMDcyNjA1NCw1Ljk1MjE5NTQ5IEw2LjQ1MDE0NjI0LDguMzY1Nzg4ODIgTDYuNDUwMTQ2MjQsOC4zNjU3ODg4MiBMMTAuNDA4NjEwMiw0LjE0NTQ4MzUzIEMxMC40ODQwMzI2LDQuMDY1MDcyMTYgMTAuNjEwMzAzLDQuMDYwODYwMTYgMTAuNjkwOTE2NCw0LjEzNjA2NjY0IFoiIGlkPSLot6/lvoQtMTPlpIfku70iIGZpbGw9IiNGRkZGRkYiIGZpbGwtcnVsZT0ibm9uemVybyI+PC9wYXRoPg0KICAgICAgICA8L2c+DQogICAgPC9nPg0KPC9zdmc+)}.farris-checkradio-ver{display:flex!important;flex-direction:column}.farris-checkradio-hor{flex-wrap:wrap;display:inline-flex}.farris-input-wrap.farris-checkradio-hor{display:inline-flex}.custom-radio .custom-control-label::before{border-radius:50%;content:"\e309"}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:none}.custom-radio .custom-control-input:checked~.custom-control-label::before{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjE0cHgiIGhlaWdodD0iMTRweCIgdmlld0JveD0iMCAwIDE0IDE0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgIDx0aXRsZT5SZWN0YW5nbGUgMjcxIENvcHkgMTHlpIfku70gMjwvdGl0bGU+DQogICAgPGRlZnM+DQogICAgICAgIDxsaW5lYXJHcmFkaWVudCB4MT0iODcuMTg5NzA2NSUiIHkxPSIwJSIgeDI9IjE4LjI0MDQ0OTIlIiB5Mj0iMTAwJSIgaWQ9ImxpbmVhckdyYWRpZW50LTEiPg0KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzNGNjVGRiIgb2Zmc2V0PSIwJSI+PC9zdG9wPg0KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzREOUFGRiIgb2Zmc2V0PSIxMDAlIj48L3N0b3A+DQogICAgICAgIDwvbGluZWFyR3JhZGllbnQ+DQogICAgPC9kZWZzPg0KICAgIDxnIGlkPSLmlrDniYgiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPg0KICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlLTI3MS1Db3B5LTEx5aSH5Lu9LTIiIHN0cm9rZT0idXJsKCNsaW5lYXJHcmFkaWVudC0xKSIgc3Ryb2tlLXdpZHRoPSI0IiB4PSIyIiB5PSIyIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIHJ4PSI1Ij48L3JlY3Q+DQogICAgPC9nPg0KPC9zdmc+)}.farris-checkradio-hor .farris-radio-button .btn{border-radius:0}.farris-checkradio-hor .farris-radio-button:first-child .btn{border-top-left-radius:6px;border-bottom-left-radius:6px}.farris-checkradio-hor .farris-radio-button:last-child .btn{border-top-right-radius:6px;border-bottom-right-radius:6px}.f-radio-button,.f-radio-tag{color:#2d2f33;background:#fff;border:1px solid #e8ebf2}.f-radio-button-success:hover{color:#6cc77f;background:#fff;border-color:#6cc77f;box-shadow:0 2px 6px 0 rgba(31,35,41,.06)}.f-radio-button-warning:hover{color:#f5a144;background:#fff;border-color:#f5a144;box-shadow:0 2px 6px 0 rgba(31,35,41,.06)}.f-radio-button-danger:hover{color:#f46160;background:#fff;border-color:#f46160;box-shadow:0 2px 6px 0 rgba(31,35,41,.06)}.f-radio-button-primary:hover{color:#2a87ff;background:#fff;border-color:#2a87ff;box-shadow:0 2px 6px 0 rgba(31,35,41,.06)}.f-radio-button-success.active{color:#fff;background:#6cc77f;border-color:#6cc77f}.f-radio-button-warning.active{color:#fff;background:#f5a144;border-color:#f5a144}.f-radio-button-danger.active{color:#fff;background:#f46160;border-color:#f46160}.f-radio-button-primary.active{color:#fff;background:#2a87ff;border-color:#2a87ff}.f-radio-tag{display:inline-block;margin-right:8px;padding:3px 16px;border:1px solid rgba(0,0,0,.15);border-radius:2px;overflow:hidden;cursor:pointer}.f-radio-icon,.f-radio-tag>.tip{position:absolute;display:block}.f-radio-icon{right:-4px;bottom:-3px;font-size:12px;color:#fff}.f-radio-tag>.tip{right:0;bottom:0;width:14px;height:14px;border:7px solid #dadada;border-top:7px solid transparent;border-left:7px solid transparent}.f-radio-tag-success.active{color:#6cc77f;border-color:#6cc77f;background:rgba(108,199,127,.05)}.f-radio-tag-warning.active{color:#f5a144;border-color:#f5a144;background:rgba(245,161,68,.05)}.f-radio-tag-danger.active{color:#f46160;border-color:#f56161;background:rgba(245,97,97,.05)}.f-radio-tag-primary.active{color:#2a87ff;border-color:#2a87ff;background:rgba(42,135,255,.05)}.f-radio-tag-success.active>.tip{border-right-color:#6cc77f;border-bottom-color:#6cc77f}.f-radio-tag-warning.active>.tip{border-right-color:#f5a144;border-bottom-color:#f5a144}.f-radio-tag-danger.active>.tip{border-right-color:#f46160;border-bottom-color:#f46160}.f-radio-tag-primary.active>.tip{border-right-color:#2a87ff;border-bottom-color:#2a87ff}.f-color-picker-component{display:inline-block;position:relative;line-height:normal}.f-color-picker-component .color-picker-wrapper{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.f-color-picker-component .color-picker-wrapper .color-picker-input{border-top-right-radius:0;border-bottom-right-radius:0;flex:1 1 auto;width:1%;min-width:200px}.f-color-picker-component .color-picker-wrapper .color-picker-trigger{display:inline-block;box-sizing:border-box;height:calc(1.62503rem + 2px);width:calc(1.62503rem + 2px);padding:.1875rem;border:1px solid #e6e6e6;border-left:none;border-top-right-radius:4px;border-bottom-right-radius:4px;font-size:0;position:relative;cursor:pointer}.f-color-picker-component .color-picker-wrapper .color-picker-trigger .color-picker-trigger-inner{position:relative;display:block;box-sizing:border-box;border:1px solid #999;border-radius:2px;width:100%;height:100%;text-align:center}.f-color-picker-component .color-picker-wrapper .color-picker-trigger .color-picker-trigger-inner.is-alpha{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.f-color-picker-component .color-picker-wrapper .color-picker-trigger .color-picker-trigger-inner div{width:100%;height:100%}.f-color-picker-component .color-picker-panel{display:block;position:absolute;width:300px;z-index:3000;padding:6px;box-sizing:content-box;background-color:#fff;border:1px solid #ebeef5;border-radius:4px;box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.f-color-picker-component .color-picker-panel.disabled{display:none}.f-color-picker-component .color-picker-panel .color-picker-main{padding-bottom:6px}.f-color-picker-component .color-picker-panel .input-btn{margin-top:6px;text-align:right}.f-color-picker-component .color-picker-panel .input-btn input{float:left;width:180px;height:28px;line-height:28px;cursor:pointer;-webkit-appearance:none;background-color:#fff;border-radius:4px;border:1px solid #dcdfe6;box-sizing:border-box;color:#606266;font-size:inherit;outline:0;padding:0 7px;transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.f-color-picker-component .color-picker-panel .input-btn input:focus{border-color:#409eff}.f-color-picker-component .color-picker-panel .input-btn .btn-clear{background-color:#fff;border:none;outline:0;color:#409eff}.color-picker-wrapper .color-picker-trigger{border-color:var(--f-neutral-04)!important;height:calc(1.5rem + .125rem)!important}.f-alpha-component{display:flex;flex-direction:column;position:relative;box-sizing:border-box;width:280px;height:12px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.f-alpha-component .color-alpha-slider__bar{position:relative;background:linear-gradient(to right,rgba(255,69,0,0) 0,#ff4500 100%);height:100%}.f-alpha-component .color-alpha-slider__thumb{position:absolute;cursor:pointer;box-sizing:border-box;left:189px;top:0;width:4px;height:100%;border-radius:1px;background:#fff;border:1px solid #f0f0f0;box-shadow:0 0 2px rgba(0,0,0,.6);z-index:1}.f-hue-component{position:relative;box-sizing:border-box;width:12px;height:180px;background-color:red;padding:2px 0;float:right}.f-hue-component .color-hue-slider__bar{position:relative;background:linear-gradient(red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red);height:100%}.f-hue-component .color-hue-slider__thumb{position:absolute;cursor:pointer;box-sizing:border-box;top:10px;left:0;width:100%;height:4px;border-radius:1px;background:#fff;border:1px solid #f0f0f0;box-shadow:0 0 2px rgba(0,0,0,.6);z-index:1}.f-preset-component{display:flex;font-size:12px;margin-top:8px;width:280px}.f-preset-component .color-preset__colors{display:flex;flex:1;flex-wrap:wrap}.f-preset-component .color-preset__colors .color-preset__color-selector{margin:0 0 8px 8px;width:20px;height:20px;border-radius:4px;cursor:pointer}.f-preset-component .color-preset__colors .color-preset__color-selector:nth-child(10n+1){margin-left:0}.f-preset-component .color-preset__colors .color-preset__color-selector.selected{box-shadow:0 0 3px 2px #409eff}.f-preset-component .color-preset__colors .color-preset__color-selector div{display:flex;height:100%;border-radius:3px}.f-sv-panel-component{display:inline-block;position:relative;width:280px;height:180px}.f-sv-panel-component .color-svpanel__white{position:absolute;top:0;left:0;right:0;bottom:0;background:linear-gradient(90deg,#fff,hsla(0,0%,100%,0))}.f-sv-panel-component .color-svpanel__black{position:absolute;top:0;left:0;right:0;bottom:0;background:linear-gradient(0deg,#000,transparent)}.f-sv-panel-component .color-svpanel__cursor{position:absolute}.f-sv-panel-component .color-svpanel__cursor div{cursor:pointer;width:6px;height:6px;box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px rgba(0,0,0,.3),0 0 1px 2px rgba(0,0,0,.4);border-radius:50%;transform:translate(-3px,-3px)}input-group.actived .input-group{box-shadow:0 0 4px 2px rgba(99,136,255,.12);border-color:var(--f-theme-08)}.popover.f-combo-list-wrapper{background:var(--f-neutral-20)}.f-combo-list-container{overflow:auto;z-index:9;padding:.25rem}.f-combo-list-container .f-empty-title,.f-combo-list-container .f-list-view-group{margin:0}.f-combo-list-container .f-combo-list-search-box{margin:.25rem .5rem}.f-combo-list-container .f-combo-list-search-box .f-combo-list-item{padding:.125rem .5rem}.f-combo-list-item{position:relative;display:block;padding:.3125rem .5rem;background-color:#fff;border-radius:6px}.f-combo-list-item.f-un-select{color:var(--f-text-09)}.f-combo-list-item:not(.f-un-select):hover{background:var(--f-neutral-11);color:var(--f-text-02)}.f-combo-list-item.f-listview-active{color:var(--f-text-02);background:var(--f-neutral-10)}.f-combo-tree-container .fv-tree,.f-combo-tree-container .fv-tree-content{overflow:auto}.condition-list{width:100%;display:flex;flex-direction:column;overflow-y:hidden;resize:vertical;min-height:50px}.condition-list .condition-list-body{height:calc(100% - 32px);overflow-y:auto}.condition-list .condition-list-body-maxh{max-height:380px}.condition-list .condition-list-bottom{position:relative;margin:14px 0 14px 6px}.condition-list .condition-list-reset{position:absolute;right:32px;bottom:4px}.condition-list .add-group-btn{width:100%;background:rgba(239,245,255,.65);border:1px solid #dbe9ff;border-radius:6px;color:#2a87ff;font-size:13px}.condition-list .add-condition-btn{color:#2A87FF;font-size:13px;display:inline-block}.condition-list .add-condition-btn:hover{cursor:pointer}.condition-list .add-condition-btn .f-icon{vertical-align:text-bottom;position:relative;width:16px;height:16px;border-radius:50%}.condition-list .add-condition-btn .f-icon-filter-add::before{position:relative;bottom:3px;left:2px;font-size:12px}.condition-list .add-condition-btn .f-icon-filter-grouping::before{position:relative;bottom:3px;left:1px;font-size:12px}.condition-list .condition-list-content{display:flex}.condition-list .condition-list-content-group{flex:0 0 auto}.condition-list .condition-list-item{padding:4px;display:flex;height:40px}.condition-list .condition-list-item-type{width:200px}.condition-list .condition-list-type button{text-align:left;position:relative;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.condition-list .condition-list-item-compare{width:134px}.condition-list .condition-list-compare button{text-align:left;position:relative}.condition-list .condition-list-compare .f-icon-arrow-chevron-down::before,.condition-list .condition-list-compare .f-icon-arrowhead-s::before,.condition-list .condition-list-type .f-icon-arrow-chevron-down::before,.condition-list .condition-list-type .f-icon-arrowhead-s::before{position:absolute;right:8px;bottom:4px}.condition-list .condition-list-content .dropdown-toggle::after{display:none}.condition-list .condition-list-item-control{line-height:26px;width:200px}.condition-list .condition-list-item-extend .f-icon{vertical-align:text-bottom}.condition-list .condition-list-item-extend .f-icon:hover{cursor:pointer}.condition-list .condition-list-item-extend .f-icon-plus-sm::before,.condition-list .condition-list-item-extend .f-icon-splus::before{font-size:14px;color:#2a87ff;background-color:#e8f2ff;border-radius:50%;position:relative;top:1px}.condition-list .condition-list-item-extend .f-icon-minus-sm::before,.condition-list .condition-list-item-extend .f-icon-sminus::before{font-size:14px;color:#f46160;background-color:#fadcdd;border-radius:50%;position:relative;top:1px}.condition-list .condition-list-relation{margin:2px 0 2px 12px;border-left:1px solid #dee3f0;position:relative;display:flex;align-items:center;padding-left:12px;font-size:13px;color:#2a87ff;text-align:center;cursor:pointer}.condition-list .condition-list-relation:hover .condition-list-relation-close{display:inline}.condition-list .condition-list-relation-close{position:absolute;top:-4px;display:none}.fv-grid,.fv-grid-header,.fv-grid-header-cell{display:flex;overflow:hidden}.condition-list .condition-list-relation:hover .condition-list-relation-text{text-decoration:underline}.condition-list .condition-list-item .custom-control-label:before{position:relative;top:2px}.condition-list .condition-list-relation button{width:20px}.fv-grid{position:relative;flex-direction:column;border-style:solid;border-width:1px;border-color:transparent;flex:1;color:#424347}.fv-grid-header{position:relative;z-index:2;color:#5a5e66;font-weight:400;border-bottom:1px solid #e4e7ef;background-color:#f4f5f9}.fv-grid-header-corner{background-color:#f4f5f9;border-style:solid;border-width:1px;border-color:transparent;padding:.375rem 0}.fv-grid-header-left-fixed,.fv-grid-header-right-fixed{position:relative;overflow:hidden;background-color:#f4f5f9;z-index:1}.fv-grid-header-left-fixed{box-shadow:4px 0 10px 0 rgba(31,35,41,.06)}.fv-grid-header-right-fixed{box-shadow:-4px 0 10px 0 rgba(31,35,41,.06)}.fv-grid-header-primary{flex:1;position:relative;overflow:hidden;background-color:#f4f5f9}.fv-grid-header-columns{position:relative}.fv-grid-header-cell{position:absolute;border:1px solid transparent;top:0;padding:.4375rem .75rem;line-height:18px;color:#2d2f33;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle}.fv-grid-header-cell::after{content:"";position:absolute;left:0;top:50%;margin-top:-.5625rem;display:block;height:1.125rem;width:1px;background-color:#e6e9f0}.fv-grid-header-group-columns .fv-grid-header-cell{border-bottom-color:#eaecf3;border-right-color:#eaecf3;padding:0 .75rem;text-align:center}.fv-grid-header-group-columns .fv-grid-header-cell::after{display:none}.fv-grid-content{flex:1;display:flex;position:relative;overflow:hidden;z-index:0;background:#fff}.fv-grid-content-hover{cursor:pointer}.fv-grid-content-side{position:relative}.fv-grid-content-primary{flex:1;position:relative;overflow:hidden}.fv-grid-content-left-fixed,.fv-grid-content-right-fixed{position:relative;overflow:hidden;z-index:1}.fv-grid-content-left-fixed{box-shadow:4px 0 10px 0 rgba(31,35,41,.06);background-color:#fff}.fv-grid-content-right-fixed{box-shadow:-6px 0 6px -4px rgba(0,0,0,.12);background-color:#fff}.fv-grid-data{height:100%}.fv-grid-merge-date{position:absolute;top:0}.fv-grid-row{left:0;position:absolute}.fv-datagrid-strip .fv-grid-row-odd{background-color:#fff}.fv-datagrid-strip .fv-grid-row-even{background-color:#f7f8fb}.fv-grid-row-hover{cursor:pointer;color:#424347;background:#edf5ff!important;border-color:#eaecf3}.fv-grid-row-selected{color:#424347!important;border-color:#95bef1;background-color:#dae9ff!important}.fv-grid-cell,.fv-grid-group-row,.fv-grid-summary-row{border-color:transparent;background-color:transparent;border-style:solid;border-width:1px;position:absolute}.fv-grid-group-row,.fv-grid-summary-row{left:0;font-weight:600}.fv-grid-group-row-icon{width:28px;height:28px;flex-shrink:0;color:rgba(0,0,0,.45);line-height:24px;padding:.25rem .75rem}@keyframes rotate-group-collapse{0%{transform:rotate(0)}100%{transform:rotate(-90deg)}}.fv-grid-group-row-icon-collapse{transform:rotate(-90deg)}.fv-grid-cell{line-height:26px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;top:0;padding:0 .75rem}.fv-grid-wrap-content .fv-grid-cell{text-overflow:initial;overflow:initial;white-space:initial}.fv-grid-cell .f-form-control-textarea,.fv-grid-cell textarea.form-control{min-height:initial}.fv-grid-merged-cell{border-left-color:#eaecf3;background-color:#fff;text-align:center}.fv-grid-sidebar-row{left:0;position:absolute;line-height:24px;border-style:solid;border-width:1px;border-color:transparent;background-color:transparent}.fv-datagrid-strip .fv-grid-sidebar-row-odd{background-color:#fff}.fv-datagrid-strip .fv-grid-sidebar-row-even{background-color:#f7f8fb}.fv-grid-sidebar-row-hover{cursor:pointer;color:#424347;background:#edf5ff!important}.fv-grid-sidebar-row-selected{color:#424347!important;background-color:#dae9ff!important}.fv-grid-sidebar-row-checkbox{vertical-align:middle;margin:.25rem .5rem .25rem 1rem}.fv-grid-sidebar-row-number{display:inline-flex;width:32px;padding:0 .25rem}.fv-grid-content-hover .fv-grid-vertical-scroll{opacity:1}.fv-grid-vertical-scroll{opacity:0;position:absolute;background-color:transparent;right:0;left:auto!important;width:10px;cursor:default;transition:width .2s linear,opacity .2s linear,background-color .2s linear;height:288px;z-index:1}.fv-grid-vertical-scroll-thumb{transition:background-color .2s linear,width .2s ease-in-out;width:10px;right:0;background-color:rgba(0,0,0,.25);border-radius:10px;position:absolute}.fv-grid-content-hover .fv-grid-horizontal-scroll{opacity:1}.fv-grid-horizontal-scroll{opacity:0;position:absolute;background-color:transparent;bottom:0;top:auto!important;height:10px;cursor:default;transition:width .2s linear,opacity .2s linear,background-color .2s linear;width:812px;z-index:1}.fv-grid-horizontal-scroll-thumb{transition:background-color .2s linear,width .2s ease-in-out;height:10px;bottom:0;background-color:rgba(0,0,0,.25);border-radius:10px;position:absolute}.fv-grid-header-cell>.fv-column-title{flex:1;text-overflow:ellipsis;overflow:hidden;word-break:break-all;white-space:nowrap}.fv-grid-header-cell>.fv-column-resize-bar{display:block;position:absolute!important;top:-2px;bottom:-2px;right:0;margin:0;width:5px;padding:0;cursor:e-resize;border:1px solid transparent}.fv-grid-header-cell:hover>.fv-column-resize-bar{border-right:3px solid #2a87ff;border-top:none}.fv-grid-header-cell:hover>.fv-column-handler{display:block}.fv-grid-header-cell>.fv-column-handler{float:right;cursor:pointer;display:none;color:#2a87ff}.fv-grid-header-cell>.fv-column-handler.fv-column-handler-active{display:block!important;color:#2a87ff}.fv-grid-header-cell>.fv-column-handler:hover{color:#2a87ff}.fv-grid-header-cell>.fv-grid-settings-icon{display:block;cursor:pointer;margin-left:8px}.fv-datagrid-resize-overlay{z-index:98;width:100%;height:100%;cursor:e-resize;background:0 0;position:absolute}.fv-datagrid-resize-proxy{width:1px;border-left:1px dashed #2a87ff;left:0;display:none;position:absolute;height:100%;z-index:99}.fv-datagrid-summary{padding:3px;background-color:#fff}.fv-datagrid-summary .fv-datagird-summary-panel{height:40px;background:linear-gradient(90deg,#eff8f8 0,#fffbeb 100%);border-radius:8px;display:flex;justify-content:space-between}.fv-datagrid-summary-title{line-height:40px;width:100px;padding:0 16px;font-size:14px;font-weight:500}.fv-datagrid-summary-content{display:flex;line-height:40px}.fv-datagrid-summary-field{line-height:40px;margin-right:10px}.fv-datagrid-summary-field-title{font-size:14px;margin:0 16px}.fv-datagrid-summary-field-value{color:#ff6c29;font-size:18px;font-weight:700}.fv-datagrid-pagination{display:flex;flex-direction:row-reverse;background-color:#fff}.fv-column-handler-popover .popover-body{max-width:none}.fv-column-sort-filter-container{width:300px}.fv-column-sort-filter-container .fv-column-filter-section .fv-column-filter-section-title{font-size:15px;margin:10px 0}.fv-column-sort-filter-container .fv-column-filter-section .fv-column-filter-section-editor{margin-bottom:10px;max-height:240px;overflow:hidden;display:flex;flex-direction:column}.fv-column-sort-filter-container .fv-column-sort-filter-footer{display:flex}.fv-column-sort-filter-container .fv-column-sort-filter-footer .fv-column-confirm-section{flex:1;display:flex;flex-direction:row-reverse}.fv-grid-filter-panel{padding:0 6px 4px}.fv-grid-settings{min-width:800px;min-height:480px}.fv-grid-settings .f-btn-icon{color:#878d99!important}.fv-grid-settings .f-btn-icon:hover{color:#529dff!important}.fv-grid-settings .farris-tabs-header-pre{color:#000;font-weight:500}.fv-grid-settings .farris-tabs-header-post,.fv-grid-settings .farris-tabs-header-pre{padding:.75rem .5rem .75rem 1.125rem}.fv-grid-settings .farris-tabs-header{margin:0!important}.fv-grid-settings .container{padding-left:24px;padding-right:24px}.fv-grid-group-panel{border-bottom:1px solid #e4e7ef;background-color:#f4f5f9;height:40px}.fv-grid-bordered{border:1px solid #EAECF3}.fv-grid-bordered .fv-grid-cell{border-right-color:#EAECF3}.fv-grid-bordered .fv-grid-cell:last-child{border-right-color:transparent}.fv-grid-horizontal-bordered .fv-grid-cell,.fv-grid-horizontal-bordered .fv-grid-group-row,.fv-grid-horizontal-bordered .fv-grid-merged-cell,.fv-grid-horizontal-bordered .fv-grid-sidebar-row,.fv-grid-horizontal-bordered .fv-grid-summary-row{border-bottom-color:#eaecf3}.fv-grid-hierarchy-cell .custom-checkbox{display:flex;padding-right:0!important;margin:auto 0}.fv-grid-hierarchy-cell .fv-tree-node-toggle,.fv-grid-hierarchy-cell .fv-tree-node-toggle-minus{padding-right:6px}.fv-grid-hierarchy-cell .custom-label{padding-left:1.2rem}.fv-grid-hierarchy-cell div#treeNodeIcons{margin:auto 5px auto 0;color:#a5a6ab}.fv-grid-hierarchy-cell .fv-tree-node-toggle::before{font-family:FarrisIcons;color:#2D2F33;content:"\e11f"}.fv-grid-hierarchy-cell .fv-tree-node-toggle-minus::before{font-family:FarrisIcons;color:#2D2F33;content:"\e122"}.fv-grid-hierarchy-cell .fv-tree-node-toggle:hover::before{color:#59a1ff}.f-datepicker-container{display:flex;position:absolute;margin:.25rem 0 0;padding:0;box-shadow:0 2px 20px 0 rgba(3,18,51,.12);background:var(--f-neutral-20);border-radius:10px;z-index:9999;animation:selectorfadein 60ms;box-sizing:border-box;color:var(--f-text-01);flex-wrap:wrap;font-family:PingFangSC-Regular,Arial}.f-datepicker-container:focus{border:none;outline:0}.f-datepicker-container .arrow{display:none;width:1rem;height:6px;margin:0;position:absolute;left:8px}.f-datepicker-container .arrow::after,.f-datepicker-container .arrow::before{content:"";border-color:transparent;border-style:solid;position:absolute;display:block;border-width:0 6px 6px}.f-datepicker-container .arrow::after{top:1px}.f-datepicker-container .arrow::before{top:0}.f-datepicker-container.container-position-bottom .arrow{top:-6px}.f-datepicker-container.container-position-bottom .arrow::after,.f-datepicker-container.container-position-bottom .arrow::before{border-width:0 6px 6px;border-bottom-color:#fff}.f-datepicker-container.container-position-top{margin:-6px}.f-datepicker-container.container-position-top .arrow{top:auto;bottom:-6px}.f-datepicker-container.container-position-top .arrow::after,.f-datepicker-container.container-position-top .arrow::before{border-width:6px 6px 0;border-top-color:#fff}.f-datepicker-container .f-datepicker-sidebar{position:absolute;top:0;bottom:0;width:100px;border-right:1px solid var(--f-neutral-13);box-sizing:border-box;padding-top:6px;background-color:#fff;overflow:auto}.f-datepicker-container .f-datepicker-sidebar button{display:block;width:100%;border:0;background-color:transparent;line-height:28px;font-size:14px;color:#606266;padding-left:12px;text-align:left;outline:0;cursor:pointer}.f-datepicker-container .f-datepicker-sidebar button:hover{color:#409eff}.f-datepicker-container .f-datepicker-content{width:287px}.f-datepicker-container .f-datepicker-content .f-datepicker-header{display:flex;justify-content:space-between;border-bottom:1px solid var(--f-neutral-13)}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-prev-btn{padding-left:1rem}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-prev-btn .f-datepicker-header-btn{color:var(--f-text-02);padding:1px 8px 1px 0}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-next-btn{padding-right:1rem}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-next-btn .f-datepicker-header-btn{color:var(--f-text-02);padding:1px 0 1px 8px}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-header-btn{height:40px;outline:0;border:0;background:var(--f-neutral-20);line-height:35px;font-size:14px;padding:1px 4px;cursor:pointer}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-header-btn:hover{color:var(--f-theme-05)}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-header-btn:active{color:var(--f-theme-01)}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-header-btn.f-datepicker-header-btn-disabled,.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-header-btn.f-datepicker-header-btn-disabled:active,.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-header-btn.f-datepicker-header-btn-disabled:hover{color:var(--f-text-07)}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-monthYearText .f-datepicker-header-btn{color:var(--f-text-02)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper{width:100%;height:254px;padding:8px 12px}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table{width:100%;height:100%;max-width:100%;background-color:transparent;border-collapse:collapse;text-align:center;border:0}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table th{font-weight:400;color:var(--f-text-08)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table tr.f-datepicker-selectWeek{cursor:pointer;transition:all .3s}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table tr.f-datepicker-selectWeek:not(.f-datepicker-selectedWeek):hover{background:var(--f-neutral-10)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table tr.f-datepicker-selectedWeek{background:var(--f-neutral-09)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td{padding:0;position:relative}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td:focus{border:0;outline:0;box-shadow:none}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td.f-datepicker-weeknbr{color:f-text-05}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-date:hover,.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-month:hover,.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-year:hover,.f-datepicker-container .f-datepicker-select-btn:hover{color:var(--f-theme-05)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td.f-datepicker-range::before{position:absolute;top:3px;right:0;bottom:3px;left:0;display:block;background:var(--f-neutral-10);border:0;border-radius:0;content:""}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-markdate{position:absolute;top:5px;left:5px;width:4px;height:4px;border-radius:50%}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-date,.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-month,.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-year{display:block;padding:0;margin:0 auto;text-align:center;background:0 0;border-radius:2px;transition:all .3s ease;cursor:pointer}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-date:active,.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-month:active,.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-year:active{color:var(--f-theme-01)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-date{width:28px;height:28px;line-height:28px;position:relative;z-index:1;border:1px solid transparent;border-radius:100%}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-month-cell,.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-year-cell{display:inline-block;padding:3px 8px;line-height:20px;border-radius:100%;border:1px solid transparent}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-current{border:1px solid var(--f-theme-03);color:var(--f-theme-03);background:#fff;box-shadow:0 0 4px 2px rgba(var(--f-theme-03),.12)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-range{color:var(--f-theme-03);border:1px solid var(--f-aid-02);background:var(--f-aid-02)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-selected{border:1px solid transparent;background:linear-gradient(214deg,#3F65FF 0,#4D9AFF 100%);color:#fff;border-radius:100%;box-shadow:0 2px 6px 0 rgba(var(--f-theme-03),.4)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-selected:hover{color:#fff}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-highlight{background:#75abf2;color:#fff}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-highlight:hover{color:#fff}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td.f-datepicker-no-currmonth{color:var(--f-text-07)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-disabled{background-color:var(--f-neutral-09);color:var(--f-text-07)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-disabled:hover{color:var(--f-text-07)}.f-datepicker-container .datepicker-content-has-timer .time-picker-panel{display:flex;bottom:0}.f-datepicker-container .datepicker-content-has-timer .time-picker-panel .farris-timer-picker{display:flex;flex:1 1 0}.f-datepicker-container .datepicker-content-has-timer .time-picker-panel .farris-timer-picker .time-picker-panel-inner{box-shadow:none;display:flex;flex:1 1 0}.f-datepicker-container .datepicker-content-has-timer .time-picker-panel .farris-timer-picker .time-picker-panel-inner .time-picker-panel-combobox{flex:1 1 0;overflow:hidden}.f-datepicker-container .datepicker-content-has-timer .time-picker-panel .farris-timer-picker .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select{height:100%;max-height:none}.f-datepicker-container .f-datepicker-commitBtn-wrapper{width:100%;text-align:right;height:2.8125rem;display:flex;align-items:center;padding:0 1.5rem;border-top:1px solid var(--f-neutral-13)}.f-datepicker-container .f-datepicker-select-btn{outline:0;border:0;cursor:pointer;flex-shrink:1;flex-grow:1;flex-basis:0}.f-datepicker-container .datepicker-multi-days-wrapper{border-left:1px solid var(--f-neutral-13)}.f-datepicker-multi-selectdays-header{border-bottom:1px solid var(--f-neutral-13)}.f-datepicker-multi-selectdays-clear{color:var(--f-text-09)}.f-datepicker-multi-selectdays-clear:hover{color:var(--f-theme-05)}.f-datepicker-multi-selectdays{color:var(--f-text-02)}.f-datepicker-multi-selectdays:hover{background:var(--f-neutral-10);color:var(--f-text-02)}.f-datepicker-multi-selectdays .remove{color:var(--f-text-09)}.f-datepicker-multi-selectdays .remove:hover{color:var(--f-theme-05)}.f-cmp-datepicker .date-range-wrapper{display:flex;padding-top:0;padding-bottom:0;align-items:center;flex-shrink:1;flex-grow:1;flex-basis:0%;background:0 0}.f-cmp-datepicker .date-range-wrapper .sub-input{outline:0;border:0;height:100%;display:block;width:100%}.f-cmp-datepicker .date-range-wrapper .sub-input.form-control{width:100%;padding:0}.f-cmp-datepicker .date-range-wrapper .sub-input-wrapper-end{flex:1 1 auto}.f-cmp-datepicker .date-range-wrapper .sub-input-wrapper{position:relative}.f-cmp-datepicker .date-range-wrapper .sub-input-wrapper::after{content:"";position:absolute;height:1px;background:var(--f-theme-04);left:0;bottom:0;width:0;transition:all .3s linear}.dropdown,.dropdown-left,.dropdown-submenu,.dropleft,.dropleft-up,.dropright,.dropright-up,.dropup,.dropup-left{position:relative}.f-cmp-datepicker .date-range-wrapper .sub-input-spliter{margin:0 4px;flex-shrink:0;line-height:1;font-size:12px;color:var(--f-text-04)}.f-cmp-datepicker .date-range-wrapper .sub-input-wrapper.f-state-focus::after{width:100%}.f-cmp-datepicker .input-group{display:flex}.f-cmp-datepicker .input-group.f-state-focus{border-color:var(--f-theme-08);box-shadow:0 0 0 2px rgba(var(--f-theme-03),.14)}.f-cmp-datepicker .input-group.f-state-disabled,.f-cmp-datepicker .input-group.f-state-readonly{box-shadow:none}@keyframes selectorfadein{from{opacity:0}to{opacity:1}}.f-datepicker-footer{display:flex;justify-content:space-between;border-top:1px solid #e4e7ef}.f-datepicker-footer .f-datepicker-redirect{margin:4px auto;line-height:32px;font-size:1rem}.f-datepicker-footer .f-datepicker-redirect>button{font-size:14px;font-weight:800}.f-dial .f-dial-range,.f-dial .f-dial-value{fill:none}.f-dial .f-dial-text{font-size:1.3rem;text-align:center}.f-discussion-group-edit{border:1px solid var(--f-neutral-04)!important;background:var(--f-neutral-12)!important}.f-discussion-group-edit .f-discussion-group-edit-container .textarea-editor a{color:var(--f-theme-03)}.f-discussion-group-edit .f-discussion-group-edit-footer{background:var(--f-neutral-09)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-item{color:var(--f-text-06)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-item .toolbar-icon{color:var(--f-text-08)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown{background:var(--f-neutral-20)!important;box-shadow:0 2px 20px 0 rgba(3,18,51,.12)!important}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item .f-discussion-group-about-dropdown-list-detail .about-list-detail-text{color:var(--f-text-02)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item .f-discussion-group-about-dropdown-list-detail .about-list-detail-subtext{color:var(--f-text-06)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item .f-icon-check,.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item .f-icon-tick::before{border:1px solid var(--f-neutral-02);color:#fff}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item.active .f-icon-check,.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item.active .f-icon-tick::before{background:linear-gradient(214deg,#3F65FF 0,#4D9AFF 100%)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item .about-list-item-avatar-tip{background-color:linear-gradient(214deg,#3F65FF 0,#4D9AFF 100%);color:#fff}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item:not(.about-dropdown-list-item-empty):hover{background:var(--f-neutral-11)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-about-list-btns{border-top:1px solid var(--f-neutral-06)!important;background:var(--f-neutral-09)!important}.f-discussion-dialog-content-left .f-discussion-tab-content,.f-discussion-dialog-content-right{border:1px solid var(--f-neutral-04)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-dropdown .toolbar-icon{color:var(--f-text-09)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-dropdown .toolbar-dropdown-list{background:0 2px 20px 0 rgba(3,18,51,.12);box-shadow:var(--f-neutral-20)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-dropdown .toolbar-dropdown-list ul li:hover{background:var(--f-neutral-11)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-btns .f-discussion-cancel,.farris-discussion-group-reply-tip{color:var(--f-text-04)}.f-discussion-dialog-content-left .f-discussion-tab-content .f-discussion-personnel-content .f-discussion-personnel-crumbs .crumbs-list-item{color:var(--f-text-02)}.f-discussion-dialog-content-left .f-discussion-tab-content .f-discussion-personnel-content .f-discussion-personnel-crumbs .crumbs-list-item.crumbs-list-item-disabled{color:var(--f-text-07)}.f-discussion-dialog-content-right .f-discussion-selected-personnel-header{background:var(--f-neutral-09)}.f-discussion-dialog-content-right .f-discussion-selected-personnel-content .f-discussion-selected-list .f-discussion-selected-item-text .f-discussion-selected-name{color:var(--f-text-02)}.f-discussion-dialog-content-right .f-discussion-selected-personnel-content .f-discussion-selected-list .f-discussion-selected-item-tip{color:var(--f-text-09)}.f-discussion-dialog-content-right .f-discussion-selected-personnel-content .f-discussion-selected-list .f-discussion-selected-item-remove{color:var(--f-theme-05)}.f-discussion-dialog-content-right .f-discussion-selected-personnel-content .f-discussion-selected-list .f-discussion-selected-item:hover{background:var(--f-neutral-11)}.f-discussion-dialog-content .f-discussion-personnel-item:hover,.f-listview-active .f-tmpl-card--header-multicontent01,.f-listview-active .f-tmpl-list--columns01{background:var(--f-aid-03)}.f-discussion-dialog-content .f-discussion-personnel-item-text .f-discussion-personnel-name{color:var(--f-text-01)}.f-discussion-dialog-content .f-discussion-personnel-item-text .f-discussion-personnel-mail{color:var(--f-text-06)}.f-discussion-dialog-content .f-discussion-personnel-item.active,.f-discussion-dialog-content .f-discussion-personnel-item.selected{background:var(--f-aid-02)}.f-discussion-dialog-content .f-discussion-personnel-item.selected .f-discussion-personnel-mail,.f-discussion-dialog-content .f-discussion-personnel-item.selected .f-discussion-personnel-name{color:#c1c1c1}.f-discussion-dialog-content .f-discussion-section-list-empty .f-icon{color:var(--f-text-08)}.f-discussion-dialog-content .f-discussion-section-list-empty .section-list-empty-text{color:var(--f-text-09)}.f-discussion-dialog-content .f-discussion-personnel-item-tip{color:#fff;background-color:#4796FF}.f-discussion-dialog-content .f-discussion-section-list .section-list-item-name{color:var(--f-text-02);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.f-discussion-dialog-content .f-discussion-section-list .section-list-item-next{color:var(--f-theme-03)}.f-discussion-dialog-content .f-discussion-section-list .section-list-item-next::before{background:var(--f-neutral-06)}.f-discussion-dialog-content .f-discussion-section-list .section-list-item:hover{background:var(--f-neutral-11)}.f-discussion-dialog-content .f-discussion-section-list .person-list-item-content .section-list-item-name{color:var(--f-text-02)}.f-discussion-dialog-content .f-discussion-section-list .person-list-item-content .section-list-item-tip{color:var(--f-text-09)}.f-discussion-person-list-page .section-page-text{color:var(--f-text-05)}.f-discussion-person-list-page:hover .section-page-text{color:var(--f-text-02)}.f-discussion-group-content-item .discussion-item-avatar-tip{color:var(--f-text-00);background-color:var(--f-theme-05)}.dropdown-menu,.f-discussion-group-content-item .discussion-item-inner .discussion-item-username{color:var(--f-text-02)}.f-discussion-group-content-item .discussion-item-inner{border-bottom:1px solid var(--f-neutral-06)}.dropdown-item,.f-discussion-group-content-item .discussion-item-inner .discussion-item-text,.f-discussion-group-content-item .discussion-item-inner .discussion-item-text-reply-content,.f-discussion-group-content-item .discussion-item-inner .discussion-item-text-reply-title{color:var(--f-text-04)}.f-discussion-group-content-item .discussion-item-inner .discussion-item-text-reply{background:var(--f-neutral-09)!important;border-radius:6px!important}.f-discussion-group-content-item .discussion-item-inner .discussion-item-text-reply-title .discussion-item-text-reply-name{color:rgba(var(--f-theme-05),.8)}.f-discussion-group-content-item .discussion-item-inner .discussion-item-footer .discussion-item-time{color:var(--f-text-09)}.f-discussion-group-content-item .discussion-item-inner .discussion-item-footer .discussion-item-btns .discussion-item-btns-start .discussion-item-btns-start-text,.f-discussion-group-content-item .discussion-item-inner .discussion-item-footer .discussion-item-btns .discussion-item-btns-start .f-icon{color:var(--f-text-12)!important}.f-discussion-group-content-item .discussion-item-inner .discussion-item-footer .discussion-item-btns .discussion-item-btns-start:hover .discussion-item-btns-start-text,.f-discussion-group-content-item .discussion-item-inner .discussion-item-footer .discussion-item-btns .discussion-item-btns-start:hover .f-icon{color:var(--f-theme-05)!important}.f-discussion-group-content-item .discussion-item-inner .discussion-item-footer .discussion-item-btns .discussion-item-btns-start:active .discussion-item-btns-start-text,.f-discussion-group-content-item .discussion-item-inner .discussion-item-footer .discussion-item-btns .discussion-item-btns-start:active .f-icon{color:var(--f-theme-01)!important}.f-discussion-group-content-item .discussion-item-inner .discussion-item-text .discussion-item-text-message a{color:var(--f-theme-03)!important}.f-discussion-group-content-item .discussion-item-inner .discussion-item-text .discussion-item-text-message a:hover{color:var(--f-theme-05)!important}.f-discussion-group-content-item .discussion-item-inner .discussion-item-text .discussion-item-text-message a:active{color:var(--f-theme-01)!important}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.125rem;vertical-align:.125rem;content:"";border-top:.25rem solid;border-right:.25rem solid transparent;border-bottom:0;border-left:.25rem solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:300;display:none;float:left;min-width:10rem;padding:.25rem;margin:.25rem 0;font-size:.8125rem;text-align:left;list-style:none;background-color:var(--f-neutral-20);background-clip:padding-box;border:0 solid rgba(0,0,0,.15);border-radius:6px;box-shadow:0 2px 20px 0 rgba(3,18,51,.12)}.dropup .dropdown-toggle::after,.dropup-left .dropdown-toggle::after{width:0;height:0;vertical-align:.125rem;content:"";border-right:.25rem solid transparent;border-bottom:.25rem solid;border-left:.25rem solid transparent;border-top:0}.dropdown-submenu .dropdown-toggle,.f-btn-icon.f-bare,.f-response-content .dropdown-item{box-shadow:none!important}.dropdown-menu-right{right:0;left:auto}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.25rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.125rem}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropup-left .dropdown-menu{top:auto;right:0;left:auto;bottom:100%;margin-top:0;margin-bottom:.25rem}.dropup-left .dropdown-toggle::after{display:inline-block;margin-left:.125rem}.dropright .dropdown-toggle::after,.dropright-up .dropdown-toggle::after{display:inline-block;border-top:.25rem solid transparent;border-bottom:.25rem solid transparent;border-left:.25rem solid;vertical-align:0;width:0;height:0;content:"";border-right:0}.dropup-left .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.25rem}.dropright .dropdown-toggle::after{margin-left:.125rem}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright-up .dropdown-menu{top:auto;right:auto;left:100%;bottom:0;margin-top:0;margin-left:.25rem}.dropright-up .dropdown-toggle::after{margin-left:.125rem}.dropright-up .dropdown-toggle:empty::after{margin-left:0}.dropleft-up .dropdown-menu{top:auto;right:100%;left:auto;bottom:0;margin-top:0;margin-bottom:.25rem}.dropleft-up .dropdown-toggle::after{width:0;height:0;margin-left:.125rem;vertical-align:.125rem;content:"";display:none}.dropleft .dropdown-toggle::before,.dropleft-up .dropdown-toggle::before{display:inline-block;width:0;border-top:.25rem solid transparent;border-right:.25rem solid;border-bottom:.25rem solid transparent;height:0}.dropleft-up .dropdown-toggle::before{margin-right:.125rem;content:"";vertical-align:0}.dropleft-up .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.25rem}.dropleft .dropdown-toggle::after{width:0;height:0;margin-left:.125rem;vertical-align:.125rem;content:"";display:none}.dropleft .dropdown-toggle::before{margin-right:.125rem;content:"";vertical-align:0}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;overflow:hidden;border-top:1px solid var(--f-neutral-06)}.dropdown-item{display:block;clear:both;font-weight:400;text-align:inherit;white-space:nowrap;background-color:transparent;border:0;cursor:pointer;border-radius:6px}.dropdown-item:focus,.dropdown-item:hover{color:var(--f-text-02);text-decoration:none;background-color:var(--f-neutral-11)}.dropdown-item.active,.dropdown-item:active{color:var(--f-text-02);text-decoration:none;background-color:var(--f-neutral-10)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--f-text-09);background-color:transparent;cursor:default}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.25rem .5rem;margin-bottom:0;font-size:.75rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.3125rem .5rem;color:var(--f-text-04)}.dropdown-divider{margin:.25rem 0}.btn-group .btn+.dropdown-toggle-split{margin-left:-1px}.btn-group .btn-primary+.dropdown-toggle-split{margin-left:-1px;border-left-color:var(--f-neutral-06)}.dropdown-item{padding:.25rem .5rem}.dropdown-left>.dropdown-menu{right:0;left:auto}.dropleft>.dropdown-menu{top:0;right:100%;left:auto!important;margin-right:-1px}.dropdown-submenu .dropdown-item.dropdown-toggle{padding-right:1rem}.dropdown-submenu>.dropdown-toggle.dropdown-toggle-split{position:absolute;width:24px;height:24px;top:50%;right:0;left:auto;margin-top:-12px;cursor:pointer;border-radius:4px;text-align:center}.dropdown-submenu>.dropdown-toggle.dropdown-toggle-split:hover{color:var(--f-text-04);background:var(--f-aid-02)}.dropdown-item .btn-link,.dropdown-item .btn-link:hover,.f-btn-icon.f-bare,.f-btn-icon.f-bare.f-state-active,.f-btn-icon.f-bare.f-state-hover,.f-btn-icon.f-bare:active,.f-btn-icon.f-bare:hover,.f-btn-icon.f-bare:hover.f-state-active,.f-btn-icon.f-bare:hover:active{color:inherit}.dropdown-submenu>.dropdown-item.dropdown-toggle::after,.dropdown-submenu>.dropdown-item.dropdown-toggle::before{position:absolute;top:50%;right:9px;left:auto;margin-top:-4px}.dropdown-submenu.dropleft>.dropdown-item.dropdown-toggle::before,.dropdown-submenu.dropright>.dropdown-item.dropdown-toggle::before{margin-top:-.25rem}.btn-group .btn-secondary+.dropdown-toggle-split,.dropright>.dropdown-menu{margin-left:-1px}.f-response-content .dropdown-item.f-rt-btn,.f-response-content .dropdown-item.f-rt-toggle{cursor:pointer}.f-response-content .dropdown-item.f-rt-btn.disabled,.f-response-content .dropdown-item.f-rt-toggle.disabled{cursor:default}.farris-dropdown.btn-group .dropdown-menu{max-height:unset!important;width:unset!important}.f-filter-footer .footer-container,.f-sort-editor .footer-container{height:2rem;min-height:2rem;background-color:var(--f-neutral-07);line-height:2rem;flex-shrink:0}.f-list-filter .filter-expand{color:var(--f-text-07);cursor:pointer}.f-list-filter .filter-expand:hover{color:var(--f-theme-05)}.f-list-filter .filter-expand.active{color:var(--f-theme-03);background:rgba(var(--f-theme-05),.1)}.f-list-filter .filter-expand .filter-expand-tag{background-color:var(--f-semantic-danger-01)}.f-list-filter .filter-inputs-extend{border:none;background:var(--f-neutral-20)}.f-filter-wrapper .f-filter-inputs-extend .f-filter-typelist-arrow,.f-list-filter .filter-inputs-extend .filter-typelist-arrow{border-top-color:var(--f-neutral-20);border-right-color:transparent;border-bottom-color:transparent;border-left-color:var(--f-neutral-20)}.f-list-filter .filter-inputs-extend .filter-typelist-arrow{background:0 0;box-shadow:-2px -2px 5px rgba(0,0,0,.08)}.f-list-filter .filter-inputs-extend .filter-form-btns .filter-form-btn-reset::after{background:var(--f-neutral-06)}.f-list-filter .filter-search-btn-reset{color:var(--f-text-04)}.f-list-filter .filter-search-btn-reset:hover{color:var(--f-theme-05)}.f-list-filter .filter-inputs-extend{box-shadow:0 0 5px 0 rgba(0,0,0,.15)!important;border-radius:10px}.f-filter{display:block;flex-grow:1;flex-shrink:1;flex-basis:0;max-width:100%}.f-filter-wrapper{display:flex;align-items:flex-start;position:relative}.f-filter-wrapper .f-filter-wrapper-inner{display:flex;align-items:flex-start}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn{display:flex;align-items:center;flex-shrink:0;height:26px;line-height:26px;padding-left:10px}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn .extend-btn-text{margin-right:2px}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn .extend-btn-arrow{margin-left:8px}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn-advanced{flex-shrink:0;width:24px;height:24px;margin-left:21px;line-height:24px;color:var(--f-text-07);cursor:pointer}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn-advanced:hover{color:var(--f-theme-05)}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn-advanced.active{box-shadow:0 2px 5px 0 rgba(0,0,0,.15);color:var(--f-theme-01);background:rgba(var(--f-theme-03),.1);border-radius:2px}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn-advanced .f-icon{display:block;line-height:24px;margin:0 auto;font-size:18px}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn-advanced .filter-expand-tag{position:absolute;right:0;top:0;display:block;width:6px;height:6px;background-color:#f5222d;border-radius:50%}.f-filter-wrapper .f-filter-inputs-extend{width:429px;right:0;top:38px;border-radius:10px;background-color:var(--f-neutral-20);box-shadow:0 0 5px 0 rgba(0,0,0,.15);z-index:101;padding:20px 0}.f-filter-wrapper .f-filter-inputs-extend .f-filter-typelist-arrow{display:block;position:absolute;right:7px;top:-4px;width:8.49px;height:8.49px;background:0 0;border-style:solid;border-width:4.24px;box-shadow:-2px -2px 5px rgba(0,0,0,.08);transform:translateX(-50%) rotate(45deg)}.f-filter-wrapper .f-filter-inputs-extend .f-filter-form-btns{margin-top:6px;padding:0 14px}.f-filter-wrapper .f-filter-inputs-extend .f-filter-form-btns .btn{margin-left:6px}.f-filter-wrapper .f-filter-inputs-extend .f-filter-form-btns .filter-form-btn-reset{position:relative;padding-right:10px;margin-right:4px}.f-filter-wrapper .f-filter-inputs-extend .f-filter-form-btns .filter-form-btn-reset::after{content:"";position:absolute;right:0;top:50%;width:1px;height:16px;margin-top:-8px;background:#d9d9d9}.f-filter-wrapper .f-filter-main{display:flex}.f-filter-wrapper .f-filter-main .f-filter-list-wrapper{max-width:100%;margin-right:26px;overflow:hidden}.f-filter-wrapper .f-filter-list{display:flex;align-items:center;flex-wrap:nowrap;height:26px}.f-filter-wrapper .f-filter-list .f-filter-item{display:flex;align-items:center;flex-shrink:0;position:relative;height:26px;line-height:26px;margin-right:8px;font-size:13px;color:var(--f-text-02);border:1px solid #fff;border-radius:3px;cursor:pointer}.f-filter-wrapper .f-filter-list .f-filter-item-text{flex-shrink:0;color:var(--f-text-04)}.f-filter-wrapper .f-filter-list .f-filter-item-content{margin-left:4px;color:var(--f-text-02);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.f-filter-wrapper .f-filter-list .f-filter-item-arrow{flex-shrink:0;margin-left:8px;color:var(--f-text-04)}.f-filter-wrapper .f-filter-list .f-filter-item.f-filter-item-edit,.f-filter-wrapper .f-filter-list .f-filter-item:hover{background:rgba(var(--f-aid-05),.35);border-color:var(--f-aid-05)}.f-filter-wrapper .f-filter-list .f-filter-item.f-filter-item-actived{background:rgba(var(--f-aid-05),.35);border:1px solid var(--f-aid-05);border-radius:3px}.f-filter-wrapper .f-filter-list .f-filter-item.f-filter-item-actived:hover .f-filter-item-clear{display:flex}.f-filter-wrapper .f-filter-list .f-filter-item.f-filter-item-actived:hover .f-filter-item-arrow{opacity:0}.f-filter-wrapper .f-filter-list .f-filter-item-clear{display:none;flex-direction:column;justify-content:center;position:absolute;right:2px;top:0;bottom:0;cursor:pointer}.f-filter-wrapper .f-filter-list .f-filter-item-clear .f-icon{font-size:12px;color:#6388FF}.f-filter-wrapper .f-filter-list .f-filter-item-required{flex-shrink:0;margin-right:2px}.f-filter-wrapper .f-filter-list.f-filter-list-extend .f-filter-item-last,.f-filter-wrapper .f-filter-toolbars .btn,.form-group--has-tips .farris-input-wrap{margin-right:18px}.f-filter-wrapper .f-filter-list .f-filter-item-inner{display:flex;align-items:center;max-width:286px}.f-filter-wrapper .f-filter-list.f-filter-list-extend{height:auto}.f-filter-wrapper .f-filter-list.f-filter-list-extend .f-filter-item{margin-bottom:6px}.f-filter-wrapper .f-filter-list-ellipsis{flex-shrink:0;width:48px;height:26px;line-height:20px;padding-right:18px;text-align:center;cursor:pointer}.f-filter-wrapper .f-filter-toolbars{flex-shrink:0;display:flex;align-items:center;padding:3px 0}.f-filter-wrapper .f-filter-list-extend .f-filter-toolbars{margin-bottom:8px}.f-filter-wrapper .f-filter-item-reminder{position:absolute;top:calc(100% - 6px);left:0;padding-top:11px;z-index:100}.f-filter-wrapper .f-filter-item-reminder .reminder-arrow{position:absolute;top:2px;left:10%}.f-filter-wrapper .f-filter-item-reminder .reminder-arrow::after{position:absolute;top:2px;display:block;content:"";border-color:transparent;border-style:solid;border-width:0 6px 8px;border-bottom-color:var(--f-theme-03)}.f-filter-wrapper .f-filter-item-reminder .reminder-inner{padding:8px 12px;font-size:13px;color:#fff;white-space:nowrap;background:linear-gradient(46deg,#2E77FF 0,#2A87FF 100%);box-shadow:2px 2px 8px 0 rgba(0,0,0,.14);border-radius:10px}.f-filter-wrapper .f-filter-item-reminder .reminder-inner .f-icon{margin-right:6px;font-size:13px}.f-filter-panel-form .filter-type-checkboxgroup .farris-form-group .farris-input-wrap .custom-checkbox,.f-filter-panel-form .filter-type-radio .farris-form-group .farris-input-wrap .custom-radio{margin-bottom:0;margin-top:0}.f-filter-panel-form .filter-type-checkboxgroup .farris-form-group .farris-input-wrap .custom-checkbox:last-child,.f-filter-panel-form .filter-type-radio .farris-form-group .farris-input-wrap .custom-radio:last-child{margin-bottom:0}.f-filter-panel-form .filter-type-checkboxgroup .farris-form-group .farris-input-wrap .custom-checkbox .custom-control-label,.f-filter-panel-form .filter-type-radio .farris-form-group .farris-input-wrap .custom-radio .custom-control-label{display:block;width:100%;line-height:30px}.f-filter-panel-form .filter-type-checkboxgroup .farris-form-group .farris-input-wrap .custom-checkbox .custom-control-label::before,.f-filter-panel-form .filter-type-radio .farris-form-group .farris-input-wrap .custom-radio .custom-control-label::before{top:8px}.f-filter-panel-form .filter-type-checkboxgroup .farris-form-group .farris-input-wrap .custom-checkbox:hover,.f-filter-panel-form .filter-type-radio .farris-form-group .farris-input-wrap .custom-radio:hover{background-color:var(--f-neutral-11)}.f-sidebar-filter-main .f-sidebar-filter-footer{display:flex;align-items:center;justify-content:space-between!important;height:72px!important;padding:10px 24px!important;border-top:1px dashed #eaedf3!important;background:var(--f-neutral-00)!important}.f-sidebar-filter-main .f-sidebar-header .f-tmpl-for-title-withline::before{display:none}.f-sidebar-filter-main .f-sidebar-filter-content{padding:24px 48px 24px 12px!important}.f-sidebar-filter-main .f-sidebar-filter-content .farris-form-controls-inline .farris-group-wrap .form-group{margin-bottom:10px}.f-sidebar-filter-main .f-sidebar-filter-btns .btn{height:32px;margin-right:12px}.f-sidebar-filter-main .f-sidebar-filter-btns .f-sidebar-filter-btn-confirm{padding-left:66px;padding-right:66px;margin-right:0}.f-filter-inputs-extend-list .form-group,.f-sidebar-filter-list .form-group{display:block}.f-filter-inputs-extend-list.farris-form-controls-inline .form-group,.f-sidebar-filter-list.farris-form-controls-inline .form-group{display:flex}.f-filter-panel-flexible-icon{flex-shrink:0;margin:0 6px;font-size:14px;color:#999}.f-filter-panel-wrapper{position:fixed;z-index:1050;top:0;left:0;height:100%;width:100%;pointer-events:auto}.f-filter-panel{position:absolute;z-index:100;padding-top:14px}.f-filter-panel-header{display:flex;justify-content:space-between;align-items:center}.f-filter-panel-header .panel-header-title{line-height:22px;font-size:15px;color:rgba(0,0,0,.85);font-weight:600}.f-filter-panel-content{padding-top:8px}.f-filter-panel-content .filter-type-checkboxgroup{max-height:216px;padding:6px 8px 6px 0;border-radius:2px;overflow-y:auto}.f-filter-panel-content .filter-type-checkboxgroup .custom-checkbox{padding-left:14px}.f-filter-panel-footer{display:flex;justify-content:space-between;padding-top:16px;align-items:center}.f-filter-panel-footer .filter-panel-submit{padding-left:22px;padding-right:22px;margin-left:8px}.f-filter-panel-footer .btn-link{padding-right:8px}.f-filter-panel-footer .btn-empty{position:relative;padding-left:8px}.f-filter-panel-footer .btn-empty::before{position:absolute;left:0;top:50%;width:1px;height:16px;margin-top:-8px;background-color:var(--f-neutral-08);content:""}.f-filter-panel .f-filter-panel-inner{position:relative;min-width:380px;padding:14px 24px 18px;background:var(--f-neutral-20);box-shadow:0 2px 12px 0 rgba(31,35,41,.1);border-radius:10px}.f-filter-panel .f-filter-panel-inner.f-filter-panel-inner-xs{padding:10px 4px 16px}.f-filter-panel .f-filter-panel-inner.f-filter-panel-inner-auto{min-width:auto;padding:0}.f-filter-panel-arrow{position:absolute;top:-12px;left:26px}.f-filter-panel-arrow::after{position:absolute;top:2px;display:block;content:"";border-color:transparent;border-style:solid;border-width:0 8px 10px;border-bottom-color:var(--f-neutral-20)}.f-filter-panel.f-filter-panel-radio .f-filter-panel-inner{min-width:230px}.f-filter-panel .f-panel-filter-tip{display:flex;align-items:center;margin-bottom:12px}.f-filter-panel .f-panel-filter-tip .panel-filter-tip-text{margin-right:8px}.f-filter-panel .panel-flexible-range-wrapper{align-items:center}.f-filter-panel .panel-flexible-range-wrapper .f-icon{flex-shrink:0;margin:0 8px;font-size:14px;color:#999}.f-filter-panel .panel-flexible-range-wrapper .f-cmp-datepicker,.f-filter-panel .panel-flexible-range-wrapper .f-cmp-number-spinner{width:150px}.f-filter-panel-date-tags{display:flex;flex-direction:row;align-items:center;padding-top:12px}.f-filter-panel-date-tags .panel-date-tag{height:24px;line-height:22px;padding:0 14px;margin-right:8px;font-size:12px;background-color:var(--f-neutral-00);border:1px solid var(--f-neutral-08);border-radius:13px;cursor:pointer}.f-filter-panel-date-tags .panel-date-tag.active{background:rgba(var(--f-theme-03),.09);border:1px solid}.filter-panel-checkbox{width:100%;height:30px;line-height:30px;margin:0;padding-right:0;background:var(--f-neutral-09)}.filter-panel-checkbox .custom-control-label{display:block;cursor:pointer;width:100%}.filter-panel-checkbox .custom-control-label::before{top:50%;transform:translateY(-50%)}.f-filter-panel-radiogroup .panel-radiogroup-item{display:flex;align-items:center;padding:.5rem 1.375rem;border:0;cursor:pointer}.f-filter-panel-radiogroup .panel-radiogroup-item.panel-radiogroup-item-active{color:var(--f-text-02);background:var(--f-neutral-10);border-radius:3px}.f-filter-panel-radiogroup .panel-radiogroup-item-text{font-size:14px;line-height:18px}.f-filter-panel-radiogroup .panel-radiogroup-item:hover{color:var(--f-text-02);background-color:var(--f-neutral-11)}.f-filter-search-result-panel{position:absolute;left:0;top:26px;z-index:100;width:200px;padding:8px;color:rgba(0,0,0,.85);background-color:#fff;box-shadow:0 2px 12px 0 rgba(31,35,41,.1);border-radius:4px}.f-filter-search-result-panel .search-result-title{line-height:22px;font-size:14px;font-weight:600}.f-filter-search-result-panel .search-result-list .search-result-item{line-height:26px;font-size:14px;cursor:pointer;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.f-filter-search-result-panel .search-result-list .search-result-item:hover{background:rgba(42,135,255,.06)}.f-filter-panel-search-tags{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap;max-width:320px;padding-top:12px}.f-filter-panel-search-tags .panel-search-tag{display:flex;align-items:center;height:24px;line-height:22px;margin-right:8px;margin-bottom:8px;font-size:12px;color:#333;background-color:#fff;border:1px solid rgba(216,220,230,.6);border-radius:2px;cursor:pointer}.f-filter-panel-search-tags .panel-search-tag:last-child{margin-right:0}.f-filter-panel-search-tags .panel-search-tag .panel-search-tag-text{max-width:72px;padding-left:8px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.f-filter-panel-search-tags .panel-search-tag .panel-search-tag-remove{height:22px;line-height:22px;margin-left:6px;margin-right:8px;font-size:14px;color:#999;cursor:pointer}.f-filter-panel-search-tags .panel-search-tag:active{background:rgba(42,135,255,.06);border:1px solid rgba(42,135,255,.16)}.f-filter-container{padding-bottom:12px}.f-filter-wrapper .f-filter-list .f-filter-item{padding:0 20px 0 12px!important}.f-filter-wrapper .f-filter-list .f-filter-item-clear{padding:0 2px!important}.container,.container-fluid{padding-right:14px;padding-left:14px;margin-right:auto;margin-left:auto;width:100%}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:888px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.row{display:flex;flex-wrap:wrap;margin-right:-14px;margin-left:-14px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-el,.col-el-1,.col-el-10,.col-el-11,.col-el-12,.col-el-2,.col-el-3,.col-el-4,.col-el-5,.col-el-6,.col-el-7,.col-el-8,.col-el-9,.col-el-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:14px;padding-left:14px}.col{flex-basis:0;flex-grow:1;max-width:100%}.col-auto{flex-grow:0;flex-shrink:0;flex-basis:auto;width:auto;max-width:none}.col-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.col-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.col-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.col-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.col-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.col-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.col-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.col-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.col-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.col-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.col-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.col-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.3333333333%}.offset-2{margin-left:16.6666666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.3333333333%}.offset-5{margin-left:41.6666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.3333333333%}.offset-8{margin-left:66.6666666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.3333333333%}.offset-11{margin-left:91.6666666667%}.f-area-response [class*=col-xs]{flex:none;max-width:none}.f-area-response.f-area-response--xs .col-xs-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.f-area-response.f-area-response--xs .col-xs-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.f-area-response.f-area-response--xs .col-xs-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.f-area-response.f-area-response--xs .col-xs-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.f-area-response.f-area-response--xs .col-xs-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.f-area-response.f-area-response--xs .col-xs-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.f-area-response.f-area-response--xs .col-xs-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.f-area-response.f-area-response--xs .col-xs-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.f-area-response.f-area-response--xs .col-xs-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.f-area-response.f-area-response--xs .col-xs-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.f-area-response.f-area-response--xs .col-xs-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.f-area-response.f-area-response--xs .col-xs-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}@media (min-width:576px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.col-sm-auto{flex-grow:0;flex-shrink:0;flex-basis:auto;width:auto;max-width:none}.col-sm-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.col-sm-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.col-sm-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.col-sm-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.col-sm-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.col-sm-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.col-sm-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.col-sm-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.col-sm-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.col-sm-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.col-sm-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.col-sm-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.3333333333%}.offset-sm-2{margin-left:16.6666666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.3333333333%}.offset-sm-5{margin-left:41.6666666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.3333333333%}.offset-sm-8{margin-left:66.6666666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.3333333333%}.offset-sm-11{margin-left:91.6666666667%}}.f-area-response [class*=col-sm]{flex:none;max-width:none}.f-area-response.f-area-response--sm .col-sm-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.f-area-response.f-area-response--sm .col-sm-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.f-area-response.f-area-response--sm .col-sm-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.f-area-response.f-area-response--sm .col-sm-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.f-area-response.f-area-response--sm .col-sm-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.f-area-response.f-area-response--sm .col-sm-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.f-area-response.f-area-response--sm .col-sm-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.f-area-response.f-area-response--sm .col-sm-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.f-area-response.f-area-response--sm .col-sm-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.f-area-response.f-area-response--sm .col-sm-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.f-area-response.f-area-response--sm .col-sm-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.f-area-response.f-area-response--sm .col-sm-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}@media (min-width:768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.col-md-auto{flex-grow:0;flex-shrink:0;flex-basis:auto;width:auto;max-width:none}.col-md-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.col-md-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.col-md-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.col-md-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.col-md-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.col-md-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.col-md-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.col-md-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.col-md-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.col-md-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.col-md-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.col-md-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.3333333333%}.offset-md-2{margin-left:16.6666666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.3333333333%}.offset-md-5{margin-left:41.6666666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.3333333333%}.offset-md-8{margin-left:66.6666666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.3333333333%}.offset-md-11{margin-left:91.6666666667%}}.f-area-response [class*=col-md]{flex:none;max-width:none}.f-area-response.f-area-response--md .col-md-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.f-area-response.f-area-response--md .col-md-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.f-area-response.f-area-response--md .col-md-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.f-area-response.f-area-response--md .col-md-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.f-area-response.f-area-response--md .col-md-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.f-area-response.f-area-response--md .col-md-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.f-area-response.f-area-response--md .col-md-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.f-area-response.f-area-response--md .col-md-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.f-area-response.f-area-response--md .col-md-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.f-area-response.f-area-response--md .col-md-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.f-area-response.f-area-response--md .col-md-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.f-area-response.f-area-response--md .col-md-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}@media (min-width:888px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.col-lg-auto{flex-grow:0;flex-shrink:0;flex-basis:auto;width:auto;max-width:none}.col-lg-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.col-lg-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.col-lg-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.col-lg-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.col-lg-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.col-lg-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.col-lg-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.col-lg-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.col-lg-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.col-lg-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.col-lg-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.col-lg-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.3333333333%}.offset-lg-2{margin-left:16.6666666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.3333333333%}.offset-lg-5{margin-left:41.6666666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.3333333333%}.offset-lg-8{margin-left:66.6666666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.3333333333%}.offset-lg-11{margin-left:91.6666666667%}}.f-area-response [class*=col-lg]{flex:none;max-width:none}.f-area-response.f-area-response--lg .col-lg-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.f-area-response.f-area-response--lg .col-lg-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.f-area-response.f-area-response--lg .col-lg-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.f-area-response.f-area-response--lg .col-lg-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.f-area-response.f-area-response--lg .col-lg-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.f-area-response.f-area-response--lg .col-lg-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.f-area-response.f-area-response--lg .col-lg-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.f-area-response.f-area-response--lg .col-lg-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.f-area-response.f-area-response--lg .col-lg-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.f-area-response.f-area-response--lg .col-lg-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.f-area-response.f-area-response--lg .col-lg-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.f-area-response.f-area-response--lg .col-lg-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}@media (min-width:1200px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.col-xl-auto{flex-grow:0;flex-shrink:0;flex-basis:auto;width:auto;max-width:none}.col-xl-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.col-xl-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.col-xl-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.col-xl-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.col-xl-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.col-xl-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.col-xl-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.col-xl-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.col-xl-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.col-xl-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.col-xl-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.col-xl-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.3333333333%}.offset-xl-2{margin-left:16.6666666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.3333333333%}.offset-xl-5{margin-left:41.6666666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.3333333333%}.offset-xl-8{margin-left:66.6666666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.3333333333%}.offset-xl-11{margin-left:91.6666666667%}}.f-area-response [class*=col-xl]{flex:none;max-width:none}.f-area-response.f-area-response--xl .col-xl-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.f-area-response.f-area-response--xl .col-xl-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.f-area-response.f-area-response--xl .col-xl-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.f-area-response.f-area-response--xl .col-xl-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.f-area-response.f-area-response--xl .col-xl-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.f-area-response.f-area-response--xl .col-xl-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.f-area-response.f-area-response--xl .col-xl-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.f-area-response.f-area-response--xl .col-xl-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.f-area-response.f-area-response--xl .col-xl-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.f-area-response.f-area-response--xl .col-xl-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.f-area-response.f-area-response--xl .col-xl-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.f-area-response.f-area-response--xl .col-xl-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}@media (min-width:1690px){.col-el{flex-basis:0;flex-grow:1;max-width:100%}.col-el-auto{flex-grow:0;flex-shrink:0;flex-basis:auto;width:auto;max-width:none}.col-el-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.col-el-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.col-el-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.col-el-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.col-el-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.col-el-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.col-el-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.col-el-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.col-el-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.col-el-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.col-el-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.col-el-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}.order-el-first{order:-1}.order-el-last{order:13}.order-el-0{order:0}.order-el-1{order:1}.order-el-2{order:2}.order-el-3{order:3}.order-el-4{order:4}.order-el-5{order:5}.order-el-6{order:6}.order-el-7{order:7}.order-el-8{order:8}.order-el-9{order:9}.order-el-10{order:10}.order-el-11{order:11}.order-el-12{order:12}.offset-el-0{margin-left:0}.offset-el-1{margin-left:8.3333333333%}.offset-el-2{margin-left:16.6666666667%}.offset-el-3{margin-left:25%}.offset-el-4{margin-left:33.3333333333%}.offset-el-5{margin-left:41.6666666667%}.offset-el-6{margin-left:50%}.offset-el-7{margin-left:58.3333333333%}.offset-el-8{margin-left:66.6666666667%}.offset-el-9{margin-left:75%}.offset-el-10{margin-left:83.3333333333%}.offset-el-11{margin-left:91.6666666667%}}.f-area-response [class*=col-el]{flex:none;max-width:none}.f-area-response.f-area-response--el .col-el-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.f-area-response.f-area-response--el .col-el-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.f-area-response.f-area-response--el .col-el-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.f-area-response.f-area-response--el .col-el-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.f-area-response.f-area-response--el .col-el-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.f-area-response.f-area-response--el .col-el-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.f-area-response.f-area-response--el .col-el-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.f-area-response.f-area-response--el .col-el-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.f-area-response.f-area-response--el .col-el-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.f-area-response.f-area-response--el .col-el-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.f-area-response.f-area-response--el .col-el-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.f-area-response.f-area-response--el .col-el-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}@font-face{font-family:FarrisIcons;font-style:normal;font-weight:400;src:url(data:font/ttf;base64,AAEAAAALAIAAAwAwR1NVQiCLJXoAAAE4AAAAVE9TLzI2JE+JAAABjAAAAGBjbWFwTohH7gAAC/AAACWUZ2x5ZqfrFDEAADaIAAH0DGhlYWQnvvaKAAAA4AAAADZoaGVhCNUHTgAAALwAAAAkaG10eApz/50AAAHsAAAKBGxvY2GWVxNEAAAxhAAABQRtYXhwA6wBEAAAARgAAAAgbmFtZchH0mwAAiqUAAACi3Bvc3QSpDltAAItIAAAK3cAAQAAA4D/gABcBVX/9v/3BQAAAQAAAAAAAAAAAAAAAAAAAoEAAQAAAAEAAGP+/t1fDzz1AAsEAAAAAADh1NlIAAAAAOHU2Uj/9v9xBQADjAAAAAgAAgAAAAAAAAABAAACgQEEACEAAAAAAAIAAAAKAAoAAAD/AAAAAAAAAAEAAAAKADAAPgACREZMVAAObGF0bgAaAAQAAAAAAAAAAQAAAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAQEAgGQAAUAAAKJAswAAACPAokCzAAAAesAMgEIAAACAAUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBmRWQAwOAA7LcDgP+AAAAD3ACPAAAAAQAAAAAAAAAAAAAAAAACBAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAD//wQA//8EAP//BAD//wQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAQAABAD/+QQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP/5BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP/2BAD/9gQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//kEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAP//BAD//wQA//8EAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEVQAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABEQAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEkgAABJIAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAASSAAAEAAAABJIAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAD//wQAAAAEAAAABAAAAAQAAAAEAP/9BAAAAAQAAAAEAAAABAD//wQA//8EAP/9BAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAREAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQB//8EAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQ8AAAENf/+BAAAAAQA//8EAAAABAD//wQAAAAEAP//BAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQB//4ETgAABAAAAAVVAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAE/wAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAAAAAFAAAAAwAAACwAAAAEAAAHMAABAAAAAAYqAAMAAQAAACwAAwAKAAAHMAAEBf4AAAA4ACAABAAY4DLhSeIO4wrlKuYr5kPmmua85tfnBegs6SLrGOs/60/rb+t/64nrqeu568nr2evp6/nsqey3//8AAOAA4QDiAOMA5QDmAOYt5kXmvObX5wDoAOkA6wTrGutB61HrceuB65rrsOvA69Dr4evw7KDssP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAOACcAS4BSgFeAbICCAI0At4C3gLeAugDQAOEA6wD9gQSBE4EagR6BJgEqgS8BM4E3gTwBQIAAAGPAGsAZgBhAoACfgJ/An0AZwBlAGIAZAJzAnECcgJwAngAYwBsAnwCegJ7AnkAbQBoAGkAagBeAA8AEQAVABMAEgBYAFMCdgJ3AnUBrwBSAFYAUQBZAF0AXwBgAFoCbwBOAFUCXgAEAE8AWwA5ABQAOgA9AAMBrwA/AFwASwJ0AEYAQgBKADwANwA7ADgAPgAKAAgABwBAACECawJsAEgCagHpAm0AKgHoAm4AIwAkACkAJgAWAA0AJQBBAEUATABJAEQARwAoACcAIAAiADYALgAvADIBsAA1Ak4ATQBDAAkCaQBXADQAFwAMADEALQAsADMAMAArAB0AGgAZAAsAHwAbABwAGAAeAAYABQAQAFAAVAGOAYUBiQGMAmgCZwHnAkkCQAGHAYsCSAJHAY0BiAGGAYoBfAGDAX8BgQGCAYABewGEAX4BfQF1AXMBcQFyAXkBdwF6AXQBeAF2AWoBbQFvAWcBaQFsAW4BcAFoAWsBZgFiAV0BZAFfAWEBYwFeAWUBYAFDAUgBSQFAAUIBRgFHAUUBQQFPAVABTQFLAU4BTAFEAVwBWgFbAVYBVAFXAVgBVQFZAVIBUwFKAVEBAAECAQEA/wD6ASYBPQEsATsBOQEvAPsBKgE0APwBBwEJAREBCgEIAQ0BBgEFAQ4BAwEQATMBIQEgAPUAkAE3ARkBMgD4AI4AigEkAI8AiwEXAP0BOgE+AT8BMQD+ARUBEwESAR8A+QEbARQBGAEaATUBIgDzASMBKwELARwBHgEoAScBJQEtATgBNgEEAQwBFgD3APIBKQD0AS4BMAE8AR0BDwCMAI0AngCXAJ8AkQCTAJ0AqACmAKAApwClAKsAnACWAJIAlACbAJoAlQCYAH4AfACjAKQAqgCtAK4AoQB9AIEAiQCHAIQAiACAAIYAhQB7AKkB5wD2AIIAfwCDAG4AegB5AHgAdwB2AHMAdAB1AHIAcQBvAHAArACiAJkA5gDsAOsA7gDpAOoA7wDnAOMA5ADwAO0A5QDoAPEA2QDbANoA4gDcAN4A3QDfAOAA4QDXANAA0wDRANYA1QDUANIAzwDYAMYAzADIAMkAxQDOAMoAxwDNAMsAwQDAAMMAvADCALsAxAC/AL0AvgCwALkArwC1ALQAtgCyALgAsQC6ALcAswJfAlwCYAJmAmUCZAJjAmICYQJdAlsCWgJZAlMCVgJRAlICVAJVAlcCWAJQAk8CTgJNAkwBsAJLAkoCRQJGAkECQgJDAkQCMQIwAj8CPgI9AjwCOwI4AjkCOgIzAjQCNQI2AjcCMgIvAi4CLQIsAisCKgIpAigCJwImAiUCJAIjAiICIAIhAh8CHgIdAhwCGwIaAhkCGAIXAhYCFQIUAhMCEgIRAhACDwIOAg0CDAILAgoCCQIIAgcCBgIFAgQCAwICAgECAAH/Af4B/QH8AfsB+gH5AfgB9wH2AfUB9AHzAfIB8QHwAe8B7gHtAewBrwHrAeoB5gHlAeQB4wHiAeEB4AHfAd4B3QHcAdsB2gHZAdgB1wHWAdUB1AHTAdIB0QHQ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AAAAhAAA5pUAAOaVAAAAiAAA5pYAAOaWAAAAgAAA5pcAAOaXAAAAhgAA5pgAAOaYAAAAhQAA5pkAAOaZAAAAewAA5poAAOaaAAAAqQAA5rwAAOa8AAAB5wAA5tcAAObXAAAA9gAA5wAAAOcAAAAAggAA5wEAAOcBAAAAfwAA5wIAAOcCAAAAgwAA5wMAAOcDAAAAbgAA5wQAAOcEAAAAegAA5wUAAOcFAAAAeQAA6AAAAOgAAAAAeAAA6AEAAOgBAAAAdwAA6AIAAOgCAAAAdgAA6AMAAOgDAAAAcwAA6AQAAOgEAAAAdAAA6AUAAOgFAAAAdQAA6AYAAOgGAAAAcgAA6AcAAOgHAAAAcQAA6AgAAOgIAAAAbwAA6AkAAOgJAAAAcAAA6AoAAOgKAAAArAAA6AsAAOgLAAAAogAA6AwAAOgMAAAAmQAA6A0AAOgNAAAA5gAA6A4AAOgOAAAA7AAA6A8AAOgPAAAA6wAA6BAAAOgQAAAA7gAA6BEAAOgRAAAA6QAA6BIAAOgSAAAA6gAA6BMAAOgTAAAA7wAA6BQAAOgUAAAA5wAA6BUAAOgVAAAA4wAA6BYAAOgWAAAA5AAA6BcAAOgXAAAA8AAA6BgAAOgYAAAA7QAA6BkAAOgZAAAA5QAA6BoAAOgaAAAA6AAA6BsAAOgbAAAA8QAA6BwAAOgcAAAA2QAA6B0AAOgdAAAA2wAA6B4AAOgeAAAA2gAA6B8AAOgfAAAA4gAA6CAAAOggAAAA3AAA6CEAAOghAAAA3gAA6CIAAOgiAAAA3QAA6CMAAOgjAAAA3wAA6CQAAOgkAAAA4AAA6CUAAOglAAAA4QAA6CYAAOgmAAAA1wAA6CcAAOgnAAAA0AAA6CgAAOgoAAAA0wAA6CkAAOgpAAAA0QAA6CoAAOgqAAAA1gAA6CsAAOgrAAAA1QAA6CwAAOgsAAAA1AAA6QAAAOkAAAAA0gAA6QEAAOkBAAAAzwAA6QIAAOkCAAAA2AAA6QMAAOkDAAAAxgAA6QQAAOkEAAAAzAAA6QUAAOkFAAAAyAAA6QYAAOkGAAAAyQAA6QcAAOkHAAAAxQAA6QgAAOkIAAAAzgAA6QkAAOkJAAAAygAA6QoAAOkKAAAAxwAA6QsAAOkLAAAAzQAA6QwAAOkMAAAAywAA6Q0AAOkNAAAAwQAA6Q4AAOkOAAAAwAAA6Q8AAOkPAAAAwwAA6RAAAOkQAAAAvAAA6REAAOkRAAAAwgAA6RIAAOkSAAAAuwAA6RMAAOkTAAAAxAAA6RQAAOkUAAAAvwAA6RUAAOkVAAAAvQAA6RYAAOkWAAAAvgAA6RcAAOkXAAAAsAAA6RgAAOkYAAAAuQAA6RkAAOkZAAAArwAA6RoAAOkaAAAAtQAA6RsAAOkbAAAAtAAA6RwAAOkcAAAAtgAA6R0AAOkdAAAAsgAA6R4AAOkeAAAAuAAA6R8AAOkfAAAAsQAA6SAAAOkgAAAAugAA6SEAAOkhAAAAtwAA6SIAAOkiAAAAswAA6wQAAOsEAAACXwAA6wUAAOsFAAACXAAA6wYAAOsGAAACYAAA6wcAAOsHAAACZgAA6wgAAOsIAAACZQAA6wkAAOsJAAACZAAA6woAAOsKAAACYwAA6wsAAOsLAAACYgAA6wwAAOsMAAACYQAA6w0AAOsNAAACXQAA6w4AAOsOAAACWwAA6w8AAOsPAAACWgAA6xAAAOsQAAACWQAA6xEAAOsRAAACUwAA6xIAAOsSAAACVgAA6xMAAOsTAAACUQAA6xQAAOsUAAACUgAA6xUAAOsVAAACVAAA6xYAAOsWAAACVQAA6xcAAOsXAAACVwAA6xgAAOsYAAACWAAA6xoAAOsaAAACUAAA6xsAAOsbAAACTwAA6xwAAOscAAACTgAA6x0AAOsdAAACTQAA6x4AAOseAAACTAAA6x8AAOsfAAABsAAA6yAAAOsgAAACSwAA6yEAAOshAAACSgAA6yIAAOsiAAACRQAA6yMAAOsjAAACRgAA6yQAAOskAAACQQAA6yUAAOslAAACQgAA6yYAAOsmAAACQwAA6ycAAOsnAAACRAAA6ygAAOsoAAACMQAA6ykAAOspAAACMAAA6yoAAOsqAAACPwAA6ysAAOsrAAACPgAA6ywAAOssAAACPQAA6y0AAOstAAACPAAA6y4AAOsuAAACOwAA6y8AAOsvAAACOAAA6zAAAOswAAACOQAA6zEAAOsxAAACOgAA6zIAAOsyAAACMwAA6zMAAOszAAACNAAA6zQAAOs0AAACNQAA6zUAAOs1AAACNgAA6zYAAOs2AAACNwAA6zcAAOs3AAACMgAA6zgAAOs4AAACLwAA6zkAAOs5AAACLgAA6zoAAOs6AAACLQAA6zsAAOs7AAACLAAA6zwAAOs8AAACKwAA6z0AAOs9AAACKgAA6z4AAOs+AAACKQAA6z8AAOs/AAACKAAA60EAAOtBAAACJwAA60IAAOtCAAACJgAA60MAAOtDAAACJQAA60QAAOtEAAACJAAA60UAAOtFAAACIwAA60YAAOtGAAACIgAA60cAAOtHAAACIAAA60gAAOtIAAACIQAA60kAAOtJAAACHwAA60oAAOtKAAACHgAA60sAAOtLAAACHQAA60wAAOtMAAACHAAA600AAOtNAAACGwAA604AAOtOAAACGgAA608AAOtPAAACGQAA61EAAOtRAAACGAAA61IAAOtSAAACFwAA61MAAOtTAAACFgAA61QAAOtUAAACFQAA61UAAOtVAAACFAAA61YAAOtWAAACEwAA61cAAOtXAAACEgAA61gAAOtYAAACEQAA61kAAOtZAAACEAAA61oAAOtaAAACDwAA61sAAOtbAAACDgAA61wAAOtcAAACDQAA610AAOtdAAACDAAA614AAOteAAACCwAA618AAOtfAAACCgAA62AAAOtgAAACCQAA62EAAOthAAACCAAA62IAAOtiAAACBwAA62MAAOtjAAACBgAA62QAAOtkAAACBQAA62UAAOtlAAACBAAA62YAAOtmAAACAwAA62cAAOtnAAACAgAA62gAAOtoAAACAQAA62kAAOtpAAACAAAA62oAAOtqAAAB/wAA62sAAOtrAAAB/gAA62wAAOtsAAAB/QAA620AAOttAAAB/AAA624AAOtuAAAB+wAA628AAOtvAAAB+gAA63EAAOtxAAAB+QAA63IAAOtyAAAB+AAA63MAAOtzAAAB9wAA63QAAOt0AAAB9gAA63UAAOt1AAAB9QAA63YAAOt2AAAB9AAA63cAAOt3AAAB8wAA63gAAOt4AAAB8gAA63kAAOt5AAAB8QAA63oAAOt6AAAB8AAA63sAAOt7AAAB7wAA63wAAOt8AAAB7gAA630AAOt9AAAB7QAA634AAOt+AAAB7AAA638AAOt/AAABrwAA64EAAOuBAAAB6wAA64IAAOuCAAAB6gAA64MAAOuDAAAB5gAA64QAAOuEAAAB5QAA64UAAOuFAAAB5AAA64YAAOuGAAAB4wAA64cAAOuHAAAB4gAA64gAAOuIAAAB4QAA64kAAOuJAAAB4AAA65oAAOuaAAAB3wAA65sAAOubAAAB3gAA65wAAOucAAAB3QAA650AAOudAAAB3AAA654AAOueAAAB2wAA658AAOufAAAB2gAA66AAAOugAAAB2QAA66EAAOuhAAAB2AAA66IAAOuiAAAB1wAA66MAAOujAAAB1gAA66QAAOukAAAB1QAA66UAAOulAAAB1AAA66YAAOumAAAB0wAA66cAAOunAAAB0gAA66gAAOuoAAAB0QAA66kAAOupAAAB0AAA67AAAOuwAAABzwAA67EAAOuxAAABzgAA67IAAOuyAAABzQAA67MAAOuzAAABzAAA67QAAOu0AAABywAA67UAAOu1AAABygAA67YAAOu2AAAByQAA67cAAOu3AAAByAAA67gAAOu4AAABxwAA67kAAOu5AAABxgAA68AAAOvAAAABxQAA68EAAOvBAAABxAAA68IAAOvCAAABwwAA68MAAOvDAAABwgAA68QAAOvEAAABwQAA68UAAOvFAAABwAAA68YAAOvGAAABvwAA68cAAOvHAAABvgAA68gAAOvIAAABvQAA68kAAOvJAAABvAAA69AAAOvQAAABuwAA69EAAOvRAAABugAA69IAAOvSAAABuQAA69MAAOvTAAABuAAA69QAAOvUAAABtwAA69UAAOvVAAABtgAA69YAAOvWAAABtQAA69cAAOvXAAABtAAA69gAAOvYAAABswAA69kAAOvZAAABsgAA6+EAAOvhAAABsQAA6+IAAOviAAABsAAA6+MAAOvjAAABrwAA6+QAAOvkAAABrgAA6+UAAOvlAAABrQAA6+YAAOvmAAABrAAA6+cAAOvnAAABqwAA6+gAAOvoAAABqgAA6+kAAOvpAAABqQAA6/AAAOvwAAABqAAA6/EAAOvxAAABpwAA6/IAAOvyAAABpgAA6/MAAOvzAAABpQAA6/QAAOv0AAABpAAA6/UAAOv1AAABowAA6/YAAOv2AAABogAA6/cAAOv3AAABoQAA6/gAAOv4AAABoAAA6/kAAOv5AAABnwAA7KAAAOygAAABngAA7KEAAOyhAAABnQAA7KIAAOyiAAABnAAA7KMAAOyjAAABmwAA7KQAAOykAAABlgAA7KUAAOylAAABlQAA7KYAAOymAAABlAAA7KcAAOynAAABkwAA7KgAAOyoAAABkgAA7KkAAOypAAABkQAA7LAAAOywAAABkAAA7LEAAOyx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Ad8B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AgACAQICAgMCBAIFAgYCBwIIAgkCCgILAgwCDQIOAg8CEAIRAhICEwIUAhUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIgIjAiQCJQImAicCKAIpAioCKwIsAi0CLgIvAjACMQIyAjMCNAI1AjYCNwI4AjkCOgI7AjwCPQI+Aj8CQAJBAkICQwJEAkUCRgJHAkgCSQJKAksCTAJNAk4CTwJQAlECUgJTAlQCVQJWAlcCWAJZAloCWwJcAl0CXgJfAmACYQJiAmMCZAJlAmYCZwJoAmkCagJrAmwCbQJuAm8CcAJxAnICcwJ0AnUCdgJ3AngCeQJ6AnsCfAJ9An4CfwKAAoECggKDAoQChQKGAocCiAKJAooCiwKMAo0CjgKPApACkQKSApMClAKVApYClwKYApkCmgKbApwCnQKeAp8CoAKhAqICowKkAqUCpgKnAqgCqQKqAqsCrAKtAq4CrwKwArECsgKzArQCtQK2ArcCuAK5AroCuwK8Ar0CvgK/AsACwQLCAsMCxALFAsYCxwLIAskCygLLAswCzQLOAs8C0ALRAtIC0wLUAtUC1gLXAtgC2QLaAtsC3ALdAt4C3wLgAuEC4gLjAuQC5QLmAucC6ALpAuoC6wLsAu0C7gLvAvAC8QLyAvMC9AL1AvYC9wL4AvkC+gL7AvwC/QL+Av8DAAMBAwIDAwMEAwUDBgMHAwgDCQMKAwsDDAMNAw4DDwMQAxEDEgMTAxQDFQMWAxcDGAMZAxoDGwMcAx0DHgMfAyADIQMiAyMDJAMlAyYDJwMoAykDKgMrAywDLQMuAy8DMAMxAzIDMwM0AzUDNgM3AzgDOQM6AzsDPAM9Az4DPwNAA0EDQgNDA0QDRQNGA0cDSANJA0oDSwNMA00DTgNPA1ADUQNSA1MDVANVA1YDVwNYA1kDWgNbA1wDXQNeA18DYANhA2IDYwNkA2UDZgNnA2gDaQNqA2sDbANtA24DbwNwA3EDcgNzA3QDdQN2A3cDeAN5A3oDewN8A30DfgN/A4ADgQOCAAphLWNodWxpcmVuCmNsb2NrLWVjYjUKY2xvY2stZTEwNwllMTAwLXVuZG8OZTIwOS1zdWJ0aXRsZXMHZTIwOC1oZBJlMTE3LWNhbmNlbC1jaXJjbGUTZTExNi1jYW5jZWwtb3V0bGluZQxlMTNkLXByZXZpZXcLZTExNS1jYW5jZWwEc3RvcApjYWxjdWxhdG9yDHNvcnQtZGVzYy1zbQ5lbmNsb3N1cmVfZWRpdBJlMDFjLWFycm93LXBhcmVudDENZTIwYS1wbGF5bGlzdBBlMDFkLWFycm93LXJvb3QxEWUwMjAtYXJyb3dzLXN3YXAxF2UwMWYtYXJyb3dzLWRpbWVuc2lvbnMxE2UxMDQtbm9uLXJlY3VycmVuY2UVZTAxZS1hcnJvd3MtcmVzaXppbmcxEGUxMjctc29ydC1hc2Mtc20IZTE0MS1wYW4OZTIwNi12b2x1bWUtdXAKZTIwMS1wYXVzZQllMjAwLXBsYXkMZTIwNC1mb3J3YXJkEGUyMDUtdm9sdW1lLWRvd24UZTE0OS1rcGktc3RhdHVzLW9wZW4PZTIwNy12b2x1bWUtb2ZmC2UyMDMtcmV3aW5kDWUxMzItZG93bmxvYWQSZTExOS1jaGVjay1vdXRsaW5lC2UxMzMtdXBsb2FkEmUxMjMtbWludXMtY2lyY2xlMQ1lMTI0LXNvcnQtYXNjC2UxMjktZmlsdGVyC2UxMjYtdW5zb3J0C2UxMzEtbG9nb3V0CmUxMzAtbG9naW4OZTEyNS1zb3J0LWRlc2MQZTEyMC1wbHVzLWNpcmNsZRRlMTQ4LWtwaS1zdGF0dXMtaG9sZAxlMTQ1LXBsdXMtc20OZTE0NC1jb25uZWN0b3IWZTEzNS1oeXBlcmxpbmstb3Blbi1zbQtlMTM2LWxhdW5jaBRlMTQ3LWtwaS1zdGF0dXMtZGVueQllMTQzLWNhcnQLZTEzNy13aW5kb3cNZTE0Ni1taW51cy1zbQ1lMTQwLXpvb20tb3V0FGUxMzktd2luZG93LW1pbmltaXplE2UxMzQtaHlwZXJsaW5rLW9wZW4SZTExMS1saW5rLXZlcnRpY2FsCWUxMTMtbG9jawtlMTAzLXJlbG9hZA1lMTA1LXJlc2V0LXNtFGUxMTItdW5saW5rLXZlcnRpY2FsFmUxMTAtdW5saW5rLWhvcml6b250YWwOZTEwNi1yZWxvYWQtc20LZTExNC11bmxvY2sLZTEwOS1mbG9wcHkKZTExOC1jaGVjaxFlMTJhLWZpbHRlci1jbGVhchJlMTBlLWF0dGFjaG1lbnQtNDULZTEzYy13cmVuY2gaZTEyZS1maWx0ZXItYWRkLWV4cHJlc3Npb24OZTEyYi1maWx0ZXItc20PZTEwZC1hdHRhY2htZW50FWUxMmYtZmlsdGVyLWFkZC1ncm91cBJlMTFjLWNsb3NlLW91dGxpbmUYZTEyZC1maWx0ZXItc29ydC1kZXNjLXNtFGUxMGYtbGluay1ob3Jpem9udGFsCGUxMGItZGl0F2UxMmMtZmlsdGVyLXNvcnQtYXNjLXNtCmUxM2ItZ2VhcnMJZTAzMC1tZW51CWUxMDEtcmVkbwplMjBiLWF1ZGlvEmUwMjktbGF5b3V0LTEtYnktNBFlMDI3LWhhbmRsZXItZHJhZw9lMDIyLWNhdGVnb3JpemUMZTIwYy1wbGF5LXNtEmUwMzEtbW9yZS12ZXJ0aWNhbAtlMDI4LWxheW91dAxlMTNmLXpvb20taW4SZTAyMS1kcmFnLWFuZC1kcm9wEmUwMmEtbGF5b3V0LTItYnktMgllMDJlLXJvd3MKZTEwMi1yZXNldAplMTBhLXByaW50GGUwMmItbGF5b3V0LXNpZGUtYnktc2lkZRBlMDFiLWFycm93LWRyaWxsE2UwMmMtbGF5b3V0LXN0YWNrZWQMZTAyZC1jb2x1bW5zFWUwMDMtYXJyb3ctNDUtdXAtbGVmdBNlMDBhLWFycm93LWVuZC1kb3duFWUwMTEtYXJyb3dzLW5vLWNoYW5nZQtlMDBiLXNlZWstdxRlMDA5LWFycm93LWVuZC1yaWdodBdlMDAyLWFycm93LTQ1LWRvd24tbGVmdBFlMDA4LWFycm93LWVuZC11cBBlMDE4LWFycm93LXJpZ2h0D2UwMTktYXJyb3ctZG93bg9lMDFhLWFycm93LWxlZnQYZTAwMS1hcnJvdy00NS1kb3duLXJpZ2h0GGUwMTItYXJyb3ctb3ZlcmZsb3ctZG93bg1lMDE3LWFycm93LXVwFmU3MDMtbWFya2VyLXBpbi10YXJnZXQNZTgwOC1kaWdnLWJveAplODA5LWVtYWlsCWU4MDctZGlnZxJlODA2LWRlbGljaW91cy1ib3gMZTgwMy1ibG9nZ2VyEGU4MDQtYmxvZ2dlci1ib3gOZTgwNS1kZWxpY2lvdXMKZTgwMi1pbmJveAllODAxLXVzZXIKZTgwMC1zaGFyZQplNzA1LXVucGluCGU3MDQtcGluDmU2OTktZm9udC1zaXplEGU2ODktcGFuZS1mcmVlemUcZTY5MC10b2dnbGUtZnVsbC1zY3JlZW4tbW9kZRJlNjg4LXRhYmxlLXVubWVyZ2UKZTcwMS1nbG9iZRJlNjk2LWN1c3RvbS1mb3JtYXQPZTY5MS1mb3JtdWxhLWZ4EmU3MDAtZ2xvYmUtb3V0bGluZQ9lNzAyLW1hcmtlci1waW4LZTY5NC1kb2xsYXIVZTY5OC1kZWNpbWFsLWRlY3JlYXNlFWU2OTctZGVjaW1hbC1pbmNyZWFzZQtlNjkzLXN5bWJvbAxlNjk1LXBlcmNlbnQIZTY5Mi1zdW0TZTY0My10ZXh0Ym94LWhpZGRlbhVlNjQ3LXRlbXBsYXRlLW1hbmFnZXIUZTY3Mi1oeXBlcmxpbmstZ2xvYmUbZTY3My1oeXBlcmxpbmstZ2xvYmUtcmVtb3ZlDGU2NDItdGV4dGJveA9lNjQ2LWVkaXQtdG9vbHMLZTYzZC1idXR0b24KZTY3Ny10YWJsZRFlNjgyLXRhYmxlLWRlbGV0ZRVlNjc4LXRhYmxlLXByb3BlcnRpZXMQZTY4My1jZWxscy1tZXJnZRxlNjg2LWNlbGwtc3BsaXQtaG9yaXpvbnRhbGx5FmU2ODEtdGFibGUtY2VsbC1kZWxldGULZTY3NS1hbmNob3IbZTY4Ny1jY2VsbC1zcGxpdC12ZXJ0aWNhbGx5EWU4MGMtZmFjZWJvb2stYm94G2U2ODUtY2VsbHMtbWVyZ2UtdmVydGljYWxseR1lNjg0LWNlbGxzLW1lcmdlLWhvcml6b250YWxseRVlNjgwLXRhYmxlLXJvdy1kZWxldGUPZTY3OS10YWJsZS1jZWxsFGU2NzQtaHlwZXJsaW5rLWVtYWlsF2U2NzYtdGFibGUtbGlnaHQtZGlhbG9nHmU2N2MtdGFibGUtY29sdW1uLWluc2VydC1yaWdodBRlNjhmLXZhbGlkYXRpb24tZGF0YQ1lODBiLWZjYWVib29rD2U2OGEtcm93LWZyZWV6ZRJlNjhiLWNvbHVtbi1mcmVlemUbZTY3ZS10YWJsZS1yb3ctaW5zZXJ0LWJlbG93HWU2N2ItdGFibGUtY29sdW1uLWluc2VydC1sZWZ0G2U2N2QtdGFibGUtcm93LWluc2VydC1hYm92ZRplNjdhLXRhYmxlLWNlbGwtcHJvcGVydGllcxxlNjlhLWltYWdlLWFic29sdXRlLXBvc2l0aW9uEmU2OGMtdG9vbGJhci1mbG9hdBhlNjdmLXRhYmxlLWNvbHVtbi1kZWxldGUOZTgwYS1lbWFpbC1ib3gSZTY4ZC1zcGVsbC1jaGVja2VyFWU2OGUtdmFsaWRhdGlvbi14aHRtbAhlOTE5LWNzcwplOTE3LWh0bWw1B2U5MWYtdmILZTkxZC12YnByb2oUZTkyMi1maWxlLWhvcml6b250YWwIZTkxYi1leGUHZTkxYS1qcwtlOTFjLWNzcHJvagplOTIxLWNsb3VkB2U5MWUtY3MJZTkxOC1odG1sCGU5MjAtc2xuDmU5MTItZmlsZS1hc2N4D2U5MTAtZmlsZS1mbGFzaAllOTE1LWZpbG0JZTkxNi1jc3MzDWU5MTQtZmlsZS16aXANZTkwZS1maWxlLXBkZg1lOTBkLWZpbGUtcHB0EGU5MTEtZmlsZS1jb25maWcNZTkwZi1maWxlLXBzZA1lOTEzLWZpbGUtYmFjDWU5MDctZmlsZS1hZGQOZTkwMy1mb2xkZXItdXAPZTkwYS1maWxlLWV4Y2VsFWU5MDUtYWdncmVnYXRlLWZpZWxkcwllOTA2LWZpbGUIZTkwOS1jc3YIZTkwYy1tZGIQZTkwNC1mb2xkZXItbW9yZQ5lOTBiLWZpbGUtd29yZA1lOTA4LWZpbGUtdHh0EGU5MDEtZm9sZGVyLW9wZW4IZTgyNy1yc3MKZTgyOS12aW1lbwtlOTAwLWZvbGRlcgxlODI4LXJzcy1ib3gQZTgyYy15b3V0dWJlLWJveAxlODJiLXlvdXR1YmUOZTgyYS12aW1lby1ib3gRZTgyNi1kcmliYmJsZS1ib3gPZTkwMi1mb2xkZXItYWRkFmU4MWMtdGVsbC1hLWZyaWVuZC1ib3gPZTgxZS10dW1ibHItYm94C2U4MWQtdHVtYmxyEGU4MjAtdHdpdHRlci1ib3gPZTgyMi15YW1tZXItYm94C2U4MjEteWFtbWVyDGU4MjMtYmVoYW5jZRBlODI0LWJlaGFuY2UtYm94DWU4MjUtZHJpYmJibGUMZTgxZi10d2l0dGVyDmU4MTUtcGludGVyZXN0EmU4MTYtcGludGVyZXN0LWJveBFlODE5LXN0dW1ibGUtdXBvbgtlODBkLWdvb2dsZRBlODE0LW15c3BhY2UtYm94FWU4MWEtc3R1bWJsZS11cG9uLWJveA1lODExLWxpbmtlZGluEWU4MTItbGlua2VkaW4tYm94EGU4MGYtZ29vZ2xlLXBsdXMPZTgwZS1nb29nbGUtYm94D2U4MTgtcmVkZGl0LWJveBRlODEwLWdvb2dsZS1wbHVzLWJveAxlODEzLW15c3BhY2ULZTgxNy1yZWRkaXQSZTgxYi10ZWxsLWEtZnJpZW5kEHN0cmlwLWNzcy1mb3JtYXQOdmlkZW8tZXh0ZXJuYWwTc3RyaXAtc3Bhbi1lbGVtZW50cwpzZWxlY3QtYWxsGHRhYmxlLWFsaWduLWJvdHRvbS1yaWdodBNzdHJpcC1hbGwtZm9ybWF0aW5nCHRleHRhcmVhCmltYWdlLWVkaXQJdGV4dC13cmFwGHRhYmxlLWFsaWduLW1pZGRsZS1yaWdodBJ0YWJsZS1hbGlnbi1yZW1vdmUNdHJhY2stY2hhbmdlcxh0cmFjay1jaGFuZ2VzLXJlamVjdC1hbGwMYWxpZ24tcmVtb3ZlDGFsaWduLWNlbnRlcg1hbGlnbi1qdXN0aWZ5C2FsaWduLXJpZ2h0CWJvcmRlci1ubwxhcHBseS1mb3JtYXQLYm9yZGVyLWxlZnQNYm9yZGVyLWJvdHRvbQtib3JkZXJzLWFsbBdib3JkZXJzLWluc2lkZS12ZXJ0aWNhbA9ib3JkZXJzLW91dHNpZGUZYm9yZGVycy1pbnNpZGUtaG9yaXpvbnRhbARjb3B5CWNsZWFyLWNzcwpib3JkZXItdG9wDGJvcmRlci1yaWdodBtlNjcxLWh5cGVybGluay1saWdodC1kaWFsb2cRYm9yZGVycy1zaG93LWhpZGUOYm9yZGVycy1pbnNpZGUOZGljdGlvbmFyeS1hZGQLY3VzdG9tLWljb24HY29tbWVudBBkb2N1bWVudC1tYW5hZ2VyC2NvcHktZm9ybWF0D2NoYW5nZS1tYW51YWxseQ5jb21tZW50LXJlbW92ZQ1jYWxlbmRhci1kYXRlE2NvbW1lbnRzLXJlbW92ZS1hbGwQaW1hZ2UtbWFwLWVkaXRvcgNjdXQObW9kdWxlLW1hbmFnZXIFcGFzdGUSaW1hZ2UtbGlnaHQtZGlhbG9nDGNvZGUtc25pcHBldAxmb3JtLWVsZW1lbnQNbWVkaWEtbWFuYWdlcg1mbGFzaC1tYW5hZ2VyDXBhcmFncmFwaC1hZGQacGFzdGUtZnJvbS13b3JkLXN0cmlwLWZpbGUPcnVsZS1ob3Jpem9udGFsD3Bhc3RlLWZyb20td29yZA1wYXN0ZS1hcy1odG1sE3N0cmlwLWZvbnQtZWxlbWVudHMXdGFibGUtYWxpZ24tYm90dG9tLWxlZnQQZmluZC1hbmQtcmVwbGFjZRZ0YWJsZS1hbGlnbi10b3AtY2VudGVyCnBhc3RlLWh0bWwVc3RyaXAtd29yZC1mb3JtYXR0aW5nGXRhYmxlLWFsaWduLW1pZGRsZS1jZW50ZXIRZm9ybWF0LWNvZGUtYmxvY2sUdHJhY2stY2hhbmdlcy1yZWplY3QJZ3JvdXAtYm94BGZvcm0ZdGFibGUtYWxpZ24tYm90dG9tLWNlbnRlcgtzaWx2ZXJsaWdodBBwYXN0ZS1wbGFpbi10ZXh0CnNlbGVjdC1ib3gOcGFzdGUtbWFya2Rvd24XdGFibGUtYWxpZ24tbWlkZGxlLWxlZnQUdHJhY2stY2hhbmdlcy1lbmFibGUVdGFibGUtYWxpZ24tdG9wLXJpZ2h0DXN0eWxlLWJ1aWxkZXIUdGFibGUtYWxpZ24tdG9wLWxlZnQUdHJhY2stY2hhbmdlcy1hY2NlcHQYdHJhY2stY2hhbmdlcy1hY2NlcHQtYWxsEWEtZTYwNGZvbnQtZmFtaWx5EGEtZTYwOXN1Yi1zY3JpcHQWYS1lNjA1Zm9yZWdyb3VuZC1jb2xvcgphLWU2MDFib2xkCGEtZTYxMGg0E2EtZTYwOHN0cmlrZXRocm91Z2gXYS1lNjA2Y29udmVydC1sb3dlcmNhc2UXYS1lNjA3Y29udmVydC11cHBlcmNhc2UMYS1lNjAyaXRhbGljD2EtZTYwM3VuZGVybGluZRJhLWU2MWNhbGlnbi1ib3R0b20IYS1lNjBkaDEIYS1lNjBmaDMJYS1lNjBjYWxsCGEtZTYwZWgyEGEtZTYwYXN1cC1zY3JpcHQJYS1lNjBiZGl2EGEtZTYxZGFsaWduLWxlZnQPYS1lNjFhYWxpZ24tdG9wEmEtZTYxYmFsaWduLW1pZGRsZRVhLWU2MTVpbmRlbnQtaW5jcmVhc2UTYS1lNjE4aW5zZXJ0LW1pZGRsZRRhLWU2MTRsaXN0LXVub3JkZXJlZBVhLWU2MTZpbmRlbnQtZGVjcmVhc2UPYS1lNjE3aW5zZXJ0LXVwEWEtZTYxOWluc2VydC1kb3duCGEtZTYxMmg2EmEtZTYxM2xpc3Qtb3JkZXJlZAhhLWU2MTFoNRNhLWU1MjR0aHVtYm5haWxzLXVwFmEtZTUyOWZ1bGwtc2NyZWVuLWV4aXQVYS1lNTI2dGh1bWJuYWlscy1kb3duFWEtZTYwMHBhZ2UtcHJvcGVydGllcxVhLWU1Mjd0aHVtYm5haWxzLWxlZnQaYS1lNTIzYWxpZ24tYm90dG9tLWVsZW1lbnQRYS1lNTI4ZnVsbC1zY3JlZW4WYS1lNTI1dGh1bWJuYWlscy1yaWdodBFhLWU1MmFyZXNldC1jb2xvchphLWU1MjJhbGlnbi1taWRkbGUtZWxlbWVudBJhLWU1MWJiYWNrLWVsZW1lbnQZYS1lNTIwYWxpZ24tcmlnaHQtZWxlbWVudBVhLWU1MWNmb3J3YXJkLWVsZW1lbnQLYS1lNTE4c2hhcGUXYS1lNTIxYWxpZ24tdG9wLWVsZW1lbnQWYS1lNTFkYmFja3dhcmQtZWxlbWVudBNhLWU1MTlyb3VuZC1jb3JuZXJzGGEtZTUxZWFsaWduLWxlZnQtZWxlbWVudBNhLWU1MWFmcm9udC1lbGVtZW50GmEtZTUxZmFsaWduLWNlbnRlci1lbGVtZW50CmEtZTUxMGxpbmUZYS1lNTExYnJpZ2h0bmVzcy1jb250cmFzdAthLWU1MGZwYWludA9hLWU1MTVncmV5c2NhbGUNYS1lNTBlcGFsZXR0ZQ1hLWU1MTdzaGFycGVuE2EtZTUxM2ludmVydC1jb2xvcnMKYS1lNTE2Ymx1chBhLWU1MTJzYXR1cmF0aW9uEmEtZTUxNHRyYW5zcGVyYW5jeQxhLWU1MGFyb3RhdGUTYS1lNTA0em9vbS1iZXN0LWZpdAthLWU1MGRicnVzaBFhLWU1MGNyb3RhdGUtbGVmdAphLWU1MDZjcm9wE2EtZTUwOWZsaXAtdmVydGljYWwMYS1lNTA3bWlycm9yFWEtZTUwOGZsaXAtaG9yaXpvbnRhbBJhLWU1MDVpbWFnZS1yZXNpemUSYS1lNTBicm90YXRlLXJpZ2h0DWEtZTIwZXN0b3Atc20SYS1lNTAyaW1hZ2UtZXhwb3J0FGEtZTMwN3RyaS1zdGF0ZS1udWxsC2EtZTUwMWltYWdlE2EtZTMwMGhlYXJ0LW91dGxpbmUWYS1lNTAzem9vbS1hY3R1YWwtc2l6ZQxhLWUzMDhjaXJjbGULYS1lMzAxaGVhcnQSYS1lNTAwcGhvdG8tY2FtZXJhDmEtZTIwZHBhdXNlLXNtC2NvbGxhcHNlLW5lCXRodW1idGFjawtzLXRodW1idGFjawZtb3ZldG8NZmlsdGVyX2RlbGV0ZQ9maWx0ZXJfZ3JvdXBpbmcKZmlsdGVyX2FkZBNmaWx0ZXJfY2FuY2VsbGF0aW9uBnZlcm5hdgpjdy1hcnJvd2RlCGN3LWhvdGVsB2N3LXRyaXAFemhhZ2UHZGVuZ2hhbw10aXNoaXNodW9taW5nBERyYWcGYmlhbmppBmNoYWthbgJiZwRsaGp0CGR1bGltaW1hEXFpYW5taW5ncWlhbnpoYW5nBmZhbmt1aRRhLUNGX0Rlc2NlbmRpbmdPcmRlchNhLUNGX0FzY2VuZGluZ09yZGVyBWFib3V0CXl1bnhpYW94aRBlbmNsb3N1cmVfZGVsZXRlEmVuY2xvc3VyZV9kb3dubG9hZBBlbmNsb3N1cmVfdXBsb2FkEGVuY2xvc3VyZV9icm93c2UKdXBsb2FkX2JpZw9jYWxlbmRhcnNfbGluZTEJbW9yZV9saW5lDmRyb3AtZG93bl9saW5lEHBlcnNwZWN0aXZlX3ZpZXcKY2hhcnRfdmlldwlmb3JtX3ZpZXcJbGlzdF92aWV3CWNhcmRfdmlldwtyZW1vdmVfZmFjZQtkdWl6aGFuZ2Rhbg1kaXpoaXNoZW5xaW5nDWppbmd4aWFvcmVud3UHYmFpZmFuZwprZWh1Z3VhbnhpCGZheXVuZGFuCWxpYW54aXJlbg1mdWt1YW50b25nemhpD2thaXBpYW9zaGVucWluZw94aWFvc2hvdWRhY2hlbmcOeGlhb3Nob3VxaWFubGkOeGlhb3Nob3VtdWJpYW8Nc2h1anVzaGFuZ2Jhbwx4dWtlc2hhbmdwaW4Jemhlbmd6aGFvDHhpYW9zaG91eXVjZQ94aWFvc2hvdXR1YW5kdWkFaGVscDELaW5mby1jaXJjbGUKZGVwYXJ0bWVudARjb2RlBHBhdGgPZmxvd2xpbmUtbWFudWFsDWZsb3dsaW5lLW1vcmUSZmxvd2xpbmUtc2NoZWR1bGVkEWZsb3dsaW5lLWNhbmNlbGVkEGZsb3dsaW5lLXBlbmRpbmcMZmxvd2xpbmUtcnVuEGZsb3dsaW5lLWNyZWF0ZWQQZmxvd2xpbmUtcnVubmluZxBmbG93bGluZS13YWl0aW5nEGZsb3dsaW5lLXNraXBwZWQNZmxvd2xpbmUtdmlldxBmbG93bGluZS13YXJuaW5nC29yaWVudGF0aW9uBGxhc3QFZmlyc3QOeXVuaGFuZ3NoaWljb24aQ29sdW1uLWZpbHRlcmFuZGRlc2NlbmRpbmcZQ29sdW1uLWZpbHRlcmFuZGFzY2VuZGluZxxDb2x1bW5zLURlZmF1bHRmaWx0ZXJhbmRzb3J0DUNvbHVtbi1maWx0ZXISQ29sdW1ucy1kZXNjZW5kaW5nEUNvbHVtbnMtYXNjZW5kaW5nE0NvbHVtbnMtRGVmYXVsdHNvcnQPbGF1bmNocGFkLWZhY2UyCmxhdW5jaHBhZDIPZi1pY29uLWNoZWNrYm94DGYtaWNvbi1taW51cwpmLWljb24tYWRkCGRyb3Bkb3duCm5hdmlnYXRpb24Ray1pLW1lc3NhZ2VfZXJyb3ITay1pLW1lc3NhZ2Vfc3VjY2VzcwpzdWRva3UtbmV3CGxpc3QtbmV3CXRpbGVkLW5ldwxxaWVodWFuenV6aGkHcmFkaW8tMgZ0ZW5hbnQGc3Vkb2t1BXRpbGVkBWxpc3QxC3Nob3VjYW5namlhCmNvbGxlY3Rpb24DaWRlDG9jY2x1ZGUtZmFjZQdvY2NsdWRlDmxhdW5jaHBhZC1mYWNlCWxhdW5jaHBhZAtpbmZvcm1hdGlvbgdiYWNrbG9nB21lc3NhZ2UJbWF4aW1pemUxBnNlYXJjaAppbmRleC1mYWNlBWluZGV4CHl4c190ZXh0DXl4c19jb250YWluZXILeXhzX2NvbHVtbnMIeXhzX21vdmUIeXhzX2NvcHkKeXhzX2RlbGV0ZQl5eHNfbGV2ZWwJeXhzX2VhcnRoDXl4c19jdXN0b21pemUIc2lnbl9vdXQLdXNlcl9jZW50ZXIGcmVtb3ZlBnBhY2t1cAZjYW1lcmEGbmFycm93DWFtcGxpZmljYXRpb24JY2xvY2t3aXNlEGNvdW50ZXJjbG9ja3dpc2UGZWRpdG9yBHNraW4EYXJlYQhwYXNzd29yZAhsYW5ndWFnZQViYXNpYwhtaW5pbWl6ZQxtYXhpbWl6YXRpb24NbmV3LWRpbWVuc2lvbhFmaWxlLWZvbGRlci1jbG9zZRBmaWxlLWZvbGRlci1vcGVuCG5ldy1lZGl0CG5ldy1mb3JtBXdvbWFuA21hbgZyZWNvcmQEbW9yZQRsaXN0CXRlbGVwaG9uZQhmdW5jdGlvbgtwcm9kdWN0bGlzdA5hdHRhY2htZW50bGlzdBNkb2N1bWVudGluZm9ybWF0aW9uDG5ldy1maWx0cmF0ZQ5uZXctZnVsbHNjcmVlbgdyb29maW5nDUJvdHRvbXNldHRpbmcPcGFnZS10aXRsZS10YXNrEXBhZ2UtdGl0bGUtcmV2aWV3EHBhZ2UtdGl0bGUtc3RhcnQPcGFnZS10aXRsZS10eXBlEXBhZ2UtdGl0bGUtcmVjb3JkEnBhZ2UtdGl0bGUtdm91Y2hlchBwYWdlLXRpdGxlLXF1ZXJ5EXBhZ2UtdGl0bGUtbnVtYmVyEXBhZ2UtdGl0bGUtbWFuYWdlFnBhZ2UtdGl0bGUtbWFpbnRlbmFuY2UVcGFnZS10aXRsZS1kaWN0aW9uYXJ5GHBhZ2UtdGl0bGUtY29uZmlndXJhdGlvbhVwYWdlLXRpdGxlLWFkbWluaXN0ZXIRcGFnZS10aXRsZS1kZWZpbmUXdHJpLXN0YXRlLWluZGV0ZXJtaW5hdGUQcGFuZWwtcmV0cmFjdGlvbgtlZGl0LWJ1dHRvbg5pbnB1dC1sYW5ndWFnZRdhdHRyaWJ1dGUtY29uZmlndXJhdGlvbgtFbmdpbmVlcmluZwNnaXQTcmFkaW9idXR0b24tY2hlY2tlZAxzaGFwZS1jaXJjbGUQY2hlY2tib3gtY2hlY2tlZBVrLWktaG9tZS13ZWF0aGVyLWxlYWYNay1pLWhvbWUtbW9yZQ1rLWktaG9tZS1yaW5nDGstaS1ob21lLWFkZA5rLWktaG9tZS1zZXR1cA5rLWktaG9tZS13b21hbgxrLWktaG9tZS1tYW4Oay1pLXRvcF9hZ2VuY3kMay1pLXRvcF9uZXdzDGstaS10b3BfaG9tZRJrLWktdG9wX2ltX2RlZmF1bHQXay1pLXRvcF9kZXZlbG9wbWVudHRvb2wMay1pLXRvcF9tZW51DmstaS10b3Bfc2VhcmNoCmstaS10b3BfbXkPay1pLWZsYWdfdXJnZW50DGstaS1uZXh0cGFnZRBrLWktcHJldmlvdXNwYWdlE2staS1tZXNzYWdlX3JvdXRpbmUTay1pLUV4aGFsZS1EaXNjb3VudBNrLWktbW9yZS1ob3Jpem9udGFsEGstaS1tZXNzYWdlX2hlbHATay1pLW1lc3NhZ2Vfd2FybmluZxZrLWktc3RlcHMtZGVsaXZlcmdvb2RzFWstaS1zdGVwcy1yZWNlaXZhYmxlcxFrLWktc3RlcHMtaW52b2ljZRRrLWktc3RlcHMtb3V0b2ZzdG9jaxRrLWktc3RlcHMtc2V0dGxlbWVudBNrLWktc3RlcHMtdHJhbnNwb3J0DGstaS1ib29rbWFyaxBrLWktc3Rhci1vdXRsaW5lCGstaS16b29tEGstaS1jbG9zZS1jaXJjbGUQay1pLWNoZWNrLWNpcmNsZQlrLWktY2xvc2UQay1pLXBsdXMtb3V0bGluZRFrLWktbWludXMtb3V0bGluZQtrLWktcmVvcmRlcg1rLWktcmV3aW5kLXNtDmstaS1mb3J3YXJkLXNtE2staS1hcnJvdy1zZWVrLWRvd24Ray1pLWFycm93LXNlZWstdXAKay1pLWRlbGV0ZQlrLWktZ3JvdXAIay1pLWdyaWQPay1pLWdyaWQtbGF5b3V0DmstaS1hcnJvd3Mta3BpFmstaS1hcnJvdy1jaGV2cm9uLWxlZnQXay1pLWFycm93LWNoZXZyb24tcmlnaHQWay1pLWFycm93LWNoZXZyb24tZG93bhRrLWktYXJyb3ctY2hldnJvbi11cBFrLWktYXJyb3ctNjAtbGVmdAtrLWktYXJyb3ctZRFrLWktYXJyb3ctNjAtZG93bg9rLWktYXJyb3ctNjAtdXAAAAA=) format("truetype")}.f-icon{height:1em;font-size:1rem;line-height:1;text-decoration:none;display:inline-block}.f-icon:focus,.f-icon:hover{text-decoration:none}.f-icon-sm{font-size:.75rem}.f-icon-lg{font-size:1.5rem}.f-icon-none::before{content:"";display:none}.f-icon-arrow-45-up-right::before,.f-icon-collapse-ne::before,.f-icon-resize-ne::before{content:"\e000"}.f-icon-arrow-45-down-right::before,.f-icon-collapse-se::before,.f-icon-resize-se::before{content:"\e001"}.f-icon-arrow-45-down-left::before,.f-icon-collapse-sw::before,.f-icon-resize-sw::before{content:"\e002"}.f-icon-arrow-45-up-left::before,.f-icon-collapse-nw::before,.f-icon-resize-new::before,.f-icon-resize-nw::before{content:"\e003"}.f-icon-arrow-60-up::before,.f-icon-arrow-n::before,.f-icon-expand-n::before,.f-icon-kpi-trend-increase::before,.f-icon-sarrow-n::before{content:"\e004"}.f-icon-arrow-60-right::before,.f-icon-arrow-e::before,.f-icon-expand-e::before,.f-icon-expand::before,.f-icon-sarrow-e::before{content:"\e005"}.f-icon-arrow-60-down::before,.f-icon-arrow-s::before,.f-icon-collapse::before,.f-icon-expand-s::before,.f-icon-kpi-trend-decrease::before,.f-icon-sarrow-s::before{content:"\e006"}.f-icon-arrow-60-left::before,.f-icon-arrow-w::before,.f-icon-expand-w::before,.f-icon-sarrow-w::before{content:"\e007"}.f-icon-arrow-end-up::before{content:"\e008"}.f-icon-arrow-end-right::before,.f-icon-seek-e::before{content:"\e009"}.f-icon-arrow-end-down::before{content:"\e00a"}.f-icon-arrow-end-left::before,.f-icon-seek-w::before{content:"\e00b"}.f-icon-arrow-double-60-up::before,.f-icon-arrow-seek-up::before,.f-icon-seek-n::before{content:"\e00c"}.f-icon-arrow-double-60-right::before,.f-icon-arrow-seek-right::before,.f-icon-forward-sm::before{content:"\e00d"}.f-icon-arrow-double-60-down::before,.f-icon-arrow-seek-down::before,.f-icon-seek-s::before{content:"\e00e"}.f-icon-arrow-double-60-left::before{content:"\e00f"}.f-icon-arrow-chevron-up::before,.f-icon-arrowhead-n::before{content:"\e013"}.f-icon-arrow-chevron-right::before,.f-icon-arrowhead-e::before{content:"\e014"}.f-icon-arrow-chevron-down::before,.f-icon-arrowhead-s::before{content:"\e015"}.f-icon-arrow-chevron-left::before,.f-icon-arrowhead-w::before{content:"\e016"}.f-icon-grid::before{content:"\e023"}.f-icon-grid-layout::before{content:"\e024"}.f-icon-group::before{content:"\e025"}.f-icon-ungroup::before{content:"\e026"}.f-icon-undo-large::before,.f-icon-undo::before{content:"\e100"}.f-icon-redo-large::before,.f-icon-redo::before{content:"\e101"}.f-icon-reset::before{content:"\e102"}.f-icon-refresh::before,.f-icon-reload::before{content:"\e103"}.f-icon-clock::before{content:"\ecb5"}.f-icon-calendar::before{content:"\e108"}.f-icon-save::before{content:"\e109"}.f-icon-edit::before,.f-icon-pencil::before{content:"\e10b"}.f-icon-delete::before,.f-icon-trash::before{content:"\e10c"}.f-icon-attachment::before,.f-icon-clip::before{content:"\e10d"}.f-icon-attachment-45::before,.f-icon-clip-45::before{content:"\e10e"}.f-icon-lock::before{content:"\e113"}.f-icon-unlock::before{content:"\e114"}.f-icon-cancel::before{content:"\e115"}.f-icon-cancel-outline::before,.f-icon-deny::before{content:"\e116"}.f-icon-cancel-circle::before{content:"\e117"}.f-icon-check::before,.f-icon-checkmark::before,.f-icon-tick::before{content:"\e118"}.f-icon-check-outline::before,.f-icon-checkmark-outline::before{content:"\e119"}.f-icon-success::before{content:"\eb7d"}.f-icon-check-circle::before,.f-icon-checkmark-circle::before{content:"\e11a"}.f-icon-x::before{content:"\e11b"}.f-icon-close-outline::before,.f-icon-x-outline::before{content:"\e11c"}.f-icon-error::before{content:"\eb7e"}.f-icon-close-circle::before,.f-icon-x-circle::before,.input-group .input-group-append>.input-group-clear .modal_close::before,.input-group .input-group-prepend>.input-group-clear .modal_close::before{content:"\e11d"}.f-icon-add::before,.f-icon-plus::before{content:"\e11e"}.f-icon-plus-outline::before{content:"\e11f"}.f-icon-plus-circle::before{content:"\e120"}.f-icon-kpi-trend-equal::before,.f-icon-minus::before,.k-minus::before{content:"\e121"}.f-icon-minus-outline::before{content:"\e122"}.f-icon-minus-circle::before{content:"\e123"}.f-icon-filter::before{content:"\e129"}.f-icon-filter-clear::before{content:"\e12a"}.f-icon-filter-sort-asc-sm::before{content:"\e12c"}.f-icon-filter-sort-desc-sm::before{content:"\e12d"}.f-icon-download::before{content:"\e132"}.f-icon-upload::before{content:"\e133"}.f-icon-minimize::before,.f-icon-window-minimize::before{content:"\e139"}.f-icon-cog::before,.f-icon-gear::before{content:"\e13a"}.f-icon-cogs::before,.f-icon-gears::before{content:"\e13b"}.f-icon-eye::before,.f-icon-preview::before{content:"\e13d"}.f-icon-search::before,.f-icon-zoom::before{content:"\e13e"}.f-icon-fav-outline::before,.f-icon-favorite-outline::before{content:"\e300"}.f-icon-fav::before,.f-icon-favorite::before,.f-icon-heart::before{content:"\e301"}.f-icon-bookmark-outline::before,.f-icon-star-outline::before{content:"\e302"}.f-icon-bookmark::before,.f-icon-star::before{content:"\e303"}.f-icon-checkbox::before,.f-icon-shape-rect::before{content:"\e304"}.f-icon-checkbox-checked::before{content:"\e305"}.f-icon-radiobutton::before,.f-icon-shape-circle::before{content:"\e309"}.f-icon-radiobutton-checked::before{content:"\e30a"}.f-icon-folder::before{content:"\e900"}.f-icon-folder-open::before{content:"\e901"}.f-icon-file::before{content:"\e906"}.f-icon-message_help::before{content:"\eb04"}.f-icon-message_routine::before{content:"\eb05"}.f-icon-message_warning::before{content:"\eb06"}.f-icon-previouspage::before{content:"\eb0e"}.f-icon-nextpage::before{content:"\eb0f"}.f-icon-top_menu::before{content:"\eb12"}.f-icon-edit-button::before{content:"\eb25"}.f-icon-file-folder-close::before{content:"\eb47"}.f-icon-file-folder-open::before{content:"\eb48"}.f-icon-maximization::before{content:"\eb4a"}.f-icon-minimize::before{content:"\eb4b"}.f-icon-editor::before{content:"\eb52"}.f-icon-occlude::before{content:"\eb6e"}.f-icon-occlude-face::before{content:"\eb6f"}.f-icon-camera::before{content:"\eb57"}.f-icon-date::before{content:"\eb7f"}.f-icon-dropdown::before{content:"\eb82"}.f-icon-timepicker::before{content:"\e107"}.f-icon-info::before,.f-icon-note::before{content:"\eb05"}.f-icon-question::before{content:"\eb04"}.f-icon-help::before{content:"\e402"}.f-icon-warning::before{content:"\eb06"}.f-icon-drag-vertical::before{content:"\eca0"}.f-icon-page-title-define::before{content:"\eb2a"}.f-icon-page-title-administer::before{content:"\eb2b"}.f-icon-page-title-configuration::before{content:"\eb2c"}.f-icon-page-title-dictionary::before{content:"\eb2d"}.f-icon-page-title-maintenance::before{content:"\eb2e"}.f-icon-page-title-query::before{content:"\eb2f"}.f-icon-page-title-number::before{content:"\eb30"}.f-icon-page-title-manage::before{content:"\eb31"}.f-icon-page-title-review::before{content:"\eb32"}.f-icon-page-title-start::before{content:"\eb33"}.f-icon-page-title-type::before{content:"\eb34"}.f-icon-page-title-record::before{content:"\eb35"}.f-icon-page-title-voucher::before{content:"\eb36"}.f-icon-page-title-task::before{content:"\eb37"}.f-icon-remove_face::before{content:"\ebd4"}.f-icon-enclosure_delete::before{content:"\ebe8"}.f-icon-enclosure_download::before{content:"\ebe7"}.f-icon-enclosure_upload::before{content:"\ebe6"}.f-icon-enclosure_browse::before{content:"\ebe5"}.f-icon-upload_big::before{content:"\ebe4"}.f-icon-arrow-seek-left::before,.f-icon-rewind-sm::before,.f-list-nav.f-list-nav-left .f-list-nav-toggle-sidebar .triangle::before{content:"\e00f"}.f-icon-spin{animation:spinicon 2s infinite linear}@keyframes spinicon{0%{transform:rotate(0)}100%{transform:rotate(359deg)}}.f-icon-with-modifier{position:relative;margin:.25em}.f-icon-modifier{position:absolute;font-size:.5em;bottom:0;right:0;margin:0 -.5em -.5em 0}.f-icon-xs{font-size:.5rem}.f-icon-md,.f-legend-icon::after,.modal_close{font-size:1.25rem}.f-icon-xl{font-size:2rem}.f-icon-arrows-kpi::before,.f-icon-kpi::before{content:"\e010"}.f-icon-arrows-no-change::before{content:"\e011"}.f-icon-arrow-overflow-down::before{content:"\e012"}.f-icon-arrow-up::before{content:"\e017"}.f-icon-arrow-right::before{content:"\e018"}.f-icon-arrow-down::before{content:"\e019"}.f-icon-arrow-left::before{content:"\e01a"}.f-icon-arrow-drill::before{content:"\e01b"}.f-icon-arrow-parent::before{content:"\e01c"}.f-icon-arrow-root::before{content:"\e01d"}.f-icon-arrows-resizing::before{content:"\e01e"}.f-icon-arrows-dimensions::before,.f-icon-dimension::before{content:"\e01f"}.f-icon-arrows-swap::before{content:"\e020"}.f-icon-drag-and-drop::before{content:"\e021"}.f-icon-categorize::before{content:"\e022"}.f-icon-handler-drag::before{content:"\e027"}.f-icon-layout::before{content:"\e028"}.f-icon-layout-1-by-4::before{content:"\e029"}.f-icon-layout-2-by-2::before,.f-icon-page-layout::before{content:"\e02a"}.f-icon-layout-side-by-side::before{content:"\e02b"}.f-icon-layout-stacked::before{content:"\e02c"}.f-icon-columns::before{content:"\e02d"}.f-icon-rows::before{content:"\e02e"}.f-icon-reorder::before{content:"\e02f"}.f-icon-hamburger::before,.f-icon-menu::before{content:"\e030"}.f-icon-more-vertical::before,.f-icon-vbars::before{content:"\e031"}.f-icon-hbars::before,.f-icon-more-horizontal::before{content:"\e032"}.f-icon-recurrence::before{content:"\e103"}.f-icon-non-recurrence::before,.f-icon-refresh-clear::before{content:"\e104"}.f-icon-reset-sm::before{content:"\e105"}.f-icon-recurrence-sm::before,.f-icon-refresh-sm::before,.f-icon-reload-sm::before{content:"\e106"}.f-icon-floppy::before{content:"\e109"}.f-icon-print::before,.f-icon-printer::before{content:"\e10a"}.f-icon-hyperlink::before,.f-icon-link-horizontal::before{content:"\e10f"}.f-icon-hyperlink-remove::before,.f-icon-unlink-horizontal::before{content:"\e110"}.f-icon-link-vertical::before{content:"\e111"}.f-icon-unlink-vertical::before{content:"\e112"}.f-icon-sort-asc::before{content:"\e124"}.f-icon-sort-desc::before{content:"\e125"}.f-icon-sort-clear::before,.f-icon-unsort::before{content:"\e126"}.f-icon-sort-asc-sm::before{content:"\e127"}.f-icon-sort-desc-sm::before{content:"\e128"}.f-icon-filter-sm::before{content:"\e12b"}.f-icon-filter-add-expression::before{content:"\e12e"}.f-icon-filter-add-group::before{content:"\e12f"}.f-icon-login::before{content:"\e130"}.f-icon-logout::before{content:"\e131"}.f-icon-hyperlink-open::before{content:"\e134"}.f-icon-hyperlink-open-sm::before{content:"\e135"}.f-icon-launch::before{content:"\e136"}.f-icon-maximize::before,.f-icon-window-maximize::before,.f-icon-window::before{content:"\e137"}.f-icon-restore::before,.f-icon-tiles::before,.f-icon-window-restore::before,.f-icon-windows::before{content:"\e138"}.f-icon-custom::before{content:"\e13a"}.f-icon-settings::before,.f-icon-wrench::before{content:"\e13c"}.f-icon-zoom-in::before{content:"\e13f"}.f-icon-zoom-out::before{content:"\e140"}.f-icon-move::before,.f-icon-pan::before{content:"\e141"}.f-icon-calculator::before{content:"\e142"}.f-icon-cart::before,.f-icon-shopping-cart::before{content:"\e143"}.f-icon-connector::before{content:"\e144"}.f-icon-plus-sm::before,.f-icon-splus::before{content:"\e145"}.f-icon-minus-sm::before,.f-icon-sminus::before{content:"\e146"}.f-icon-kpi-status-deny::before{content:"\e147"}.f-icon-kpi-status-hold::before{content:"\e148"}.f-icon-kpi-status-open::before{content:"\e149"}.f-icon-play::before{content:"\e200"}.f-icon-pause::before{content:"\e201"}.f-icon-stop::before{content:"\e202"}.f-icon-rewind::before{content:"\e203"}.f-icon-forward::before{content:"\e204"}.f-icon-volume-down::before,.f-icon-volume-low::before{content:"\e205"}.f-icon-volume-high::before,.f-icon-volume-up::before{content:"\e206"}.f-icon-volume-mute::before,.f-icon-volume-off::before{content:"\e207"}.f-icon-hd::before{content:"\e208"}.f-icon-subtitles::before{content:"\e209"}.f-icon-playlist::before{content:"\e20a"}.f-icon-audio::before{content:"\e20b"}.f-icon-play-sm::before{content:"\e20c"}.f-icon-pause-sm::before{content:"\e20d"}.f-icon-stop-sm::before{content:"\e20e"}.f-icon-heart-outline::before{content:"\e300"}.f-icon-tri-state-indeterminate::before{content:"\e306"}.f-icon-tri-state-null::before{content:"\e307"}.f-icon-circle::before{content:"\e308"}.f-icon-bell::before,.f-icon-notification::before{content:"\e400"}.f-icon-exception::before{content:"\e403"}.f-icon-photo-camera::before{content:"\e500"}.f-icon-image::before,.f-icon-photo::before{content:"\e501"}.f-icon-image-export::before,.f-icon-photo-export::before{content:"\e502"}.f-icon-zoom-actual-size::before{content:"\e503"}.f-icon-zoom-best-fit::before{content:"\e504"}.f-icon-image-resize::before{content:"\e505"}.f-icon-crop::before{content:"\e506"}.f-icon-mirror::before{content:"\e507"}.f-icon-flip-horizontal::before{content:"\e508"}.f-icon-flip-vertical::before{content:"\e509"}.f-icon-rotate::before{content:"\e50a"}.f-icon-rotate-cw::before,.f-icon-rotate-right::before{content:"\e50b"}.f-icon-rotate-ccw::before,.f-icon-rotate-left::before{content:"\e50c"}.f-icon-brush::before{content:"\e50d"}.f-icon-palette::before{content:"\e50e"}.f-icon-background::before,.f-icon-droplet::before,.f-icon-paint::before{content:"\e50f"}.f-icon-line::before,.f-icon-shape-line::before{content:"\e510"}.f-icon-brightness-contrast::before{content:"\e511"}.f-icon-saturation::before{content:"\e512"}.f-icon-invert-colors::before{content:"\e513"}.f-icon-opacity::before,.f-icon-transperancy::before{content:"\e514"}.f-icon-greyscale::before{content:"\e515"}.f-icon-blur::before{content:"\e516"}.f-icon-sharpen::before{content:"\e517"}.f-icon-shape::before{content:"\e518"}.f-icon-round-corners::before{content:"\e519"}.f-icon-front-element::before{content:"\e51a"}.f-icon-back-element::before{content:"\e51b"}.f-icon-forward-element::before{content:"\e51c"}.f-icon-backward-element::before{content:"\e51d"}.f-icon-align-left-element::before{content:"\e51e"}.f-icon-align-center-element::before{content:"\e51f"}.f-icon-align-right-element::before{content:"\e520"}.f-icon-align-top-element::before{content:"\e521"}.f-icon-align-middle-element::before{content:"\e522"}.f-icon-align-bottom-element::before{content:"\e523"}.f-icon-thumbnails-up::before{content:"\e524"}.f-icon-thumbnails-right::before{content:"\e525"}.f-icon-thumbnails-down::before{content:"\e526"}.f-icon-thumbnails-left::before{content:"\e527"}.f-icon-full-screen::before,.f-icon-fullscreen-enter::before,.f-icon-fullscreen::before{content:"\e528"}.f-icon-full-screen-exit::before,.f-icon-fullscreen-exit::before{content:"\e529"}.f-icon-background-remove::before,.f-icon-paint-remove::before,.f-icon-reset-color::before{content:"\e52a"}.f-icon-page-properties::before{content:"\e600"}.f-icon-bold::before{content:"\e601"}.f-icon-italic::before{content:"\e602"}.f-icon-underline::before{content:"\e603"}.f-icon-font-family::before{content:"\e604"}.f-icon-foreground-color::before,.f-icon-text::before{content:"\e605"}.f-icon-convert-lowercase::before{content:"\e606"}.f-icon-convert-uppercase::before{content:"\e607"}.f-icon-strike-through::before,.f-icon-strikethrough::before{content:"\e608"}.f-icon-sub-script::before,.f-icon-subscript::before{content:"\e609"}.f-icon-sup-script::before,.f-icon-superscript::before{content:"\e60a"}.f-icon-div::before{content:"\e60b"}.f-icon-all::before{content:"\e60c"}.f-icon-h1::before{content:"\e60d"}.f-icon-h2::before{content:"\e60e"}.f-icon-h3::before{content:"\e60f"}.f-icon-h4::before{content:"\e610"}.f-icon-h5::before{content:"\e611"}.f-icon-h6::before{content:"\e612"}.f-icon-insert-ordered-list::before,.f-icon-list-numbered::before,.f-icon-list-ordered::before{content:"\e613"}.f-icon-insert-unordered-list::before,.f-icon-list-bulleted::before,.f-icon-list-unordered::before{content:"\e614"}.f-icon-indent-increase::before,.f-icon-indent::before{content:"\e615"}.f-icon-indent-decrease::before,.f-icon-outdent::before{content:"\e616"}.f-icon-insert-n::before,.f-icon-insert-top::before,.f-icon-insert-up::before{content:"\e617"}.f-icon-insert-m::before,.f-icon-insert-middle::before{content:"\e618"}.f-icon-insert-bottom::before,.f-icon-insert-down::before,.f-icon-insert-s::before{content:"\e619"}.f-icon-align-top::before{content:"\e61a"}.f-icon-align-middle::before{content:"\e61b"}.f-icon-align-bottom::before{content:"\e61c"}.f-icon-align-left::before,.f-icon-justify-left::before{content:"\e61d"}.f-icon-align-center::before,.f-icon-justify-center::before{content:"\e61e"}.f-icon-align-right::before,.f-icon-justify-right::before{content:"\e61f"}.f-icon-align-justify::before,.f-icon-justify-full::before{content:"\e620"}.f-icon-align-remove::before,.f-icon-justify-clear::before{content:"\e621"}.f-icon-text-wrap::before{content:"\e622"}.f-icon-rule-horizontal::before{content:"\e623"}.f-icon-table-align-top-left::before{content:"\e624"}.f-icon-table-align-top-center::before{content:"\e625"}.f-icon-table-align-top-right::before{content:"\e626"}.f-icon-table-align-middle-left::before{content:"\e627"}.f-icon-table-align-middle-center::before{content:"\e628"}.f-icon-table-align-middle-right::before{content:"\e629"}.f-icon-table-align-bottom-left::before{content:"\e62a"}.f-icon-table-align-bottom-center::before{content:"\e62b"}.f-icon-table-align-bottom-right::before{content:"\e6d7"}.f-icon-table-align-remove::before{content:"\e62d"}.f-icon-all-borders::before,.f-icon-borders-all::before{content:"\e62e"}.f-icon-borders-outside::before,.f-icon-outside-borders::before{content:"\e62f"}.f-icon-borders-inside::before,.f-icon-inside-borders::before{content:"\e630"}.f-icon-borders-inside-horizontal::before,.f-icon-inside-horizontal-borders::before{content:"\e631"}.f-icon-borders-inside-vertical::before,.f-icon-inside-vertical-borders::before{content:"\e632"}.f-icon-border-top::before,.f-icon-top-border::before{content:"\e633"}.f-icon-border-bottom::before,.f-icon-bottom-border::before{content:"\e634"}.f-icon-border-left::before,.f-icon-left-border::before{content:"\e635"}.f-icon-border-right::before,.f-icon-right-border::before{content:"\e636"}.f-icon-border-no::before,.f-icon-no-borders::before{content:"\e637"}.f-icon-borders-show-hide::before{content:"\e638"}.f-icon-border::before,.f-icon-form::before{content:"\e639"}.f-icon-form-element::before{content:"\e63a"}.f-icon-code-snippet::before{content:"\e63b"}.f-icon-select-all::before{content:"\e63c"}.f-icon-button::before{content:"\e63d"}.f-icon-select-box::before{content:"\e63e"}.f-icon-calendar-date::before{content:"\e63f"}.f-icon-group-box::before{content:"\e640"}.f-icon-textarea::before{content:"\e641"}.f-icon-textbox::before{content:"\e642"}.f-icon-textbox-hidden::before{content:"\e643"}.f-icon-paragraph-add::before{content:"\e645"}.f-icon-edit-tools::before{content:"\e646"}.f-icon-template-manager::before{content:"\e647"}.f-icon-change-manually::before{content:"\e648"}.f-icon-track-changes::before{content:"\e649"}.f-icon-track-changes-enable::before{content:"\e64a"}.f-icon-track-changes-accept::before{content:"\e64b"}.f-icon-track-changes-accept-all::before{content:"\e64c"}.f-icon-track-changes-reject::before{content:"\e64d"}.f-icon-track-changes-reject-all::before{content:"\e64e"}.f-icon-document-manager::before{content:"\e64f"}.f-icon-custom-icon::before{content:"\e650"}.f-icon-dictionary-add::before{content:"\e651"}.f-icon-image-insert::before,.f-icon-image-light-dialog::before,.f-icon-insert-image::before{content:"\e652"}.f-icon-image-edit::before{content:"\e653"}.f-icon-image-map-editor::before{content:"\e654"}.f-icon-comment::before{content:"\e655"}.f-icon-comment-remove::before{content:"\e656"}.f-icon-comments-remove-all::before{content:"\e657"}.f-icon-silverlight::before{content:"\e658"}.f-icon-media-manager::before{content:"\e659"}.f-icon-video-external::before{content:"\e65a"}.f-icon-flash-manager::before{content:"\e65b"}.f-icon-find-and-replace::before,.f-icon-find::before{content:"\e65c"}.f-icon-copy::before,.f-icon-files::before{content:"\e65d"}.f-icon-cut::before{content:"\e65e"}.f-icon-paste::before{content:"\e65f"}.f-icon-paste-as-html::before{content:"\e660"}.f-icon-paste-from-word::before{content:"\e661"}.f-icon-paste-from-word-strip-file::before{content:"\e662"}.f-icon-paste-html::before{content:"\e663"}.f-icon-paste-markdown::before{content:"\e664"}.f-icon-paste-plain-text::before{content:"\e665"}.f-icon-apply-format::before{content:"\e666"}.f-icon-clear-css::before,.f-icon-clearformat::before{content:"\e667"}.f-icon-copy-format::before{content:"\e668"}.f-icon-strip-all-formating::before{content:"\e669"}.f-icon-strip-css-format::before{content:"\e66a"}.f-icon-strip-font-elements::before{content:"\e66b"}.f-icon-strip-span-elements::before{content:"\e66c"}.f-icon-strip-word-formatting::before{content:"\e66d"}.f-icon-format-code-block::before{content:"\e66e"}.f-icon-style-builder::before{content:"\e66f"}.f-icon-module-manager::before{content:"\e670"}.f-icon-hyperlink-insert::before,.f-icon-hyperlink-light-dialog::before{content:"\e671"}.f-icon-hyperlink-globe::before{content:"\e672"}.f-icon-hyperlink-globe-remove::before{content:"\e673"}.f-icon-hyperlink-email::before{content:"\e674"}.f-icon-anchor::before{content:"\e675"}.f-icon-create-table::before,.f-icon-table-insert::before,.f-icon-table-light-dialog::before{content:"\e676"}.f-icon-table::before{content:"\e677"}.f-icon-table-properties::before,.f-icon-table-wizard::before{content:"\e678"}.f-icon-table-cell::before{content:"\e679"}.f-icon-table-cell-properties::before{content:"\e67a"}.f-icon-add-column-left::before,.f-icon-table-column-insert-left::before{content:"\e67b"}.f-icon-add-column-right::before,.f-icon-table-column-insert-right::before{content:"\e67c"}.f-icon-add-row-above::before,.f-icon-table-row-insert-above::before{content:"\e67d"}.f-icon-add-row-below::before,.f-icon-table-row-insert-below::before{content:"\e67e"}.f-icon-delete-column::before,.f-icon-table-column-delete::before{content:"\e67f"}.f-icon-delete-row::before,.f-icon-table-row-delete::before{content:"\e680"}.f-icon-table-cell-delete::before{content:"\e681"}.f-icon-table-delete::before{content:"\e682"}.f-icon-cells-merge::before,.f-icon-merge-cells::before{content:"\e683"}.f-icon-cells-merge-horizontally::before,.f-icon-merge-horizontally::before{content:"\e684"}.f-icon-cells-merge-vertically::before,.f-icon-merge-vertically::before{content:"\e685"}.f-icon-cell-split-horizontally::before{content:"\e686"}.f-icon-cell-split-vertically::before{content:"\e687"}.f-icon-normal-layout::before,.f-icon-table-unmerge::before{content:"\e688"}.f-icon-freeze-panes::before,.f-icon-pane-freeze::before{content:"\e689"}.f-icon-freeze-row::before,.f-icon-row-freeze::before{content:"\e68a"}.f-icon-column-freeze::before,.f-icon-freeze-col::before{content:"\e68b"}.f-icon-toolbar-float::before{content:"\e68c"}.f-icon-spell-checker::before{content:"\e68d"}.f-icon-validation-xhtml::before{content:"\e68e"}.f-icon-validation-data::before{content:"\e68f"}.f-icon-toggle-full-screen-mode::before{content:"\e690"}.f-icon-formula-fx::before,.f-icon-fx::before{content:"\e691"}.f-icon-sum::before{content:"\e692"}.f-icon-symbol::before{content:"\e693"}.f-icon-currency::before,.f-icon-dollar::before{content:"\e694"}.f-icon-percent::before{content:"\e695"}.f-icon-custom-format::before,.f-icon-format-number::before{content:"\e696"}.f-icon-decimal-increase::before,.f-icon-increase-decimal::before{content:"\e697"}.f-icon-decimal-decrease::before,.f-icon-decrease-decimal::before{content:"\e698"}.f-icon-font-size::before{content:"\e699"}.f-icon-image-absolute-position::before{content:"\e69a"}.f-icon-globe-outline::before{content:"\e700"}.f-icon-globe::before{content:"\e701"}.f-icon-marker-pin::before{content:"\e702"}.f-icon-marker-pin-target::before{content:"\e703"}.f-icon-pin::before{content:"\e704"}.f-icon-unpin::before{content:"\e705"}.f-icon-share::before{content:"\e800"}.f-icon-user::before{content:"\e801"}.f-icon-inbox::before{content:"\e802"}.f-icon-blogger::before{content:"\e803"}.f-icon-blogger-box::before{content:"\e804"}.f-icon-delicious::before{content:"\e805"}.f-icon-delicious-box::before{content:"\e806"}.f-icon-digg::before{content:"\e807"}.f-icon-digg-box::before{content:"\e808"}.f-icon-email::before,.f-icon-envelop::before,.f-icon-letter::before{content:"\e809"}.f-icon-email-box::before,.f-icon-envelop-box::before,.f-icon-letter-box::before{content:"\e80a"}.f-icon-facebook::before{content:"\e80b"}.f-icon-facebook-box::before{content:"\e80c"}.f-icon-google::before{content:"\e80d"}.f-icon-google-box::before{content:"\e80e"}.f-icon-google-plus::before{content:"\e80f"}.f-icon-google-plus-box::before{content:"\e810"}.f-icon-linkedin::before{content:"\e811"}.f-icon-linkedin-box::before{content:"\e812"}.f-icon-myspace::before{content:"\e813"}.f-icon-myspace-box::before{content:"\e814"}.f-icon-pinterest::before{content:"\e815"}.f-icon-pinterest-box::before{content:"\e816"}.f-icon-reddit::before{content:"\e817"}.f-icon-reddit-box::before{content:"\e818"}.f-icon-stumble-upon::before{content:"\e819"}.f-icon-stumble-upon-box::before{content:"\e81a"}.f-icon-tell-a-friend::before{content:"\e81b"}.f-icon-tell-a-friend-box::before{content:"\e81c"}.f-icon-tumblr::before{content:"\e81d"}.f-icon-tumblr-box::before{content:"\e81e"}.f-icon-twitter::before{content:"\e81f"}.f-icon-twitter-box::before{content:"\e820"}.f-icon-yammer::before{content:"\e821"}.f-icon-yammer-box::before{content:"\e822"}.f-icon-behance::before{content:"\e823"}.f-icon-behance-box::before{content:"\e824"}.f-icon-dribbble::before{content:"\e825"}.f-icon-dribbble-box::before{content:"\e826"}.f-icon-rss::before{content:"\e827"}.f-icon-rss-box::before{content:"\e828"}.f-icon-vimeo::before{content:"\e829"}.f-icon-vimeo-box::before{content:"\e82a"}.f-icon-youtube::before{content:"\e82b"}.f-icon-youtube-box::before{content:"\e82c"}.f-icon-folder-add::before{content:"\e902"}.f-icon-folder-up::before{content:"\e903"}.f-icon-fields-more::before,.f-icon-folder-more::before{content:"\e904"}.f-icon-aggregate-fields::before{content:"\e905"}.f-icon-file-vertical::before,.f-icon-page-portrait::before{content:"\e906"}.f-icon-file-add::before,.f-icon-insert-file::before{content:"\e907"}.f-icon-file-txt::before,.f-icon-txt::before{content:"\e908"}.f-icon-csv::before,.f-icon-file-csv::before{content:"\e909"}.f-icon-excel::before,.f-icon-file-excel::before,.f-icon-file-xls::before,.f-icon-xls::before,.f-icon-xlsa::before{content:"\e90a"}.f-icon-doc::before,.f-icon-file-doc::before,.f-icon-file-word::before,.f-icon-word::before{content:"\e90b"}.f-icon-file-mdb::before,.f-icon-mdb::before{content:"\e90c"}.f-icon-file-ppt::before,.f-icon-ppt::before{content:"\e90d"}.f-icon-file-pdf::before,.f-icon-pdf::before,.f-icon-pdfa::before{content:"\e90e"}.f-icon-file-psd::before,.f-icon-psd::before{content:"\e90f"}.f-icon-file-flash::before,.f-icon-flash::before{content:"\e910"}.f-icon-config::before,.f-icon-file-config::before{content:"\e911"}.f-icon-ascx::before,.f-icon-file-ascx::before{content:"\e912"}.f-icon-bac::before,.f-icon-file-bac::before{content:"\e913"}.f-icon-file-zip::before,.f-icon-zip::before{content:"\e914"}.f-icon-film::before{content:"\e915"}.f-icon-css3::before{content:"\e916"}.f-icon-html5::before{content:"\e917"}.f-icon-html::before,.f-icon-source-code::before,.f-icon-view-source::before{content:"\e918"}.f-icon-css::before{content:"\e919"}.f-icon-js::before{content:"\e91a"}.f-icon-exe::before{content:"\e91b"}.f-icon-csproj::before{content:"\e91c"}.f-icon-vbproj::before{content:"\e91d"}.f-icon-cs::before{content:"\e91e"}.f-icon-vb::before{content:"\e91f"}.f-icon-sln::before{content:"\e920"}.f-icon-cloud::before{content:"\e921"}.f-icon-file-horizontal::before,.f-icon-page-landscape::before{content:"\e922"}.f-icon-steps-transport::before{content:"\eb07"}.f-icon-steps-settlement::before{content:"\eb08"}.f-icon-steps-outofstock::before{content:"\eb09"}.f-icon-steps-invoice::before{content:"\eb0a"}.f-icon-steps-receivables::before{content:"\eb0b"}.f-icon-steps-delivergoods::before{content:"\eb0c"}.f-icon-exhale-discount::before{content:"\eb0d"}.f-icon-flag_urgent::before{content:"\eb10"}.f-icon-top_home::before{content:"\eb11"}.f-icon-top_agency::before{content:"\eb13"}.f-icon-top_news::before{content:"\eb14"}.f-icon-top_im_default::before{content:"\eb15"}.f-icon-top_developmenttool::before{content:"\eb16"}.f-icon-top_search::before{content:"\eb17"}.f-icon-top_my::before{content:"\eb18"}.f-icon-home-man::before{content:"\eb1a"}.f-icon-home-woman::before{content:"\eb1b"}.f-icon-home-setup::before{content:"\eb1c"}.f-icon-home-add::before{content:"\eb1d"}.f-icon-home-ring::before{content:"\eb1e"}.f-icon-home-operation::before{content:"\eb1f"}.f-icon-home-more::before{content:"\eb20"}.f-icon-home-weather-leaf::before{content:"\eb21"}.f-icon-engineering::before{content:"\eb22"}.f-icon-git::before{content:"\eb23"}.f-icon-panel-retraction::before{content:"\eb24"}.f-icon-input-language::before{content:"\eb26"}.f-icon-attribute-configuration::before{content:"\eb27"}.f-icon-bottomsetting::before{content:"\eb28"}.f-icon-roofing::before{content:"\eb29"}.f-icon-new-fullscreen::before{content:"\eb38"}.f-icon-filtrate::before{content:"\eb39"}.f-icon-document-information::before{content:"\eb3a"}.f-icon-attachment-list::before{content:"\eb3b"}.f-icon-product-list::before{content:"\eb3c"}.f-icon-new-function::before{content:"\eb3d"}.f-icon-telephone::before{content:"\eb3e"}.f-icon-list::before{content:"\eb3f"}.f-icon-more::before{content:"\eb41"}.f-icon-record::before{content:"\eb42"}.f-icon-man::before{content:"\eb43"}.f-icon-woman::before{content:"\eb44"}.f-icon-new-form::before{content:"\eb45"}.f-icon-new-edit::before{content:"\eb46"}.f-icon-new-dimension::before{content:"\eb49"}.f-icon-basic::before{content:"\eb4c"}.f-icon-language::before{content:"\eb4d"}.f-icon-password::before{content:"\eb4e"}.f-icon-area::before{content:"\eb4f"}.f-icon-skin::before{content:"\eb51"}.f-icon-counterclockwise::before{content:"\eb53"}.f-icon-clockwise::before{content:"\eb54"}.f-icon-amplification::before{content:"\eb55"}.f-icon-narrow::before{content:"\eb56"}.f-cmp-footer .f-cmp-footer-header .f-toolbar .toolbar--collapse-icon::before,.f-icon-packup::before{content:"\eb58"}.f-icon-remove::before{content:"\eb59"}.f-icon-user_center::before{content:"\eb5a"}.f-icon-sign_out::before{content:"\eb5b"}.f-icon-yxs_customize::before{content:"\eb5c"}.f-icon-yxs_earth::before{content:"\eb5d"}.f-icon-yxs_level::before{content:"\eb5e"}.f-icon-yxs_delete::before{content:"\eb5f"}.f-icon-yxs_copy::before{content:"\eb60"}.f-icon-yxs_move::before{content:"\eb61"}.f-icon-index::before{content:"\eb65"}.f-icon-index-face::before{content:"\eb66"}.f-icon-search::before{content:"\eb67"}.f-icon-message::before{content:"\eb69"}.f-icon-backlog::before{content:"\eb6a"}.f-icon-information::before{content:"\eb6b"}.f-icon-launchpad::before{content:"\eb6c"}.f-icon-launchpad-face::before{content:"\eb6d"}.f-icon-ide::before{content:"\eb71"}.f-icon-collection::before{content:"\eb72"}.f-icon-shoucangjia::before{content:"\eb73"}.f-icon-list1::before{content:"\eb74"}.f-icon-tiled::before{content:"\eb75"}.f-icon-sudoku::before{content:"\eb76"}.f-icon-tenant::before{content:"\eb77"}.f-icon-radio-2::before{content:"\eb78"}.f-icon-qiehuanzuzhi::before{content:"\eb79"}.f-icon-tiled-new::before{content:"\eb7a"}.f-icon-list-new::before{content:"\eb7b"}.f-icon-sudoku-new::before{content:"\eb7c"}.f-icon-danger::before{content:"\eb7e"}.f-icon-default::before{content:"\eb14"}.f-icon-navigation::before{content:"\eb81"}.f-icon-launchpad-face2::before{content:"\eb84"}.f-icon-launchpad2::before{content:"\eb83"}.f-icon-col-filteranddescending::before{content:"\eb9b"}.f-icon-col-filterandascending::before{content:"\eb9a"}.f-icon-col-defaultfilterandsort::before{content:"\eb89"}.f-icon-col-filter::before{content:"\eb88"}.f-icon-col-descending::before{content:"\eb87"}.f-icon-col-ascending::before{content:"\eb86"}.f-icon-col-defaultsort::before{content:"\eb85"}.f-icon-runtime::before{content:"\eb9c"}.f-icon-page-last::before{content:"\eb9e"}.f-icon-page-first::before{content:"\eb9d"}.f-icon-orientation-arrow::before{content:"\eb9f"}.f-icon-flowline-scheduled:before{content:"\eba9"}.f-icon-flowline-canceled::before{content:"\eba8"}.f-icon-flowline-pending::before{content:"\eba7"}.f-icon-flowline-run::before{content:"\eba6"}.f-icon-flowline-created::before{content:"\eba5"}.f-icon-flowline-running::before{content:"\eba4"}.f-icon-flowline-waiting::before{content:"\eba3"}.f-icon-flowline-skipped::before{content:"\eba2"}.f-icon-flowline-view::before{content:"\eba1"}.f-icon-flowline-warning::before{content:"\eba0"}.f-icon-flowline-more::before{content:"\ebb0"}.f-icon-flowline-manual::before{content:"\ebb1"}.f-icon-path::before{content:"\ebb2"}.f-icon-code::before{content:"\ebb3"}.f-icon-department::before{content:"\ebb4"}.f-icon-info-circle::before{content:"\ebb5"}.f-icon-help-01::before{content:"\ebb6"}.f-icon-statement::before{content:"\ebd3"}.f-icon-address-location::before{content:"\ebd2"}.f-icon-task-record::before{content:"\ebd1"}.f-icon-visit:before{content:"\ebd0"}.f-icon-relationship::before{content:"\ebc9"}.f-icon-truck-delivery::before{content:"\ebc8"}.f-icon-concat-list::before{content:"\ebc7"}.f-icon-payment-notice::before{content:"\ebc6"}.f-icon-application-for-invoicing::before{content:"\ebc5"}.f-icon-accomplishment:before{content:"\ebc4"}.f-icon-potential:before{content:"\ebc3"}.f-icon-aim::before{content:"\ebc2"}.f-icon-declaration-form::before{content:"\ebc1"}.f-icon-licensed::before{content:"\ebc0"}.f-icon-profile-picture::before{content:"\ebb9"}.f-icon-forecast-of-completion::before{content:"\ebb8"}.f-icon-team::before{content:"\ebb7"}.f-icon-table_view::before{content:"\ebf7"}.f-icon-card_view::before{content:"\ebd5"}.f-icon-list_view::before{content:"\ebd6"}.f-icon-form_view::before{content:"\ebd7"}.f-icon-chart_view::before{content:"\ebd8"}.f-icon-perspective_view::before{content:"\ebd9"}.f-icon-drop-down_line::before{content:"\ebe1"}.f-icon-more_line::before{content:"\ebe2"}.f-icon-calendars_line1::before{content:"\ebe3"}.f-icon-message_round::before{content:"\ebe9"}.f-icon-col-descendingorder::before{content:"\ebf2"}.f-icon-col-ascendingorder::before{content:"\ebf1"}.f-icon-feedback::before{content:"\ebf3"}.f-icon-signature::before{content:"\ebf4"}.f-icon-indep-password::before{content:"\ebf5"}.f-icon-honor::before{content:"\ebf6"}.f-icon-view-cardview::before{content:"\ebf8"}.f-icon-edit-cardview::before{content:"\ebf9"}.f-icon-description-tips::before{content:"\eca1"}.f-icon-equalsign::before{content:"\eca2"}.f-icon-column-rectangle::before{content:"\eca3"}.f-icon-position::before{content:"\ecb4"}.f-icon-hotel::before{content:"\ecb3"}.f-icon-arrowwide::before{content:"\ecb2"}.f-icon-foldin::before{content:"\ecb1"}.f-icon-filter-cancel::before{content:"\eca4"}.f-icon-filter-add::before{content:"\eca5"}.f-icon-filter-grouping::before{content:"\eca6"}.f-icon-filter-delete::before{content:"\eca7"}.f-icon-moverto::before{content:"\eca8"}.f-icon-thumbtack-fill::before{content:"\eca9"}.f-icon-thumbtack::before{content:"\ecb0"}.f-icon-enclosure-edit::before{content:"\ecb6"}.f-icon-notifier::before{content:"\ecb7"}.f-iconmage{display:inline-block}.f-btn-icon{cursor:pointer;font-size:.8125rem;line-height:1.4286;padding:.1875rem;border:1px solid var(--f-neutral-08);border-radius:6px;position:relative;display:flex;align-items:center;justify-content:center;width:1.6607375rem;height:1.6607375rem}.f-btn-icon.f-bare{border-color:transparent!important;background:0 0!important;transition:color .2s ease-in-out}.f-btn-icon::before,.f-cmp-inputgroup .input-append-button,.f-cmp-text-input-append .input-append-button,.f-component-text .input-append-button,.input-append-button{background:var(--f-neutral-00)}.f-btn-icon::after,.f-btn-icon::before{border-radius:6px;content:"";position:absolute;left:-1px;right:-1px;top:-1px;bottom:-1px;z-index:0;transition:opacity .2s ease-in-out;pointer-events:none}.f-btn-icon.f-bare::before{display:block}.f-btn-icon::before{opacity:0;display:none}.f-btn-icon.f-state-hover::before,.f-btn-icon:hover::before{opacity:.08}.f-btn-icon::after{opacity:0;display:none}.btn-icontext{display:inline-flex;align-items:center}.btn-icontext .f-icon{margin:0 .4375rem 0 0}.f-icon-danger,.f-icon-error{color:var(--f-semantic-danger-01)}.f-icon-info,.f-icon-note::before{color:var(--f-semantic-info-01)}.f-icon-question,.f-icon-warning{color:var(--f-semantic-warning-01)}.f-icon-success{color:var(--f-semantic-success-01)}.f-icon-default{color:var(--f-semantic-info-01)}.f-icon-lookup::before{content:"\e032"}.f-page-pre::before{content:"\e016"}.f-page-first::before{content:"\eb9d"}.f-page-last::before{content:"\eb9e"}.f-page-next::before{content:"\e014"}.modal_minimize{font-family:FarrisIcons}.modal_minimize::before{content:"\eb4b"}.modal_maximize{font-family:FarrisIcons}.modal_maximize::before{content:"\eb68"}.f-icon-close::before,.f-icon-group-delete::before,.modal_close::before{content:"\e11b"}.f-icon-close,.f-icon-group-delete::before{font-family:FarrisIcons}.modal_close{font-family:FarrisIcons}.modalrevert::before{content:"\eb4b"}.f-legend-icon::after{content:"";width:1.125rem;height:.875rem;overflow:hidden;display:inline-block;line-height:1.125rem;margin:0 .25rem 0 0;color:var(--f-neutral-01)}.f-legend-collapse::after,.f-legend-show::after{font-size:.875rem;font-family:FarrisIcons}.f-legend-collapse::after{content:"\e013"}.f-legend-show::after{content:"\e015"}.f-sidebar-close::before{content:"\e11b"}.f-sidebar-entry::before{content:"\e014"}.farris-image-cropper-frame{display:flex;position:relative;width:100%;max-width:100%;max-height:100%;overflow:hidden;text-align:center}.farris-image-cropper-frame .farris-image-cropper{width:100%;position:relative}.farris-image-cropper-frame .farris-image-cropper .farris-source-image{max-width:100%;max-height:100%;transform-origin:center}.farris-image-cropper-frame .farris-image-overlay{position:absolute;pointer-events:none;touch-action:none;outline:#fff solid 100vw;top:0;left:0}.farris-image-cropper-frame .farris-image-cropper-wrapper{position:absolute;display:flex;color:#53535C;background:0 0;outline:rgba(0,0,0,.3) solid 100vw;outline:solid var(--cropper-outline-color,rgba(0,0,0,.3));touch-action:none}.farris-image-cropper-frame .farris-image-cropper-wrapper:after{position:absolute;content:"";top:0;bottom:0;left:0;right:0;pointer-events:none;border:1px dashed;opacity:.75;color:inherit;z-index:1}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-move{width:100%;cursor:move;border-radius:100%;border:1px solid #388fff}.farris-image-cropper-frame .farris-image-cropper-wrapper:focus .farris-image-cropper-move{border-color:#1e90ff;border-width:2px}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize{position:absolute;display:inline-block;line-height:6px;padding:8px;opacity:.85;z-index:1}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize .farris-image-cropper-square{display:inline-block;background:#388fff;width:6px;height:6px;border:1px solid #59a1ff;box-sizing:content-box}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.topleft{top:-12px;left:-12px;cursor:nwse-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.top{top:-12px;left:calc(50% - 12px);cursor:ns-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.topright{top:-12px;right:-12px;cursor:nesw-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.right{top:calc(50% - 12px);right:-12px;cursor:ew-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.bottomright{bottom:-12px;right:-12px;cursor:nwse-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.bottom{bottom:-12px;left:calc(50% - 12px);cursor:ns-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.bottomleft{bottom:-12px;left:-12px;cursor:nesw-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.left{top:calc(50% - 12px);left:-12px;cursor:ew-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize-bar{position:absolute;z-index:1}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize-bar.top{top:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize-bar.right{top:11px;right:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize-bar.bottom{bottom:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize-bar.left{top:11px;left:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper.farris-image-cropper-rounded{outline-color:transparent;width:161px;height:161px}.farris-image-cropper-frame .farris-image-cropper-wrapper.farris-image-cropper-rounded:after{border-radius:100%;box-shadow:0 0 0 100vw rgba(0,0,0,.3);box-shadow:0 0 0 100vw var(--cropper-outline-color,rgba(0,0,0,.3))}@media (orientation:portrait){.farris-image-cropper-frame .farris-image-cropper-wrapper{outline-width:100vh}.farris-image-cropper-frame .farris-image-cropper-wrapper.farris-image-cropper-rounded:after{box-shadow:0 0 0 100vh rgba(0,0,0,.3);box-shadow:0 0 0 100vh var(--cropper-outline-color,rgba(0,0,0,.3))}}.farris-image-cropper-frame .farris-image-cropper-wrapper.farris-image-cropper-rounded .farris-image-cropper-move{border-radius:100%}.farris-image-cropper-frame.farris-image-cropper-disabled .farris-image-cropper-wrapper .farris-image-cropper-move,.farris-image-cropper-frame.farris-image-cropper-disabled .farris-image-cropper-wrapper .farris-image-cropper-resize,.farris-image-cropper-frame.farris-image-cropper-disabled .farris-image-cropper-wrapper .farris-image-cropper-resize-bar{display:none}.farris-image-cropper-frame .farris-image-cropper-error{width:100%;text-align:center;font-size:14px}.farris-image-cropper-frame .farris-image-cropper-loading{position:absolute;top:0;left:0;width:100%;height:100%}.farris-image-cropper-frame .farris-image-cropper-loading .farris-image-cropper-loading-spinner{width:31px;height:31px;margin:0 auto;border:2px solid #388fff;border-radius:50%;border-left-color:transparent;border-right-color:transparent;-webkit-animation:cssload-spin 425ms infinite linear;position:absolute;top:calc(50% - 15px);left:calc(50% - 15px);animation:cssload-spin 425ms infinite linear}.input-group-append,.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text,.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control{margin-left:-1px}@keyframes cssload-spin{to{transform:rotate(360deg)}}.f-cmp-static-text-input-append,.f-cmp-text-input-append,.f-cmp-textarea-input-append{display:flex;height:100%}.f-cmp-static-text-input-append,.f-cmp-textarea-input-append{align-items:flex-start}.f-cmp-static-text-input-append .f-form-control-text,.f-cmp-static-text-input-append .f-form-control-textarea{flex:1 1 0}.f-cmp-static-text-input-append .input-append-wrapper,.f-cmp-text-input-append .input-append-wrapper,.f-cmp-textarea-input-append .input-append-wrapper{flex-shrink:0;height:100%}.input-append-text .input-group-text{color:var(--f-text-02);cursor:default}.input-append-button .input-group-text{color:var(--f-theme-03)}.f-cmp-inputgroup .input-append-text .input-group-text,.f-cmp-text-input-append .input-append-text .input-group-text,.f-component-text .input-append-text .input-group-text{color:var(--f-text-02)}.f-cmp-inputgroup .input-append-button .input-group-text,.f-cmp-text-input-append .input-append-button .input-group-text,.f-component-text .input-append-button .input-group-text{color:var(--f-theme-03)}.f-cmp-text-input-append .input-append-wrapper,.f-cmp-textarea-input-append .input-append-wrapper,.f-component-text .input-append-wrapper,.input-group .input-append-wrapper{background:var(--f-neutral-12)}.f-cmp-text-input-append .input-append-wrapper>.input-group-text,.f-cmp-textarea-input-append .input-append-wrapper>.input-group-text,.f-component-text .input-append-wrapper>.input-group-text,.input-group .input-append-wrapper>.input-group-text{border:0;background:0 0}.f-cmp-input-append-form .input-append-wrapper{position:absolute;right:1px;height:auto;top:1px;bottom:1px;border-radius:0 6px 6px 0;display:block}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after,.input-group>.custom-select:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-append-wrapper.f-state-disabled{display:none!important}.was-validated .farris-input-wrap .form-check-input:invalid~.invalid-feedback,.was-validated .farris-input-wrap .form-check-input:invalid~.invalid-tooltip,.was-validated .farris-input-wrap .form-check-input:valid~.valid-feedback,.was-validated .farris-input-wrap .form-check-input:valid~.valid-tooltip{display:block}.f-cmp-text-is-textarea.f-cmp-input-append-form .input-append-wrapper,.f-cmp-textarea-input-append.f-cmp-input-append-form .input-append-wrapper{bottom:auto}.form-control:disabled,.form-control:disabled:hover,.form-control[readonly],.form-control[readonly]:hover{border-color:var(--f-neutral-04);color:var(--f-text-02);background:var(--f-neutral-12);cursor:default}.form-control:hover{background-color:var(--f-neutral-12);color:var(--f-text-02);border-color:var(--f-theme-08);box-shadow:none}.was-validated .farris-input-wrap .custom-control-input:invalid~.custom-control-label,.was-validated .farris-input-wrap .custom-control-input:valid~.custom-control-label,.was-validated .farris-input-wrap .form-check-input:invalid~.form-check-label,.was-validated .farris-input-wrap .form-check-input:valid~.form-check-label{color:var(--f-neutral-04)}.form-control[readonly]:focus{box-shadow:none}.farris-input-wrap .custom-select.is-valid,.farris-input-wrap .form-control.is-valid,.was-validated .farris-input-wrap .custom-select:valid,.was-validated .farris-input-wrap .form-control:valid{border-color:var(--f-neutral-04)}.farris-input-wrap .custom-select.is-valid:focus,.farris-input-wrap .form-control.is-valid:focus,.was-validated .farris-input-wrap .custom-select:valid:focus,.was-validated .farris-input-wrap .form-control:valid:focus{border-color:var(--f-neutral-04);box-shadow:0 0 0 .2rem rgba(var(--f-neutral-04),.25)}.was-validated .farris-input-wrap .custom-control-input:valid~.custom-control-label::before{background-color:rgba(var(--f-neutral-04),.75)}.was-validated .farris-input-wrap .custom-control-input:valid:checked~.custom-control-label::before{background-color:rgba(var(--f-neutral-04),.9)}.was-validated .farris-input-wrap .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(var(--f-neutral-04),.25)}.was-validated .farris-input-wrap .custom-file-input:valid~.custom-file-label{border-color:var(--f-neutral-04)}.was-validated .farris-input-wrap .custom-file-input:valid~.custom-file-label::after{border-color:inherit}.was-validated .farris-input-wrap .custom-file-input:valid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(var(--f-neutral-04),.25)}.farris-input-wrap .custom-select.is-invalid,.farris-input-wrap .form-control.is-invalid,.was-validated .farris-input-wrap .custom-select:invalid,.was-validated .farris-input-wrap .form-control:invalid{border-color:var(--f-neutral-04)}.farris-input-wrap .custom-select.is-invalid:focus,.farris-input-wrap .form-control.is-invalid:focus,.was-validated .farris-input-wrap .custom-select:invalid:focus,.was-validated .farris-input-wrap .form-control:invalid:focus{border-color:var(--f-neutral-04);box-shadow:0 0 0 .2rem rgba(var(--f-neutral-04),.25)}.was-validated .farris-input-wrap .custom-control-input:invalid~.custom-control-label::before{background-color:rgba(var(--f-neutral-04),.75)}.was-validated .farris-input-wrap .custom-control-input:invalid:checked~.custom-control-label::before{background-color:rgba(var(--f-neutral-04),.9)}.was-validated .farris-input-wrap .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(var(--f-neutral-04),.25)}.was-validated .farris-input-wrap .custom-file-input:invalid~.custom-file-label{border-color:var(--f-neutral-04)}.was-validated .farris-input-wrap .custom-file-input:invalid~.custom-file-label::after{border-color:inherit}.was-validated .farris-input-wrap .custom-file-input:invalid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(var(--f-neutral-04),.25)}.f-cmp-inputgroup .f-state-focus,.input-group.f-state-focus{box-shadow:0 0 0,0 0 4px 2px rgba(99,136,255,.12);outline:0}input:-internal-autofill-selected{background:var(--f-neutral-12)}.f-empty-input-placeholder{padding-top:1.1607375rem;margin-top:.375rem;height:calc(1.5rem + .125rem);margin-bottom:.375rem;box-sizing:content-box}textarea::-webkit-input-placeholder{color:var(--f-text-09)!important}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control{position:relative;flex-grow:1;flex-shrink:1;flex-basis:0;width:1%;margin-bottom:0}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-file{display:flex;align-items:center}.input-group-append,.input-group-prepend{display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-prepend{margin-right:-1px}.input-group-text{display:flex;align-items:center;padding:.1875rem .5rem;margin-bottom:0;font-size:.8125rem;font-weight:400;line-height:1.4286;color:var(--f-text-02);text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid var(--f-neutral-04);border-radius:6px}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{height:calc(1.750025rem + 2px);padding:.25rem .3125rem;font-size:.875rem;line-height:1.4286;border-radius:6px}.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{height:calc(1.32145rem + 2px);padding:.125rem .4375rem;font-size:.75rem;line-height:1.4286;border-radius:6px}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.input-group.f-state-focus{border-color:var(--f-theme-08)}.input-group{border:1px solid var(--f-neutral-04);border-radius:6px}.input-group .form-control{border:0;height:1.5rem;box-shadow:none}.input-group .form-control:focus{box-shadow:none}.input-group .input-group-prepend{border-radius:6px 0 0 6px}.input-group .input-group-append{border-radius:0 6px 6px 0}.input-group .input-group-append,.input-group .input-group-prepend{background:#e4e7eb}.input-group .input-group-append>.btn,.input-group .input-group-append>.dropdown,.input-group .input-group-append>.input-group-text,.input-group .input-group-prepend>.btn,.input-group .input-group-prepend>.dropdown,.input-group .input-group-prepend>.input-group-text{border:0}.input-group .input-group-append>.input-group-text,.input-group .input-group-prepend>.input-group-text{background:0 0}.input-group .input-group-append>.input-group-clear,.input-group .input-group-prepend>.input-group-clear{padding:0 8px;border-radius:6px!important;background:var(--f-neutral-12)}.input-group .input-group-append>.input-group-clear .modal_close,.input-group .input-group-prepend>.input-group-clear .modal_close{color:var(--f-text-10);font-size:.75rem}.input-group .input-group-append>.input-group-clear:hover .modal_close,.input-group .input-group-prepend>.input-group-clear:hover .modal_close{color:var(--f-text-08)}.input-group:not(.farris-input-group-readonly):not(.farris-input-group-disable):not(.f-state-readonly):not(.f-state-disabled):not(.f-state-focus):hover{border-color:var(--f-theme-08)}.f-cmp-inputgroup .input-group-before-tips{background:var(--f-neutral-04);border:none;border-right:1px solid var(--f-neutral-04);position:relative;border-radius:6px 0 0 6px;padding:0 8px;display:flex;align-items:center}.f-cmp-inputgroup .input-group-before-tips .f-icon{font-size:14px}.f-cmp-inputgroup .input-group-before-tips .tips-arrow{width:4px;height:4px;margin:-4px 0 0;position:absolute;top:50%;right:0}.f-cmp-inputgroup .input-group-before-tips .tips-arrow::after,.f-cmp-inputgroup .input-group-before-tips .tips-arrow::before{content:"";border-color:transparent;border-style:solid;border-width:4px 4px 4px 0;position:absolute}.f-cmp-inputgroup .input-group-before-tips .tips-arrow::before{left:0;border-right-color:var(--f-neutral-04)}.f-cmp-inputgroup .input-group-before-tips .tips-arrow::after{left:1px;border-right-color:var(--f-neutral-12)}.f-cmp-inputgroup .f-state-disabled,.f-cmp-inputgroup .f-state-editable{border-color:var(--f-neutral-04);background:var(--f-neutral-12)}.f-cmp-inputgroup.input-group{flex-wrap:nowrap}.f-cmp-inputgroup .input-group-append{margin-left:0;background:var(--f-neutral-12)}.f-cmp-inputgroup.input-group>.form-control:not(:last-child){border-radius:6px}.f-cmp-inputgroup.input-group--has-clear>.form-control:last-of-type{border-top-right-radius:0;border-bottom-right-radius:0}.f-cmp-inputgroup .input-group-text{justify-content:center;color:rgba(0,0,0,.25);padding-left:.26786875rem;padding-right:.26786875rem;cursor:pointer}.f-cmp-inputgroup .input-group-text:hover{color:var(--f-theme-05)}.f-cmp-inputgroup .f-state-disabled .input-group-append,.f-cmp-inputgroup .f-state-readonly .input-group-append,.f-cmp-inputgroup .farris-input-group-disable .input-group-append,.f-cmp-inputgroup .farris-input-group-readonly .input-group-append{background:var(--f-neutral-12)}.f-cmp-inputgroup .f-state-disabled .input-group-append:not(.input-append-wrapper),.f-cmp-inputgroup .f-state-readonly .input-group-append:not(.input-append-wrapper),.f-cmp-inputgroup .farris-input-group-disable .input-group-append:not(.input-append-wrapper),.f-cmp-inputgroup .farris-input-group-readonly .input-group-append:not(.input-append-wrapper){display:none}.f-cmp-inputgroup .f-state-disabled .input-append-wrapper,.f-cmp-inputgroup .f-state-readonly .input-append-wrapper,.f-cmp-inputgroup .farris-input-group-disable .input-append-wrapper,.f-cmp-inputgroup .farris-input-group-readonly .input-append-wrapper{color:var(--f-text-02)}.f-cmp-inputgroup .f-state-disabled .input-append-wrapper .input-append-text:hover,.f-cmp-inputgroup .f-state-readonly .input-append-wrapper .input-append-text:hover,.f-cmp-inputgroup .farris-input-group-disable .input-append-wrapper .input-append-text:hover,.f-cmp-inputgroup .farris-input-group-readonly .input-append-wrapper .input-append-text:hover{color:inherit}.f-cmp-inputgroup .f-state-disabled .append-force-show,.f-cmp-inputgroup .f-state-readonly .append-force-show,.f-cmp-inputgroup .farris-input-group-disable .append-force-show,.f-cmp-inputgroup .farris-input-group-readonly .append-force-show{display:flex}.f-cmp-inputgroup .f-state-disabled .input-group-text,.f-cmp-inputgroup .f-state-readonly .input-group-text,.f-cmp-inputgroup .farris-input-group-disable .input-group-text,.f-cmp-inputgroup .farris-input-group-readonly .input-group-text{cursor:default}.f-cmp-inputgroup .f-state-disabled .form-control{color:var(--f-text-02)}.f-cmp-inputgroup .f-state-editable .form-control{color:var(--f-text-02)!important}.f-cmp-inputgroup .f-state-focus{border-color:var(--f-theme-08)}.f-cmp-inputgroup .f-state-readonly{box-shadow:none;background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-cmp-inputgroup .f-state-readonly .form-control{color:var(--f-text-02)}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper{display:flex;flex-direction:row;align-items:center}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--content{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden;height:100%;word-break:break-all}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--content .multi--close{color:var(--f-text-10);font-size:14px;cursor:pointer;margin-left:4px}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--content .multi--close::before{content:"\e11d"}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--item{display:inline-flex;align-items:center;border-radius:4px;margin:0 4px 0 0;padding:0 6px;background:var(--f-neutral-09)}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--item:last-child{margin:0}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--more{flex-shrink:0;font-size:13px;color:var(--f-theme-03);display:flex;align-items:center}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--more .multi--more-icon{font-size:13px}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--more .multi--more-icon::before{content:"\e11e"}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi-date-display .multi--item{padding:0 14px 0 6px}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi-date-display .multi-date-display-readonly{padding:0 6px}.language-textbox-panel{background:var(--f-neutral-20)!important;margin:.25rem 0 0;border-radius:10px;box-shadow:0 2px 20px 0 rgba(3,18,51,.12)!important}.f-layout-pane.f-page-content-main,.f-splitter-pane.f-splitter-pane-bottom,.f-splitter-pane.f-splitter-pane-left,.f-splitter-pane.f-splitter-pane-right,.f-splitter-pane.f-splitter-pane-top{box-shadow:0 0 8px 0 rgba(0,28,64,.08)}.language-textbox-panel .list-group-item{background:0 0}.f-layout{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:row;flex-wrap:nowrap;overflow:hidden;position:relative}.f-layout-pane.f-page-content-main{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:auto;display:flex}.f-layout-pane.f-page-content-nav{display:flex;flex-direction:column;box-shadow:none!important;padding:0;position:relative;z-index:100}.f-layout-pane>.f-layout-resize-bar.f-layout-resize-bar-e{cursor:e-resize;width:.4375rem;right:-.3125rem;height:100%;top:0}.f-layout-pane>.f-layout-resize-bar.f-layout-resize-bar-w{cursor:w-resize;width:.4375rem;left:-.3125rem;height:100%;top:0}.f-layout-pane>.f-layout-resize-bar.f-layout-resize-bar-s{cursor:s-resize;height:.4375rem;bottom:-.3125rem;width:100%;left:0}.f-layout-pane>.f-layout-resize-bar.f-layout-resize-bar-n{cursor:n-resize;height:.4375rem;top:-.3125rem;width:100%;left:0}.f-layout-pane>.f-layout-resize-bar{position:absolute;font-size:.1px;display:block;touch-action:none}.f-layout-pane>.f-layout-resize-bar:hover{background:rgba(42,135,255,.07)}.f-layout-resize-overlay{z-index:98;width:100%;height:100%;cursor:e-resize;background:0 0;position:absolute}.f-layout-horizontal-resize-proxy,.f-layout-vertical-resize-proxy{background:rgba(42,135,255,.07);display:none;z-index:100;position:absolute}.f-layout-horizontal-resize-proxy{width:.4375rem;left:0;height:100%}.f-layout-vertical-resize-proxy{height:.4375rem;top:0;width:100%}.f-list-nav{height:100%;min-height:200px}.f-list-nav .f-list-nav-in{position:relative;height:100%;background-color:#fff;box-shadow:1px 1px 8px 0 rgba(0,28,64,.08);z-index:100}.f-list-nav .f-list-nav-main{display:flex;flex-direction:column;height:100%;overflow-x:hidden}.f-list-nav .f-list-nav-main .f-list-nav-footer,.f-list-nav .f-list-nav-main .f-list-nav-header{flex-shrink:0}.f-list-nav .f-list-nav-main .f-list-nav-content{flex-grow:1;flex-shrink:1;flex-basis:0;overflow-y:auto;padding:.625rem 0}.f-list-nav .f-list-nav-main .f-list-nav-header .f-list-nav-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:.625rem .875rem .375rem!important;border:none!important;font-size:17px;color:var(--f-text-02);line-height:24px}.f-list-nav.f-list-nav-left{padding-right:0}.f-list-nav.f-list-nav-right{padding-left:0}.f-list-nav.f-list-nav-bottom,.f-list-nav.f-list-nav-top{width:100%;height:auto;min-height:auto}.f-list-nav .f-list-nav-in>.ng-resizable-handle{z-index:105}.splitter-pane-collapse-animate{transition:width .5s ease 0s}.f-template-listnav-row .list-nav-link{margin:4px 8px;border-radius:8px;color:var(--f-text-02);display:flex;align-items:center;padding:.5625rem 1.25rem}.f-template-listnav-row .list-nav-link.link-disable{background-color:#F9F9F9}.f-template-listnav-row .list-nav-link .nav-item-name{flex:1;font-size:.875rem;line-height:1.25rem;color:var(--f-text-02);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.f-template-listnav-row .list-nav-link .nav-item-counter{display:inline-block;padding:0 .3125rem;height:.875rem;line-height:.875rem;border-radius:.5rem;font-size:.625rem;color:var(--f-theme-03)}.f-template-listnav-row .list-nav-link:hover{background:var(--f-aid-02)}.f-listview-active .f-template-listnav-row .list-nav-link{border:none;background:var(--f-theme-04);box-shadow:0 4px 10px 0 rgba(var(--f-theme-03),.2)}.f-listview-active .f-template-listnav-row .list-nav-link .nav-item-name{color:#fff}.f-listview-active .f-template-listnav-row .list-nav-link .nav-item-counter{color:#fff;font-size:13px;background:0 0}.f-list-nav .f-list-nav-toggle-sidebar{width:22px;height:22px;background:#fff;border:1px solid var(--f-neutral-07);display:flex;align-items:center;position:absolute;z-index:120;margin:0;cursor:pointer}.f-list-nav .f-list-nav-toggle-sidebar .triangle{color:var(--f-text-02);border:none;font-family:FarrisIcons;width:14px;height:14px;-webkit-font-smoothing:antialiased;font-size:14px;font-weight:400;text-transform:none;display:block;line-height:14px;margin:0 auto}.f-list-nav .f-list-nav-toggle-sidebar .triangle::before{line-height:1}.f-list-nav .f-list-nav-toggle-sidebar .active,.f-list-nav .f-list-nav-toggle-sidebar:hover{border-color:var(--f-theme-03);color:#fff;background-image:linear-gradient(214deg,#3F65FF 0,#4D9AFF 100%);box-shadow:0 3px 8px 0 rgba(var(--f-semantic-info-01),.4)}.f-list-nav.f-list-nav-left .f-list-nav-toggle-sidebar{border-radius:12px;top:14px;right:-12px;left:auto}.f-list-nav.f-list-nav-left .f-list-nav-toggle-sidebar .triangle{border:none}.f-list-nav.f-list-nav-left .f-list-nav-toggle-sidebar.active{right:-12px;transform:rotateY(180deg)}.f-list-nav.f-list-nav-right .f-list-nav-toggle-sidebar{border-radius:12px;top:14px;left:-12px;right:auto}.f-list-nav.f-list-nav-right .f-list-nav-toggle-sidebar .triangle{border:none}.f-list-nav.f-list-nav-right .f-list-nav-toggle-sidebar .triangle::before{content:"\e00d"}.f-list-nav.f-list-nav-right .f-list-nav-toggle-sidebar.active{left:-12px;transform:rotateY(180deg)}.f-list-nav.f-list-nav-top .f-list-nav-toggle-sidebar{border-radius:12px;top:auto;bottom:-12px;right:14px;width:22px;height:22px;left:auto}.f-list-nav.f-list-nav-top .f-list-nav-toggle-sidebar .triangle{border:none}.f-list-nav.f-list-nav-top .f-list-nav-toggle-sidebar .triangle::before{content:"\e00c"}.f-list-nav.f-list-nav-top .f-list-nav-toggle-sidebar.active{top:auto;left:auto;right:14px;bottom:-12px;transform:rotateX(180deg)}.f-list-nav.f-list-nav-bottom .f-list-nav-toggle-sidebar{border-radius:12px;top:-12px;bottom:auto;right:14px;width:22px;height:22px;left:auto}.f-list-nav.f-list-nav-bottom .f-list-nav-toggle-sidebar .triangle{border:none}.f-list-nav.f-list-nav-bottom .f-list-nav-toggle-sidebar .triangle::before{content:"\e00e"}.f-list-nav.f-list-nav-bottom .f-list-nav-toggle-sidebar.active{right:14px;left:auto;top:-12px;bottom:auto;transform:rotateX(180deg)}.f-template-timeline-new-row .f-timeline{padding-right:26px}.f-template-timeline-new-row .f-timeline .timeline-date{position:relative;padding-bottom:16px;padding-left:18px;color:rgba(0,0,0,.45);font-size:14px;line-height:20px}.f-template-timeline-new-row .f-timeline .timeline-date::before{position:absolute;left:0;top:0;width:1px;height:35px;border-left:1px dotted #dcdcdc;content:"";z-index:9}.f-template-timeline-new-row .f-timeline .timeline-date::after{position:absolute;left:-3px;top:6.5px;display:block;width:7px;height:7px;background:#66B869;border-radius:100%;content:"";z-index:10}.f-template-timeline-new-row .f-timeline .timeline-content-wrapper{padding-left:18px;padding-bottom:13px;border-left:1px dotted #dcdcdc}.f-template-timeline-new-row .f-timeline .timeline-content-wrapper .timeline-content{padding:15px 14px;background:#F9F9F9;border:1px solid #F2F2F2}.f-template-timeline-new-row .f-timeline .timeline-content-wrapper .timeline-content-title{padding-bottom:12px;font-size:14px;line-height:20px;color:rgba(0,0,0,.65);border-bottom:1px solid rgba(220,220,220,.6)}.f-template-timeline-new-row .f-timeline .timeline-content-wrapper .timeline-content-title .title-sum{line-height:22px;font-size:16px;color:#F49730}.f-template-timeline-new-row .f-timeline .timeline-content-wrapper .timeline-content-main .content-data{font-size:0;margin-top:16px}.f-template-timeline-new-row .f-timeline .timeline-content-wrapper .timeline-content-main .content-data li{display:inline-block;padding-right:30px;margin-bottom:18px;font-size:14px;line-height:20px;color:rgba(0,0,0,.65)}.f-template-timeline-new-row .f-timeline.f-timeline-first .timeline-date::before{height:28px;top:7px}.f-template-timeline-new-row .f-timeline.f-timeline-success .timeline-date::after{background:var(--f-semantic-success-01)}.f-template-timeline-new-row .f-timeline.f-timeline-info .timeline-date::after{background-color:var(--f-semantic-info-01)}.f-template-timeline-new-row .f-timeline.f-timeline-error .timeline-date::after{background-color:var(--f-semantic-danger-01)}.f-template-timeline-new-row .f-timeline.f-timeline-warn .timeline-date::after{background-color:var(--f-semantic-warning-01)}.f-list-view .f-list-view-hover,.f-tmpl-subgrid-by-card .subgrid-by-card-item.f-state-edit{background:linear-gradient(270deg,rgba(235,244,255,.6) 0,#EBF4FF 100%)}.f-listview-fill{flex-grow:1;flex-shrink:1;flex-basis:0;overflow:hidden}.f-listview-fill .f-list-view{height:100%}.f-listview-fill .f-list-view .f-list-view-footer,.f-listview-fill .f-list-view .f-list-view-header{flex-shrink:0}.f-listview-fill .f-list-view .f-list-view-content{overflow-y:auto;flex-grow:1;flex-shrink:1;flex-basis:0}.f-list-view{display:flex;flex-direction:column;overflow:hidden}.f-list-view .f-list-view-content{flex:1;overflow:auto}.f-list-view .f-list-view-group{padding:0}.f-list-view .f-paging-wrapper{padding:14px 0}.f-list-view .f-list-view-group-item{display:flex;align-items:center;float:none;text-align:initial}.f-list-view .f-list-view-group-item.f-none-border{border-bottom:0}.f-list-view .f-list-view-group-item.f-listview-active,.f-list-view .f-list-view-group-item.f-listview-hover{cursor:pointer;color:#424347}.f-list-view .f-list-view-group-item.f-listview-active{border-color:#529dff}.f-list-view .f-list-view-group-item.f-un-select{color:#848c9a}.f-list-view .f-list-view-group-item .f-list-content{flex:1 1 auto;width:100%}.f-list-view .f-list-view-draggable-item{border:1px solid #e2e3e5;background-color:#fafbfd;border-radius:10px;margin:4px 2px}.f-list-view .f-list-view-draggable-item.f-listview-hover{cursor:pointer;color:#424347;background:#edf5ff!important}.f-list-view .f-list-view-draggable-item.f-listview-hover .f-list-remove-icon{display:initial}.f-list-view .f-list-view-draggable-item.f-listview-active{border-color:#529dff}.f-list-view .f-list-view-draggable-item.moving{opacity:0}.f-list-view .f-list-view-draggable-item.draggable-item--text-truncate .f-list-content{overflow:hidden}.f-list-view .f-list-view-draggable-item.draggable-item--text-truncate .f-list-content div{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.f-list-view .f-list-select{padding:0 0 0 14px}.f-list-view .f-list-select .listview-checkbox{margin:.25rem 0}.f-list-view .f-list-pin{color:#2986ff;padding:0 14px 0 0}.f-list-view .f-list-remove{width:30px;color:#f4625f;padding:0 14px 0 0}.f-list-view .f-list-remove-icon{display:none}.f-list-view .f-list-handle{padding:0 14px 0 0}.f-list-view .f-list-view-emptydata .f-empty-title{font-size:14px;line-height:22px;color:#999;padding:20px 0;text-align:center}.f-list-view.small-item .f-list-select{padding:initial}::highlight(search-result){background-color:#F7B500;color:#fff}.f-list-view-group-item .custom-control.listview-checkbox{margin-right:0;padding-right:4px}.f-listview-card-content-fill .f-list-content{height:100%;display:flex;flex-direction:column}.f-listview-card-content-fill .f-list-content>*{height:100%}.f-tmpl-card-listview--header-multicontent02 .f-list-view{margin:0}.f-tmpl-card-listview--header-multicontent02 .f-list-view-group{margin:0 -10px}.f-tmpl-card-listview--header-multicontent02 .f-list-view-content{overflow-x:hidden}.f-tmpl-card--header-multicontent02{position:relative;margin:0 10px 20px}.f-tmpl-card--header-multicontent02 .f-list-select{position:absolute;padding:0!important;top:10px;left:14px}.f-tmpl-card--header-multicontent02 .f-list-select .custom-checkbox{margin:0;padding:0}.f-tmpl-card--header-multicontent02 .f-list-select .custom-control-label::before{font-size:1rem}.f-tmpl-card--header-multicontent02 .header-multicontent02{background:#FEFEFF;border:1px solid #E9ECF3;border-radius:6px;width:310px;margin:0}.f-tmpl-card--header-multicontent02 .header-multicontent02 .text-label{color:#5A5E66}.f-tmpl-card--header-multicontent02 .header-multicontent02 .f-emphasize{font-size:16px;color:var(--f-semantic-warning-01)}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--header{padding:0 0 0 38px;height:40px;display:flex;align-items:center;border-bottom:1px solid #E9ECF3}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--header .f-title{margin:0;flex-shrink:1;flex-grow:1;flex-basis:0;font-size:16px;font-weight:600;color:#2D2F33;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--header .f-state{margin:0 0 0 8px}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--header .f-state .badge{border-radius:20px 0 0 20px;height:28px;line-height:28px;padding:0 13px}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--content{padding:14px 0 0 14px;color:#2D2F33;font-size:13px}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--content p{margin:0 0 10px}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer{padding:8px 14px 18px}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer p{margin:0}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer .footer--auxiliary{width:32px;border-radius:16px;margin:0 8px 0 0}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer .footer--auxiliary img{display:block;width:32px;height:32px}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer .text--name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:13px;color:#5A5E66}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer .icon-btn{padding:2px;margin:0 8px;cursor:pointer}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer .icon-btn.disabled{color:var(--f-text-07)}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer .icon-btn:hover{color:var(--f-theme-03)}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer .icon-btn .f-icon{font-size:14px}.f-tmpl-list01-container{border-top:1px solid rgba(0,0,0,.07);border-bottom:1px solid rgba(0,0,0,.07);margin-top:-1px}.f-tmpl-list01-container .f-list-select{padding-right:0!important}.f-tmpl-list01-container .gutter{margin:0 30px 0 0}.f-tmpl-list01-container .list01--header{font-size:13px;margin:0 0 3px}.f-tmpl-list01-container .list01--header .f-title{font-weight:600;margin:0 8px 0 0;vertical-align:top}.f-tmpl-list01-container .list01--header li{display:inline-block;margin:0 30px 3px 0}.f-tmpl-list01-container .list01--header li:last-child{margin-right:0}.f-tmpl-list01-container .list01--header .badge{border-radius:10px;line-height:20px;padding:0 8px}.f-tmpl-list01-container .list01--des{font-size:12px;color:rgba(0,0,0,.5)}.modal-header,.modal-header .close,.modal-header .close:not(:disabled):not(.disabled):focus,.modal-header .close:not(:disabled):not(.disabled):hover,.ng-busy-default-sign,.ng-busy-default-text{color:var(--f-text-02)}.f-tmpl-list01-container .list01--des span{display:inline-block;margin-bottom:3px}.f-tmpl-list01-container .list01--des span:last-child{margin-right:0}.f-tmpl-list01-container .list01--content{padding:16px 12px 16px 8px}.f-tmpl-list01-container .list01--toolbar{width:150px;padding:0 14px;text-align:right}.f-list-view-footer .f-paging-wrapper{padding:0!important}.f-list-view-footer .f-paging-wrapper .pagination-container{height:2.5rem}.f-list-view-footer .f-paging-wrapper .pagination{padding:.875rem 0 0}.f-component-loading{z-index:1060;top:0;left:0;right:0;bottom:0;position:absolute}.farris-loading-backdrop{position:absolute;top:0;left:0;right:0;bottom:0;z-index:1061;opacity:0;background-color:transparent}.farris-loading{position:absolute;top:50%;left:50%}.ng-busy-default-wrapper{text-align:center}.ng-busy-default-sign{position:relative;display:flex;align-items:center;z-index:1063;padding:8px 16px 8px 8px;border:0 solid #E5E9EF;border-radius:8px;box-shadow:0 6px 16px -8px rgba(0,0,0,.06),0 0 30px 12px rgba(0,0,0,.04);background:#fff}.ng-busy-default-text{display:inline-block;margin-left:.375rem;max-width:25rem;text-align:left;padding:0 4px;font-size:15px}.ng-busy-default-spinner{position:relative;display:inline-block;width:1.5625rem;height:1.5625rem;vertical-align:middle}.ng-busy-default-spinner div{position:absolute;left:44.5%;top:37%;width:10%;height:26%;background:#666;border-radius:3.125rem;box-shadow:0 0 3px rgba(0,0,0,.2);opacity:0;animation:busy-spinner-anim 1s linear infinite}.f-loading-round{font-size:10px;margin:0;width:100%;height:100%;border-radius:50%;position:relative;animation:loadingRountAnimation 1s infinite linear;transform:translateZ(0)}.f-loading-round::before{width:50%;height:50%;background:var(--f-theme-03);border-radius:100% 0 0;position:absolute;top:0;left:0;content:""}.f-loading-round::after{background:#fff;width:90%;height:90%;border-radius:50%;content:"";margin:auto;position:absolute;top:0;left:0;bottom:0;right:0}.f-loading-dot,.f-loading-dot-wrapper{height:100%;width:100%;overflow:hidden}@keyframes loadingRountAnimation{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.f-loading-dot-wrapper .dot1{background:var(--f-semantic-danger-01)}.f-loading-dot-wrapper .dot2{background:var(--f-semantic-warning-01)}.f-loading-dot-wrapper .dot3{background:var(--f-semantic-success-01)}.f-loading-dot{position:absolute;margin:auto;top:0;bottom:0;left:0;right:0;animation:fLoadingDotRotate 1.8s linear infinite}.f-loading-dot-wrapper{position:relative}.f-loading-dot-wrapper .dot{position:absolute;margin:auto;width:25%;height:25%;border-radius:100%;transition:all 1s ease}.f-loading-dot-wrapper .dot1{top:0;bottom:0;left:0;animation:dotsY 1.8s linear infinite}.f-loading-dot-wrapper .dot2{left:0;right:0;top:0;animation:dotsX 1.8s linear infinite}.f-loading-dot-wrapper .dot3{top:0;bottom:0;right:0;animation:dotsY 1.8s linear infinite}.f-loading-dot-wrapper .dot4{background:var(--f-semantic-info-01);left:0;right:0;bottom:0;animation:dotsX 1.8s linear infinite}@keyframes fLoadingDotRotate{0%{transform:rotate(0)}10%{width:100%;height:100%}66%{width:25%;height:25%}100%{transform:rotate(360deg);width:100%;height:100%}}@keyframes dotsY{66%{opacity:.3;width:25%}77%{opacity:1;width:0}}@keyframes dotsX{66%{opacity:.3;height:25%}77%{opacity:1;height:0}}.farris-notify .toast-title-beforeshow,.modal-backdrop.fade{opacity:0}.modal-tips{padding:.5625rem .625rem .5625rem 1.25rem}.modal-tips .modal-tips-content{margin-top:0;margin-left:2.25rem;margin-right:1.75rem}.modal-tips .modal-tips-title{color:var(--f-text-04);font-size:.875rem;line-height:1.25rem;font-weight:400;margin:0}.modal-tips .toast-msg{margin:0;word-break:break-all;font-size:1rem;line-height:1.375rem}.modal-tips .only-toast-msg{color:var(--f-text-04);font-size:1rem;line-height:1.375rem}.modal-tips .toast-msg-title{margin:1px 0 0;word-break:break-all;font-size:1rem;line-height:1.375rem;color:var(--f-text-01)}.modal-tips .toast-msg-detail{word-break:break-all;color:var(--f-text-06);font-size:.875rem;margin:.625rem 0 0}.modal-tips .modal-tips-iconwrap .f-icon{font-size:1.625rem;margin-right:.75rem}.modal-footer .btn,.modal-footer .k-button{font-size:.8125rem;padding:.375rem 1.3125rem}.message-container{height:8.75rem;display:flex;flex-direction:column}.message-container .btn{min-width:3.75rem;margin:auto .3125rem}.farris-messager{display:flex}.farris-messager .icon{background-position:center .1875rem;background-size:4.375rem;background-repeat:no-repeat;width:4.375rem;height:4.375rem}.farris-messager .msg{flex:1 1 auto}.modal-message .modal-tips,.modal-message .modal-tips.messager-type-error{padding:1.875rem 1.5rem 1.75rem 1.875rem}.modal-message .modal-tips .modal-tips-content{padding:0}.modal-message .modal-tips .modal-tips-iconwrap{margin:0}.modal-message .modal-tips .modal-tips-iconwrap .f-icon{font-size:1.625rem}.modal-message .modal-footer{background:#fff!important;box-shadow:none;border:none;padding:0 1.5rem 1.25rem 1.875rem}.modal-message .modal-cotnent--has-header .modal-tips{padding:1.875rem 1.5rem 1.75rem 1.875rem}.modal.farris-modal .modal-message.model-dialog-maximize{width:60%!important;max-width:50rem!important;height:auto!important;max-height:60%!important;top:0!important;left:0!important;margin:0!important}.modal,.modal-backdrop{left:0;bottom:0;right:0}.modal.farris-modal .modal-message .modal-body{padding:0}.modal-open{overflow:hidden}.modal-open .modal{overflow-y:auto}.modal{position:fixed;top:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-25%)}@media screen and (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:translate(0,0)}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - .5rem * 2)}.modal-dialog-centered::before{display:block;height:calc(100vh - .5rem * 2);content:""}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:0 solid #E5E9EF;border-radius:16px;box-shadow:0 2px 12px 0 rgba(0,0,0,.06);outline:0}.modal-backdrop{position:fixed;top:0;z-index:1040;background-color:#000}.modal-backdrop.show{opacity:.15}.modal-title{margin-bottom:0;line-height:1.375rem}.modal-body{position:relative;flex-grow:1;flex-shrink:1;flex-basis:auto;padding:.625rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:3.125rem;height:3.125rem;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:31.25rem;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - 1.75rem * 2)}.modal-dialog-centered::before{height:calc(100vh - 1.75rem * 2)}.modal-content{box-shadow:0 2px 12px 0 rgba(0,0,0,.06)}.modal-sm{max-width:18.75rem}}@media (min-width:888px){.modal-lg{max-width:50rem}}.modal-header{display:flex;justify-content:space-between;flex-shrink:0;padding:.75rem .5rem .75rem 1.125rem;background:#fff;align-items:center;border-top-left-radius:16px;border-top-right-radius:16px;border-bottom:none}.modal-header .close{opacity:1;padding:.1875rem;margin:-.25rem 0;border:1px solid transparent;font-size:1rem;width:1.6607375rem;height:1.6607375rem}.modal-title{font-size:1rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.modal-footer,.showtype-modal .fe-modal-footer-base{display:flex;align-items:center;justify-content:flex-end;flex-shrink:0;background:var(--f-neutral-00);padding:.875rem 1.5rem;box-shadow:none}.modal-footer>:not(:first-child),.showtype-modal .fe-modal-footer-base>:not(:first-child){margin-left:.3125rem}.modal-footer>:not(:last-child),.showtype-modal .fe-modal-footer-base>:not(:last-child){margin-right:.3125rem}.modal-open .modal{overflow-x:auto}.modal.farris-modal .actions{flex:1;margin:-.25rem 0}.modal.farris-modal .actions ul{list-style:none;margin:0;padding:0;display:flex;justify-content:flex-end}.modal.farris-modal .actions .f-btn-icon{cursor:pointer;color:var(--f-text-07);text-align:center}.modal.farris-modal .actions .f-btn-icon:hover{color:var(--f-theme-05)}.modal.farris-modal .actions .f-btn-icon:active{color:var(--f-theme-01)}.modal.farris-modal .actions .modal-tips-iconwrap .f-icon{font-size:2rem}.fe-cmp-page-modal .action-list .f-icon,.fe-cmp-page-modal .close-icon .f-icon{font-size:14px}.modal.farris-modal .actions .modal-tips-iconwrap .modal-tips-content{padding-top:.25rem}.modal.farris-modal .ng-draggable{cursor:move}.modal.farris-modal .modal-dialog{max-width:none;margin:0;top:50%;left:50%;position:absolute;pointer-events:all}.modal.farris-modal.fade .modal-dialog{transform:none;transition:none}.modal.farris-modal .modal-content{height:100%;overflow:hidden}.modal.farris-modal .modal-body{padding:0}.farris-messager{flex-direction:column;position:absolute;top:0;bottom:0;left:0;right:0}.farris-messager .modal-tips{margin-bottom:0;flex-shrink:1;flex-grow:1;flex-basis:auto;overflow-y:auto;display:flex;flex-direction:row}.farris-messager .modal-tips .modal-tips-iconwrap{margin:.5625rem 0;padding:0}.farris-messager .modal-tips .modal-tips-content{margin:0;padding:.5625rem .9375rem .5625rem 0}.farris-messager .fixdiv{overflow:auto}.f-modal-fitContent{display:flex!important;align-items:center;justify-content:center}.f-modal-fitContent-scroll{align-items:flex-start}.f-modal-fitContent .modal-dialog{position:relative!important;top:0!important;left:0!important;margin:1.875rem 0!important;min-height:7.5rem}.f-modal-fitContent .farris-messager{position:relative!important}.overlay-container{position:fixed;z-index:9999;pointer-events:none;top:0;left:0;height:100%;width:100%}.fe-cmp-page-modal .action-wrapper{position:absolute;right:-12px;top:-12px;z-index:400}.fe-cmp-page-modal .action-wrapper .close-icon{background:rgba(0,0,0,.4);width:22px;height:22px;border-radius:12px;color:#fff;text-align:center;line-height:22px;display:block;cursor:pointer}.fe-cmp-page-modal .action-wrapper .close-icon:hover{background:rgba(0,0,0,.6)}.fe-cmp-page-modal .action-list{position:absolute;right:-32px;top:20px;color:rgba(255,255,255,.85)}.fe-cmp-page-modal .action-list .action-list--item{display:block;width:32px;height:32px;text-align:center}.fe-cmp-page-modal .action-list .action-list--icon{display:block;cursor:pointer;margin:0 auto;line-height:32px;border-radius:0 3px 3px 0}.fe-cmp-page-modal .action-list .action-list--icon:hover{color:#fff}.fe-cmp-page-modal .action-list .max-icon{background:linear-gradient(-63deg,#517BFF 0,#74A1FF 95%)}.fe-cmp-page-modal .action-list .close-icon{background:linear-gradient(-51deg,#FE6568 0,#FA6568 0,#F67574 100%)}.fe-cmp-page-modal .modal-body{border-radius:16px}.fe-cmp-page-modal.modal .modal-content{overflow:visible}.farris-modal{background-color:rgba(0,0,0,.45)}.farris-nav{display:flex;flex-direction:row;align-items:center;border-bottom:1px solid #e9e9e9;overflow:hidden;border-color:var(--f-neutral-06)!important}.farris-nav-item{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.farris-nav-item-link{padding:.75rem 1rem;cursor:pointer;border-bottom:2px solid transparent}.farris-nav-item-link-text{position:relative;font-size:1rem;font-weight:400}.farris-nav-item-tag{position:absolute;right:-.75rem;top:calc(10px - 100%);padding:0 .375rem;color:#fff;font-size:.75rem;line-height:1.125rem;border-radius:1.125rem;background-color:var(--f-semantic-danger-01)}.nav,.pagination{padding-left:0;list-style:none}.farris-nav.farris-nav-vertical{flex-direction:column;align-items:flex-start}.farris-nav.farris-nav-vertical .farris-nav-item{width:100%}.farris-nav-item-link-text{color:var(--f-text-03)}.farris-nav-item.active .farris-nav-item-link{border-color:var(--f-theme-03)}.farris-nav-item.active .farris-nav-item-link-text{color:var(--f-theme-03)}.farris-nav-item.disabled .farris-nav-item-link-text{color:var(--f-text-07)}.farris-nav-item:hover:not(.disabled):not(.active) .farris-nav-item-link-text{color:var(--f-theme-05)}.nav{display:flex;flex-wrap:wrap;margin-bottom:0}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:6px;border-top-right-radius:6px}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:6px}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--f-text-00);background:var(--f-theme-04)}.nav-fill .nav-item{flex-grow:1;flex-shrink:1;flex-basis:auto;text-align:center}.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.farris-notify{position:fixed;z-index:999999}.farris-notify.toasty-position-top-left{top:.75rem;left:.75rem}.farris-notify.toasty-position-top-right{top:.75rem;right:.75rem}.farris-notify.toasty-position-bottom-right{bottom:.75rem;right:.75rem}.farris-notify.toasty-position-bottom-left{bottom:.75rem;left:.75rem}.farris-notify.toasty-position-top-center{top:.75rem;left:50%;transform:translate(-50%,0)}.farris-notify.toasty-position-bottom-center{bottom:.75rem;left:50%;transform:translate(-50%,0)}.farris-notify.toasty-position-center-center{top:50%;left:50%;transform:translate(-50%,0)}.f-message-strip .toast,.farris-notify .toast{margin:0 0 .625rem;padding:0;width:24rem;border:1px solid var(--f-neutral-08);background:#fff;display:table;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);border-radius:8px;position:relative}.f-message-strip .toast .toast-close,.farris-notify .toast .toast-close{position:absolute;border:0;top:.625rem;right:.625rem;color:rgba(0,0,0,.25)}.f-message-strip .toast.toasty-type-danger,.f-message-strip .toast.toasty-type-info,.f-message-strip .toast.toasty-type-success,.f-message-strip .toast.toasty-type-warning,.farris-notify .toast.toasty-type-danger,.farris-notify .toast.toasty-type-info,.farris-notify .toast.toasty-type-success,.farris-notify .toast.toasty-type-warning{border-color:var(--f-neutral-08)}.f-message-strip .toast .toast-close .modal_close,.farris-notify .toast .toast-close .modal_close{font-size:1rem}.f-message-strip .toast .toast-close.f-btn-icon.f-bare,.farris-notify .toast .toast-close.f-btn-icon.f-bare{outline:unset}.f-message-strip .toast .modal-tips,.farris-notify .toast .modal-tips{padding:.625rem .75rem .625rem 1.25rem}.f-message-strip .toast .modal-tips-content,.farris-notify .toast .modal-tips-content{margin:0 1.75rem}.f-message-strip .toast .modal-tips-iconwrap .f-icon,.farris-notify .toast .modal-tips-iconwrap .f-icon{font-size:1rem;border-radius:100%;vertical-align:middle}.f-message-strip .toast.toasty-type-info .modal-tips-iconwrap .f-icon,.farris-notify .toast.toasty-type-info .modal-tips-iconwrap .f-icon{box-shadow:0 3px 8px 0 rgba(var(--f-semantic-info-01),.3)}.f-message-strip .toast.toasty-type-success .modal-tips-iconwrap .f-icon,.farris-notify .toast.toasty-type-success .modal-tips-iconwrap .f-icon{box-shadow:0 3px 8px 0 rgba(var(--f-semantic-success-01),.3)}.f-message-strip .toast.toasty-type-danger .modal-tips-iconwrap .f-icon,.farris-notify .toast.toasty-type-danger .modal-tips-iconwrap .f-icon{box-shadow:0 3px 8px 0 rgba(var(--f-semantic-danger-01),.3)}.f-message-strip .toast.toasty-type-warning .modal-tips-iconwrap .f-icon,.farris-notify .toast.toasty-type-warning .modal-tips-iconwrap .f-icon{box-shadow:0 3px 8px 0 rgba(var(--f-semantic-warning-01),.3)}.farris-notify .toast.toasty-type-danger,.farris-notify .toast.toasty-type-info,.farris-notify .toast.toasty-type-success,.farris-notify .toast.toasty-type-warning{background:#fff}.f-message-strip .toast{width:100%;box-shadow:none}.f-message-strip .toast.toasty-type-info{background:var(--f-semantic-info-03)}.f-message-strip .toast.toasty-type-success{background:var(--f-semantic-success-03)}.f-message-strip .toast.toasty-type-danger{background:var(--f-semantic-danger-03)}.f-message-strip .toast.toasty-type-warning{background:var(--f-semantic-warning-03)}.f-message-strip .toast .modal-tips{display:flex;padding:.5rem 1rem}.f-message-strip .toast .modal-tips-content{margin:0}.f-catch-attention-debounce{position:relative;z-index:1;outline:var(--f-theme-03) solid 1px;animation:debounceAttention .2s ease 0s infinite normal}@keyframes debounceAttention{0%{outline:solid var(--f-theme-03)}100%{outline:solid 18px}}@keyframes farrisMoveUpIn{0%{transform:translateY(-100%);transform-origin:0 0;opacity:0}100%{transform:translateY(0);transform-origin:0 0;opacity:1}}@keyframes farrisMoveUpOut{0%{transform:translateY(0);transform-origin:0 0;opacity:1}100%{transform:translateY(-100%);transform-origin:0 0;opacity:0}}.f-cmp-footer-accordion.f-state-collapse .f-toolbar .toolbar--collapse-icon,.f-cmp-number-spinner .btn-number-flag-up .number-arrow-chevron,.pagination .pg-pagelist.show .pg-pagelist-info .f-icon{transform:rotate(180deg)}.toast.fadeIn{animation:farrisMoveUpIn .2s linear}.toast.fadeOut{animation:farrisMoveUpOut .2s linear}.f-cmp-number-spinner .sub-btn-group{border-right:1px solid var(--f-neutral-04)}.f-cmp-number-spinner .number-arrow-chevron{font-size:12px;min-width:12px}.f-cmp-number-spinner .input-group .btn-group-number,.input-group .btn-group-number{background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-cmp-number-spinner .input-group .btn-group-number.btn-number-flag .number-arrow-chevron,.input-group .btn-group-number.btn-number-flag .number-arrow-chevron{color:var(--f-text-07);border-left:1px solid var(--f-neutral-04)}.f-cmp-number-spinner .input-group .btn-group-number.btn-number-flag .number-arrow-chevron:nth-child(2),.input-group .btn-group-number.btn-number-flag .number-arrow-chevron:nth-child(2){border-top:1px solid var(--f-neutral-04)}.f-cmp-number-spinner .input-group .btn-group-number.btn-number-flag .number-arrow-chevron:active,.f-cmp-number-spinner .input-group .btn-group-number.btn-number-flag .number-arrow-chevron:hover,.input-group .btn-group-number.btn-number-flag .number-arrow-chevron:active,.input-group .btn-group-number.btn-number-flag .number-arrow-chevron:hover{color:var(--f-theme-05);background:var(--f-neutral-12)}.f-cmp-number-spinner .input-group .btn-group-number.btn-number-flag .number-arrow-chevron.not-allowed,.input-group .btn-group-number.btn-number-flag .number-arrow-chevron.not-allowed{background:var(--f-neutral-12)}.input-group .btn-group-number{height:1.5rem;flex-direction:column;background-color:var(--f-neutral-12);border-left:1px solid var(--f-neutral-04);width:1.5rem;overflow:hidden;margin:0;flex-shrink:0}.input-group .btn-group-number .btn-number-flag{height:50%;display:flex;box-shadow:none;padding:0 5px;margin-left:1px;overflow:hidden;transition:all .1s linear}.input-group .btn-group-number .btn-number-flag .number-arrow-chevron{flex:1;line-height:1}.input-group .btn-group-number .btn-number-flag:hover{height:60%!important}.input-group .btn-group-number .btn-number-flag:nth-child(2){border-top:1px solid var(--f-neutral-04);border-top-right-radius:0}input::-webkit-inner-spin-button,input::-webkit-outer-spin-button{-webkit-appearance:none!important;margin:0}.input-group.number-range{position:relative}.input-group.number-range .input-container{display:flex;padding:0}.input-group.number-range .input-container .sub-input-group{flex:1;position:relative;display:flex;transition:all .3s ease-out}.input-group.number-range .input-container .sub-input-group .sub-input{width:100%;border:none;outline:0;background-color:rgba(0,0,0,0);min-width:2px;padding:.125rem 4px .125rem .5rem}.input-group.number-range .input-container .sub-input-group .btn-group-number .btn-number-flag,.input-group.number-range .input-container .sub-input-group:first-child .sub-btn-group{border-radius:0}.input-group.number-range .input-container .spliter{width:15px;text-align:center}.number-range .input-container .sub-input-group .sub-input{background-color:transparent}.number-range .input-container .sub-input-group .sub-input::-moz-placeholder{color:var(--f-text-09)}.number-range .input-container .sub-input-group .sub-input::placeholder{color:var(--f-text-09)}.number-range .input-container .sub-input-group .sub-input:disabled::-moz-placeholder,.number-range .input-container .sub-input-group .sub-input[readonly]::-moz-placeholder{color:var(--f-text-09)}.number-range .input-container .sub-input-group .sub-input:disabled::placeholder,.number-range .input-container .sub-input-group .sub-input[readonly]::placeholder{color:var(--f-text-09)}.number-range .sub-input-group:last-of-type .sub-btn-group{border-right:none}.f-order .f-list-view-emptydata .f-empty-title{padding:10px 0;margin-bottom:0}.f-order .f-order-item{border:none;background-color:initial}.f-order .f-order-item.f-listview-hover{cursor:pointer;color:#424347;background:#edf5ff!important}.f-order .f-order-item.f-listview-hover .f-list-remove-icon{display:initial}.f-order .f-order-item.f-listview-active{border-color:none}.f-order .f-order-item.moving{opacity:0}.f-order .f-order-add-button{display:flex!important;align-items:center!important}.f-order .f-order-add-icon{width:1.2rem;height:1.2rem;background-color:#f0f8ff;border-radius:1.2rem;display:inline-block;margin-right:4px}.f-order .f-order-add-icon .f-icon{line-height:1.2!important}.f-order .f-order-header{display:flex;margin:4px 60px 0 0}.f-order .f-order-header .f-order-header-order-field,.f-order .f-order-header .f-order-header-order-type{flex:1}.f-order .f-order-header .f-order-header-order-field{margin:0 4px 0 10px}.f-order .f-order-header .f-order-header-order-type{margin:0 10px 0 4px}.f-order-item-content{display:flex;margin:4px 0}.f-order-item-content .f-order-item-content-order-field,.f-order-item-content .f-order-item-content-order-type{flex:1}.f-order-item-content .f-order-item-content-order-field{margin:0 4px 0 10px}.f-order-item-content .f-order-item-content-order-type{margin:0 10px 0 4px}.f-cmp-footer{display:flex;flex-direction:column;padding:.875rem;margin:0;background:var(--f-neutral-19);border-radius:4px;box-shadow:0 4px 10px 0 rgba(31,35,41,.1)}.f-cmp-footer .f-cmp-footer-header{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:space-between;margin:0 0 .5rem;border-bottom:1px dashed rgba(0,0,0,.1);padding:0 0 .75rem}.f-cmp-footer .f-cmp-footer-header .f-content{display:inline-flex;align-items:center;white-space:nowrap;flex-shrink:1;flex-grow:1;flex-basis:0}.f-cmp-footer .f-cmp-footer-header .f-toolbar{min-width:10rem;flex-shrink:0;display:inline-flex;align-items:center;justify-content:flex-end;color:var(--f-text-04);margin-left:auto}.f-cmp-footer .f-cmp-footer-header .f-toolbar .toolbar--collapse{cursor:pointer}.f-cmp-footer .f-cmp-footer-header .f-toolbar .toolbar--collapse-icon{font-family:FarrisIcons;margin:0 .375rem;font-size:.875rem;transition:transform .1s linear}.f-cmp-footer .f-cmp-footer-header .f-toolbar .toolbar--collapse-icon:hover{color:var(--f-theme-01)}.f-cmp-footer-accordion.f-state-collapse .f-cmp-footer-header{border-bottom:none;margin-bottom:0;padding-bottom:0}.f-cmp-footer-accordion.f-state-collapse .f-cmp-footer-content{display:none}.f-tmpl-footer-same-gutter{margin:0 10rem 0 0}.f-page-header-el-mt,.f-page-header-el-my{margin-top:.8125rem}.f-page-header-el-mb,.f-page-header-el-my{margin-bottom:.8125rem}.f-cmp-footer-hasgap{position:relative}.f-cmp-footer-nogap::before{display:none!important}#page-header,.f-page-header,.f-pt-header{z-index:unset}.f-page-card #page-header,.f-page-card .f-page-header,.f-page-card .f-pt-header{z-index:105!important}.f-page-header{flex-shrink:0;background:var(--f-neutral-00);box-shadow:none}.f-page-header-el-mx{margin-left:.875rem;margin-right:.875rem}.f-page-header-base{padding:.75rem .875rem;min-height:2.875rem;display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:space-between}.f-page-header-base .f-title{display:inline-flex;align-items:center}.f-page-header-base .f-title .f-title-text{font-size:1.0625rem;line-height:1.625rem;color:var(--f-text-01);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0 .875rem 0 0}.f-page-header-base .f-title .f-title-icon{display:inline-flex;width:1.625rem;height:1.625rem;line-height:1.625rem;text-align:center;background:var(--f-ornament-02);border-radius:.25rem;color:var(--f-text-00);justify-content:center;align-items:center;flex-shrink:0;overflow:hidden;margin:0 .625rem 0 0}.f-page-header-base .f-title .f-title-icon img{display:block;width:1.625rem;height:1.625rem}.f-page-header-base .f-title .f-title-icon .f-icon::before{vertical-align:bottom}.f-page-header-base .f-title .f-title-subtitle{padding:0 0 0 .875rem;font-size:.8125rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-left:1px solid var(--f-neutral-08);margin:0 .875rem 0 0}.fv-grid-hierarchy-cell,.fv-tree{border-width:1px;border-style:solid}.f-page-header-base .f-title .f-title-pagination,.f-page-header-base .f-title .f-title-status{margin:0 .875rem 0 0}.f-page-header-base .f-title .f-title-pagination span{width:1.25rem;height:1.25rem;margin:0 .375rem 0 0;color:var(--f-text-02);line-height:1.125rem;border-width:1px;border-style:solid;border-color:var(--f-neutral-08);border-radius:6px;background:var(--f-neutral-12);cursor:pointer}.f-page-header-base .f-title .f-title-pagination span.f-state-disabled{cursor:default;color:var(--f-text-07);border-color:var(--f-neutral-05);background:var(--f-neutral-09)}.f-page-header-base .f-title .f-title-pagination span:not(.f-state-disabled):hover{color:var(--f-theme-05);border-color:var(--f-theme-05);background:var(--f-neutral-12)}.f-page-header-base .f-title .f-title-pagination span:last-child{margin:0}.f-page-header-base .f-content{display:inline-flex;align-items:center;white-space:nowrap;flex-shrink:1;flex-grow:1;flex-basis:0}.f-page-header-base .f-toolbar{flex-shrink:0;display:inline-flex;align-items:center;justify-content:flex-end;color:var(--f-text-04);margin-left:auto}.f-text-orna-bill,.f-text-orna-dict,.f-text-orna-manage,.f-text-orna-param,.f-text-orna-query{color:var(--f-text-00)!important}.f-page-header-base .f-toolbar-viewchange{margin-left:.375rem}.page-item:first-child .page-link,.page-link{margin-left:0}.f-text-orna-manage{background:linear-gradient(135deg,#4190FF 0,#657CFF 100%)!important;box-shadow:0 3px 10px 0 rgba(var(--f-ornament-03-start),.3)}.f-text-orna-dict{background:linear-gradient(135deg,#4EC87A 0,#52D389 100%)!important;box-shadow:0 3px 10px 0 rgba(var(--f-ornament-05-start),.3)}.f-text-orna-bill{background:linear-gradient(135deg,#1FC8DC 0,#41D2BD 100%)!important;box-shadow:0 3px 10px 0 rgba(var(--f-ornament-02-start),.3)}.f-text-orna-query{background:linear-gradient(135deg,#FC8249 0,#FE9539 100%)!important;box-shadow:0 3px 10px 0 rgba(var(--f-ornament-01-start),.3)}.f-text-orna-param{background:linear-gradient(135deg,#8B82FF 0,#A082FF 100%)!important;box-shadow:0 3px 10px 0 rgba(var(--f-ornament-04-start),.3)}.page-link,.page-link:hover{background-color:var(--f-neutral-12)}.f-color-orna-manage{color:var(--f-ornament-03-start)!important}.f-color-orna-dict{color:var(--f-ornament-05-start)!important}.f-color-orna-bill{color:var(--f-ornament-02-start)!important}.f-color-orna-query{color:var(--f-ornament-01-start)!important}.f-color-orna-param{color:var(--f-ornament-04-start)!important}.pagination{display:flex;border-radius:6px}.page-link{position:relative;display:block;padding:.1875rem;line-height:1rem;color:var(--f-text-02);border:1px solid var(--f-neutral-08)}.page-item:first-child .page-link,.pagination-lg .page-item:first-child .page-link,.pagination-sm .page-item:first-child .page-link{border-top-left-radius:6px;border-bottom-left-radius:6px}.page-item:last-child .page-link,.pagination-lg .page-item:last-child .page-link,.pagination-sm .page-item:last-child .page-link{border-top-right-radius:6px;border-bottom-right-radius:6px}.page-link:hover{z-index:2;text-decoration:none}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 4px 2px rgba(99,136,255,.12)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item.active .page-link{z-index:1;color:var(--f-text-00);background:var(--f-theme-06)!important;border-color:var(--f-theme-05)}.page-item.disabled .page-link{color:var(--f-text-07);pointer-events:none;cursor:auto;background:var(--f-neutral-09);border-color:var(--f-neutral-05);box-shadow:none}.page-link,.query-solution .solution-action .icon-group .f-icon-remove,.switch small,.switch.checked small{box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.pagination-lg .page-link{padding:.75rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-link{padding:.1875rem;font-size:.75rem;line-height:1.5}.ngx-pagination::after,.ngx-pagination::before{content:" ";display:table}.ngx-pagination::after{clear:both}.ngx-pagination li{-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:.0625rem;border-radius:0;display:inline-block}.ngx-pagination a,.ngx-pagination button{color:var(--f-text-02);display:block;cursor:pointer}.ngx-pagination .current{cursor:default}.ngx-pagination .disabled{color:var(--f-neutral-09);cursor:default}.ngx-pagination .disabled:hover{background:0 0}.ngx-pagination .pagination-next a::after,.ngx-pagination .pagination-next.disabled::after,.ngx-pagination .pagination-previous a::before,.ngx-pagination .pagination-previous.disabled::before{display:inline-block;margin-right:.5rem}.ngx-pagination .small-screen,.pagination-container .page-item.ellipsis:hover>.page-link>.page-link-label,.pagination-container .page-item.ellipsis>.page-link>.f-icon{display:none}.ngx-pagination .show-for-sr{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}.pagination{font-size:.75rem;padding:.625rem}.page-link{border-radius:6px;min-width:calc(1rem + .375rem + 2px);height:calc(1rem + .375rem + 2px);text-align:center;overflow:hidden}.page-link .f-icon{vertical-align:top}.page-link:focus{color:var(--f-theme-01);border-color:var(--f-theme-03)}.page-link.disabled{color:var(--f-text-07);background:var(--f-neutral-09);border-color:var(--f-neutral-05);box-shadow:none}.page-link:hover{color:var(--f-theme-05);background:var(--f-neutral-12);border-color:var(--f-theme-05)}.page-link:active{color:var(--f-theme-01);background:var(--f-neutral-12);border-color:var(--f-theme-01)}.page-item{margin:auto 3px}.pagination-lg .page-link{height:auto;width:auto}.page-item.current .page-link,.page-item.current:active .page-link,.page-item.current:hover .page-link{z-index:1;color:var(--f-text-00);background:var(--f-theme-06)!important;border-color:var(--f-theme-05);box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.15)}.page-item .page-link .f-icon{vertical-align:baseline}.pagination .pg-pagelist{margin:0 12px;height:100%}.pagination .pg-pagelist .pg-pagelist-info{font-size:13px;color:var(--f-text-02);cursor:pointer;height:100%;display:inline-flex;align-items:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pagination .pg-pagelist .pg-pagelist-info:hover,.pagination .pg-pagelist.show .pg-pagelist-info{color:var(--f-theme-03)}.pagination .pg-pagelist .pg-pagelist-info .cur-pagesize{padding:0 4px;font-size:15px;font-weight:600}.pagination .pg-pagelist .pg-pagelist-info .f-icon{font-size:12px;margin:0 0 0 8px;transition:transform .2s linear}.pagination .pg-pagelist .dropdown-menu{min-width:120px;margin-bottom:.25rem}.pagination .pg-pagelist .dropdown-menu .dropdown-item{padding-left:14px}.pagination .pagination-message{color:var(--f-text-02);font-size:13px;display:inline-flex;align-items:center;height:100%}.pagination .pagination-message .badge{font-size:13px}.pagination .pagination-message .pg-message-total{font-size:15px;font-weight:600;padding:0 4px;line-height:20px}.badge,.popover,.table thead th,.tooltip{font-weight:400}.farris-gotopagenumber{text-align:center;-moz-appearance:textfield;width:40px}.farris-gotopagenumber::-webkit-inner-spin-button,.farris-gotopagenumber::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.pagination-container .page-item.ellipsis>.page-link{background:0 0;border:none;box-shadow:none;line-height:8px;font-size:16px}.pagination-container .page-item.ellipsis:hover>.page-link{line-height:20px}.badge-round-success,.pagination-container .page-item.ellipsis:hover>.page-link>.f-icon{display:inline-block!important}@media screen and (max-width:601px){.ngx-pagination.responsive .small-screen{display:inline-block}.ngx-pagination.responsive li:not(.small-screen):not(.pagination-previous):not(.pagination-next){display:none}}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;font-style:normal;line-height:1.4286;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.75rem;word-wrap:break-word;background-color:rgba(var(--f-neutral-00-rgb),.9);background-clip:padding-box;border:1px solid var(--f-neutral-00);border-radius:4px;box-shadow:0 2px 8px 0 rgba(0,32,74,.15)}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 6px}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top] .arrow,.bs-popover-top .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom:0;border-top-color:rgba(var(--f-neutral-00-rgb),.4)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-top .arrow::after{bottom:1px;border-top-color:rgba(var(--f-neutral-00-rgb),.9)}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right] .arrow,.bs-popover-right .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:6px 0}.bs-popover-auto[x-placement^=left],.bs-popover-left,.bs3.bs-popover-auto[x-placement^=left],.bs3.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left:0;border-right-color:rgba(var(--f-neutral-00-rgb),.4)}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-right .arrow::after{left:1px;border-right-color:rgba(var(--f-neutral-00-rgb),.9)}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom] .arrow,.bs-popover-bottom .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(var(--f-neutral-00-rgb),.4)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;border-bottom-color:rgba(var(--f-neutral-00-rgb),.9)}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid rgba(var(--f-neutral-00-rgb),.9)}.bs-popover-auto[x-placement^=left] .arrow,.bs-popover-left .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:6px 0}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(var(--f-neutral-00-rgb),.4)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:rgba(var(--f-neutral-00-rgb),.9)}.popover-header{line-height:1;padding:.5rem .75rem;margin-bottom:0;font-size:.8125rem;color:var(--f-text-01);background-color:rgba(var(--f-neutral-00-rgb),.9);border-bottom:1px solid rgba(var(--f-neutral-00-rgb),.9);border-top-left-radius:calc(6px - 1px);border-top-right-radius:calc(6px - 1px)}.bs3.popover-top,.bs3.popover.top{margin-bottom:10px}.popover-header:empty{display:none}.popover-body{max-width:17.25rem;padding:.5rem .75rem;color:var(--f-text-02)}.bs3.popover.top>.arrow{margin-left:-2px}.popover.bottom>.arrow{margin-left:-4px}.bs3.bs-popover-auto[x-placement^=left] .arrow,.bs3.bs-popover-auto[x-placement^=right] .arrow,.bs3.bs-popover-left .arrow,.bs3.bs-popover-right .arrow{margin:.3rem 0}.bs-popover-bottom-left .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-bottom-left .arrow::before{top:0;border-bottom-color:rgba(255,255,255,.4)!important}.bs-popover-bottom-left .arrow::after,.bs-popover-bottom-left .arrow::before{border-width:0 .5rem .5rem}.bs-popover-bottom-left .arrow::after{top:1px;border-bottom-color:#fff!important}.popover.popover-fitcontent .popover-body{max-width:initial;padding:initial}.popover .arrow-left .arrow{left:calc(50% - 10px)}.f-progress-step .f-progress-step-list{display:flex;flex-direction:row;align-items:center}.f-progress-step .step{display:inline-block}.f-progress-step .step .f-progressstep-row{display:flex;position:relative;padding-right:.4375rem;padding-bottom:.9375rem}.f-progress-step .step .f-progressstep-row .f-progress-step-content{display:inline-block}.f-progress-step .step .f-progressstep-row .f-progress-step-content .step-icon{display:inline-block;width:1.875rem;height:1.875rem;margin-right:.5rem;margin-left:.5rem;line-height:1.875rem;border-radius:100%;font-size:.75rem;text-align:center;vertical-align:middle}.f-progress-step .step .f-progressstep-row .f-progress-step-content .f-progress-step-title{display:inline-block;vertical-align:middle}.f-progress-step .step .f-progressstep-row .f-progress-step-content .f-progress-step-title .step-message,.f-progress-step .step .f-progressstep-row .f-progress-step-content .f-progress-step-title .step-name{margin-bottom:0}.f-progress-step .step .f-progressstep-row .f-progress-step-content .f-progress-step-title .step-name{font-size:.875rem;line-height:1.25rem;padding-right:.625rem}.f-progress-step .step .f-progressstep-row .f-progress-step-content .f-progress-step-title .step-name.step-name-success{opacity:.85}.f-progress-step .step .f-progressstep-row .f-progress-step-line{flex:1 1 auto;position:relative;display:inline-flex;min-width:3.75rem;vertical-align:middle}.f-progress-step .step .f-progressstep-row .f-progress-step-line::after{content:"";left:0;height:.125rem;overflow:hidden;position:absolute;right:.625rem;top:50%;margin-top:-.0625rem}.f-progress-step .step .f-progressstep-row .f-progress-step-line .triangle{position:absolute;right:0;top:50%;display:inline-block;width:.4375rem;height:.4375rem;margin-top:-.21875rem;transform:rotate(45deg)}.f-progress-step .f-progress-step-list-block .step{display:block}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row{padding:0;flex-direction:column}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line{flex:1 1 auto;width:.625rem;min-width:.625rem;min-height:2.5rem;margin:.5rem 0 1.25rem 1.375rem}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line::after{content:"";border-top:0}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line .triangle{top:auto;left:-.3125rem;bottom:-.5rem;border-top:0}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line .f-progress-step-title .step-name{padding-right:.875rem}.f-progress-step .f-progress-step-horizontal-fill{display:flex;justify-content:space-between;flex-wrap:wrap}.f-progress-step .f-progress-step-horizontal-fill .step{flex:1 1 auto}.f-progress-step .f-progress-step-vertical-fill{display:flex;flex-direction:column;align-content:space-between}.f-progress-step .f-progress-step-vertical-fill .step{display:flex;flex:1 1 auto}.f-progress-step .f-progress-step-vertical-fill .step .f-progressstep-row{flex:1 1 auto;display:flex}.f-progress-step li.clickable{cursor:pointer}.f-progress-step li.click-disable{cursor:not-allowed}.f-progress-step .f-progress-step-empty{color:#000;opacity:.65;font-size:.875rem}.f-progress-step .f-progressstep-row-multi{display:flex;flex-direction:column;align-items:left}.f-progress-step .f-progressstep-row-multi .f-progressstep-multi-item-content{display:flex;flex-direction:row;align-items:center;cursor:pointer}.f-progress-step .f-progressstep-row-multi .f-step-multi-item{position:relative;padding-right:.4375rem;padding-bottom:.9375rem}.f-progress-step .f-progressstep-row-multi .f-step-multi-item:last-child{padding-bottom:0}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row.f-progressstep-row-multi{flex-direction:row}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row.f-progressstep-row-multi .f-step-multi-item{padding:0;flex-direction:column}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row.f-progressstep-row-multi .f-step-multi-item .f-progress-step-line{display:block}.f-progress-step .step .f-progressstep-row .f-progress-step-content .step-icon{color:#fff;background:var(--f-neutral-02)}.f-progress-step .step .f-progressstep-row .f-progress-step-content .f-progress-step-title .step-name{color:#8C8C8C}.f-progress-step .step .f-progressstep-row .f-progress-step-content .f-progress-step-title .step-name.step-name-success{color:var(--f-text-03)}.f-progress-step .step .f-progressstep-row .f-progress-step-line::after{border-top:2px dotted rgba(0,0,0,.2)}.f-progress-step .step .f-progressstep-row .f-progress-step-line .triangle{border-top:1px solid rgba(0,0,0,.2);border-right:1px solid rgba(0,0,0,.2)}.f-progress-step .step .f-progressstep-row .f-progress-step-line.f-progress-step-line-success .triangle,.f-progress-step .step .f-progressstep-row .f-progress-step-line.f-progress-step-line-success::after{border-color:var(--f-theme-03)}.f-progress-step .step .f-progressstep-row.step-finish .f-progress-step-content .step-icon{color:#fff;background:linear-gradient(135deg,#529DFF 0,#559FFF 100%)}.f-progress-step .step .f-progressstep-row.step-finish:hover .f-progress-step-content .step-icon{background:var(--f-theme-04)}.f-progress-step .step .f-progressstep-row.step-finish:active .f-progress-step-content .step-icon{background:var(--f-theme-02)}.f-progress-step .step .f-progressstep-row.step-active .f-progress-step-content .step-icon{color:#fff;background:var(--f-theme-04)}.f-progress-step .step .f-progressstep-row.step-active:hover .f-progress-step-content .step-icon{background:linear-gradient(135deg,#529DFF 0,#559FFF 100%)}.f-progress-step .step .f-progressstep-row.step-active:active .f-progress-step-content .step-icon{background:var(--f-theme-02)}.f-progress-step .step .f-progressstep-row.step-error .f-progress-step-content .step-icon{background:#F46160}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line{border-left:2px dotted rgba(0,0,0,.2)}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line .triangle{border-bottom:1px solid rgba(0,0,0,.2)}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line.f-progress-step-line-success,.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line.f-progress-step-line-success .triangle{border-color:var(--f-theme-05)}.f-progress-step .f-progress-step-empty{color:var(--f-text-05)}.f-progress-step .f-progressstep-row-multi .f-step-multi-item.f-step-multi-item-active .f-progress-step-title .step-name,.f-progress-step .f-progressstep-row-multi .f-step-multi-item.f-step-multi-item-finish .f-progress-step-title .step-name{color:var(--f-text-03)!important}.f-progress-step .f-progressstep-row-multi .f-step-multi-item.f-step-multi-item-active .step-icon{background:var(--f-theme-04)}.f-progress-step .f-progressstep-row-multi .f-step-multi-item.f-step-multi-item-finish .step-icon,.f-progress-step .f-progressstep-row-multi .f-step-multi-item:hover.f-step-multi-item-active .step-icon{background:linear-gradient(135deg,#529DFF 0,#559FFF 100%)}.f-progress-step .f-progressstep-row-multi .f-step-multi-item:hover.f-step-multi-item-finish .step-icon{background:var(--f-theme-04)}.f-progress{display:inline-block;font-size:.875rem;color:rgba(0,0,0,.65)}.f-progress.f-progress-line{position:relative;width:100%}.f-progress.f-progress-line .f-progress-text .f-progress-text-icon{font-size:1.25rem}.f-progress .f-progress-outer{display:inline-block;width:100%}.f-progress .f-progress-inner{position:relative;display:inline-block;width:100%;overflow:hidden;vertical-align:middle;background-color:#efefef;border-radius:100px}.f-progress .f-progress-bg,.f-progress .f-progress-success-bg{position:relative;border-radius:100px;transition:all .4s cubic-bezier(.08,.82,.17,1) 0s}.f-progress .f-progress-success-bg{position:absolute;top:0;left:0}.f-progress .f-progress-text{display:inline-block;width:1.75rem;margin-left:.5rem;color:rgba(0,0,0,.65);font-size:1em;line-height:1;white-space:nowrap;text-align:left;vertical-align:middle;word-break:normal}.f-progress-status-active .f-progress-bg::before{position:absolute;top:0;right:0;bottom:0;left:0;background:#fff;border-radius:.625rem;opacity:0;animation:f-progress-active 2.4s ease-in-out infinite;content:""}.condition-with-line.farris-form-controls-inline .input-group,.query-solution .farris-panel{border:none}.f-progress-show-info .f-progress-outer{padding-right:48px;margin-right:-48px}.f-progress.f-progress-circle .f-progress-inner{position:relative;line-height:1;background-color:transparent}.f-progress.f-progress-circle .f-progress-text{position:absolute;top:50%;left:50%;width:100%;margin:0;padding:0;color:rgba(0,0,0,.65);line-height:1;white-space:normal;text-align:center;transform:translate(-50%,-50%)}.f-progress.f-progress-circle .f-progress-text .f-progress-text-icon{font-size:1.3em}@keyframes f-progress-active{0%{width:0;opacity:.1}20%{width:0;opacity:.5}100%{width:100%;opacity:0}}.f-progress .f-progress-bg{background:var(--f-theme-04)}.f-progress .f-progress-success-bg,.f-progress-status-success .f-progress-bg{background:var(--f-semantic-success-01)}.f-progress-status-error .f-progress-bg{background:var(--f-semantic-danger-01)}.f-progress.f-progress-circle .f-progress-text .f-progress-text-icon.f-icon-checkmark{color:var(--f-semantic-success-01)}.f-progress.f-progress-circle .f-progress-text .f-progress-text-icon.f-icon-x{color:var(--f-semantic-danger-01)}.f-progress .f-progress-inner:not(.f-progress-circle-gradient) .f-progress-circle-path{stroke:var(--f-semantic-info-01)}.f-progress-status-success .f-progress-inner:not(.f-progress-circle-gradient) .f-progress-circle-path{stroke:var(--f-semantic-success-01)}.f-progress-status-error .f-progress-inner:not(.f-progress-circle-gradient) .f-progress-circle-path{stroke:var(--f-semantic-danger-01)}.farris-star-rating{cursor:pointer;display:flex;position:relative}.farris-star-rating .default-light-color{color:#FBDB10}.farris-star-rating .default-dark-color{color:#E8E8E8}.star-dark-area span,.star-light-area span{box-sizing:content-box;padding-right:4px}.farris-star-rating .f-star-sm{font-size:14px}.farris-star-rating .f-star-md{font-size:16px}.farris-star-rating .f-star-lg{font-size:18px}.farris-star-rating .f-star-exlarge{font-size:24px}.farris-star-rating .star-dark-area{overflow:hidden;display:flex;flex-wrap:nowrap}.farris-star-rating .f-utils-fill{padding-left:2px;font-size:14px}.farris-star-rating .font-small{line-height:14px}.farris-star-rating .font-middle{line-height:16px}.farris-star-rating .font-large{line-height:18px}.farris-star-rating .font-exlarge{line-height:24px}.farris-star-rating .star-light-area{position:absolute;left:0;top:0;z-index:2;width:0%;overflow:hidden;display:flex;flex-wrap:nowrap}.farris-star-rating .star-dark-area span,.farris-star-rating .star-light-area span{flex-shrink:0}.f-toolbar{flex-shrink:0;display:inline-flex;align-items:center;justify-content:flex-end}.f-toolbar .f-btn-separator{display:inline-block;width:1px;background-color:#c2cbd1;height:1em;margin:0 .5rem}.f-response-toolbar{display:block}.f-response-toolbar-lg .btn{line-height:1.4286;padding:.25rem 1.125rem}.f-response-toolbar-sm .btn{line-height:1.4286;padding:.125rem .5rem}.query-solution .solution-header{height:auto!important;margin-bottom:10px!important;display:flex;align-items:center;justify-content:space-between}.query-solution .solution-header-title{padding:.25rem 6px .25rem 12px;border-radius:6px;display:flex;flex-direction:row;align-items:center;color:var(--f-theme-03);font-size:.8125rem;vertical-align:middle;cursor:pointer}.query-solution .solution-header-title .header-title--change{margin:0 4px}.query-solution .solution-header-title .solution-header-title-text{margin-right:6px;overflow:hidden;height:22px}.query-solution .solution-header-title .f-accordion-expand{color:var(--f-theme-03)}.query-solution .solution-header-title .f-icon{font-size:16px;margin:0;width:auto;height:auto}.query-solution .solution-action{display:flex;align-items:center;flex-shrink:0}.query-solution .solution-action .dropdown .btn{border:0}.query-solution .solution-action .icon-group{display:flex!important;align-items:center}.query-solution .solution-action .icon-group .f-icon-remove{color:var(--f-text-02);background:var(--f-neutral-12);border:1px solid var(--f-neutral-08);border-radius:6px;width:calc(1.5rem + .125rem);height:calc(1.5rem + .125rem);text-align:center;line-height:20px;display:block}.query-solution .solution-action .icon-group .f-icon-remove:hover{border-color:var(--f-theme-05);color:var(--f-theme-05);background:var(--f-neutral-12)}.query-solution .solution-action .icon-group .f-icon-home-setup,.query-solution .solution-action .icon-group .f-icon-packup{font-size:.875rem}.query-solution .solution-action .icon-group .icon-group-packup{margin-right:0;margin-left:4px}.query-solution .solution-action span{vertical-align:inherit}.query-solution .solution-action .divide{color:var(--f-neutral-13);position:relative;margin:0 .3125rem}.query-solution .solution-action .divide::after{position:absolute;content:"";height:12px;width:1px;background-color:var(--f-neutral-13);left:0;top:50%;margin-top:-6px}.query-solution .solution-header-title-menu{margin-top:8px}.query-solution .solution-header-title-menu-inner{position:relative;width:18.9375rem}.query-solution .solution-header-title-menu-inner .menu-item--change{margin:0 4px 0 0}.query-solution .solution-header-title-menu-inner .solution-header-title-menu-arrow{position:absolute;content:"";display:block;left:1.5rem;top:-.5rem;width:8.49px;height:8.49px;background:0 0;border-style:solid;border-width:4.24px;box-shadow:-2px -2px 5px rgba(0,0,0,.08);transform:translateX(-50%) rotate(45deg);border-color:#fff transparent transparent #fff}.query-solution .solution-header-title-menu-inner .solution-header-dropdown-item{cursor:pointer;display:flex;flex-direction:row;align-items:center}.query-solution .solution-header-title-menu-inner .solution-header-dropdown-item.solution-header-dropdown-item-active{background:var(--f-neutral-10)}.query-solution .solution-header-title-menu-inner .solution-header-dropdown-item .solution-header-dropdown-item-title{flex-shrink:1;flex-grow:1;flex-basis:0;padding-right:.25rem;color:var(--f-text-02);font-size:.875rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.query-solution .solution-header-title-menu-inner .solution-header-dropdown-item .solution-header-dropdown-item-tip{flex-shrink:0;height:1.125rem;min-width:2.5rem;padding:0 4px;line-height:1.125rem;font-size:.75rem;background:var(--f-semantic-success-01);color:#fff;border-radius:2px;text-align:center}.query-solution .solution-header-title-menu-inner .solution-header-dropdown-item .solution-header-dropdown-item-public{flex-shrink:0;height:1.125rem;min-width:2.5rem;padding:0 4px;line-height:1.125rem;font-size:.75rem;background:#2a87ff;color:#fff;border-radius:2px;text-align:center}.query-solution .solution-header-title-menu-inner .solution-header-dropdown-item-btns{display:flex;flex-direction:row;align-items:center;justify-content:flex-end;height:2.25rem;padding:0 .875rem;line-height:2.25rem;border-top:1px solid rgba(0,0,0,.07)}.query-solution .solution-header-title-menu-inner .solution-header-dropdown-item-btns .dropdown-item-btn{margin-left:.5rem;color:var(--f-theme-03);cursor:pointer}.query-solution .summary-condition{flex-shrink:0;flex-grow:1;flex-basis:0;overflow:hidden;margin:0 12px 0 0;display:flex}.query-solution .summary-condition--item .summary-condition--label,.summary-list--tips .summary-condition--label{margin:0 2px 0 0}.query-solution .summary-list{overflow:hidden}.query-solution .summary-condition-wrapper{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;background:var(--f-aid-02);border:1px solid var(--f-aid-01);border-radius:3px;font-size:13px;color:#2D2F33;line-height:24px;height:26px;box-shadow:0 1px 4px 0 rgba(0,28,65,.08)}.query-solution .summary-condition--item{padding:0 12px;vertical-align:top}.query-solution .summary-condition--item .summary-condition--text{margin:0 0 0 8px}.query-solution .summary-condition--spliter{width:1px;height:14px;background:#DDE1EB;display:inline-block;margin:5px 0 0}.query-solution{padding:16px;background:#fff}.query-solution .solution-header .dropdown-item{width:100%}.query-solution .solution-header-title{max-width:288px;background:unset}.query-solution .solution-header .dropdown-menu{max-height:unset}.query-solution .solution-header-title-btns{border-top:1px solid rgba(0,0,0,.07);text-align:right;width:100%;color:#2A87FF;padding:8px 0}.solutionmanager-inner{padding:0 14px;flex:1;height:100%}.solutionmanager-inner .solutionmanager-grid-delete{font-size:.875rem;color:var(--f-theme-03)}.summary-list--tips .summary-condition--text{margin:0 0 0 8px}.summary-list--tips .summary-condition--gutter{margin:0 10px 0 4px}.summary-list--tips .tooltip{margin-top:-6px}.summary-list--tips .tooltip-inner{text-align:left;background:rgba(var(--f-neutral-00-rgb),.95);color:var(--f-text-02);font-size:13px;line-height:24px}.summary-list--tips .arrow{left:35px!important}.summary-list--tips .arrow::before{border-width:0 .3rem .3rem;border-bottom-color:rgba(var(--f-neutral-00-rgb),.4)}.farris-form.condition-div{margin-right:-5px;margin-left:-5px}.farris-form.condition-div .qlabel-gutter{display:none}.farris-form.condition-div>[class*=col-]{padding-left:5px!important;padding-right:5px!important}.condition-with-line.farris-form-controls-inline .qlabel-gutter{display:inline;margin-left:2px}.condition-with-line.farris-form-controls-inline .qradio-group .qlabel-gutter{margin-right:8px}.condition-with-line.farris-form-controls-inline .farris-input-wrap{flex-basis:0}.condition-with-line.farris-form-controls-inline .common-group{border:1px solid #D8DCE6;border-radius:3px;padding-left:8px;padding-right:1px}.condition-with-line.farris-form-controls-inline .common-group .col-form-label{font-size:13px;color:#6A6F79;width:auto;margin-right:0;flex-grow:0;flex-shrink:1;flex-basis:auto;max-width:220px}.f-cmp-inputgroup .f-transfer-date .search-tag-item.search-field:hover,.f-search-box .search-tag-item.search-field:hover,.querycondition-advanced .add-condition-btn{color:var(--f-theme-03)}.condition-with-line.farris-form-controls-inline .common-group .f-solution-radio-group{flex-shrink:1;flex-grow:1;flex-basis:0}.condition-with-line.farris-form-controls-inline .common-group .input-group,.condition-with-line.farris-form-controls-inline .common-group .input-group.f-state-focus{outline:0;box-shadow:none;border:none}.condition-with-line.farris-form-controls-inline .common-group:not(.q-state-readonly):hover{border-color:var(--f-theme-08);box-shadow:0 0 0,0 0 4px 2px rgba(99,136,255,.12)}.condition-with-line.farris-form-controls-inline .farris-group-multi-label .farris-group-wrap .col-form-label .farris-label-text{text-align:left}.condition-with-fixed.farris-form-controls-inline .datepicker-range-group .farris-input-wrap,.condition-with-fixed.farris-form-controls-inline .number-range-group .farris-input-wrap{min-width:120px}.condition-with-line.f-form-label-xl .farris-group-wrap .col-form-label{max-width:153px}.query-solution .condition-div{max-height:204px;overflow-y:auto}.querycondition-advanced .add-condition-btn .f-icon{background-color:var(--f-aid-03)}.query-solution .farris-input-wrap.farris-checkradio-hor{overflow-x:auto;flex-wrap:nowrap;white-space:nowrap;width:100%}.query-solution .solution-header .solution-header-item-active{background:#F7F7F7}.f-search-box-panel{height:100%;z-index:9998;position:absolute;overflow:auto;background:var(--f-neutral-20);box-shadow:0 2px 20px 0 rgba(3,18,51,.12);border-radius:3px}.f-search-field-container .switch.switch-small{min-width:1.88rem;height:.85rem}.f-search-field-container .switch.switch-small small{top:0}.multi-date-display:empty:before{color:var(--f-text-09)}.f-cmp-inputgroup .f-transfer-date .search-tag-item,.f-search-box .search-tag-item{cursor:default;padding:0 20px 0 5px!important;background:var(--f-aid-04)!important;border:1px solid var(--f-aid-05);position:relative;margin-right:3px!important;margin-top:1px!important;margin-bottom:0!important;line-height:19px;height:22px;float:left;max-width:200px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;display:inline!important;border-radius:6px}.f-cmp-inputgroup .f-transfer-date .search-tag-item .f-icon,.f-search-box .search-tag-item .f-icon{cursor:pointer;position:absolute;right:2px;font-size:12px;top:7px}.f-cmp-inputgroup .f-transfer-date .search-tag-item.search-field,.f-search-box .search-tag-item.search-field{background:0 0;border:0;cursor:pointer;height:26px;line-height:24px}.f-cmp-inputgroup .f-transfer-date .search-tag-item.search-field:hover.search-field-remove>.f-icon::before,.f-search-box .search-tag-item.search-field:hover.search-field-remove>.f-icon::before{content:"\e11b"}.f-cmp-inputgroup .f-transfer-date .search-tag-item.search-field.selected,.f-search-box .search-tag-item.search-field.selected{background:rgba(207,237,255,.35);border-color:var(--f-aid-05)}.f-cmp-inputgroup .f-transfer-date .search-tag-item.search-field.has-filter,.f-search-box .search-tag-item.search-field.has-filter{background-color:#f2f8ff;border:1px solid #e4f0ff}.f-cmp-inputgroup .f-transfer-date .inputbox,.f-search-box .inputbox{flex:1;position:relative;min-width:50px;height:24px;margin:0;padding:0;float:left;overflow:hidden}.f-cmp-inputgroup .f-transfer-date.f-search-fields .multi--item.search-tag-item,.f-cmp-inputgroup .f-transfer-date.f-search-shadow-fields .multi--item.search-tag-item,.f-search-box.f-search-fields .multi--item.search-tag-item,.f-search-box.f-search-shadow-fields .multi--item.search-tag-item{margin-bottom:4px!important}.f-cmp-inputgroup .f-transfer-date .search-input,.f-search-box .search-input{position:absolute;top:0;align-items:center;display:flex;left:-2px;width:100%}.f-cmp-inputgroup .f-transfer-date.f-search-shadow-fields.active,.f-search-box.f-search-shadow-fields.active{border-color:var(--f-theme-05)}.f-cmp-inputgroup .f-transfer-date.f-search-fields .more,.f-search-box.f-search-fields .more{padding-right:20px}.f-cmp-inputgroup .f-transfer-date.f-search-fields .more::after,.f-search-box.f-search-fields .more::after{content:"...";position:absolute;right:10px;top:0;cursor:pointer}.f-cmp-inputgroup .f-transfer-date.f-state-disabled .search-tag-item{background:var(--f-neutral-09);border-color:var(--f-neutral-09);color:var(--f-text-02)}.f-cmp-inputgroup .f-transfer-date.f-state-disabled .multi--more-text{color:var(--f-text-09)}.search-tip-info{height:32px;line-height:32px;border-bottom:1px solid var(--f-neutral-04);font-size:12px;color:#848C9A;margin-bottom:5px;padding:0 7px;align-items:center;justify-content:space-between}.search-tip-info .f-icon-close,.search-tip-info .f-icon-group-delete::before{cursor:pointer;top:2px;position:relative;right:-5px;font-size:12px}.search-tip-info .f-icon-close:hover,.search-tip-info .f-icon-group-delete:hover::before{color:red}.lookup-filter-bar .clear-search-fields{width:28px;height:28px;display:flex;align-items:center;justify-content:center;border:1px solid var(--f-neutral-04);margin-left:3px;border-radius:3px;cursor:pointer}.lookup-filter-bar .clear-search-fields:hover{color:var(--f-aid-10);border-color:var(--f-theme-05)}.search-box-container{background-color:#fff;background-clip:padding-box}.search-box-container-title{color:#878d99;text-align:left;margin-bottom:10px}.f-section{display:flex;flex-direction:column;position:relative;padding:.625rem .875rem .75rem;margin:0;border-radius:8px;background:#fff}.f-section.f-section-fill{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.f-section.f-section-fill>.f-section-content{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column;min-height:0}.f-section.f-section-content-fill{display:flex;flex-direction:column}.f-section.f-section-content-fill .f-section-content{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column}.f-section-header{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:space-between;padding:0 .625rem 0 0;margin:0 0 .5rem}.f-section-header .f-title::before .f-content{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.f-section-header .f-toolbar{flex-shrink:0;display:inline-flex;align-items:center;justify-content:flex-end;color:var(--f-text-04);margin-left:auto}.f-section-header .f-btn-collapse-expand span,.f-section.f-state-collapse>.f-section-extend{display:none}.f-section-header .f-btn-collapse-expand{color:var(--f-theme-03)}.f-section-header .f-btn-collapse-expand::after{width:1rem;height:1rem;font-size:.875rem;line-height:1rem;margin-left:0;color:var(--f-text-07);background:var(--f-neutral-07);border-radius:10px}.f-section-header .f-btn-collapse-expand:hover::after{background:var(--f-neutral-05)}.f-section-header .f-max-accordion .f-icon-maximize,.f-section-header .f-max-accordion .f-icon-minimize{color:var(--f-text-03);font-size:14px;cursor:pointer;margin-left:.5rem;vertical-align:middle}.f-section-header .f-max-accordion .f-icon-maximize:hover,.f-section-header .f-max-accordion .f-icon-minimize:hover{color:var(--f-theme-05)}.f-section-header .f-max-accordion .f-icon-maximize:active,.f-section-header .f-max-accordion .f-icon-minimize:active{color:var(--f-theme-01)}.f-section-extend{margin:0 0 .75rem}.f-section-accordion.f-state-collapse>.f-section-header{margin-bottom:0}.f-section-accordion.f-state-collapse>.f-section-content{height:0;overflow:hidden;flex:0 1 0!important}.f-section-maximize{position:fixed;top:0;bottom:0;left:0;right:0;z-index:1031;background:var(--f-neutral-19)}.f-section-maximize>.f-section-content{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column;overflow-y:auto;overflow-x:hidden}.f-section-maximize>.f-section-content>.f-struct-is-subgrid{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column}.f-section-maximize>.f-section-content>.f-struct-is-subgrid .f-grid-is-sub{flex-shrink:1;flex-grow:1;flex-basis:0;height:auto}.f-section-maximize .f-tabs-content-fill .f-struct-is-subgrid{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column}.f-section-maximize .f-tabs-content-fill .f-grid-is-sub{flex-shrink:1;flex-grow:1;flex-basis:0;height:auto}.f-section-form.f-section-custom-accordion.f-state-collapse .f-form-layout>:not(.f-state-visible),.f-section-form.f-section-custom-accordion.f-state-collapse .f-section-formgroup-inputs>:not(.f-state-visible),.f-section-form.f-section-custom-accordion.f-state-collapse .f-section-formgroup.f-state-visible>:not(.f-state-visible){display:none}.f-section-form.f-section-custom-accordion.f-state-collapse .f-section-formgroup-inputs.f-state-visible-all>*{display:initial}.f-section-nogap::before,.f-section-nogutter::before{display:none!important}.f-section-tabs{padding:0 .875rem 1rem}.f-section-treegrid.f-section-in-nav{flex-shrink:1;flex-grow:1;flex-basis:0}.f-section-treegrid.f-section-in-nav>.f-section-content{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column}.f-section-treegrid.f-section-in-nav>.f-section-content .f-componet-treetable{flex-shrink:1;flex-grow:1;flex-basis:0}.f-section--header-manage .f-section-header .f-title::before{background:linear-gradient(135deg,#4190FF 0,#657CFF 100%)!important}.f-section--header-dict .f-section-header .f-title::before{background:linear-gradient(135deg,#4EC87A 0,#52D389 100%)!important}.f-section--header-bill .f-section-header .f-title::before{background:linear-gradient(135deg,#1FC8DC 0,#41D2BD 100%)!important}.f-section--header-query .f-section-header .f-title::before{background:linear-gradient(135deg,#FC8249 0,#FE9539 100%)!important}.f-section--header-param .f-section-header .f-title::before{background:linear-gradient(135deg,#8B82FF 0,#A082FF 100%)!important}.f-page-main .f-section-like-query.f-section,.f-page-main .f-section-query.f-section{margin:0}.f-title-noline{padding-left:0}.f-title-noline::before{display:none}.f-section .f-section-content--toolbar{padding:0 0 0 .75rem;margin-top:.40625rem;margin-bottom:.40625rem}.f-section .f-section-header--toolbar{overflow:hidden;flex:1;margin-left:.875rem!important}.f-splitter{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:row;flex-wrap:nowrap;overflow:hidden;position:relative}.f-splitter-pane{position:relative;padding:0}.f-splitter-pane.f-splitter-pane-main{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:auto;display:flex}.f-splitter-pane>.f-splitter-resize-bar{position:absolute;font-size:.1px;display:block;touch-action:none}.f-splitter-pane>.f-splitter-resize-bar:hover{background:rgba(42,135,255,.07)}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-e{cursor:e-resize;width:.4375rem;right:-.3125rem;height:100%;top:0}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-w{cursor:w-resize;width:.4375rem;left:-.3125rem;height:100%;top:0}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s{cursor:s-resize;height:.4375rem;bottom:-.3125rem;width:100%;left:0}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n{cursor:n-resize;height:.4375rem;top:-.3125rem;width:100%;left:0}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-e::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-w::before{content:"";position:absolute;background:#E9ECF3}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-e::after,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n::after,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s::after,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-w::after{content:"";position:absolute;top:50%;left:50%;width:6px;height:60px;margin:-30px 0 0 -3px;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjdweCIgaGVpZ2h0PSI2MHB4IiB2aWV3Qm94PSIwIDAgNyA2MCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDY0ICg5MzUzNykgLSBodHRwczovL3NrZXRjaC5jb20gLS0+DQogICAgPHRpdGxlPue8lue7hCAyMjwvdGl0bGU+DQogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+DQogICAgPGcgaWQ9IuaWsOeJiCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+DQogICAgICAgIDxnIGlkPSI2LuW3puagkeWPs+S4u+S7jiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQ1NS4wMDAwMDAsIC00MTguMDAwMDAwKSI+DQogICAgICAgICAgICA8ZyBpZD0i57yW57uELTIyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0NTUuNTAwMDAwLCA0MTguMDAwMDAwKSI+DQogICAgICAgICAgICAgICAgPHBhdGggZD0iTTMsMCBDNSwxLjc3NTIwMjYgNiwzLjE3ODcxMTM4IDYsNC4yMTA1MjYzMiBDNiwxMi4xMDQzMjc2IDYsNTMuNzk4NDE1MyA2LDU1Ljc4OTQ3MzcgQzYsNTYuNzEzMzQ4NiA1LDU4LjExNjg1NzQgMyw2MCBDMSw1OC4xMTAyOTA0IDAsNTYuNzA2NzgxNiAwLDU1Ljc4OTQ3MzcgQzAsMzMuMDcyNzA3MSAwLDE1Ljg5NDM0MTIgMCw0LjIxMDUyNjMyIEMwLDMuMzUxODIxNjQgMSwxLjk0ODMxMjg3IDMsMCBaIiBpZD0i55+p5b2iIiBmaWxsPSIjRTlFQ0YzIj48L3BhdGg+DQogICAgICAgICAgICAgICAgPHBhdGggZD0iTTMsNDUgQzMuNTUyMjg0NzUsNDUgNCw0NS40NDc3MTUzIDQsNDYgQzQsNDYuNTUyMjg0NyAzLjU1MjI4NDc1LDQ3IDMsNDcgQzIuNDQ3NzE1MjUsNDcgMiw0Ni41NTIyODQ3IDIsNDYgQzIsNDUuNDQ3NzE1MyAyLjQ0NzcxNTI1LDQ1IDMsNDUgWiBNMyw0MSBDMy41NTIyODQ3NSw0MSA0LDQxLjQ0NzcxNTMgNCw0MiBDNCw0Mi41NTIyODQ3IDMuNTUyMjg0NzUsNDMgMyw0MyBDMi40NDc3MTUyNSw0MyAyLDQyLjU1MjI4NDcgMiw0MiBDMiw0MS40NDc3MTUzIDIuNDQ3NzE1MjUsNDEgMyw0MSBaIE0zLDM3IEMzLjU1MjI4NDc1LDM3IDQsMzcuNDQ3NzE1MyA0LDM4IEM0LDM4LjU1MjI4NDcgMy41NTIyODQ3NSwzOSAzLDM5IEMyLjQ0NzcxNTI1LDM5IDIsMzguNTUyMjg0NyAyLDM4IEMyLDM3LjQ0NzcxNTMgMi40NDc3MTUyNSwzNyAzLDM3IFogTTMsMzMgQzMuNTUyMjg0NzUsMzMgNCwzMy40NDc3MTUzIDQsMzQgQzQsMzQuNTUyMjg0NyAzLjU1MjI4NDc1LDM1IDMsMzUgQzIuNDQ3NzE1MjUsMzUgMiwzNC41NTIyODQ3IDIsMzQgQzIsMzMuNDQ3NzE1MyAyLjQ0NzcxNTI1LDMzIDMsMzMgWiBNMywyOSBDMy41NTIyODQ3NSwyOSA0LDI5LjQ0NzcxNTMgNCwzMCBDNCwzMC41NTIyODQ3IDMuNTUyMjg0NzUsMzEgMywzMSBDMi40NDc3MTUyNSwzMSAyLDMwLjU1MjI4NDcgMiwzMCBDMiwyOS40NDc3MTUzIDIuNDQ3NzE1MjUsMjkgMywyOSBaIE0zLDI1IEMzLjU1MjI4NDc1LDI1IDQsMjUuNDQ3NzE1MyA0LDI2IEM0LDI2LjU1MjI4NDcgMy41NTIyODQ3NSwyNyAzLDI3IEMyLjQ0NzcxNTI1LDI3IDIsMjYuNTUyMjg0NyAyLDI2IEMyLDI1LjQ0NzcxNTMgMi40NDc3MTUyNSwyNSAzLDI1IFogTTMsMjEgQzMuNTUyMjg0NzUsMjEgNCwyMS40NDc3MTUzIDQsMjIgQzQsMjIuNTUyMjg0NyAzLjU1MjI4NDc1LDIzIDMsMjMgQzIuNDQ3NzE1MjUsMjMgMiwyMi41NTIyODQ3IDIsMjIgQzIsMjEuNDQ3NzE1MyAyLjQ0NzcxNTI1LDIxIDMsMjEgWiBNMywxNyBDMy41NTIyODQ3NSwxNyA0LDE3LjQ0NzcxNTMgNCwxOCBDNCwxOC41NTIyODQ3IDMuNTUyMjg0NzUsMTkgMywxOSBDMi40NDc3MTUyNSwxOSAyLDE4LjU1MjI4NDcgMiwxOCBDMiwxNy40NDc3MTUzIDIuNDQ3NzE1MjUsMTcgMywxNyBaIE0zLDEzIEMzLjU1MjI4NDc1LDEzIDQsMTMuNDQ3NzE1MyA0LDE0IEM0LDE0LjU1MjI4NDcgMy41NTIyODQ3NSwxNSAzLDE1IEMyLjQ0NzcxNTI1LDE1IDIsMTQuNTUyMjg0NyAyLDE0IEMyLDEzLjQ0NzcxNTMgMi40NDc3MTUyNSwxMyAzLDEzIFoiIGlkPSLlvaLnirbnu5PlkIgiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4NCiAgICAgICAgICAgIDwvZz4NCiAgICAgICAgPC9nPg0KICAgIDwvZz4NCjwvc3ZnPg==);background-repeat:no-repeat;background-size:cover;background-position:center center}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-e:hover,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n:hover,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s:hover,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-w:hover{background:0 0}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-e:hover::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n:hover::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s:hover::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-w:hover::before{background-image:linear-gradient(214deg,#3F65FF 0,#4D9AFF 100%);box-shadow:0 2px 5px 0 rgba(42,135,255,.2)}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-e:hover::after,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n:hover::after,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s:hover::after,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-w:hover::after{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjdweCIgaGVpZ2h0PSI2MHB4IiB2aWV3Qm94PSIwIDAgNyA2MCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDY0ICg5MzUzNykgLSBodHRwczovL3NrZXRjaC5jb20gLS0+DQogICAgPHRpdGxlPue8lue7hCAyMjwvdGl0bGU+DQogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+DQogICAgPGRlZnM+DQogICAgICAgIDxsaW5lYXJHcmFkaWVudCB4MT0iNTAuMzcxODk3MSUiIHkxPSIwJSIgeDI9IjQ5LjY4MjQwNDUlIiB5Mj0iMTAwJSIgaWQ9ImxpbmVhckdyYWRpZW50LTEiPg0KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzNGNjVGRiIgb2Zmc2V0PSIwJSI+PC9zdG9wPg0KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzREOUFGRiIgb2Zmc2V0PSIxMDAlIj48L3N0b3A+DQogICAgICAgIDwvbGluZWFyR3JhZGllbnQ+DQogICAgPC9kZWZzPg0KICAgIDxnIGlkPSLmlrDniYgiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPg0KICAgICAgICA8ZyBpZD0iNi7lt6bmoJHlj7PkuLvku47lpIfku70tMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQ1NS4wMDAwMDAsIC00MTguMDAwMDAwKSI+DQogICAgICAgICAgICA8ZyBpZD0i57yW57uELTIyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0NTUuNTAwMDAwLCA0MTguMDAwMDAwKSI+DQogICAgICAgICAgICAgICAgPHBhdGggZD0iTTMsMCBDNSwxLjc3NTIwMjYgNiwzLjE3ODcxMTM4IDYsNC4yMTA1MjYzMiBDNiwxMi4xMDQzMjc2IDYsNTMuNzk4NDE1MyA2LDU1Ljc4OTQ3MzcgQzYsNTYuNzEzMzQ4NiA1LDU4LjExNjg1NzQgMyw2MCBDMSw1OC4xMTAyOTA0IDAsNTYuNzA2NzgxNiAwLDU1Ljc4OTQ3MzcgQzAsMzMuMDcyNzA3MSAwLDE1Ljg5NDM0MTIgMCw0LjIxMDUyNjMyIEMwLDMuMzUxODIxNjQgMSwxLjk0ODMxMjg3IDMsMCBaIiBpZD0i55+p5b2iIiBmaWxsPSJ1cmwoI2xpbmVhckdyYWRpZW50LTEpIj48L3BhdGg+DQogICAgICAgICAgICAgICAgPHBhdGggZD0iTTMsNDUgQzMuNTUyMjg0NzUsNDUgNCw0NS40NDc3MTUzIDQsNDYgQzQsNDYuNTUyMjg0NyAzLjU1MjI4NDc1LDQ3IDMsNDcgQzIuNDQ3NzE1MjUsNDcgMiw0Ni41NTIyODQ3IDIsNDYgQzIsNDUuNDQ3NzE1MyAyLjQ0NzcxNTI1LDQ1IDMsNDUgWiBNMyw0MSBDMy41NTIyODQ3NSw0MSA0LDQxLjQ0NzcxNTMgNCw0MiBDNCw0Mi41NTIyODQ3IDMuNTUyMjg0NzUsNDMgMyw0MyBDMi40NDc3MTUyNSw0MyAyLDQyLjU1MjI4NDcgMiw0MiBDMiw0MS40NDc3MTUzIDIuNDQ3NzE1MjUsNDEgMyw0MSBaIE0zLDM3IEMzLjU1MjI4NDc1LDM3IDQsMzcuNDQ3NzE1MyA0LDM4IEM0LDM4LjU1MjI4NDcgMy41NTIyODQ3NSwzOSAzLDM5IEMyLjQ0NzcxNTI1LDM5IDIsMzguNTUyMjg0NyAyLDM4IEMyLDM3LjQ0NzcxNTMgMi40NDc3MTUyNSwzNyAzLDM3IFogTTMsMzMgQzMuNTUyMjg0NzUsMzMgNCwzMy40NDc3MTUzIDQsMzQgQzQsMzQuNTUyMjg0NyAzLjU1MjI4NDc1LDM1IDMsMzUgQzIuNDQ3NzE1MjUsMzUgMiwzNC41NTIyODQ3IDIsMzQgQzIsMzMuNDQ3NzE1MyAyLjQ0NzcxNTI1LDMzIDMsMzMgWiBNMywyOSBDMy41NTIyODQ3NSwyOSA0LDI5LjQ0NzcxNTMgNCwzMCBDNCwzMC41NTIyODQ3IDMuNTUyMjg0NzUsMzEgMywzMSBDMi40NDc3MTUyNSwzMSAyLDMwLjU1MjI4NDcgMiwzMCBDMiwyOS40NDc3MTUzIDIuNDQ3NzE1MjUsMjkgMywyOSBaIE0zLDI1IEMzLjU1MjI4NDc1LDI1IDQsMjUuNDQ3NzE1MyA0LDI2IEM0LDI2LjU1MjI4NDcgMy41NTIyODQ3NSwyNyAzLDI3IEMyLjQ0NzcxNTI1LDI3IDIsMjYuNTUyMjg0NyAyLDI2IEMyLDI1LjQ0NzcxNTMgMi40NDc3MTUyNSwyNSAzLDI1IFogTTMsMjEgQzMuNTUyMjg0NzUsMjEgNCwyMS40NDc3MTUzIDQsMjIgQzQsMjIuNTUyMjg0NyAzLjU1MjI4NDc1LDIzIDMsMjMgQzIuNDQ3NzE1MjUsMjMgMiwyMi41NTIyODQ3IDIsMjIgQzIsMjEuNDQ3NzE1MyAyLjQ0NzcxNTI1LDIxIDMsMjEgWiBNMywxNyBDMy41NTIyODQ3NSwxNyA0LDE3LjQ0NzcxNTMgNCwxOCBDNCwxOC41NTIyODQ3IDMuNTUyMjg0NzUsMTkgMywxOSBDMi40NDc3MTUyNSwxOSAyLDE4LjU1MjI4NDcgMiwxOCBDMiwxNy40NDc3MTUzIDIuNDQ3NzE1MjUsMTcgMywxNyBaIE0zLDEzIEMzLjU1MjI4NDc1LDEzIDQsMTMuNDQ3NzE1MyA0LDE0IEM0LDE0LjU1MjI4NDcgMy41NTIyODQ3NSwxNSAzLDE1IEMyLjQ0NzcxNTI1LDE1IDIsMTQuNTUyMjg0NyAyLDE0IEMyLDEzLjQ0NzcxNTMgMi40NDc3MTUyNSwxMyAzLDEzIFoiIGlkPSLlvaLnirbnu5PlkIgiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4NCiAgICAgICAgICAgIDwvZz4NCiAgICAgICAgPC9nPg0KICAgIDwvZz4NCjwvc3ZnPg==);box-shadow:0 2px 5px 0 rgba(42,135,255,.2)}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s::before{height:1px;top:50%;left:0;right:0}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n::after,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s::after{transform:rotate(90deg)}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-e::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-w::before{width:1px;top:0;left:50%;bottom:0}.f-splitter-resize-overlay{z-index:98;width:100%;height:100%;cursor:e-resize;background:0 0;position:absolute}.f-splitter-horizontal-resize-proxy,.f-splitter-vertical-resize-proxy{background:rgba(42,135,255,.04);display:none;position:absolute;z-index:100}.f-splitter-horizontal-resize-proxy{width:.4375rem;left:0;height:100%}.f-splitter-vertical-resize-proxy{height:.4375rem;top:0;width:100%}.f-component-text{display:block;width:100%;overflow:hidden}.f-form-control-text{height:calc(1.5rem + .125rem);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.f-form-control-textarea{height:calc(calc(1.5rem + .125rem) + 2.321475rem);word-break:break-all;overflow-y:auto;white-space:pre-wrap}.f-form-control-textarea,textarea.form-control{min-height:60px}.f-form-control-text,.f-form-control-textarea{display:block;padding:.1875rem .5rem;font-size:.8125rem;line-height:1.4286;color:var(--f-text-02);background:0 0;background-clip:padding-box;border:1px solid transparent;border-bottom-color:var(--f-neutral-06);border-radius:0}.f-state-view .form-group .farris-label-text{color:var(--f-text-02)}.f-form-control-textarea.f-component-text-auto-size{min-height:calc(calc(1.5357375rem + 2px) + 1.1607375rem);height:auto}.f-form-control-text.f-component-text-auto-size{overflow-y:auto;word-break:break-all;white-space:pre-wrap;min-height:calc(1.5357375rem + 2px);height:auto}.switch{color:var(--f-text-02);background:var(--f-neutral-04);position:relative;display:inline-block;box-sizing:content-box;padding:0;margin:0;cursor:pointer;transition:.3s ease-out all;white-space:nowrap}.switch.checked{background:var(--f-theme-04)}.switch.disabled{background:rgba(var(--f-neutral-04),.5)}.switch.disabled .switch-pane{opacity:.5}.switch.checked.disabled{background:rgba(var(--f-theme-03),.5)}.switch.readonly{background:rgba(var(--f-neutral-04),.5)}.switch.readonly .switch-pane{opacity:.5}.switch.checked.readonly{background:rgba(var(--f-theme-03),.5)}.switch small{right:calc(100% - 1.875rem);border-radius:100%;position:absolute;transition:.3s ease-out all;background:var(--f-neutral-00)}.switch.switch-small{min-width:1.625rem;height:.75rem;border-radius:.75rem}.switch.switch-small small{width:.875rem;height:.875rem;left:0;top:-2px}.switch.switch-small.checked small{right:-1px;left:auto}.switch.switch-small>.switch-pane>span{font-size:12px}.switch.switch-small>.switch-pane .switch-label-checked{padding-right:1rem;padding-left:.25rem}.switch.switch-small>.switch-pane .switch-label-unchecked{padding-left:1rem;padding-right:.25rem}.switch.switch-medium{min-width:2.5rem;height:1.375rem;border-radius:1.375rem}.switch.switch-medium small{width:1.125rem;height:1.125rem;left:2px;top:2px}.switch.switch-medium.checked small{right:2px;left:auto}.switch.switch-medium>.switch-pane>span{font-size:12px;line-height:1.375rem}.switch.switch-medium>.switch-pane .switch-label-checked{padding-right:1.625rem;padding-left:.4583333333rem}.switch.switch-medium>.switch-pane .switch-label-unchecked{padding-left:1.625rem;padding-right:.4583333333rem}.switch.switch-large{min-width:2.75rem;height:1.5rem;border-radius:1.5rem}.switch.switch-large small{width:1.25rem;height:1.25rem;left:2px;top:2px}.switch.switch-large.checked small{right:2px;left:auto}.switch.switch-large>.switch-pane>span{font-size:14px;line-height:1.5rem}.switch.switch-large>.switch-pane .switch-label-checked{padding-right:1.75rem;padding-left:.5rem}.switch.switch-large>.switch-pane .switch-label-unchecked{padding-left:1.75rem;padding-right:.5rem}.switch.switch-small>.switch-pane>span{line-height:unset}.switch.checked .switch-pane{top:0}.switch.checked .switch-pane .switch-label-checked{opacity:1;display:inline-block}.switch.checked .switch-pane .switch-label-unchecked{opacity:0;display:none}.switch.disabled,.switch.readonly{cursor:not-allowed}.switch.square,.switch.square small{border-radius:4px}.switch .switch-pane{display:flex;flex-direction:column;height:100%;min-height:100%;justify-content:flex-start;align-items:center;top:0;position:relative;pointer-events:none}.switch .switch-pane>span{display:block;min-height:100%}.switch .switch-pane .switch-label-checked{color:var(--f-text-00);opacity:0;display:none}.switch .switch-pane .switch-label-unchecked{opacity:1;display:inline-block}.f-datagrid-cell-content .switch.switch-medium{min-width:1.625rem;height:.75rem;border-radius:.75rem}.f-datagrid-cell-content .switch.switch-medium small{width:.875rem;height:.875rem;left:0;top:-1px;box-shadow:0 2px 3px 0 rgba(0,0,0,.16)}.f-datagrid-cell-content .switch.switch-medium.checked small{right:0;left:auto}.f-datagrid-cell-content .switch.switch-medium>.switch-pane>span{font-size:12px;line-height:.75rem}.f-datagrid-cell-content .switch.switch-medium>.switch-pane .switch-label-checked{padding-right:1rem;padding-left:.25rem}.f-datagrid-cell-content .switch.switch-medium>.switch-pane .switch-label-unchecked{padding-left:1rem;padding-right:.25rem}.f-cmp-switch{max-width:100%}.f-cmp-switch .switch-pane .switch-label-checked,.f-cmp-switch .switch-pane .switch-label-unchecked{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.table{width:100%;margin-bottom:1rem;background-color:var(--f-neutral-00);table-layout:fixed}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid var(--f-neutral-07)}.table thead th{vertical-align:middle;border-bottom:2px solid var(--f-neutral-07)}.table tbody+tbody{border-top:2px solid var(--f-neutral-07)}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered,.table-bordered td,.table-bordered th{border:1px solid var(--f-neutral-07)}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(even){background-color:var(--f-neutral-11)}.table-active,.table-active>td,.table-active>th,.table-hover .table-active:hover,.table-hover .table-active:hover>td,.table-hover .table-active:hover>th,.table-hover tbody tr:hover{background-color:var(--f-aid-03)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:var(--f-neutral-07)}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width:887.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}@media (max-width:1689.98px){.table-responsive-el{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-el>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.table thead{background:var(--f-neutral-09);color:var(--f-text-04)}.table thead th{padding:.4375rem .75rem;line-height:1.25rem;border-width:0 0 1px;border-color:var(--f-neutral-13);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;position:relative}.table thead th::after{content:"";position:absolute;right:0;top:50%;margin-top:-.5625rem;display:block;height:1.125rem;width:1px;background-color:var(--f-neutral-06)}.table thead th:last-child::after{display:none}.table td{border-top-width:0;border-bottom:1px solid var(--f-neutral-07);border-color:var(--f-neutral-07);padding:.25rem .75rem;height:calc(.5rem + 1px + 1.1607375rem);line-height:1.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.table td.selected,.table th.selected,.table tr.selected{border-color:var(--f-neutral-07);color:var(--f-text-03);background-color:var(--f-aid-02)}.table-striped tbody tr.selected:nth-of-type(even){background-color:var(--f-aid-02)}.f-datagrid-norecords{width:100%;position:relative;flex:1 1 0;height:100%;justify-content:center}.f-datagrid-norecords-content,.f-table-norecords-content,.f-transfer-norecords .f-transfer-norecords-content{height:7.5rem;padding:5rem 0 0;width:100%;text-align:center;font-size:1rem;color:var(--f-text-07);background:url(data:image/png;base64,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) top center no-repeat;position:absolute;top:50%;margin:-3.75rem 0 0 -.625rem;line-height:2.5rem}.f-transfer-norecords{height:100%;position:relative}.table-hover tbody .f-table-norecords-row:hover{background:initial}.f-table-norecords,.f-table-norecords .f-table-norecords-row td{border:none}.farris-tabs{position:relative;display:flex;flex:1 1 auto}.farris-tabs .margin-right-14{margin-right:14px}.farris-tabs .farris-tabs-header-extend{height:auto;display:flex;align-items:center}.farris-tabs .farris-tabs-header{display:flex;flex-shrink:0;flex-grow:0;align-items:center;margin:0 0 .625rem;padding:.75rem 0 0}.farris-tabs .farris-tabs-header .farris-tabs-title{position:relative;display:flex;width:100%}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer{margin:0}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer.spacer-sides{margin:0 1.5625rem}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer.spacer-sides-dropdown{margin:0 3.75rem 0 1.75rem}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs{overflow:hidden}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item{color:var(--f-text-04);border-width:0;border-style:solid;border-color:transparent;font-size:1rem;margin:0 2rem 0 0;position:relative}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item::after{content:"";position:absolute;bottom:0;left:0;right:0;height:3px;display:none;border-radius:10px;box-shadow:0 2px 6px 0 rgba(78,148,255,.4)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item:hover{color:var(--f-theme-05);border-color:transparent}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item:last-child{margin-right:0}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link{border:none;padding:0 0 .375rem;color:inherit;cursor:pointer;text-decoration:none}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link.tabs-text-truncate{overflow:hidden;white-space:nowrap;display:flex;align-items:center}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link.disabled{color:var(--f-text-07);background-color:transparent;border-color:transparent;pointer-events:none}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link .st-tab-text{max-width:310px;overflow:hidden}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link .farris-title-text-custom{position:relative}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link .farris-title-text-custom::after{content:"";height:100%;position:absolute;right:0;width:30px;background-image:linear-gradient(to left,rgba(255,255,255,.8) 0,rgba(255,255,255,.3) 100%)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item.f-state-active{border-color:var(--f-theme-03);color:var(--f-theme-03)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item.f-state-active::after{display:block;background:var(--f-theme-04)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-fill .nav-item.f-state-active::after,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills .nav-item .nav-link .farris-title-text-custom::after,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills .nav-item.f-state-active::after,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills.nav-fill .nav-item.f-state-active::after{display:none}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item.f-state-active:hover{border-color:var(--f-theme-05)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item.f-state-active .nav-link{color:var(--f-theme-03)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item:active{color:var(--f-theme-02);border-color:transparent}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-fill .nav-item{flex-shrink:1;flex-grow:1;flex-basis:0;background:var(--f-neutral-10);border:none;margin-right:0;margin-left:0}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-fill .nav-item.f-state-active{background-color:var(--f-neutral-00)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-fill .nav-item .nav-link{padding-top:.4375rem;padding-bottom:.4375rem;justify-content:center}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-fill .nav-item .nav-link .st-tab-text{max-width:none}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills .nav-item{border:none;font-size:.875rem;margin:0 .875rem 0 0}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills .nav-item .nav-link{padding:.3125rem .75rem;color:var(--f-text-02);background:var(--f-neutral-09)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills .nav-item .nav-link:hover{color:var(--f-theme-03);background:var(--f-aid-02)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills .nav-item .nav-link.disabled{opacity:.6}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills .nav-item.f-state-active .nav-link{color:var(--f-text-00);background:var(--f-theme-04)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills.nav-fill .nav-item{margin-left:0;margin-right:0}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn{position:absolute;z-index:120}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn:has(>.show){z-index:140}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .dropdown-toggle-split,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .sc-nav-rg,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn.sc-nav-lr{height:1.25rem;width:1.25rem;border-radius:6px;border:1px solid var(--f-neutral-06);background:var(--f-neutral-12)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .dropdown-toggle-split:hover,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .sc-nav-rg:hover,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn.sc-nav-lr:hover{border-color:var(--f-theme-05)}.farris-tabs .farris-tabs-header.farris-tabs-inContent .farris-tabs-title,.farris-tabs .farris-tabs-header.farris-tabs-inHead{border-bottom:none}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn.sc-nav-lr{left:0;top:50%;margin-top:-.625rem}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn.sc-nav-lr::after{content:" ";width:.5rem;height:.5rem;border-top:1px solid var(--f-text-04);border-right:1px solid var(--f-text-04);transform:rotate(225deg);position:absolute;top:.25rem;left:.4375rem}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .sc-nav-rg{padding:0}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .sc-nav-rg::after{content:" ";width:.5rem;height:.5rem;border-top:1px solid var(--f-text-04);border-right:1px solid var(--f-text-04);transform:rotate(45deg);position:absolute;top:.25rem;right:.4375rem}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .dropdown-toggle-split{color:var(--f-text-04);margin-left:.3125rem;padding:0}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn.dropdown{position:absolute;top:50%;margin-top:-.625rem;right:.375rem}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .dropdown-toggle:active,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .dropdown-toggle:hover{color:var(--f-theme-05)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .dropdown-toggle::after{width:1em;height:1em;content:"\eb82";font-family:FarrisIcons;border:none;font-size:12px;line-height:1;vertical-align:1px}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-lr:hover:after,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-rg:hover:after{border-top:1px solid var(--f-theme-05);border-right:1px solid var(--f-theme-05)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-lr:active:after,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-rg:active:after{border-top:1px solid var(--f-theme-01);border-right:1px solid var(--f-theme-01)}.farris-tabs .farris-tabs-header.farris-tabs-inHead .farris-tabs-title{width:41.6666667%}.farris-tabs .farris-tabs-header.farris-tabs-inHead .farris-tabs-toolbar{flex:1 1 0;align-items:center;display:flex;justify-content:flex-end;margin-left:.875rem;overflow:hidden}.farris-tabs .farris-tabs-header.farris-tabs-inContent{display:block}.farris-tabs .farris-tabs-header.farris-tabs-inContent .farris-tabs-toolbar{margin:.625rem 0}.farris-tabs .farris-tabs-header.farris-tabs-nav-fill,.farris-tabs .farris-tabs-header.farris-tabs-nav-fill .farris-tabs-title,.farris-tabs .farris-tabs-header.farris-tabs-nav-pills,.farris-tabs .farris-tabs-header.farris-tabs-nav-pills .farris-tabs-title{border:none}.farris-tabs .farris-tabs-header .farris-tabs-toolbar .btn-link{margin-right:.75rem}.farris-tabs .farris-tabs-header .farris-tabs-toolbar .btn-link:last-child{margin-right:0}.farris-tabs .farris-tabs-header .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0;right:0;left:auto;min-height:80px}.farris-tabs .farris-tabs-header .st-drop-close{width:1rem;height:1rem;text-align:center;cursor:pointer;position:relative;opacity:.4}.farris-tabs .farris-tabs-header .st-drop-close .material-icons{font-size:1rem;margin:-.625rem 0 0 .3125rem}.farris-tabs .farris-tabs-header .st-drop-close:hover{opacity:1}.farris-tabs .farris-tabs-header .active{color:var(--f-theme-03)}.farris-tabs .farris-tabs-header .f-tabs-toolbar-btn{padding:.125rem .8125rem;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;position:relative;color:var(--f-theme-03);border:none;background:0 0;white-space:nowrap}.farris-tabs .farris-tabs-header .f-tabs-toolbar-btn:hover{color:var(--f-theme-05)}.farris-tabs .farris-tabs-header .f-tabs-toolbar-btn:active{color:var(--f-theme-02)}.farris-tabs .farris-tabs-header .farris-tabs-inline-flex{display:inline-flex}.farris-tabs .scroll-tab-tooltips{padding:0;margin:0;width:7.5rem;text-align:left}.farris-tabs .scroll-tab-tooltips li{list-style:none;padding:0;margin:0}.farris-tabs.f-tabs-content-fill .f-tab-active,.farris-tabs.f-tabstrip-fill .f-tab-active{display:flex;flex:1 1 auto;flex-direction:column;overflow:auto}.farris-tabs.f-tabs-content-fill .f-tab-active{position:relative}.farris-tabs .f-tab-d-none{display:none}.farris-tabs.f-tabs-header-sm .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link{padding-top:.25rem;padding-bottom:.25rem}.f-cmp-tabs-with-pill .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item{border-radius:4px 4px 0 0;padding:0 .625rem;margin:0 1rem 0 0}.f-cmp-tabs-with-pill .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item.f-state-active{border-color:var(--f-theme-03);color:#fff;background:var(--f-theme-03)}.f-cmp-tabs-with-pill .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item.f-state-active:hover{border-color:var(--f-theme-03)}.f-cmp-tabs-with-pill .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item.f-state-active .nav-link{color:#fff}.nav-pills .nav-link{padding:.3125rem .75rem}.farris-tabs-toolbar .sc-nav-btn .morebtn{padding-right:12px;padding-left:12px;margin-right:0!important}.lookup-tabs-nav .nav-item-selected{color:var(--f-theme-03)!important}.lookup-tabs-nav .lookup-selected-total{color:var(--f-text-00)!important;background:var(--f-theme-04)!important}.lookup-tabs-nav .tabs-ink-bar{background:linear-gradient(214deg,#3F65FF 0,#4D9AFF 100%)!important}.farris-tabs-inContent .farris-tabs-toolbar:has(.f-component-tabs-view){display:flex}.farris-tabs-inContent .farris-tabs-toolbar .f-component-tabs-view{height:auto}.farris-tabs.one-page{overflow:hidden}.farris-tabs.one-page .farris-tabs-content{overflow:auto;position:relative}.farris-tabs .st-drop-close{line-height:1}.farris-tabs .tabs-li-absolute{padding:4px;margin:0;position:relative}.farris-tabs .farris-tabs-header{flex-wrap:nowrap!important}.farris-tabs .tabs-li-absolute input{line-height:26px;height:26px;padding-right:24px}.farris-tabs .tabs-icon-search{position:absolute;right:4px;top:50%;font-size:14px;padding:0 4px;width:auto;height:24px;color:rgba(0,0,0,.25);margin-top:-12px;line-height:20px}.farris-tabs .dropdown-no-data{height:26px;line-height:26px;text-align:center;padding-top:5px}.farris-tabs .farris-tabs-header .farris-tabs-header-post,.farris-tabs .farris-tabs-header .farris-tabs-header-pre,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item{flex-shrink:0}.farris-tabs .farris-tabs-header .farris-tabs-title{flex:1 0}.farris-tags .farris-tags-item-container li.farris-tag-item{border-color:#E6E6E6}.farris-tags .farris-tags-item-container.farris-tag-item-capsule .farris-tag-item{border-radius:24px}.farris-tags .farris-tags-item-container.farris-tag-item-capsule .farris-tag-item.farris-tag-item-checkable:not(.farris-tag-item-checked){background:#fff;border:1px solid #e6e6e6;cursor:pointer}.farris-tags.farris-tags-nowrap{overflow:hidden}.farris-tags.farris-tags-nowrap .farris-tags-item-container{display:flex;flex-wrap:nowrap;overflow:hidden}.farris-tags .farris-tags-item-container .farris-tag-item{background:rgba(var(--f-theme-03),.06);border:1px solid;color:var(--f-text-02);display:inline-block;padding:0 8px;margin:0 10px 0 0;line-height:24px;font-size:13px;white-space:nowrap;border-radius:3px;cursor:default;opacity:1;transition:all .3s cubic-bezier(.78,.14,.15,.86)}.farris-tags .farris-tags-item-container .farris-tag-item a,.farris-tags .farris-tags-item-container .farris-tag-item a:hover{color:var(--f-text-02)}.farris-tags .farris-tags-item-container .farris-tag-item>a:first-child:last-child{display:inline-block;margin:0 -8px;padding:0 8px}.farris-tags .farris-tags-item-container .farris-tag-item .tag-delete{color:var(--f-text-06);display:inline-block;font-size:10px;width:16px;text-align:right;margin:0;cursor:pointer;transition:all .3s cubic-bezier(.78,.14,.15,.86);position:relative;z-index:10}.farris-tags .farris-tags-item-container .farris-tag-item .tag-delete .f-icon{font-size:12px}.farris-tags .farris-tags-item-container .farris-tag-item .tag-delete:hover{color:var(--f-text-02)}.farris-tags .farris-tags-item-container .farris-tag-item>.f-icon+span,.farris-tags .farris-tags-item-container .farris-tag-item>span+.f-icon{margin-left:7px}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-success{color:var(--f-semantic-success-01);border-color:var(--f-semantic-success-02);background:var(--f-semantic-success-03)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-success.farris-tag-item-actived{color:var(--f-semantic-success-03);border-color:var(--f-semantic-success-01);background:var(--f-semantic-success-01)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-info{color:var(--f-semantic-info-01);border-color:var(--f-semantic-info-02);background:var(--f-semantic-info-03)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-info.farris-tag-item-actived{color:var(--f-semantic-info-03);border-color:var(--f-semantic-info-01);background:var(--f-semantic-info-01)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-error{color:var(--f-semantic-danger-01);border-color:var(--f-semantic-danger-02);background:var(--f-semantic-danger-03)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-error.farris-tag-item-actived{color:var(--f-semantic-danger-03);border-color:var(--f-semantic-danger-01);background:var(--f-semantic-danger-01)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-warning{color:var(--f-semantic-warning-01);border-color:var(--f-semantic-warning-02);background:var(--f-semantic-warning-03)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-warning.farris-tag-item-actived{color:var(--f-semantic-warning-03);border-color:var(--f-semantic-warning-01);background:var(--f-semantic-warning-01)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-checkdisabled{cursor:not-allowed;color:rgba(0,0,0,.45)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-checked{background-color:#fff}.farris-tags .farris-tags-item-container .farris-tag-item:last-child{margin-right:0}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-checkable:not(.farris-tag-item-checked){color:var(--f-text-02);background-color:transparent;border-color:transparent}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-checkable:not(.farris-tag-item-checked):active{color:var(--f-text-02)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-checkable:not(.farris-tag-item-checked):hover{color:var(--f-theme-03)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-checkdisabled{background-color:transparent;border-color:transparent;color:var(--f-text-07)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-actived,.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-checked{background:var(--f-theme-03);border-color:var(--f-theme-03);color:var(--f-text-00)}.farris-tags .farris-tags-item-container .farris-tag-add-button{cursor:pointer;background:#fff;border-radius:6px;border:1px dashed var(--f-neutral-04)}.farris-tags .farris-tags-item-container .farris-tag-add-button .farris-tag-add-text{color:var(--f-text-06)}.farris-tags .farris-tags-item-container .farris-tag-add-button .f-icon{color:var(--f-text-04)}.farris-tags .farris-tags-item-container .farris-tag-add-button:hover{border-color:var(--f-theme-05)}.farris-tags .farris-tags-item-container .farris-tag-add-button:hover .f-icon,.farris-tags .farris-tags-item-container .farris-tag-add-button:hover .farris-tag-add-text{color:var(--f-theme-05)}.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled{opacity:.6;border-style:solid;cursor:not-allowed}.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled .farris-tag-add-text{color:rgba(0,0,0,.25)}.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled,.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled:hover{background:var(--f-neutral-08);border-color:var(--f-neutral-05)}.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled .f-icon,.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled .farris-tag-add-text,.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled:hover .f-icon,.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled:hover .farris-tag-add-text{color:var(--f-text-07)}.farris-tags .farris-tags-item-container .farris-tag-input-box{display:inline-block}.farris-tags .farris-tags-item-container .farris-tag-input-box .form-control{height:24px;width:100px}.farris-tags .farris-tags-item-container .farris-tag-input-box .form-control:focus{box-shadow:none}.farris-tags.farris-tags-checkable .farris-tag-item{line-height:22px}.time-picker-panel{box-sizing:border-box;margin:0;padding:0;color:var(--f-text-04);font-size:14px;font-variant:tabular-nums;line-height:1.5;list-style:none;font-feature-settings:"tnum";position:absolute;z-index:9999}.time-picker-panel .time-picker-panel-inner{position:relative;left:0;font-size:14px;text-align:left;list-style:none;background:var(--f-neutral-20);margin:.25rem 0 0;background-clip:padding-box;border-radius:10px;outline:0;box-shadow:0 2px 20px 0 rgba(3,18,51,.12);padding:3px 0}.time-picker-panel .time-picker-panel-inner .time-picker-panel-input-wrap{position:relative;padding:7px 2px 7px 12px;border-bottom:1px solid var(--f-neutral-08)}.time-picker-panel .time-picker-panel-inner .time-picker-panel-input-wrap .time-picker-panel-input:-moz-placeholder-shown{text-overflow:ellipsis}.time-picker-panel .time-picker-panel-inner .time-picker-panel-input-wrap .time-picker-panel-input:placeholder-shown{text-overflow:ellipsis}.time-picker-panel .time-picker-panel-inner .time-picker-panel-input-wrap .time-picker-panel-input{width:100%;max-width:154px;margin:0;padding:0;line-height:normal;border:0;outline:0;cursor:auto}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox{zoom:1}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select{position:relative;float:left;width:4.125rem;max-height:192px;overflow:hidden;font-size:14px;border-left:1px solid var(--f-neutral-08)}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select ul{width:4.125rem;margin:0;padding:0 0 160px;list-style:none}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select ul li{height:2rem;margin:0 6px;padding:0;border-radius:6px;line-height:2rem;text-align:center;list-style:none;cursor:pointer;transition:all .3s;-webkit-user-select:none;-moz-user-select:none;user-select:none;color:var(--f-text-02)}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select:first-child,.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select:first-child{margin-left:0;border-left:0}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select ul li:hover{color:var(--f-theme-03)}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select ul li.time-picker-panel-select-option-selected{background:var(--f-aid-02);color:var(--f-theme-03)}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select ul li.time-picker-panel-select-option-disabled,.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select ul li.time-picker-panel-select-option-disabled:hover{color:var(--f-text-07)}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select ul li:last-child::after{height:252px;display:block;content:""}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select:last-child{border-right:0}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select:hover{overflow-y:auto}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox::after,.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox::before{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0}.calendar-time-picker{display:block;height:228px;width:100%;background:var(--f-neutral-20)}.calendar-time-picker .calendar-time-picker-panel{z-index:9999;width:100%;color:var(--f-text-04)}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner{position:relative;display:inline-block;width:100%;overflow:hidden;font-size:14px;line-height:1.5;text-align:left;list-style:none;background:var(--f-neutral-20);background-clip:padding-box;outline:0}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox{width:100%;display:flex}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-column-3 .calendar-time-picker-select{width:33.33%}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select{position:relative;flex:1;height:226px;overflow:hidden;font-size:14px;border-right:1px solid var(--f-neutral-08)}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select ul{width:100%;max-height:206px;margin:0;padding:0;list-style:none}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select li{color:var(--f-text-02);height:2rem;margin:0 6px;line-height:2rem;border-radius:6px;text-align:center;list-style:none;cursor:pointer;transition:all .3s;-webkit-user-select:none;-moz-user-select:none;user-select:none}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select li:hover{color:var(--f-theme-03)}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select li:last-child::after{display:block;height:202px;content:""}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select li.calendar-time-picker-select-option-selected{color:var(--f-theme-03);background:var(--f-aid-02)}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select li.calendar-time-picker-select-option-disabled,.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select li.calendar-time-picker-select-option-disabled:hover{color:var(--f-text-09);background:#f8f9fa;cursor:not-allowed}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select:hover{overflow-y:auto}.time-picker-overlay{top:0;bottom:0;left:0;right:0;position:fixed;z-index:8888;display:none}.tooltip,.tooltip .arrow{display:block;position:absolute}.time-picker-overlay .time-picker-panel-box{top:0;left:0;height:100%;width:100%;position:absolute;z-index:8888;flex-direction:column;min-width:1px;min-height:1px;transform:translate(0,0)}.input-group .input-group-append.f-cmp-iconbtn-wrapper{align-items:center;background:var(--f-neutral-12)}.input-group .input-group-append.f-cmp-iconbtn-wrapper .f-cmp-iconbtn{background:var(--f-neutral-12);cursor:pointer;padding:0 .5rem;color:var(--f-text-08)}.input-group .input-group-append.f-cmp-iconbtn-wrapper .f-cmp-iconbtn:hover{color:var(--f-theme-05)}.input-group .input-group-append.f-cmp-iconbtn-wrapper .f-cmp-iconbtn:active{color:var(--f-theme-03)}.input-group .input-group-append.f-cmp-iconbtn-wrapper .f-cmp-iconbtn .f-icon{font-size:.75rem}.f-component-timepicker .timepicker-btn{padding:0 .5rem;color:var(--f-text-07)}.f-component-timepicker .timepicker-btn:hover{color:var(--f-theme-05)}.tooltip{z-index:1070;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei","Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;line-height:1.4286;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.75rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:1}.tooltip .arrow{width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:rgba(var(--f-neutral-00-rgb),.4)}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:rgba(var(--f-neutral-00-rgb),.4)}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:rgba(var(--f-neutral-00-rgb),.4)}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:rgba(var(--f-neutral-00-rgb),.4)}.tooltip-inner{max-width:18.75rem;max-height:6.25rem;overflow:hidden;padding:.5rem .625rem;color:var(--f-text-02);text-align:left;background-color:rgba(var(--f-neutral-00-rgb),.95);box-shadow:0 2px 8px 0 rgba(0,0,0,.15);border-radius:6px}.tooltip-inner-lg{max-width:37.5rem;max-height:initial;overflow:initial}.f-tooltip{position:absolute;display:none;padding:.25em .5em;max-width:12.5em;line-height:1.2rem;border-radius:5px}.f-tooltip-left,.f-tooltip-right{padding:0 .6em}.f-tooltip-bottom,.f-tooltip-top{padding:.6em 0}.f-tooltip-bottom-left,.f-tooltip-top-left,.f-tooltip-top-right{padding:0}.f-tooltip-default{background-color:rgba(var(--f-neutral-00-rgb),.9);color:var(--f-text-02);border:1px solid var(--f-neutral-00)}.f-tooltip-text{padding:.5em .3em;white-space:pre-line;border-radius:3px;box-shadow:0 2px 8px 0 rgba(0,32,74,.15)}.f-tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid;border-width:1em}.f-tooltip-right .f-tooltip-arrow{top:50%;left:0;margin-top:-.5em;border-width:1em 1em 1em 0;border-right-color:var(--f-neutral-00)}.f-tooltip-left .f-tooltip-arrow{top:50%;right:0;margin-top:-.5em;border-width:1em 0 1em 1em;border-left-color:var(--f-neutral-00)}.f-tooltip-bottom .f-tooltip-arrow,.f-tooltip-top .f-tooltip-arrow{left:50%;margin-left:-.5em;border-width:1em;border-top-color:var(--f-neutral-00)}.f-tooltip-top .f-tooltip-arrow{bottom:0;border-bottom-width:0}.f-tooltip-bottom-left .f-tooltip-arrow,.f-tooltip-top-left .f-tooltip-arrow{left:10px;margin-left:-.5em;border-bottom-width:0}.f-tooltip-top-left .f-tooltip-arrow,.f-tooltip-top-right .f-tooltip-arrow{bottom:0;margin-bottom:-.5em}.f-tooltip-bottom-right .f-tooltip-arrow,.f-tooltip-top-right .f-tooltip-arrow{right:10px;margin-right:-.5em;border-bottom-width:0}.f-tooltip-bottom .f-tooltip-arrow{top:0;border-top-width:0}.f-tooltip-bottom-left .f-tooltip-arrow{top:0}.f-tooltip-info.f-tooltip-top-left .f-tooltip-arrow,.f-tooltip-info.f-tooltip-top-right .f-tooltip-arrow{border-top-color:rgba(var(--f-neutral-00-rgb),.9)}.f-tooltip-info.f-tooltip-bottom .f-tooltip-arrow{border-bottom-color:rgba(var(--f-neutral-00-rgb),.9)}.f-tooltip-info.f-tooltip-right .f-tooltip-arrow{border-right-color:rgba(var(--f-neutral-00-rgb),.9)}.f-tooltip-info.f-tooltip-left .f-tooltip-arrow{border-left-color:rgba(var(--f-neutral-00-rgb),.9)}.f-tooltip-info .f-tooltip-text{background-color:rgba(var(--f-neutral-00-rgb),.9);box-shadow:0 2px 8px 0 rgba(0,32,74,.15)}.f-tooltip-danger .f-tooltip-text{color:var(--f-semantic-danger-01);background-color:var(--f-semantic-danger-03);border-color:var(--f-semantic-danger-02)}.f-tooltip-danger.f-tooltip-top .f-tooltip-arrow,.f-tooltip-danger.f-tooltip-top-left .f-tooltip-arrow{border-top-color:var(--f-semantic-danger-02)}.f-transfer{padding:.125rem;border:1px solid var(--f-neutral-06);border-radius:6px}.f-transfer .option-pane,.f-transfer .option-pane-content .columns-box{padding:0}.transfer-search-box{margin:.75rem .875rem}.f-transfer .transfer-search-box .f-cmp-inputgroup .input-group,.f-transfer .transfer-search-box .f-cmp-inputgroup .input-group>.form-control:not(:last-child){border-radius:6px}.f-transfer .transfer-search-box .f-cmp-inputgroup .input-group>.input-group-append{border-radius:0 6px 6px 0}.f-transfer .transfer-search-box .f-cmp-inputgroup .input-group>.input-group-append>.input-group-clear{border-radius:6px!important}.f-transfer .option-pane-content .columns-box .fv-tree-view .fv-grid-hierarchy-cell div span{overflow:hidden;text-overflow:ellipsis}.f-transfer .option-pane .option-pane-group{padding:.375rem 0}.f-transfer .option-pane .f-transfer-list-item{padding:.375rem .875rem;cursor:default;margin:0;border-radius:0;color:var(--f-text-03)}.f-transfer .option-pane .f-transfer-list-item .f-list-select{padding:0}.f-transfer .option-pane .f-transfer-list-item.f-un-select{color:var(--f-text-08)}.f-transfer .option-pane .f-transfer-list-item:not(.f-un-select):hover{background:var(--f-neutral-11)}.f-transfer .option-pane .f-transfer-list-item.f-listview-active{background:var(--f-neutral-10)}.f-transfer .option-pane .f-transfer-list-item .custom-checkbox{padding:0;margin:0;width:100%;overflow:hidden}.f-transfer .option-pane .f-transfer-list-item .custom-control-label{padding-left:1.375rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.f-transfer .selection-pane{border-left:1px solid var(--f-neutral-06);padding:0}.f-transfer .selection-pane .selection-pane-title{padding:.875rem .875rem .375rem;background:var(--f-neutral-10);color:var(--f-text-01);display:flex;align-items:center}.fv-grid-hierarchy-cell,.fv-tree-node-cell{padding:0 .75rem;display:flex;line-height:28px;top:0;white-space:nowrap}.f-transfer .selection-pane .selection-pane-title>.selection-count{font-size:18px;margin:0 .25rem}.f-transfer .selection-pane .selection-pane-title>.selection-title-action{font-size:13px;color:#2a87ff;flex:1;text-align:right}.f-transfer .selection-pane .selection-pane-title>.selection-title-action>i{margin:0 .5rem}.fv-grid-hierarchy-cell{position:absolute;text-overflow:ellipsis;flex-direction:column;align-items:center;z-index:1;border-color:transparent;background-color:transparent;overflow:hidden}.fv-tree,.fv-tree-content,.fv-tree-content-primary{overflow:scroll;position:relative}.fv-grid-bordered .fv-grid-hierarchy-cell{border-right-color:#eaecf3}.fv-grid-horizontal-bordered .fv-grid-hierarchy-cell{border-bottom-color:#eaecf3}.fv-tree{display:flex;flex-direction:column;border-color:transparent;flex:1;color:#424347;width:100%}.fv-tree-content{flex:1;display:flex;width:100%;z-index:0;background:#fff}.fv-tree-content-hover{cursor:pointer}.fv-tree-content-primary{flex:1}.fv-tree-data{height:100%;width:100%;position:relative;overflow:hidden}.fv-tree-data .fv-grid-hierarchy-cell{border:none}.fv-tree-node{left:0;width:100%;position:absolute}.fv-tree-node.selected,.fv-tree-node:active,.fv-tree-node:hover{left:0;position:absolute;background:#e7f1ff}.fv-tree-strip .fv-tree-node-odd{background-color:#fff}.fv-tree-strip .fv-tree-node-even{background-color:#f7f8fb}.fv-tree-node-hover{cursor:pointer;color:#424347;background:#edf5ff!important}.fv-tree-node-selected{color:#424347!important;background-color:#dae9ff!important}.fv-tree-node-cell{position:absolute;text-overflow:ellipsis;flex-direction:column;align-items:center;z-index:1;border-style:solid;border-width:1px;border-color:transparent transparent #eaecf3;background-color:transparent}.fv-tree-data :first-child .fv-tree-node-cell{background:0 0;border-left:none}.fv-tree-node-cell-input{font-size:12px;height:12px;width:12px;border:1px solid #aeb5c6}.fv-tree-node-cell .f-icon.f-icon-checkbox-checked{color:#2a87ff!important}.fv-tree-node-cell .custom-control-input:checked~.custom-control-label::before{color:#2a87ff}.fv-tree-node-cell input[type=checkbox]{display:none}.fv-tree-node-cell input[type=checkbox]+label{position:relative;padding-left:18px;cursor:pointer;display:flex}.fv-tree-node-cell input[type=checkbox]+label::before{content:"\e304";font-family:FarrisIcons;position:absolute;left:0;top:0;color:#d8dce6}.fv-tree-node-cell input[type=checkbox]:indeterminate+label::before{content:"\e306";font-family:FarrisIcons;position:absolute;left:0;top:0;color:#2a87ff}.fv-upload-and-preview .ffileUploadAndPreview{font-size:13px}.fv-upload-and-preview .ffileUploadAndPreview-content-fill{flex-grow:1;flex-shrink:1;flex-basis:0;display:flex;flex-direction:column;overflow:hidden}.fv-upload-and-preview .ffileUploadAndPreview-content-fill .uploadAndpreview--header{flex-shrink:0}.fv-upload-and-preview .ffileUploadAndPreview-content-fill .uploadAndpreview--content{flex-grow:1;flex-shrink:1;flex-basis:0;overflow:auto}.fv-upload-and-preview .uploadAndpreview--header{display:flex;align-items:center;margin:0 0 9px;position:relative}.fv-upload-and-preview .uploadAndpreview--header .ffileupload--browser{position:absolute;margin:0;padding:0;left:1em;top:-9000px;width:calc(100% - 2em);opacity:0;font-size:0}.fv-upload-and-preview .uploadAndpreview--header .header--left-container{display:flex;align-items:center}.fv-upload-and-preview .uploadAndpreview--header .upload-container{height:44px;background:#FAFCFD;border:1px dashed #D8DFED;border-radius:6px;padding:0 22px;cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:130px;display:inline-block;line-height:44px;align-items:center;max-width:160px}.fv-upload-and-preview .uploadAndpreview--header .upload-container.f-state-disabled{opacity:.6;cursor:default}.fv-upload-and-preview .uploadAndpreview--header .upload-container .upload-icon{color:#2F8AFF;font-size:18px;margin:0 10px 0 0}.fv-upload-and-preview .uploadAndpreview--header .header--right-container{margin-left:auto;min-height:44px;display:flex;align-items:center}.fv-upload-and-preview .uploadAndpreview--header .header--countInfo{min-height:44px;display:flex;align-items:center;font-size:14px}.fv-upload-and-preview .uploadAndpreview--header .header--countInfo .count{font-size:16px;font-weight:600;margin:0 6px}.fv-upload-and-preview .uploadAndpreview--content{margin-bottom:10px}.fv-upload-and-preview .uploadAndpreview--table td{border-left:none;border-right:none;vertical-align:middle!important;padding-top:12px;padding-bottom:12px}.fv-upload-and-preview .uploadAndpreview--table .td--hascheckbox{position:relative;padding-left:44px}.fv-upload-and-preview .smooth-dnd-ghost .td--hascheckbox .preview-checkbox,.fv-upload-and-preview .uploadAndpreview--table .td--hascheckbox .preview-checkbox{position:absolute;top:50%;margin-top:-8px;left:14px}.fv-upload-and-preview .uploadAndpreview--title-container{display:flex;overflow:hidden}.fv-upload-and-preview .uploadAndpreview--title-container .uploadAndpreview--right{align-self:center;flex:1 1 0;overflow:hidden}.fv-upload-and-preview .uploadAndpreview--right .item-content--title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;cursor:pointer}.fv-upload-and-preview .uploadAndpreview--right .item-content--title.no-preview{cursor:default}.fv-upload-and-preview .uploadAndpreview--title-container .ffilepreview--filetype-icon{width:28px;height:28px}.fv-upload-and-preview .uploadAndpreview--state-container p{margin:0;padding:0}.fv-upload-and-preview .uploadAndpreview--state-container .f-icon{font-size:18px}.fv-upload-and-preview .ffileupload--support-info .support-info--wrapper{padding:0 8px;margin:0 0 8px}.fv-upload-and-preview .ffileupload--support-info .support-info--wrapper li{color:#B4BCCC;margin:0;padding:0;display:inline-block}.fv-upload-and-preview .uploadAndpreview--date-container,.fv-upload-and-preview .uploadAndpreview--filesize-container{color:rgba(45,47,51,.45);font-size:12px}.fv-upload-and-preview .uploadAndpreview--state-container .f-icon{margin:0 8px 0 0}.fv-upload-and-preview .uploadAndpreview--nodata{padding:0 8px;margin:0 0 8px;color:#B4BCCC}.fv-upload-and-preview .uploadAndpreview--action-container{display:flex;flex-direction:row;align-items:center;min-width:90px;height:100%}.fv-upload-and-preview .uploadAndpreview--action-container .preview-btn{height:22px;width:22px;border-radius:16px;display:inline-block;padding:0;color:#2b87ff;text-align:center;border:none;margin:0 14px 0 0}.fv-upload-and-preview .uploadAndpreview--action-container .preview-btn[disabled]{color:gray;opacity:.5;cursor:not-allowed;background:#e6e6e6;border:1px solid #bdbdbd}.fv-upload-and-preview .uploadAndpreview--action-container .preview-btn:not([disabled]):hover{color:#fff}.fv-upload-and-preview .uploadAndpreview--action-container .preview-btn .f-icon{margin:0 auto;display:block;font-size:16px;position:relative}.fv-upload-and-preview .ffilepreview--filetype-zip{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--filetype-xls{background-image:url(data:image/png;base64,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dGUAMjAxOS0xMi0yOFQwOTozMTo1NiswMDowMLhrE7kAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTktMDEtMDhUMTk6NDM6NTkrMDA6MDCdstIMAAAAIHRFWHRzb2Z0d2FyZQBodHRwczovL2ltYWdlbWFnaWNrLm9yZ7zPHZ0AAAAYdEVYdFRodW1iOjpEb2N1bWVudDo6UGFnZXMAMaf/uy8AAAAYdEVYdFRodW1iOjpJbWFnZTo6SGVpZ2h0ADUxMo+NU4EAAAAXdEVYdFRodW1iOjpJbWFnZTo6V2lkdGgANTEyHHwD3AAAABl0RVh0VGh1bWI6Ok1pbWV0eXBlAGltYWdlL3BuZz+yVk4AAAAXdEVYdFRodW1iOjpNVGltZQAxNTQ2OTc2NjM5OiA9twAAABN0RVh0VGh1bWI6OlNpemUAMjc5NTUxQgHjNFMAAABadEVYdFRodW1iOjpVUkkAZmlsZTovLy9kYXRhL3d3d3Jvb3Qvd3d3LmVhc3lpY29uLm5ldC9jZG4taW1nLmVhc3lpY29uLmNuL2ZpbGVzLzExOC8xMTg0MjYwLnBuZ1tLqmgAAAAASUVORK5CYII=)}.fv-upload-and-preview .ffilepreview--filetype-txt{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--filetype-ppt{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--filetype-pdf{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAAB3RJTUUH5AIKAjsgUCRbrgAAEkxJREFUeNrtnHuUHFWdxz9V1a/peXT3PBJCXpMAMQGJuyuvREPgAMsqGCIEIQSFg7CHgCirrotP4Hh4iq4HQViQ4AsIj2RZ8YhodMEsENmgPJIhQ0LCMJNkMt2Z6Z7p6WfVvftHP6aquqq7OtHj/sHvnJqux+/+fr/7vb/7u79769bA+/Q+vU9/RVKaLbC+E4YUaBUwzQ/dGhSBgAItaulXA1SlVrh0UCxt1/VImvkkxFtjHPndnzDj5KUYuo6u6xQKBTKZDPl8Hp/PRzweZ9/evUxKydz2dk674IKm6uvzyvhAJ0wKCPtgVRh+kiA0zU+3gJ68YE4euguSQFABnwKaGQG32kvbtWJ7ptjKm+4pErKqj7yiMpGepJjPUSwWyefz5HK5gpQy0RoOvychvn94OPG5L3059+pLL/Lz+++nrb2dlWvWeKp3w4Z7MAondsDuHJw/grJxGsdENVZGNJb7FBYGFSISOgC/WhGoHIJrmgySHvkGdZXcWRfy0ZtuJxTrRBgGUkqEEABFRVEmcvl8Ui8Wd4wlk5sPJhIbl5x55tsvbdrEwsWLeeEXv+CTV1556AA91AkHivDRdthbZM5sP2s7NFYHFeb6DhWBvxApwEABXs/CwpUXseymO2jp7kaWwJniUxSklOi6TjabfTeZSj26Z8+e++f29g5u+vWzzJw5i3MuvthVj+b2YF25S31pDrw+wbLeIA90alwcVImqinMP8EJe+RvFJgVIGTCsw8G3tpOJH+DIE5bgb2sDWeuDqqoSCoWira2tyzra208Z3r+//9yLV7/3pz9u4YpL1vDIU095B+iBKMT1Eji/jHPO7ADrIhrHKSZrvXSDvzYlDTigl9CK920jM3KAmSd/BH9rqyNIFaBaWlpmh8Phs/q3bXv7zPPO2/nCc7/milUX8vgzzzg2RA29OhvSBiR1ls0J8Ei7xmwnvkPxokYxW/FY1tzFzLTo/NWcevOdhGKxmu5mp1QqNbh79+41XT3dmztnHEkkFqvhqfGgH8agKGDMYHZvgAc6fBznNLiYEXYCye26HgCNwLYPZqmKB5mUJPq3kxnez5En1fckgGAoFPEHAot29vf/dnRkJHXOGWfw+NNPW3hUe6GMgFVxmB3g6naNUyoGVQ7LtXS57+Ha7QAQHnicqi0VkELy1sbH+MNN/0Y2HkdRVdxIAWLR6Cnz5s9fu/Sss5T0xEQNj8WDHonA9CCsCrNgRoDvhFSirh5RtlCxNbdTcPXaFaUsy7PJrt63Va4SpC33ywNI4q1tZOMjHHnS0rqepGkaiqLMXnH22b+aPmPGwU/OmsUjmzc7A7S0A5aHISf4bMzHKnfs/zZkqaLi0MVsz+N928gm4qXAHQ7XAymaLxSGFp944otb581jw913V59ZMAgV4WcHCUU0lntJsb2MZLIJ3kbUbOolgb6nHuWFb32F7OhB1+7m8/nojMVOu+fb3w75nnvO+sx80eOHHj/dmsLCZgE4LJCaTaYoTTXMMcmRRwEpJX3/uR4pBMtvvtM1mfQHAgv/YenSHhRl0BWgLg0E9JSnD3+VJNAcj5CgaBpquA2EwJicqMaQqvEu8mX1T31dFWVvPf0EaBqnfvNWwj09FpCklIRCoUhnJNKt+f3uABWBnGCugI5D7RpePUpKUFta6f7Ct/AdMQcjcYDMK8+T/s3TFlRkHflmD6rbMGWQ+jY8BlKy/KY7aOnqsoAkhGjPZDJzW9rb/2wuaumUwdIkswvwN4lLw0rUACcgvOR0Yld9kfyubYz/6gmia9aiTZ9ZL3XxrNtuQwXBvo3reeHmG8iNjVlikqIofhRlRltXl0WeNUirEFQJVLpAM4c5dwFnUCxlJPhnzUHx+zDGEmS2vkR+Zx+BeUcjhXe9lRNZPpAgTNfS9LxCfRvX8/yNXyF7cCpwq6qK3++PzZzba7HZZ78IKFOVOdTWs5PTEkapVUuOKosFpA7pTc9gjI/XeoBDHuTWCI1sqQjcvuExpJAsv/E2wj09KIqCpmlhVbOOdBaANGUqMbK7eWlEcEgMzcmdYiqn1IJjlymlUWZSQYXsjjdALyLNNkp3e9xAsa9W2hur8mz7xvWgKpx2420EojHQtJrQUpPuOGXGislAp/ggzf3KXjGcqeT+ZYD8/pI35HOIQramvFtW7uZB9bzHnmxuf+oxUFVO/cYtqP5ATaLkcxPiUFfPq31eSAJGKgWA2hoBDVpOXEZm6x8QmcmqPqcKexniPZNSSiaFbtC94kIFzWgMUD3QvC5H1FTIahMoUNizE5GeILRoMWpHlOAxxzL5yvOWMk4yK89iGvxdS/P21Nol4TdPMLh1M/NH97oD5DRrblTZZp9XeRQoJoYxxpP458wjMH8hWnsUUSjU2OMmI6xCqzoF+uE4lUCQP7CXaT3Avqn7tZMTaT11G67rPbdXznG5QwF97CD5d3YS6D2ayMdWIYwiUjdclzacfoXLUS8NES5lpQPKFoDqeZBZsBMAbms29RI3I5Mht3M7vu4eYpdeRXH/EELUD7xuGb5T3HRbZ3Iqb7bLFSA34XYlTooageR4X0Jm68tIXUcNBinsG2hoQ6MEtZH9rrJckLN6kImpnje4tRBNPKfcWpk3XkEfGUbqRYzJiVIu5VCmkXfaAWvU4G722qmmi1VbxJT3CHNcMqfxpmvhAqpZuTBNAyr8enIMfTSB2tpGy3EfnpJZtkWYeJuyp0HjmG2y2N0oBll+HQzBqYCTsWWN5nlRjR4BwWOOJTBrLgCdn7oMrbOzWtbusl7skTZ++yEcbLKvrXvzoL/ggdt9n0rnhZeh+APoiTgtHzqByFkrm5qsNhVnGtnTCCAnahSLnHhqPMXJKAGhoxfRcca5pH7/LAfuuwtF0+i56noCs2YjhbO+ZuxxqosXu10BMvd/L8Ok12DqyK9A9BMX4eueRvJXG0g8/iPSr7xIy6Lj6fnMteDTqrZwiPbIJu6bdbkD5NYnZX0FXt25Wl5AsPcYui68jFz/Nia2PE8xMcq+u25EHxul54rPEf2nCxCiVp+TNxxOd7TLahikHQublzHMiLsEzqoc6cBbfh79xEUEZs0hsf5hCgeGwQcTL/+e4btvQw21MPOrt9J2whKEUavDoR6u9iAdGstl4HBaqaiJQdKm0Ow99iHVblwN0g5KhYDQUR+g59KryO/ZRfI3T5dSfEAKyYGf3cvIz/6DYO9R9H5vHR1LT0caUyOPueLCgz3SZI+0tz7O5esCZPckt7jkyOfhAOg87xICM+dwcOOj5AbfnUoOFRDZLEN3fJ34Iw8SOnoh8/79YTpXrkbxBxAGpUMvHbL8KwzTuU51unJI9tmQqpnNO51D7cYBM4/iwm/mLXkIhI5aQNeqT5N7521GHl9XalXbbgh9bIz3bvoXCgeGOeLKzzPvew/RfvIy4o+vQw2ECMyagy8SQVF9KL4gis+HLBQQooAxnmTyta3k3t2JNIyalc16+yadvKhmPUiaBLkBUG9YtYNnKadC90VXEJw7j8HbvkZ+aKDkw5LSkAQofg1/dzf+aTPIDw2Q3dFH20lLmHb5Wro+uRo0H6o/gJ4aQxTypUX3au0V1JYwMp/jwI9/yP7770QWC6722BvciequB9mBqkeNeKWA8MIP0r3q00xue434+nVUVlx9sRihuUcTPfUfCR/7IcLHLkaLxEBKjPQ4yU3PInJZOj6yHF8kiiwUmNjyP4ys/xG5Pf1loBRQfQSmzaT95GVEz/g4Y5t+SWb7aw2zPXMYaQyQQ9Q/HGCmNGlMv+xa/NOOYOi7NyMMg9jHVhBZdibtJyzB3zUdPTVGfu97xDf8nNzAO2R3vImeGkUfG0UKQevxH6Zn1WeInXUunSsuoO3EUxh/8b9JPv8ck2++Wirz7gCpV14i+cJv0ccOVgeARlR9heg1BtkrX9c7XK6ri+sGRE5cStd5F1Pct5fwwsX0XPBptI4IuYHdJJ55ksk3/kSm7zWMdAojVyyVr+y4KldyYuvLpP+8heEf30Pn2SuJnv4xYmevoGvlxRipJOk3/kR+3wCKolCMx9l7zy2Wethts9veOAZJkxfZ3o855R2V7b6VVz9uuYmvvY0jr70BXzRKeuAdpK4z9INbyex4k2JiGJEv72HRynj4rC5ffdOigZCSyR3bmdyxnX3r7qZl/gLCHziejqWnEeqdT/gDH8SYTJN45kn0zOTUHiO7xzjY7K2LYe1qVQ91cKGaXMP8TIDW2oqq+Yme8XGip5/N+JbN9F97CcX9Q0hReh2GQvVlnDlzd9OjQCmmKGBMTjDx+qtMvPYqIxt+ihIIlLb9CoHI56vv8tzIXEc3trpdTHF46CTIoqDcMh2nnEr4qIVk+rcz89qvIHI5hu6+lcLeoRIgWq1ee3e2D832nR1VsAApBTKfszYo7jrsLBXHsG/79PRezLUF7NcGBKZNY8bl1xGa3cvg3bdwxKX/TOtxH2L4pw+QfPF3td7iIE+Uja/8eol9ssHzemXMSaK9jGsXc1Ng5rUYL6D1uMXM++ZdoCrs/NJnaV24mOlrriS7q5+h+7+DKBRL3cqj/EY8de1pgup9VuIIkP3cKQu1dAMBbcf/PQu+/xOMTJr+ay4BKZl7wy2owRCDP7id7O5dKFrziZobr5M9Xso7gWI6kYV6w7xlOdJhE5NjBi0gfNQCFnz/x2gtYfqvu5TiaJxj7nyQ1uMWs++hexl5+lHrhgRbDZtp9Ubdyolcd5eYzsuxRyStb56tABmALpswWIIaDDL781+nZf4C+q/7DJldbzHvhtvoOX81yT/8jsF7bkUUCigqtfMuB0WVnSLlmYPr1hdXk6RJjkmN286UCm/5tBC37Zq1bsGTkJclNFXp7P6Wvi6gZd4COs88h/h/PUHylc303nAbM6/+Iuntr7PrxuvJ7d9XBccpHQCruzut/ZhHUDd7as4d7K9Z0zLdFxJ0SWakHkAZAXlBUZS7mJfRQxTzFPbvRU8lWXTvo0SWLCf54vPs+tb1pN/aVgKnjgzzVpZGGx8OZTTz2hsEoEvGDtoAskSGYklaQpb2czYmFTJ7dtK3djX6xDjG5CS7vvEF+q6+iHTfG1VwnEZH8zceTutLFaq3GcorIHYAnfQARQWG6wZpDQiqDAATEjrrrfdMaZSk3+4jfdc3Uf0+REEvTUFcPKdRbuNWqUNZfmkQ7iz2KDARVBmwjyUWgMYMkJCIaqT8Cp2KTWGFalq1LFXo+lRmi3O8cKuwHQy3Mp7scQGmHmAFSTJlELeXtwCWKMKuHHFdsqMy9Dml3/UybdnE4VZG2H4xXVcOL/a4eZY9bRFAUbJjV45E3Rg0CnwqRi4t2GzIxl2hXqWdWtvLx8+Kh/Nm7HFrjIpMCRgSJgSbV3WSS9Xb/rLAB2/mYNxgQ04yIBso92Jso2vZ4Bq879jw0phO13nJwITBxm1ZONomxALQtUnYW4Rrxtg5KXjMkFZhzRhwqJXxMhVxk+E0O29kjyFhUvDoNWO8PVSEtbZv6mpWa0MK3BtD7i9yX1qwRdQR7iWeuCWH1JHjNXZBfS+s3KtOnxz404It+4vcd28MWhz6sWPX3jAdcgakBcuO8PFIq8tHvQ1nmg7PzdMNc9Zb83WhyXs9/6MC0xTFC00aDA7rrGlT2RxS4YKRWh7H9f53MrAtCyuibB7RWTspGLRsUDK3mMSy4uc0StS8MZBWcLDLkVPAVCJpzb4B+68JTKe9SHZdkwaDIzprV0TYvC0Lu21fT1fI8bv53xbgvDBsmYTLutj5xwxbfQqL/AqznKYGXqYDh0tuo2HNCKi4l0MpxZy0YEsZnE0PJqBDg38dd9Zb1xnviJSSxw+GIKEze7qPq8MqlwRVeivLyWajndaAG/XCZgCq96GwY8A2PTCAgmQgbfDYiM59PT7e68tCzAdfTrnr1ahDm/KwMghdAcgJxq8Y5fenBni2KBlCoWhINKX0OtwvQPOSHB7ODjbA9bOraiIpS2AYpallKicYzkm2JA0eTuh87YpRnvxEC6moH7K6u+dYgPZCt3dAVsAMPxwVhOfGCfUG6Y6o9GQlc4AZGkQ1hRYJQWmaxrh5kb2bHo6nKaArkNclWQOSCgy3qAykDBLv5Yl/PEquPwf7CxBU4avjnuU2Rw93wv9mYKYfIj6IalCQpe/Mohq0adDjg5hq7XaVf4hSOa+AUhl5JKURo5JWaPbllnI5c9pR6UFCwqgBCQMmjNLn4kUJfqX0/z1SBrwr4SMqXJ7ifXqf3qf/P/R/ShQShKVd6yQAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMTItMjhUMDk6MzE6NTYrMDA6MDC4axO5AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTAxLTA4VDE5OjQzOjU5KzAwOjAwnbLSDAAAACB0RVh0c29mdHdhcmUAaHR0cHM6Ly9pbWFnZW1hZ2ljay5vcme8zx2dAAAAGHRFWHRUaHVtYjo6RG9jdW1lbnQ6OlBhZ2VzADGn/7svAAAAGHRFWHRUaHVtYjo6SW1hZ2U6OkhlaWdodAA1MTKPjVOBAAAAF3RFWHRUaHVtYjo6SW1hZ2U6OldpZHRoADUxMhx8A9wAAAAZdEVYdFRodW1iOjpNaW1ldHlwZQBpbWFnZS9wbmc/slZOAAAAF3RFWHRUaHVtYjo6TVRpbWUAMTU0Njk3NjYzOTogPbcAAAATdEVYdFRodW1iOjpTaXplADE4Mzc0NkJvZ7DBAAAAWnRFWHRUaHVtYjo6VVJJAGZpbGU6Ly8vZGF0YS93d3dyb290L3d3dy5lYXN5aWNvbi5uZXQvY2RuLWltZy5lYXN5aWNvbi5jbi9maWxlcy8xMTgvMTE4NDI1NS5wbmcVP1e2AAAAAElFTkSuQmCC)}.fv-upload-and-preview .ffilepreview--filetype-img{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5AIKAx4vKar87wAAByBJREFUeNrtnEtv29gZhp/vHFIXy5f4OoknbdPAQQsPZtBNgGZQYNCi6GWZxSz7P1r0R/Q3tOtidtOuBy6aFJ0OUBTpLXGSqR3PxJIpWqJEkRR5upCixLEtShZtyYnejSTykDrfo+9yziFFmGqqUSSvfnAch7m5OSqVCr7vY4wZd/8uBoIIhUKB1dVV6vU6S0tLxwE5jsP8/DxbW1tsbm5eD4LgjoisjLvzFyFjTCWfz997+PDh7u3bt2k0Gj1IPUBRFLG1tcXGxsaParXab4IgeA/Q4+78BSnO5/MP5ufnf3X//v0/3L17F9u2jwLa29tDa329XC5/6nneB+Pu8ThUKpUerK2t/SyO49319XUA1IudrVaLIAjudD3nrVQYht8NguBOq9XqbesBMsbQzTlvS1idJC0iK68WJ2uQo+RosXtjZEiv0qmABOFvz7/gUXUbEZV6wsshw4w9ww+/8RElu9QX1EAe9Ki6zWe7Wyh5M6LPmITl4hIfrn+fUq5EP0caLMREoUSj3xAPMsjAP3bmFhsYILIvjzIBZIAEIS8xSypkVtrQ3XbZNVCI9ZMBrqiQH+T2ec+qsqwCmsbicXuOP4Xv8CSeHbeN4wOUIHxLe/yiuM0tq4Z0gQlwU3t8zz7g960b3AvXxm3nmXXmEDPAnER8XHzKd6xaN8zovcbAsgr5uPCUW1bt0obbCICE9+0qm5ZLfEqbpAvpo9zXWCTjtvViAQmGm7qOnVKzDHBdNyhKfCmr20hVbBCvMEBRYnISp59wGF0Q7REACcEA81oBPGMRmOxG4Umc4Ow4tOotzju1jZSk/9W+gm9Uah+32/M0jZWZLfX9OodfHeLuVonDjD0zK0AKw7/bC/w1WjnVcAU8i4t8Fl7NpooJ+K6Pu+cC4NdaVHer57p2PlIOCozik9YN/hyu0kahuyfUHVv4Mi7xO3+D3XgGNWrSEIj8CGfHIYle5j6v4lHfr58boJEGigI4SY7f+ht8Hq2wablc1T6esfhve4G/R0tUknwmoZW0E9xdl7ARHsk7JjG4z1xyxRyFhULmyXvkqYYALaP5PFrhi2gZm4QYoY1CMJnlndrzGp7jnZiU4zDG2XFYy69hFaxMIWUyWRXohVCEIkFQGcJpuk0OvzrEJKdYLtCqt6juVEna2Q5IJ36BJ4kTfNfHLtjkZ3InttGWojCbJwqiTunPUCOH2HlLacXSNxcxBpz/OYR+dLyNrVm5uYqVz96cifcgANEK3/XxKt6J+yM/ol6uI0pQOluTJh9Qt7y7z1xMfHr2re/XaVabmY+sJx6QiTtlPGyGfY1/0S46IQRH0WQDEmg4DRpOI90zBMJGiLvnnl7t3ihAXYOru9XBDRZoHDTwDrzB2g+gY4CMMSfMbS7+WkVn5Fyl3WoPddyRkBzogH52v1LmlVKIyMvbPuSlT2tLo7Q6su285T33aB76oIf/znbYxt1zWd1YPbWqKS1Yto1t2xg6cGzbRkRQ6uUxPUBzc3OICNeuXTtCUolisbpIwS+gL+LKanfG7tUbqJI+U1EyQBCFhFHI4juLx/YnJqE0U+Ldd9dZnVklMZ3Rt4igtaZQKBwH9IKaZR0dbIkIytKIlvP3IIE4iKk8PaAdtjuJ+QzfKaYTMs5OlcJCkZnF4pEMoVCIVli2hW3bPUCv2nwM0KQoCiLyszlypc60onHQIGoNXrpFCbPLs1h5jUkgDtvH06d59W3/3DpZgAwU5goU5gqICN6BR7083FqPSQxWXrN2aw1RMnJtmcwyL9DyWjx/uE8cDL+k6u4d4j5zMym8EwkojmLKjyuEXnimqYNJDJUnBzSqzZHz5sQBMqZjnFf2RppXxWFM+dE+LS8Y6TwTB6j2da0THqNKOov6lcflI2vYw2pyAAk0q03K25W+s/ahTilCvexx8OXBma98TEwVi5oR+4/2OyX9xW0iJ1t9fFuK8c5OldxMjoVrC5cUkAHPaaC0orRU6t/hWoxqmpcQNUTLGqP7lXRD0/UpLZWGXnWcDEACV64tcCXlFzbAwl98Sk+CTnIwEM8qDj6cpV3qf4XXGNMZFw2pyQAEA3VeBBSCNtKJKgPGSHeptf+g8Kz3ek9Okh5CF7nwMpAHGZMQJzGcwUUzlYEkiUmSuEcpSQxJkhAPsWRlTEJikoGapwMysD67zger76PGfZ+0wOxGQMGOeoO/pKi4erVIXBx83mUwLOavkFN26jGpgAyGn3/7p/zkxo/HC+cFo9scM+ostx6JCJayspnNa6XRk/InoAvuxqVM0hepKaAUTQGlaAooRVNAKZoCStEUUIqmgFI0BZSiKaAUTQGl6HVAFeB8//ww2Yq7DHp6HdA94MG4ezlG/afLoKfXAe0Cv6QD6W3ypBj4J/DrLoOeTlru+CPwD+AO8FY8YIlOWN3jNThwwiO6puLII7qmmmo0/R/bJffeYyphcAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOS0xMi0yOFQwOTozMTo1NiswMDowMLhrE7kAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTktMDEtMDhUMTk6NDM6MjIrMDA6MDCVcI/vAAAAIHRFWHRzb2Z0d2FyZQBodHRwczovL2ltYWdlbWFnaWNrLm9yZ7zPHZ0AAAAYdEVYdFRodW1iOjpEb2N1bWVudDo6UGFnZXMAMaf/uy8AAAAYdEVYdFRodW1iOjpJbWFnZTo6SGVpZ2h0ADUxMo+NU4EAAAAXdEVYdFRodW1iOjpJbWFnZTo6V2lkdGgANTEyHHwD3AAAABl0RVh0VGh1bWI6Ok1pbWV0eXBlAGltYWdlL3BuZz+yVk4AAAAXdEVYdFRodW1iOjpNVGltZQAxNTQ2OTc2NjAyht+3/AAAABJ0RVh0VGh1bWI6OlNpemUAMjU4MjFCXXziJwAAAFp0RVh0VGh1bWI6OlVSSQBmaWxlOi8vL2RhdGEvd3d3cm9vdC93d3cuZWFzeWljb24ubmV0L2Nkbi1pbWcuZWFzeWljb24uY24vZmlsZXMvMTE4LzExODM3MDcucG5nZ8+z2wAAAABJRU5ErkJggg==)}.fv-upload-and-preview .ffilepreview--filetype-doc{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--filetype-any{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--filetype-wps{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--filetype-wpt{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--item-icon{margin:0 .625rem 0 0}.fv-upload-and-preview .ffilepreview--filetype-icon{display:inline-block;width:38px;height:38px;background-repeat:no-repeat;background-position:0 0;background-size:cover}.fv-upload-and-preview .smooth-dnd-ghost.uploadAndpreview--preview-item.smooth-dnd-draggable-wrapper{background-color:#dae9ff}.fv-upload-and-preview .upfile-drag-handle{position:relative;top:-2px;margin-right:5px;cursor:grab}.fv-upload-and-preview .upfile-drag-handle:active{cursor:grabbing}.fv-upload-and-preview .upload-progress{display:inline-block;font-size:.875rem;color:rgba(0,0,0,.65)}.fv-upload-and-preview .upload-progress.upload-progress-line{position:relative;width:100%}.fv-upload-and-preview .upload-progress.upload-progress-line .upload-progress-text .upload-progress-text-icon{font-size:1.25rem}.fv-upload-and-preview .upload-progress .upload-progress-outer{display:inline-block;width:100%}.fv-upload-and-preview .upload-progress .upload-progress-inner{position:relative;display:inline-block;width:100%;overflow:hidden;vertical-align:middle;background-color:#efefef;border-radius:100px}.fv-upload-and-preview .upload-progress .upload-progress-bg,.fv-upload-and-preview .upload-progress .upload-progress-success-bg{position:relative;border-radius:100px;height:6px;transition:all .4s cubic-bezier(.08,.82,.17,1) 0s}.fv-upload-and-preview .upload-progress .upload-progress-success-bg{position:absolute;top:0;left:0}.fv-upload-and-preview .upload-progress .upload-progress-text{display:inline-block;width:1.75rem;margin-left:.5rem;color:rgba(0,0,0,.65);font-size:1em;line-height:1;white-space:nowrap;text-align:left;vertical-align:middle;word-break:normal}.fv-upload-and-preview .upload-progress.upload-progress-status-active .upload-progress-bg::before{position:absolute;top:0;right:0;bottom:0;left:0;background:#fff;border-radius:.625rem;opacity:0;animation:upload-progress-active 2.4s ease-in-out infinite;content:""}.fv-upload-and-preview .upload-progress-show-info .upload-progress-outer{padding-right:48px;margin-right:-48px}@keyframes upload-progress-active{0%{width:0;opacity:.1}20%{width:0;opacity:.5}100%{width:100%;opacity:0}}.fv-upload-and-preview .uploadAndpreview--action-container .preview-btn{color:var(--f-theme-03)!important;background:var(--f-aid-02)!important}.fv-upload-and-preview .uploadAndpreview--action-container .preview-btn:not([disabled]):hover{background:var(--f-theme-05)!important}.fv-upload-and-preview .uploadAndpreview--action-container .preview-btn:not([disabled]) .f-icon:hover{color:#fff;width:22px}.fv-upload-and-preview .uploadAndpreview--table .uploadAndpreview--currentfile{background-color:var(--f-aid-02)}.fv-upload-and-preview .uploadAndpreview--table .uploadAndpreview--currentfile .preview-btn{background-color:var(--f-aid-03)}.f-verify-list .list-icon,.f-verify-nums .nums-count,.f-verify-nums .nums-icon{color:var(--f-semantic-danger-01)}.f-verify-list .list-warning{color:var(--f-semantic-warning-01)}.f-verify-detail{position:absolute;left:14px;bottom:16px;z-index:900}.f-verify-detail .f-verify-detail-content{position:relative}.f-verify-detail .f-verify-detail-content .f-verify-form-main{position:absolute;padding-bottom:.5rem;left:0;bottom:1.75rem;width:28.125rem}.f-page-has-query .f-page-header .f-page-header-base,.f-page-has-scheme .f-page-header .f-page-header-base,.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-title{padding:.75rem .875rem}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content{border-radius:4px;width:100%;overflow:hidden}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-arrow{display:block;position:absolute;left:1.125rem;bottom:.25rem;width:.625rem;height:.625rem;background:0 0;border-style:solid;border-width:.3125rem;transform:translateX(-50%) rotate(45deg)}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list{position:relative}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-close{position:absolute;right:.75rem;top:.625rem;font-size:.75rem;cursor:pointer;width:1.25rem;height:1.25rem;line-height:1.25rem;text-align:center}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list{overflow-y:auto}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list .f-verify-list-content{display:none}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list .f-verify-list-content.active{display:block}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list .f-verify-list{cursor:pointer;position:relative;padding:.5rem .875rem .5rem 2.5rem;list-style-type:none}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list .f-verify-list .list-icon{position:absolute;left:.875rem;top:.75rem;font-size:.875rem}.f-page,.f-page-root{bottom:0;right:0;left:0;overflow:hidden;position:absolute}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list .f-verify-list .list-con p{margin-bottom:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list .f-verify-list .list-con .list-title{font-size:.875rem;line-height:1.375rem}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list .f-verify-list .list-con .list-msg{font-size:.75rem;color:rgba(0,0,0,.45);line-height:1.25rem}.f-verify-detail .f-verify-nums{padding:.125rem .5rem;cursor:pointer}.f-verify-detail .f-verify-nums .nums-icon{margin-right:.25rem;vertical-align:middle}.f-verify-detail .f-verify-nums .nums-count{font-size:.875rem;line-height:1.25rem}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content{background:var(--f-neutral-20);box-shadow:0 2px 8px 0 rgba(var(--f-neutral-15-rgb),.15)}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-arrow{box-shadow:2px 2px 5px rgba(var(--f-neutral-15-rgb),.08);border-color:transparent var(--f-neutral-20) var(--f-neutral-20) transparent}.f-verify-detail .f-verify-forms-title .btn-group{border-radius:14px;padding:3px;background:var(--f-aid-04)}.f-verify-detail .f-verify-forms-title .btn-group .verify-title-btn{color:var(--f-text-02);border:1px solid var(--f-neutral-08);background:var(--f-neutral-12);box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06);margin:0;border-radius:0}.f-verify-detail .f-verify-forms-title .btn-group .verify-title-btn:first-child{border-radius:14px 0 0 14px}.f-verify-detail .f-verify-forms-title .btn-group .verify-title-btn:last-child{border-radius:0 14px 14px 0}.f-verify-detail .f-verify-forms-title .btn-group .verify-title-btn.disabled{color:var(--f-text-07);border-color:var(--f-neutral-05);background:var(--f-neutral-08);box-shadow:none}.f-verify-detail .f-verify-forms-title .btn-group .verify-title-btn+.verify-title-btn{margin-left:-1px}.f-verify-detail .f-verify-forms-title .btn-group .verify-title-btn.f-state-selected{color:var(--f-text-00);border-color:var(--f-theme-03);background:var(--f-theme-04);box-shadow:0 4px 10px 0 rgba(var(--f-theme-03),.2)}.f-verify-detail .f-verify-forms-title .f-verify-close{color:var(--f-text-07)}.f-verify-detail .f-verify-forms-list .f-verify-list-content{padding:0}.f-verify-detail .f-verify-forms-list .f-verify-list-content .f-verify-list{border-top:1px dotted var(--f-neutral-05)!important;padding:.5rem .875rem .5rem 2.5rem}.f-verify-detail .f-verify-forms-list .f-verify-list-content .f-verify-list:last-child{border:none}.f-verify-detail .f-verify-forms-list .f-verify-list-content .f-verify-list .list-icon{color:var(--f-semantic-danger-01)}.f-verify-detail .f-verify-forms-list .f-verify-list-content .f-verify-list .list-icon.list-warning{color:var(--f-semantic-warning-01)}.f-verify-detail .f-verify-forms-list .f-verify-list-content .f-verify-list .list-con .list-title{font-size:.875rem;color:var(--f-text-02);line-height:1.375rem}.f-verify-detail .f-verify-forms-list .f-verify-list-content .f-verify-list .list-con .list-msg{font-size:.75rem;color:rgba(var(--f-text-06),.9);line-height:1.25rem}.f-verify-detail .f-verify-nums{border-radius:6px!important;background:var(--f-semantic-danger-03);box-shadow:0 2px 8px 0 rgba(var(--f-neutral-15-rgb),.15)}@font-face{font-family:FarrisIcons;font-style:normal;font-weight:400;src:url(data:font/ttf;base64,AAEAAAALAIAAAwAwR1NVQiCLJXoAAAE4AAAAVE9TLzI2JE+JAAABjAAAAGBjbWFwTohH7gAAC/AAACWUZ2x5ZqfrFDEAADaIAAH0DGhlYWQnvvaKAAAA4AAAADZoaGVhCNUHTgAAALwAAAAkaG10eApz/50AAAHsAAAKBGxvY2GWVxNEAAAxhAAABQRtYXhwA6wBEAAAARgAAAAgbmFtZchH0mwAAiqUAAACi3Bvc3QSpDltAAItIAAAK3cAAQAAA4D/gABcBVX/9v/3BQAAAQAAAAAAAAAAAAAAAAAAAoEAAQAAAAEAAGP+/t1fDzz1AAsEAAAAAADh1NlIAAAAAOHU2Uj/9v9xBQADjAAAAAgAAgAAAAAAAAABAAACgQEEACEAAAAAAAIAAAAKAAoAAAD/AAAAAAAAAAEAAAAKADAAPgACREZMVAAObGF0bgAaAAQAAAAAAAAAAQAAAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAQEAgGQAAUAAAKJAswAAACPAokCzAAAAesAMgEIAAACAAUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBmRWQAwOAA7LcDgP+AAAAD3ACPAAAAAQAAAAAAAAAAAAAAAAACBAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAD//wQA//8EAP//BAD//wQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAQAABAD/+QQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP/5BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP/2BAD/9gQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//kEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAP//BAD//wQA//8EAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEVQAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABEQAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEkgAABJIAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAASSAAAEAAAABJIAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAD//wQAAAAEAAAABAAAAAQAAAAEAP/9BAAAAAQAAAAEAAAABAD//wQA//8EAP/9BAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAREAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQB//8EAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQ8AAAENf/+BAAAAAQA//8EAAAABAD//wQAAAAEAP//BAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQB//4ETgAABAAAAAVVAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAE/wAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAAAAAFAAAAAwAAACwAAAAEAAAHMAABAAAAAAYqAAMAAQAAACwAAwAKAAAHMAAEBf4AAAA4ACAABAAY4DLhSeIO4wrlKuYr5kPmmua85tfnBegs6SLrGOs/60/rb+t/64nrqeu568nr2evp6/nsqey3//8AAOAA4QDiAOMA5QDmAOYt5kXmvObX5wDoAOkA6wTrGutB61HrceuB65rrsOvA69Dr4evw7KDssP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAOACcAS4BSgFeAbICCAI0At4C3gLeAugDQAOEA6wD9gQSBE4EagR6BJgEqgS8BM4E3gTwBQIAAAGPAGsAZgBhAoACfgJ/An0AZwBlAGIAZAJzAnECcgJwAngAYwBsAnwCegJ7AnkAbQBoAGkAagBeAA8AEQAVABMAEgBYAFMCdgJ3AnUBrwBSAFYAUQBZAF0AXwBgAFoCbwBOAFUCXgAEAE8AWwA5ABQAOgA9AAMBrwA/AFwASwJ0AEYAQgBKADwANwA7ADgAPgAKAAgABwBAACECawJsAEgCagHpAm0AKgHoAm4AIwAkACkAJgAWAA0AJQBBAEUATABJAEQARwAoACcAIAAiADYALgAvADIBsAA1Ak4ATQBDAAkCaQBXADQAFwAMADEALQAsADMAMAArAB0AGgAZAAsAHwAbABwAGAAeAAYABQAQAFAAVAGOAYUBiQGMAmgCZwHnAkkCQAGHAYsCSAJHAY0BiAGGAYoBfAGDAX8BgQGCAYABewGEAX4BfQF1AXMBcQFyAXkBdwF6AXQBeAF2AWoBbQFvAWcBaQFsAW4BcAFoAWsBZgFiAV0BZAFfAWEBYwFeAWUBYAFDAUgBSQFAAUIBRgFHAUUBQQFPAVABTQFLAU4BTAFEAVwBWgFbAVYBVAFXAVgBVQFZAVIBUwFKAVEBAAECAQEA/wD6ASYBPQEsATsBOQEvAPsBKgE0APwBBwEJAREBCgEIAQ0BBgEFAQ4BAwEQATMBIQEgAPUAkAE3ARkBMgD4AI4AigEkAI8AiwEXAP0BOgE+AT8BMQD+ARUBEwESAR8A+QEbARQBGAEaATUBIgDzASMBKwELARwBHgEoAScBJQEtATgBNgEEAQwBFgD3APIBKQD0AS4BMAE8AR0BDwCMAI0AngCXAJ8AkQCTAJ0AqACmAKAApwClAKsAnACWAJIAlACbAJoAlQCYAH4AfACjAKQAqgCtAK4AoQB9AIEAiQCHAIQAiACAAIYAhQB7AKkB5wD2AIIAfwCDAG4AegB5AHgAdwB2AHMAdAB1AHIAcQBvAHAArACiAJkA5gDsAOsA7gDpAOoA7wDnAOMA5ADwAO0A5QDoAPEA2QDbANoA4gDcAN4A3QDfAOAA4QDXANAA0wDRANYA1QDUANIAzwDYAMYAzADIAMkAxQDOAMoAxwDNAMsAwQDAAMMAvADCALsAxAC/AL0AvgCwALkArwC1ALQAtgCyALgAsQC6ALcAswJfAlwCYAJmAmUCZAJjAmICYQJdAlsCWgJZAlMCVgJRAlICVAJVAlcCWAJQAk8CTgJNAkwBsAJLAkoCRQJGAkECQgJDAkQCMQIwAj8CPgI9AjwCOwI4AjkCOgIzAjQCNQI2AjcCMgIvAi4CLQIsAisCKgIpAigCJwImAiUCJAIjAiICIAIhAh8CHgIdAhwCGwIaAhkCGAIXAhYCFQIUAhMCEgIRAhACDwIOAg0CDAILAgoCCQIIAgcCBgIFAgQCAwICAgECAAH/Af4B/QH8AfsB+gH5AfgB9wH2AfUB9AHzAfIB8QHwAe8B7gHtAewBrwHrAeoB5gHlAeQB4wHiAeEB4AHfAd4B3QHcAdsB2gHZAdgB1wHWAdUB1AHTAdIB0QHQ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AAAAhAAA5pUAAOaVAAAAiAAA5pYAAOaWAAAAgAAA5pcAAOaXAAAAhgAA5pgAAOaYAAAAhQAA5pkAAOaZAAAAewAA5poAAOaaAAAAqQAA5rwAAOa8AAAB5wAA5tcAAObXAAAA9gAA5wAAAOcAAAAAggAA5wEAAOcBAAAAfwAA5wIAAOcCAAAAgwAA5wMAAOcDAAAAbgAA5wQAAOcEAAAAegAA5wUAAOcFAAAAeQAA6AAAAOgAAAAAeAAA6AEAAOgBAAAAdwAA6AIAAOgCAAAAdgAA6AMAAOgDAAAAcwAA6AQAAOgEAAAAdAAA6AUAAOgFAAAAdQAA6AYAAOgGAAAAcgAA6AcAAOgHAAAAcQAA6AgAAOgIAAAAbwAA6AkAAOgJAAAAcAAA6AoAAOgKAAAArAAA6AsAAOgLAAAAogAA6AwAAOgMAAAAmQAA6A0AAOgNAAAA5gAA6A4AAOgOAAAA7AAA6A8AAOgPAAAA6wAA6BAAAOgQAAAA7gAA6BEAAOgRAAAA6QAA6BIAAOgSAAAA6gAA6BMAAOgTAAAA7wAA6BQAAOgUAAAA5wAA6BUAAOgVAAAA4wAA6BYAAOgWAAAA5AAA6BcAAOgXAAAA8AAA6BgAAOgYAAAA7QAA6BkAAOgZAAAA5QAA6BoAAOgaAAAA6AAA6BsAAOgbAAAA8QAA6BwAAOgcAAAA2QAA6B0AAOgdAAAA2wAA6B4AAOgeAAAA2gAA6B8AAOgfAAAA4gAA6CAAAOggAAAA3AAA6CEAAOghAAAA3gAA6CIAAOgiAAAA3QAA6CMAAOgjAAAA3wAA6CQAAOgkAAAA4AAA6CUAAOglAAAA4QAA6CYAAOgmAAAA1wAA6CcAAOgnAAAA0AAA6CgAAOgoAAAA0wAA6CkAAOgpAAAA0QAA6CoAAOgqAAAA1gAA6CsAAOgrAAAA1QAA6CwAAOgsAAAA1AAA6QAAAOkAAAAA0gAA6QEAAOkBAAAAzwAA6QIAAOkCAAAA2AAA6QMAAOkDAAAAxgAA6QQAAOkEAAAAzAAA6QUAAOkFAAAAyAAA6QYAAOkGAAAAyQAA6QcAAOkHAAAAxQAA6QgAAOkIAAAAzgAA6QkAAOkJAAAAygAA6QoAAOkKAAAAxwAA6QsAAOkLAAAAzQAA6QwAAOkMAAAAywAA6Q0AAOkNAAAAwQAA6Q4AAOkOAAAAwAAA6Q8AAOkPAAAAwwAA6RAAAOkQAAAAvAAA6REAAOkRAAAAwgAA6RIAAOkSAAAAuwAA6RMAAOkTAAAAxAAA6RQAAOkUAAAAvwAA6RUAAOkVAAAAvQAA6RYAAOkWAAAAvgAA6RcAAOkXAAAAsAAA6RgAAOkYAAAAuQAA6RkAAOkZAAAArwAA6RoAAOkaAAAAtQAA6RsAAOkbAAAAtAAA6RwAAOkcAAAAtgAA6R0AAOkdAAAAsgAA6R4AAOkeAAAAuAAA6R8AAOkfAAAAsQAA6SAAAOkgAAAAugAA6SEAAOkhAAAAtwAA6SIAAOkiAAAAswAA6wQAAOsEAAACXwAA6wUAAOsFAAACXAAA6wYAAOsGAAACYAAA6wcAAOsHAAACZgAA6wgAAOsIAAACZQAA6wkAAOsJAAACZAAA6woAAOsKAAACYwAA6wsAAOsLAAACYgAA6wwAAOsMAAACYQAA6w0AAOsNAAACXQAA6w4AAOsOAAACWwAA6w8AAOsPAAACWgAA6xAAAOsQAAACWQAA6xEAAOsRAAACUwAA6xIAAOsSAAACVgAA6xMAAOsTAAACUQAA6xQAAOsUAAACUgAA6xUAAOsVAAACVAAA6xYAAOsWAAACVQAA6xcAAOsXAAACVwAA6xgAAOsYAAACWAAA6xoAAOsaAAACUAAA6xsAAOsbAAACTwAA6xwAAOscAAACTgAA6x0AAOsdAAACTQAA6x4AAOseAAACTAAA6x8AAOsfAAABsAAA6yAAAOsgAAACSwAA6yEAAOshAAACSgAA6yIAAOsiAAACRQAA6yMAAOsjAAACRgAA6yQAAOskAAACQQAA6yUAAOslAAACQgAA6yYAAOsmAAACQwAA6ycAAOsnAAACRAAA6ygAAOsoAAACMQAA6ykAAOspAAACMAAA6yoAAOsqAAACPwAA6ysAAOsrAAACPgAA6ywAAOssAAACPQAA6y0AAOstAAACPAAA6y4AAOsuAAACOwAA6y8AAOsvAAACOAAA6zAAAOswAAACOQAA6zEAAOsxAAACOgAA6zIAAOsyAAACMwAA6zMAAOszAAACNAAA6zQAAOs0AAACNQAA6zUAAOs1AAACNgAA6zYAAOs2AAACNwAA6zcAAOs3AAACMgAA6zgAAOs4AAACLwAA6zkAAOs5AAACLgAA6zoAAOs6AAACLQAA6zsAAOs7AAACLAAA6zwAAOs8AAACKwAA6z0AAOs9AAACKgAA6z4AAOs+AAACKQAA6z8AAOs/AAACKAAA60EAAOtBAAACJwAA60IAAOtCAAACJgAA60MAAOtDAAACJQAA60QAAOtEAAACJAAA60UAAOtFAAACIwAA60YAAOtGAAACIgAA60cAAOtHAAACIAAA60gAAOtIAAACIQAA60kAAOtJAAACHwAA60oAAOtKAAACHgAA60sAAOtLAAACHQAA60wAAOtMAAACHAAA600AAOtNAAACGwAA604AAOtOAAACGgAA608AAOtPAAACGQAA61EAAOtRAAACGAAA61IAAOtSAAACFwAA61MAAOtTAAACFgAA61QAAOtUAAACFQAA61UAAOtVAAACFAAA61YAAOtWAAACEwAA61cAAOtXAAACEgAA61gAAOtYAAACEQAA61kAAOtZAAACEAAA61oAAOtaAAACDwAA61sAAOtbAAACDgAA61wAAOtcAAACDQAA610AAOtdAAACDAAA614AAOteAAACCwAA618AAOtfAAACCgAA62AAAOtgAAACCQAA62EAAOthAAACCAAA62IAAOtiAAACBwAA62MAAOtjAAACBgAA62QAAOtkAAACBQAA62UAAOtlAAACBAAA62YAAOtmAAACAwAA62cAAOtnAAACAgAA62gAAOtoAAACAQAA62kAAOtpAAACAAAA62oAAOtqAAAB/wAA62sAAOtrAAAB/gAA62wAAOtsAAAB/QAA620AAOttAAAB/AAA624AAOtuAAAB+wAA628AAOtvAAAB+gAA63EAAOtxAAAB+QAA63IAAOtyAAAB+AAA63MAAOtzAAAB9wAA63QAAOt0AAAB9gAA63UAAOt1AAAB9QAA63YAAOt2AAAB9AAA63cAAOt3AAAB8wAA63gAAOt4AAAB8gAA63kAAOt5AAAB8QAA63oAAOt6AAAB8AAA63sAAOt7AAAB7wAA63wAAOt8AAAB7gAA630AAOt9AAAB7QAA634AAOt+AAAB7AAA638AAOt/AAABrwAA64EAAOuBAAAB6wAA64IAAOuCAAAB6gAA64MAAOuDAAAB5gAA64QAAOuEAAAB5QAA64UAAOuFAAAB5AAA64YAAOuGAAAB4wAA64cAAOuHAAAB4gAA64gAAOuIAAAB4QAA64kAAOuJAAAB4AAA65oAAOuaAAAB3wAA65sAAOubAAAB3gAA65wAAOucAAAB3QAA650AAOudAAAB3AAA654AAOueAAAB2wAA658AAOufAAAB2gAA66AAAOugAAAB2QAA66EAAOuhAAAB2AAA66IAAOuiAAAB1wAA66MAAOujAAAB1gAA66QAAOukAAAB1QAA66UAAOulAAAB1AAA66YAAOumAAAB0wAA66cAAOunAAAB0gAA66gAAOuoAAAB0QAA66kAAOupAAAB0AAA67AAAOuwAAABzwAA67EAAOuxAAABzgAA67IAAOuyAAABzQAA67MAAOuzAAABzAAA67QAAOu0AAABywAA67UAAOu1AAABygAA67YAAOu2AAAByQAA67cAAOu3AAAByAAA67gAAOu4AAABxwAA67kAAOu5AAABxgAA68AAAOvAAAABxQAA68EAAOvBAAABxAAA68IAAOvCAAABwwAA68MAAOvDAAABwgAA68QAAOvEAAABwQAA68UAAOvFAAABwAAA68YAAOvGAAABvwAA68cAAOvHAAABvgAA68gAAOvIAAABvQAA68kAAOvJAAABvAAA69AAAOvQAAABuwAA69EAAOvRAAABugAA69IAAOvSAAABuQAA69MAAOvTAAABuAAA69QAAOvUAAABtwAA69UAAOvVAAABtgAA69YAAOvWAAABtQAA69cAAOvXAAABtAAA69gAAOvYAAABswAA69kAAOvZAAABsgAA6+EAAOvhAAABsQAA6+IAAOviAAABsAAA6+MAAOvjAAABrwAA6+QAAOvkAAABrgAA6+UAAOvlAAABrQAA6+YAAOvmAAABrAAA6+cAAOvnAAABqwAA6+gAAOvoAAABqgAA6+kAAOvpAAABqQAA6/AAAOvwAAABqAAA6/EAAOvxAAABpwAA6/IAAOvyAAABpgAA6/MAAOvzAAABpQAA6/QAAOv0AAABpAAA6/UAAOv1AAABowAA6/YAAOv2AAABogAA6/cAAOv3AAABoQAA6/gAAOv4AAABoAAA6/kAAOv5AAABnwAA7KAAAOygAAABngAA7KEAAOyhAAABnQAA7KIAAOyiAAABnAAA7KMAAOyjAAABmwAA7KQAAOykAAABlgAA7KUAAOylAAABlQAA7KYAAOymAAABlAAA7KcAAOynAAABkwAA7KgAAOyoAAABkgAA7KkAAOypAAABkQAA7LAAAOywAAABkAAA7LEAAOyx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Ad8B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AgACAQICAgMCBAIFAgYCBwIIAgkCCgILAgwCDQIOAg8CEAIRAhICEwIUAhUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIgIjAiQCJQImAicCKAIpAioCKwIsAi0CLgIvAjACMQIyAjMCNAI1AjYCNwI4AjkCOgI7AjwCPQI+Aj8CQAJBAkICQwJEAkUCRgJHAkgCSQJKAksCTAJNAk4CTwJQAlECUgJTAlQCVQJWAlcCWAJZAloCWwJcAl0CXgJfAmACYQJiAmMCZAJlAmYCZwJoAmkCagJrAmwCbQJuAm8CcAJxAnICcwJ0AnUCdgJ3AngCeQJ6AnsCfAJ9An4CfwKAAoECggKDAoQChQKGAocCiAKJAooCiwKMAo0CjgKPApACkQKSApMClAKVApYClwKYApkCmgKbApwCnQKeAp8CoAKhAqICowKkAqUCpgKnAqgCqQKqAqsCrAKtAq4CrwKwArECsgKzArQCtQK2ArcCuAK5AroCuwK8Ar0CvgK/AsACwQLCAsMCxALFAsYCxwLIAskCygLLAswCzQLOAs8C0ALRAtIC0wLUAtUC1gLXAtgC2QLaAtsC3ALdAt4C3wLgAuEC4gLjAuQC5QLmAucC6ALpAuoC6wLsAu0C7gLvAvAC8QLyAvMC9AL1AvYC9wL4AvkC+gL7AvwC/QL+Av8DAAMBAwIDAwMEAwUDBgMHAwgDCQMKAwsDDAMNAw4DDwMQAxEDEgMTAxQDFQMWAxcDGAMZAxoDGwMcAx0DHgMfAyADIQMiAyMDJAMlAyYDJwMoAykDKgMrAywDLQMuAy8DMAMxAzIDMwM0AzUDNgM3AzgDOQM6AzsDPAM9Az4DPwNAA0EDQgNDA0QDRQNGA0cDSANJA0oDSwNMA00DTgNPA1ADUQNSA1MDVANVA1YDVwNYA1kDWgNbA1wDXQNeA18DYANhA2IDYwNkA2UDZgNnA2gDaQNqA2sDbANtA24DbwNwA3EDcgNzA3QDdQN2A3cDeAN5A3oDewN8A30DfgN/A4ADgQOCAAphLWNodWxpcmVuCmNsb2NrLWVjYjUKY2xvY2stZTEwNwllMTAwLXVuZG8OZTIwOS1zdWJ0aXRsZXMHZTIwOC1oZBJlMTE3LWNhbmNlbC1jaXJjbGUTZTExNi1jYW5jZWwtb3V0bGluZQxlMTNkLXByZXZpZXcLZTExNS1jYW5jZWwEc3RvcApjYWxjdWxhdG9yDHNvcnQtZGVzYy1zbQ5lbmNsb3N1cmVfZWRpdBJlMDFjLWFycm93LXBhcmVudDENZTIwYS1wbGF5bGlzdBBlMDFkLWFycm93LXJvb3QxEWUwMjAtYXJyb3dzLXN3YXAxF2UwMWYtYXJyb3dzLWRpbWVuc2lvbnMxE2UxMDQtbm9uLXJlY3VycmVuY2UVZTAxZS1hcnJvd3MtcmVzaXppbmcxEGUxMjctc29ydC1hc2Mtc20IZTE0MS1wYW4OZTIwNi12b2x1bWUtdXAKZTIwMS1wYXVzZQllMjAwLXBsYXkMZTIwNC1mb3J3YXJkEGUyMDUtdm9sdW1lLWRvd24UZTE0OS1rcGktc3RhdHVzLW9wZW4PZTIwNy12b2x1bWUtb2ZmC2UyMDMtcmV3aW5kDWUxMzItZG93bmxvYWQSZTExOS1jaGVjay1vdXRsaW5lC2UxMzMtdXBsb2FkEmUxMjMtbWludXMtY2lyY2xlMQ1lMTI0LXNvcnQtYXNjC2UxMjktZmlsdGVyC2UxMjYtdW5zb3J0C2UxMzEtbG9nb3V0CmUxMzAtbG9naW4OZTEyNS1zb3J0LWRlc2MQZTEyMC1wbHVzLWNpcmNsZRRlMTQ4LWtwaS1zdGF0dXMtaG9sZAxlMTQ1LXBsdXMtc20OZTE0NC1jb25uZWN0b3IWZTEzNS1oeXBlcmxpbmstb3Blbi1zbQtlMTM2LWxhdW5jaBRlMTQ3LWtwaS1zdGF0dXMtZGVueQllMTQzLWNhcnQLZTEzNy13aW5kb3cNZTE0Ni1taW51cy1zbQ1lMTQwLXpvb20tb3V0FGUxMzktd2luZG93LW1pbmltaXplE2UxMzQtaHlwZXJsaW5rLW9wZW4SZTExMS1saW5rLXZlcnRpY2FsCWUxMTMtbG9jawtlMTAzLXJlbG9hZA1lMTA1LXJlc2V0LXNtFGUxMTItdW5saW5rLXZlcnRpY2FsFmUxMTAtdW5saW5rLWhvcml6b250YWwOZTEwNi1yZWxvYWQtc20LZTExNC11bmxvY2sLZTEwOS1mbG9wcHkKZTExOC1jaGVjaxFlMTJhLWZpbHRlci1jbGVhchJlMTBlLWF0dGFjaG1lbnQtNDULZTEzYy13cmVuY2gaZTEyZS1maWx0ZXItYWRkLWV4cHJlc3Npb24OZTEyYi1maWx0ZXItc20PZTEwZC1hdHRhY2htZW50FWUxMmYtZmlsdGVyLWFkZC1ncm91cBJlMTFjLWNsb3NlLW91dGxpbmUYZTEyZC1maWx0ZXItc29ydC1kZXNjLXNtFGUxMGYtbGluay1ob3Jpem9udGFsCGUxMGItZGl0F2UxMmMtZmlsdGVyLXNvcnQtYXNjLXNtCmUxM2ItZ2VhcnMJZTAzMC1tZW51CWUxMDEtcmVkbwplMjBiLWF1ZGlvEmUwMjktbGF5b3V0LTEtYnktNBFlMDI3LWhhbmRsZXItZHJhZw9lMDIyLWNhdGVnb3JpemUMZTIwYy1wbGF5LXNtEmUwMzEtbW9yZS12ZXJ0aWNhbAtlMDI4LWxheW91dAxlMTNmLXpvb20taW4SZTAyMS1kcmFnLWFuZC1kcm9wEmUwMmEtbGF5b3V0LTItYnktMgllMDJlLXJvd3MKZTEwMi1yZXNldAplMTBhLXByaW50GGUwMmItbGF5b3V0LXNpZGUtYnktc2lkZRBlMDFiLWFycm93LWRyaWxsE2UwMmMtbGF5b3V0LXN0YWNrZWQMZTAyZC1jb2x1bW5zFWUwMDMtYXJyb3ctNDUtdXAtbGVmdBNlMDBhLWFycm93LWVuZC1kb3duFWUwMTEtYXJyb3dzLW5vLWNoYW5nZQtlMDBiLXNlZWstdxRlMDA5LWFycm93LWVuZC1yaWdodBdlMDAyLWFycm93LTQ1LWRvd24tbGVmdBFlMDA4LWFycm93LWVuZC11cBBlMDE4LWFycm93LXJpZ2h0D2UwMTktYXJyb3ctZG93bg9lMDFhLWFycm93LWxlZnQYZTAwMS1hcnJvdy00NS1kb3duLXJpZ2h0GGUwMTItYXJyb3ctb3ZlcmZsb3ctZG93bg1lMDE3LWFycm93LXVwFmU3MDMtbWFya2VyLXBpbi10YXJnZXQNZTgwOC1kaWdnLWJveAplODA5LWVtYWlsCWU4MDctZGlnZxJlODA2LWRlbGljaW91cy1ib3gMZTgwMy1ibG9nZ2VyEGU4MDQtYmxvZ2dlci1ib3gOZTgwNS1kZWxpY2lvdXMKZTgwMi1pbmJveAllODAxLXVzZXIKZTgwMC1zaGFyZQplNzA1LXVucGluCGU3MDQtcGluDmU2OTktZm9udC1zaXplEGU2ODktcGFuZS1mcmVlemUcZTY5MC10b2dnbGUtZnVsbC1zY3JlZW4tbW9kZRJlNjg4LXRhYmxlLXVubWVyZ2UKZTcwMS1nbG9iZRJlNjk2LWN1c3RvbS1mb3JtYXQPZTY5MS1mb3JtdWxhLWZ4EmU3MDAtZ2xvYmUtb3V0bGluZQ9lNzAyLW1hcmtlci1waW4LZTY5NC1kb2xsYXIVZTY5OC1kZWNpbWFsLWRlY3JlYXNlFWU2OTctZGVjaW1hbC1pbmNyZWFzZQtlNjkzLXN5bWJvbAxlNjk1LXBlcmNlbnQIZTY5Mi1zdW0TZTY0My10ZXh0Ym94LWhpZGRlbhVlNjQ3LXRlbXBsYXRlLW1hbmFnZXIUZTY3Mi1oeXBlcmxpbmstZ2xvYmUbZTY3My1oeXBlcmxpbmstZ2xvYmUtcmVtb3ZlDGU2NDItdGV4dGJveA9lNjQ2LWVkaXQtdG9vbHMLZTYzZC1idXR0b24KZTY3Ny10YWJsZRFlNjgyLXRhYmxlLWRlbGV0ZRVlNjc4LXRhYmxlLXByb3BlcnRpZXMQZTY4My1jZWxscy1tZXJnZRxlNjg2LWNlbGwtc3BsaXQtaG9yaXpvbnRhbGx5FmU2ODEtdGFibGUtY2VsbC1kZWxldGULZTY3NS1hbmNob3IbZTY4Ny1jY2VsbC1zcGxpdC12ZXJ0aWNhbGx5EWU4MGMtZmFjZWJvb2stYm94G2U2ODUtY2VsbHMtbWVyZ2UtdmVydGljYWxseR1lNjg0LWNlbGxzLW1lcmdlLWhvcml6b250YWxseRVlNjgwLXRhYmxlLXJvdy1kZWxldGUPZTY3OS10YWJsZS1jZWxsFGU2NzQtaHlwZXJsaW5rLWVtYWlsF2U2NzYtdGFibGUtbGlnaHQtZGlhbG9nHmU2N2MtdGFibGUtY29sdW1uLWluc2VydC1yaWdodBRlNjhmLXZhbGlkYXRpb24tZGF0YQ1lODBiLWZjYWVib29rD2U2OGEtcm93LWZyZWV6ZRJlNjhiLWNvbHVtbi1mcmVlemUbZTY3ZS10YWJsZS1yb3ctaW5zZXJ0LWJlbG93HWU2N2ItdGFibGUtY29sdW1uLWluc2VydC1sZWZ0G2U2N2QtdGFibGUtcm93LWluc2VydC1hYm92ZRplNjdhLXRhYmxlLWNlbGwtcHJvcGVydGllcxxlNjlhLWltYWdlLWFic29sdXRlLXBvc2l0aW9uEmU2OGMtdG9vbGJhci1mbG9hdBhlNjdmLXRhYmxlLWNvbHVtbi1kZWxldGUOZTgwYS1lbWFpbC1ib3gSZTY4ZC1zcGVsbC1jaGVja2VyFWU2OGUtdmFsaWRhdGlvbi14aHRtbAhlOTE5LWNzcwplOTE3LWh0bWw1B2U5MWYtdmILZTkxZC12YnByb2oUZTkyMi1maWxlLWhvcml6b250YWwIZTkxYi1leGUHZTkxYS1qcwtlOTFjLWNzcHJvagplOTIxLWNsb3VkB2U5MWUtY3MJZTkxOC1odG1sCGU5MjAtc2xuDmU5MTItZmlsZS1hc2N4D2U5MTAtZmlsZS1mbGFzaAllOTE1LWZpbG0JZTkxNi1jc3MzDWU5MTQtZmlsZS16aXANZTkwZS1maWxlLXBkZg1lOTBkLWZpbGUtcHB0EGU5MTEtZmlsZS1jb25maWcNZTkwZi1maWxlLXBzZA1lOTEzLWZpbGUtYmFjDWU5MDctZmlsZS1hZGQOZTkwMy1mb2xkZXItdXAPZTkwYS1maWxlLWV4Y2VsFWU5MDUtYWdncmVnYXRlLWZpZWxkcwllOTA2LWZpbGUIZTkwOS1jc3YIZTkwYy1tZGIQZTkwNC1mb2xkZXItbW9yZQ5lOTBiLWZpbGUtd29yZA1lOTA4LWZpbGUtdHh0EGU5MDEtZm9sZGVyLW9wZW4IZTgyNy1yc3MKZTgyOS12aW1lbwtlOTAwLWZvbGRlcgxlODI4LXJzcy1ib3gQZTgyYy15b3V0dWJlLWJveAxlODJiLXlvdXR1YmUOZTgyYS12aW1lby1ib3gRZTgyNi1kcmliYmJsZS1ib3gPZTkwMi1mb2xkZXItYWRkFmU4MWMtdGVsbC1hLWZyaWVuZC1ib3gPZTgxZS10dW1ibHItYm94C2U4MWQtdHVtYmxyEGU4MjAtdHdpdHRlci1ib3gPZTgyMi15YW1tZXItYm94C2U4MjEteWFtbWVyDGU4MjMtYmVoYW5jZRBlODI0LWJlaGFuY2UtYm94DWU4MjUtZHJpYmJibGUMZTgxZi10d2l0dGVyDmU4MTUtcGludGVyZXN0EmU4MTYtcGludGVyZXN0LWJveBFlODE5LXN0dW1ibGUtdXBvbgtlODBkLWdvb2dsZRBlODE0LW15c3BhY2UtYm94FWU4MWEtc3R1bWJsZS11cG9uLWJveA1lODExLWxpbmtlZGluEWU4MTItbGlua2VkaW4tYm94EGU4MGYtZ29vZ2xlLXBsdXMPZTgwZS1nb29nbGUtYm94D2U4MTgtcmVkZGl0LWJveBRlODEwLWdvb2dsZS1wbHVzLWJveAxlODEzLW15c3BhY2ULZTgxNy1yZWRkaXQSZTgxYi10ZWxsLWEtZnJpZW5kEHN0cmlwLWNzcy1mb3JtYXQOdmlkZW8tZXh0ZXJuYWwTc3RyaXAtc3Bhbi1lbGVtZW50cwpzZWxlY3QtYWxsGHRhYmxlLWFsaWduLWJvdHRvbS1yaWdodBNzdHJpcC1hbGwtZm9ybWF0aW5nCHRleHRhcmVhCmltYWdlLWVkaXQJdGV4dC13cmFwGHRhYmxlLWFsaWduLW1pZGRsZS1yaWdodBJ0YWJsZS1hbGlnbi1yZW1vdmUNdHJhY2stY2hhbmdlcxh0cmFjay1jaGFuZ2VzLXJlamVjdC1hbGwMYWxpZ24tcmVtb3ZlDGFsaWduLWNlbnRlcg1hbGlnbi1qdXN0aWZ5C2FsaWduLXJpZ2h0CWJvcmRlci1ubwxhcHBseS1mb3JtYXQLYm9yZGVyLWxlZnQNYm9yZGVyLWJvdHRvbQtib3JkZXJzLWFsbBdib3JkZXJzLWluc2lkZS12ZXJ0aWNhbA9ib3JkZXJzLW91dHNpZGUZYm9yZGVycy1pbnNpZGUtaG9yaXpvbnRhbARjb3B5CWNsZWFyLWNzcwpib3JkZXItdG9wDGJvcmRlci1yaWdodBtlNjcxLWh5cGVybGluay1saWdodC1kaWFsb2cRYm9yZGVycy1zaG93LWhpZGUOYm9yZGVycy1pbnNpZGUOZGljdGlvbmFyeS1hZGQLY3VzdG9tLWljb24HY29tbWVudBBkb2N1bWVudC1tYW5hZ2VyC2NvcHktZm9ybWF0D2NoYW5nZS1tYW51YWxseQ5jb21tZW50LXJlbW92ZQ1jYWxlbmRhci1kYXRlE2NvbW1lbnRzLXJlbW92ZS1hbGwQaW1hZ2UtbWFwLWVkaXRvcgNjdXQObW9kdWxlLW1hbmFnZXIFcGFzdGUSaW1hZ2UtbGlnaHQtZGlhbG9nDGNvZGUtc25pcHBldAxmb3JtLWVsZW1lbnQNbWVkaWEtbWFuYWdlcg1mbGFzaC1tYW5hZ2VyDXBhcmFncmFwaC1hZGQacGFzdGUtZnJvbS13b3JkLXN0cmlwLWZpbGUPcnVsZS1ob3Jpem9udGFsD3Bhc3RlLWZyb20td29yZA1wYXN0ZS1hcy1odG1sE3N0cmlwLWZvbnQtZWxlbWVudHMXdGFibGUtYWxpZ24tYm90dG9tLWxlZnQQZmluZC1hbmQtcmVwbGFjZRZ0YWJsZS1hbGlnbi10b3AtY2VudGVyCnBhc3RlLWh0bWwVc3RyaXAtd29yZC1mb3JtYXR0aW5nGXRhYmxlLWFsaWduLW1pZGRsZS1jZW50ZXIRZm9ybWF0LWNvZGUtYmxvY2sUdHJhY2stY2hhbmdlcy1yZWplY3QJZ3JvdXAtYm94BGZvcm0ZdGFibGUtYWxpZ24tYm90dG9tLWNlbnRlcgtzaWx2ZXJsaWdodBBwYXN0ZS1wbGFpbi10ZXh0CnNlbGVjdC1ib3gOcGFzdGUtbWFya2Rvd24XdGFibGUtYWxpZ24tbWlkZGxlLWxlZnQUdHJhY2stY2hhbmdlcy1lbmFibGUVdGFibGUtYWxpZ24tdG9wLXJpZ2h0DXN0eWxlLWJ1aWxkZXIUdGFibGUtYWxpZ24tdG9wLWxlZnQUdHJhY2stY2hhbmdlcy1hY2NlcHQYdHJhY2stY2hhbmdlcy1hY2NlcHQtYWxsEWEtZTYwNGZvbnQtZmFtaWx5EGEtZTYwOXN1Yi1zY3JpcHQWYS1lNjA1Zm9yZWdyb3VuZC1jb2xvcgphLWU2MDFib2xkCGEtZTYxMGg0E2EtZTYwOHN0cmlrZXRocm91Z2gXYS1lNjA2Y29udmVydC1sb3dlcmNhc2UXYS1lNjA3Y29udmVydC11cHBlcmNhc2UMYS1lNjAyaXRhbGljD2EtZTYwM3VuZGVybGluZRJhLWU2MWNhbGlnbi1ib3R0b20IYS1lNjBkaDEIYS1lNjBmaDMJYS1lNjBjYWxsCGEtZTYwZWgyEGEtZTYwYXN1cC1zY3JpcHQJYS1lNjBiZGl2EGEtZTYxZGFsaWduLWxlZnQPYS1lNjFhYWxpZ24tdG9wEmEtZTYxYmFsaWduLW1pZGRsZRVhLWU2MTVpbmRlbnQtaW5jcmVhc2UTYS1lNjE4aW5zZXJ0LW1pZGRsZRRhLWU2MTRsaXN0LXVub3JkZXJlZBVhLWU2MTZpbmRlbnQtZGVjcmVhc2UPYS1lNjE3aW5zZXJ0LXVwEWEtZTYxOWluc2VydC1kb3duCGEtZTYxMmg2EmEtZTYxM2xpc3Qtb3JkZXJlZAhhLWU2MTFoNRNhLWU1MjR0aHVtYm5haWxzLXVwFmEtZTUyOWZ1bGwtc2NyZWVuLWV4aXQVYS1lNTI2dGh1bWJuYWlscy1kb3duFWEtZTYwMHBhZ2UtcHJvcGVydGllcxVhLWU1Mjd0aHVtYm5haWxzLWxlZnQaYS1lNTIzYWxpZ24tYm90dG9tLWVsZW1lbnQRYS1lNTI4ZnVsbC1zY3JlZW4WYS1lNTI1dGh1bWJuYWlscy1yaWdodBFhLWU1MmFyZXNldC1jb2xvchphLWU1MjJhbGlnbi1taWRkbGUtZWxlbWVudBJhLWU1MWJiYWNrLWVsZW1lbnQZYS1lNTIwYWxpZ24tcmlnaHQtZWxlbWVudBVhLWU1MWNmb3J3YXJkLWVsZW1lbnQLYS1lNTE4c2hhcGUXYS1lNTIxYWxpZ24tdG9wLWVsZW1lbnQWYS1lNTFkYmFja3dhcmQtZWxlbWVudBNhLWU1MTlyb3VuZC1jb3JuZXJzGGEtZTUxZWFsaWduLWxlZnQtZWxlbWVudBNhLWU1MWFmcm9udC1lbGVtZW50GmEtZTUxZmFsaWduLWNlbnRlci1lbGVtZW50CmEtZTUxMGxpbmUZYS1lNTExYnJpZ2h0bmVzcy1jb250cmFzdAthLWU1MGZwYWludA9hLWU1MTVncmV5c2NhbGUNYS1lNTBlcGFsZXR0ZQ1hLWU1MTdzaGFycGVuE2EtZTUxM2ludmVydC1jb2xvcnMKYS1lNTE2Ymx1chBhLWU1MTJzYXR1cmF0aW9uEmEtZTUxNHRyYW5zcGVyYW5jeQxhLWU1MGFyb3RhdGUTYS1lNTA0em9vbS1iZXN0LWZpdAthLWU1MGRicnVzaBFhLWU1MGNyb3RhdGUtbGVmdAphLWU1MDZjcm9wE2EtZTUwOWZsaXAtdmVydGljYWwMYS1lNTA3bWlycm9yFWEtZTUwOGZsaXAtaG9yaXpvbnRhbBJhLWU1MDVpbWFnZS1yZXNpemUSYS1lNTBicm90YXRlLXJpZ2h0DWEtZTIwZXN0b3Atc20SYS1lNTAyaW1hZ2UtZXhwb3J0FGEtZTMwN3RyaS1zdGF0ZS1udWxsC2EtZTUwMWltYWdlE2EtZTMwMGhlYXJ0LW91dGxpbmUWYS1lNTAzem9vbS1hY3R1YWwtc2l6ZQxhLWUzMDhjaXJjbGULYS1lMzAxaGVhcnQSYS1lNTAwcGhvdG8tY2FtZXJhDmEtZTIwZHBhdXNlLXNtC2NvbGxhcHNlLW5lCXRodW1idGFjawtzLXRodW1idGFjawZtb3ZldG8NZmlsdGVyX2RlbGV0ZQ9maWx0ZXJfZ3JvdXBpbmcKZmlsdGVyX2FkZBNmaWx0ZXJfY2FuY2VsbGF0aW9uBnZlcm5hdgpjdy1hcnJvd2RlCGN3LWhvdGVsB2N3LXRyaXAFemhhZ2UHZGVuZ2hhbw10aXNoaXNodW9taW5nBERyYWcGYmlhbmppBmNoYWthbgJiZwRsaGp0CGR1bGltaW1hEXFpYW5taW5ncWlhbnpoYW5nBmZhbmt1aRRhLUNGX0Rlc2NlbmRpbmdPcmRlchNhLUNGX0FzY2VuZGluZ09yZGVyBWFib3V0CXl1bnhpYW94aRBlbmNsb3N1cmVfZGVsZXRlEmVuY2xvc3VyZV9kb3dubG9hZBBlbmNsb3N1cmVfdXBsb2FkEGVuY2xvc3VyZV9icm93c2UKdXBsb2FkX2JpZw9jYWxlbmRhcnNfbGluZTEJbW9yZV9saW5lDmRyb3AtZG93bl9saW5lEHBlcnNwZWN0aXZlX3ZpZXcKY2hhcnRfdmlldwlmb3JtX3ZpZXcJbGlzdF92aWV3CWNhcmRfdmlldwtyZW1vdmVfZmFjZQtkdWl6aGFuZ2Rhbg1kaXpoaXNoZW5xaW5nDWppbmd4aWFvcmVud3UHYmFpZmFuZwprZWh1Z3VhbnhpCGZheXVuZGFuCWxpYW54aXJlbg1mdWt1YW50b25nemhpD2thaXBpYW9zaGVucWluZw94aWFvc2hvdWRhY2hlbmcOeGlhb3Nob3VxaWFubGkOeGlhb3Nob3VtdWJpYW8Nc2h1anVzaGFuZ2Jhbwx4dWtlc2hhbmdwaW4Jemhlbmd6aGFvDHhpYW9zaG91eXVjZQ94aWFvc2hvdXR1YW5kdWkFaGVscDELaW5mby1jaXJjbGUKZGVwYXJ0bWVudARjb2RlBHBhdGgPZmxvd2xpbmUtbWFudWFsDWZsb3dsaW5lLW1vcmUSZmxvd2xpbmUtc2NoZWR1bGVkEWZsb3dsaW5lLWNhbmNlbGVkEGZsb3dsaW5lLXBlbmRpbmcMZmxvd2xpbmUtcnVuEGZsb3dsaW5lLWNyZWF0ZWQQZmxvd2xpbmUtcnVubmluZxBmbG93bGluZS13YWl0aW5nEGZsb3dsaW5lLXNraXBwZWQNZmxvd2xpbmUtdmlldxBmbG93bGluZS13YXJuaW5nC29yaWVudGF0aW9uBGxhc3QFZmlyc3QOeXVuaGFuZ3NoaWljb24aQ29sdW1uLWZpbHRlcmFuZGRlc2NlbmRpbmcZQ29sdW1uLWZpbHRlcmFuZGFzY2VuZGluZxxDb2x1bW5zLURlZmF1bHRmaWx0ZXJhbmRzb3J0DUNvbHVtbi1maWx0ZXISQ29sdW1ucy1kZXNjZW5kaW5nEUNvbHVtbnMtYXNjZW5kaW5nE0NvbHVtbnMtRGVmYXVsdHNvcnQPbGF1bmNocGFkLWZhY2UyCmxhdW5jaHBhZDIPZi1pY29uLWNoZWNrYm94DGYtaWNvbi1taW51cwpmLWljb24tYWRkCGRyb3Bkb3duCm5hdmlnYXRpb24Ray1pLW1lc3NhZ2VfZXJyb3ITay1pLW1lc3NhZ2Vfc3VjY2VzcwpzdWRva3UtbmV3CGxpc3QtbmV3CXRpbGVkLW5ldwxxaWVodWFuenV6aGkHcmFkaW8tMgZ0ZW5hbnQGc3Vkb2t1BXRpbGVkBWxpc3QxC3Nob3VjYW5namlhCmNvbGxlY3Rpb24DaWRlDG9jY2x1ZGUtZmFjZQdvY2NsdWRlDmxhdW5jaHBhZC1mYWNlCWxhdW5jaHBhZAtpbmZvcm1hdGlvbgdiYWNrbG9nB21lc3NhZ2UJbWF4aW1pemUxBnNlYXJjaAppbmRleC1mYWNlBWluZGV4CHl4c190ZXh0DXl4c19jb250YWluZXILeXhzX2NvbHVtbnMIeXhzX21vdmUIeXhzX2NvcHkKeXhzX2RlbGV0ZQl5eHNfbGV2ZWwJeXhzX2VhcnRoDXl4c19jdXN0b21pemUIc2lnbl9vdXQLdXNlcl9jZW50ZXIGcmVtb3ZlBnBhY2t1cAZjYW1lcmEGbmFycm93DWFtcGxpZmljYXRpb24JY2xvY2t3aXNlEGNvdW50ZXJjbG9ja3dpc2UGZWRpdG9yBHNraW4EYXJlYQhwYXNzd29yZAhsYW5ndWFnZQViYXNpYwhtaW5pbWl6ZQxtYXhpbWl6YXRpb24NbmV3LWRpbWVuc2lvbhFmaWxlLWZvbGRlci1jbG9zZRBmaWxlLWZvbGRlci1vcGVuCG5ldy1lZGl0CG5ldy1mb3JtBXdvbWFuA21hbgZyZWNvcmQEbW9yZQRsaXN0CXRlbGVwaG9uZQhmdW5jdGlvbgtwcm9kdWN0bGlzdA5hdHRhY2htZW50bGlzdBNkb2N1bWVudGluZm9ybWF0aW9uDG5ldy1maWx0cmF0ZQ5uZXctZnVsbHNjcmVlbgdyb29maW5nDUJvdHRvbXNldHRpbmcPcGFnZS10aXRsZS10YXNrEXBhZ2UtdGl0bGUtcmV2aWV3EHBhZ2UtdGl0bGUtc3RhcnQPcGFnZS10aXRsZS10eXBlEXBhZ2UtdGl0bGUtcmVjb3JkEnBhZ2UtdGl0bGUtdm91Y2hlchBwYWdlLXRpdGxlLXF1ZXJ5EXBhZ2UtdGl0bGUtbnVtYmVyEXBhZ2UtdGl0bGUtbWFuYWdlFnBhZ2UtdGl0bGUtbWFpbnRlbmFuY2UVcGFnZS10aXRsZS1kaWN0aW9uYXJ5GHBhZ2UtdGl0bGUtY29uZmlndXJhdGlvbhVwYWdlLXRpdGxlLWFkbWluaXN0ZXIRcGFnZS10aXRsZS1kZWZpbmUXdHJpLXN0YXRlLWluZGV0ZXJtaW5hdGUQcGFuZWwtcmV0cmFjdGlvbgtlZGl0LWJ1dHRvbg5pbnB1dC1sYW5ndWFnZRdhdHRyaWJ1dGUtY29uZmlndXJhdGlvbgtFbmdpbmVlcmluZwNnaXQTcmFkaW9idXR0b24tY2hlY2tlZAxzaGFwZS1jaXJjbGUQY2hlY2tib3gtY2hlY2tlZBVrLWktaG9tZS13ZWF0aGVyLWxlYWYNay1pLWhvbWUtbW9yZQ1rLWktaG9tZS1yaW5nDGstaS1ob21lLWFkZA5rLWktaG9tZS1zZXR1cA5rLWktaG9tZS13b21hbgxrLWktaG9tZS1tYW4Oay1pLXRvcF9hZ2VuY3kMay1pLXRvcF9uZXdzDGstaS10b3BfaG9tZRJrLWktdG9wX2ltX2RlZmF1bHQXay1pLXRvcF9kZXZlbG9wbWVudHRvb2wMay1pLXRvcF9tZW51DmstaS10b3Bfc2VhcmNoCmstaS10b3BfbXkPay1pLWZsYWdfdXJnZW50DGstaS1uZXh0cGFnZRBrLWktcHJldmlvdXNwYWdlE2staS1tZXNzYWdlX3JvdXRpbmUTay1pLUV4aGFsZS1EaXNjb3VudBNrLWktbW9yZS1ob3Jpem9udGFsEGstaS1tZXNzYWdlX2hlbHATay1pLW1lc3NhZ2Vfd2FybmluZxZrLWktc3RlcHMtZGVsaXZlcmdvb2RzFWstaS1zdGVwcy1yZWNlaXZhYmxlcxFrLWktc3RlcHMtaW52b2ljZRRrLWktc3RlcHMtb3V0b2ZzdG9jaxRrLWktc3RlcHMtc2V0dGxlbWVudBNrLWktc3RlcHMtdHJhbnNwb3J0DGstaS1ib29rbWFyaxBrLWktc3Rhci1vdXRsaW5lCGstaS16b29tEGstaS1jbG9zZS1jaXJjbGUQay1pLWNoZWNrLWNpcmNsZQlrLWktY2xvc2UQay1pLXBsdXMtb3V0bGluZRFrLWktbWludXMtb3V0bGluZQtrLWktcmVvcmRlcg1rLWktcmV3aW5kLXNtDmstaS1mb3J3YXJkLXNtE2staS1hcnJvdy1zZWVrLWRvd24Ray1pLWFycm93LXNlZWstdXAKay1pLWRlbGV0ZQlrLWktZ3JvdXAIay1pLWdyaWQPay1pLWdyaWQtbGF5b3V0DmstaS1hcnJvd3Mta3BpFmstaS1hcnJvdy1jaGV2cm9uLWxlZnQXay1pLWFycm93LWNoZXZyb24tcmlnaHQWay1pLWFycm93LWNoZXZyb24tZG93bhRrLWktYXJyb3ctY2hldnJvbi11cBFrLWktYXJyb3ctNjAtbGVmdAtrLWktYXJyb3ctZRFrLWktYXJyb3ctNjAtZG93bg9rLWktYXJyb3ctNjAtdXAAAAA=) format("truetype")}.f-page-root{top:0}.f-page{top:0;display:flex;flex-direction:column;background:#EFF2F4}.f-page-main{flex-shrink:1;flex-grow:1;flex-basis:0;background:var(--f-neutral-19);box-shadow:0 2px 20px 0 rgba(3,18,51,.05);margin:.5rem}.f-page-has-query .f-page-main,.f-page-has-scheme .f-page-main{box-shadow:1px 3px 4px 0 rgba(0,28,64,.04)}.f-page-main>.f-section:last-child{margin-bottom:0}.f-page-main>.f-section:last-child::after{display:none}.f-page-is-managelist .f-page-main,.f-page-is-managelistwithsidebar .f-page-main{display:flex;flex-direction:column;overflow:hidden}.f-page-has-scheme .f-page-header{border-radius:.5rem .5rem 0 0}.f-page-has-query .f-page-main{margin-top:-.75rem}.f-page-has-query .f-page-header{margin:.5rem .5rem 0;border-radius:.5rem .5rem 0 0}.f-page-navigate .f-page-main{display:flex;flex-direction:column;overflow:hidden}.f-page-navigate .f-page-content{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:row;flex-wrap:nowrap;overflow:hidden}.f-page-navigate .f-page-content>.col,.f-page-navigate .f-page-content>[class*=col-]{padding-left:0;padding-right:0}.f-page-navigate .f-page-content-nav{display:flex;flex-direction:column;box-shadow:none;padding:0;position:relative;z-index:100}.f-page-navigate .f-page-content-main>.f-section:last-child::after,.f-scrollspy-container .f-struct-subsub-wrapper::after{display:none}.f-page-navigate .f-page-content-nav-extend{padding:.875rem .875rem 0}.f-page-navigate .f-page-content-main{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:auto}.f-page-navigate .f-page-content-nav.f-component-splitter-pane{padding:0}.f-page-is-listnav .f-page-content-main{position:relative;margin:0 0 0 -.25rem}.f-page-is-listnav .f-page-content-main .f-section-query.f-section,.f-page-is-listnav .f-page-content-main .f-section-scheme.f-section{margin:.5rem .5rem 0;padding:.625rem .875rem .125rem}.f-page-is-listnav .f-page-content-main .f-page-header{margin:.5rem .5rem 0}.f-page-is-listnav .f-page-content-main .f-page-header-base{padding-left:.75rem;padding-right:.75rem}.f-page-is-listnav .f-page-content-main .f-page-footer{padding-left:.75rem;padding-right:.75rem;margin-bottom:.5rem}.f-page-is-grid-grid .f-page-content-main,.f-page-is-tree-grid .f-page-content-main{display:flex;flex-direction:column}.f-page-card .f-page-main{overflow:auto}.f-page-is-wizard .f-page-main{display:flex;flex-direction:column;overflow:hidden}.f-page-is-managelist .f-section+.f-section,.f-page-is-managelist .f-struct-wrapper+.f-struct-wrapper>.f-section{margin:.5rem 0 0}.f-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.f-content{flex-shrink:1;flex-grow:1;flex-basis:0}.f-struct-like-card{background:#fff;border-radius:4px;margin:0 0 .5rem}.f-page-is-mainsubcard .f-page-main,.f-page-is-mainsubcard.f-page-is-sidescrollspy .f-page-main .f-scrollspy-content{margin:0}.f-page-is-mainsubcard .f-page-main::-webkit-scrollbar-track,.f-page-is-mainsubcard.f-page-is-sidescrollspy .f-page-main .f-scrollspy-content::-webkit-scrollbar-track{background-color:#EFF2F4}.f-page-is-mainsubcard .f-page-main>.f-struct-like-card:last-child,.f-page-is-mainsubcard.f-page-is-sidescrollspy .f-page-main .f-scrollspy-content>.f-struct-like-card:last-child{margin-bottom:0}.f-struct-subsub-wrapper{position:relative}.f-struct-subsub-wrapper::before{content:"";height:4px;background:#fff;display:block;margin:0 0 4px;box-shadow:2px 3px 3px 0 rgba(31,35,41,.08)}.f-struct-subsub-wrapper::after{content:"";position:absolute;width:16px;height:16px;background:#fff;top:-4px;left:50%;box-shadow:2px 2px 3px 0 rgba(31,35,41,.08);transform:rotate(45deg);z-index:100}.f-scrollspy-container .f-struct-subsub-wrapper{position:initial}.f-cmp-lib-portlet,.f-viewchange-content-item lib-portlet{height:100%}.f-area-hide{opacity:0;visibility:hidden;z-index:100;position:absolute;transform:scaleY(0);transform-origin:100% top;backface-visibility:hidden;transition:opacity .12s linear .12s,visibility .12s linear .12s,transform .12s linear .12s}.f-area-show{opacity:1;visibility:visible;transform:scaleY(1)}.f-page-is-listnav-with-header .f-page-content-main{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column}.f-page-content-main-extend{padding:20px 22px 0}.f-page-content-main-header{text-align:center}.f-page-content-main-header .f-title{margin:0 auto;font-size:20px}.f-page-content-main-header .f-description{margin:0 auto;color:var(--f-text-04)}.f-page-content-main-overflow{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:auto;padding:20px 22px}.f-page-content-main-overflow .f-struct-like-card{margin:0 auto;width:100%;max-width:1092px;box-shadow:none}.f-subgrid-by-table-footer{padding:0 .875rem}.f-subgrid-by-table-footer .btn{color:var(--f-semantic-info-01);background:var(--f-semantic-info-03);width:100%;justify-content:center;height:36px}.f-subgrid-by-table-footer .btn:disabled{color:var(--f-text-07);background:var(--f-neutral-08)}.f-section-oa-table .f-section-header .f-title{padding-left:0}.f-section-oa-table .f-section-header .f-title::before{display:none}.f-section-form.f-section{padding:.625rem 0 .25rem}.f-section-form .f-section-header{padding:0 .875rem;margin-bottom:.875rem}.f-form-layout{display:flex;flex-wrap:wrap}.f-form-layout .f-section-formgroup{flex:0 0 100%;max-width:100%}.f-section-formgroup .f-section-formgroup-legend{width:100%}.f-section-formgroup-legend{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:space-between}.f-section-formgroup-legend .f-header{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:space-between;justify-content:flex-start;color:var(--f-text-04);flex-shrink:1;flex-grow:1;flex-basis:auto;padding:0 .875rem;cursor:pointer;font-size:.875rem}.f-section-formgroup-legend .f-toolbar{justify-content:flex-start}.f-section-formgroup-legend .f-toolbar .btn{border:none;display:flex;align-items:center;font-size:13px;padding-left:.375rem;padding-right:.375rem}.f-section-formgroup-legend .f-btn-collapse-expand{color:var(--f-text-04)}.f-section-formgroup-legend .f-btn-collapse-expand::after{margin:0;font-size:14px}.f-section-formgroup-legend:hover .f-title,.f-section-formgroup-legend:hover .f-toolbar .f-btn-collapse-expand{color:var(--f-theme-05)}.f-section-formgroup-legend:active .f-title,.f-section-formgroup-legend:active .f-toolbar .f-btn-collapse-expand{color:var(--f-theme-01)}.f-section-formgroup-legend.legend-with-toolbar{height:2rem}.f-section-formgroup-legend.legend-with-toolbar .f-header{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:space-between;flex-shrink:1;flex-grow:1;flex-basis:auto;border:1px solid var(--f-aid-08);padding:0 .875rem;height:1.875rem;background:var(--f-aid-09)}.f-section-formgroup-legend.legend-with-toolbar .f-title{font-size:.875rem;color:var(--f-text-02);flex-shrink:1;flex-grow:1;flex-basis:0;cursor:pointer}.f-section-formgroup-inputs{display:flex;flex-wrap:wrap}.f-section-formgroup.f-state-collapse .f-section-formgroup-inputs{display:none}.f-section-formgroup+.f-section-formgroup{margin:.375rem 0 0}.f-cmp-grid-is-sub{min-height:19.375rem}.farris-subgrid{min-height:25.625rem}.f-section-grid.f-section-in-main,.f-section-grid.f-section-in-managelist,.f-section-grid.f-section-in-nav{flex-shrink:1;flex-grow:1;flex-basis:0}.f-section-grid.f-section-in-main .f-section-content,.f-section-grid.f-section-in-managelist .f-section-content,.f-section-grid.f-section-in-nav .f-section-content{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column}.f-section-grid.f-section-in-main .f-component-grid,.f-section-grid.f-section-in-managelist .f-component-grid,.f-section-grid.f-section-in-nav .f-component-grid{flex-shrink:1;flex-grow:1;flex-basis:0}.f-section-extend-gridfilter,.f-tmpl-staticinfo-wrapper .staticinfo--header,.f-tmpl-staticinfo-wrapper .staticinfo--header .f-title{display:flex;align-items:center}.f-section-grid .f-component-grid{overflow:hidden}.f-grid-is-sub,.f-grid-is-subsub{height:21.875rem}.f-section-extend-gridfilter{background:var(--f-aid-02);border:1px solid;border-radius:2px;height:2.375rem;padding:.25rem .875rem}.f-page .f-page::before,.f-page-has-scheme .f-page-main .f-page-header::before,.f-page-is-listnav::before,.f-page-is-midcard::before{display:none}.f-section-extend-gridfilter>*{margin:0 .625rem 0 0}.f-grid-is-sub .f-component-grid{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.f-page .f-page{background:0 0}.f-page .f-page .f-page-layout{box-shadow:none}.f-page .f-page .f-page-header{margin:0}.f-page .f-page .f-page-main{margin-right:0;margin-left:0;margin-bottom:0}.f-page .f-page-has-scheme .f-section-scheme.f-section{margin-top:0;margin-right:0;margin-left:0}.f-page .f-page-has-scheme .f-page-header{margin-top:.5rem}.f-page-header,.farris-header{box-shadow:none}.f-page-header+.f-page-main,.f-page-header+.farris-split-section,.farris-header+.f-page-main,.farris-header+.farris-split-section{margin-top:0}.f-page-main{border-radius:8px 8px 12px 12px}.f-struct-like-card{box-shadow:none}.f-page.f-page-card,.f-page.f-page-is-managelist,.f-page.f-page-is-managelistwithsidebar,.f-page.f-page-is-onepage,.f-page.f-page-navigate{z-index:10}.f-page.f-page-card::before,.f-page.f-page-is-managelist::before,.f-page.f-page-is-managelistwithsidebar::before,.f-page.f-page-is-onepage::before,.f-page.f-page-navigate::before{z-index:-1;position:absolute;content:"";top:.5rem;bottom:.5rem;left:.5rem;right:.5rem;background:var(--f-neutral-18);box-shadow:0 2px 8px 0 rgba(var(--f-neutral-16),.1);border-radius:12px}.f-page-card .f-page-header,.f-page-card .farris-header,.f-page-is-managelist .f-page-header,.f-page-is-managelist .farris-header,.f-page-is-managelistwithsidebar .f-page-header,.f-page-is-managelistwithsidebar .farris-header,.f-page-is-onepage .f-page-header,.f-page-is-onepage .farris-header,.f-page-navigate .f-page-header,.f-page-navigate .farris-header{margin:.5rem .5rem 0;background:0 0}.f-page-footer{margin-left:.5rem;margin-right:.5rem;margin-bottom:.5rem;background:0 0}.f-page-main+.f-page-footer{margin-top:-.5rem}.f-page-navigate .f-page-main{background:rgba(255,255,255,.7);margin:0 .5rem .5rem}.f-page-navigate .f-page-content-nav{border-right:1px solid var(--f-neutral-07)}.f-page-navigate .f-page-content-nav.has-resize-bar{border-right:none}.f-page-navigate .f-page-content-nav .f-page,.f-page-navigate .f-page-content-nav .farris-main-area{background:0 0}.f-page-navigate .f-page-content-main .f-page-main{background:#fff}.f-page-headerextend{margin:.5rem .5rem 0}.f-page-is-sidescrollspy .f-page-main .f-scrollspy-content{padding:0}.f-scrollspy-tabs{position:relative;box-shadow:0 -2px 20px 0 rgba(3,18,51,.05)!important;z-index:100}.f-scrollspy-tabs .f-scrollspy-monitor-btn.active::after{background-image:var(--f-theme-11);left:14px!important;right:14px!important;width:auto!important;margin:0!important}.f-page-is-midcard .f-page-header{margin:0;background:0 0;box-shadow:none}.f-page-has-scheme .f-page-header{margin:0 .5rem;background:var(--f-neutral-19);position:relative}.f-page-has-scheme .f-page-header::before{content:"";position:absolute;top:-1px;left:0;right:0;box-shadow:0 2px 20px 0 rgba(3,18,51,.05);bottom:5px;z-index:-1;border-radius:.5rem .5rem 0 0}.f-page-has-scheme .f-page-main{margin-top:-.5rem}.f-page-is-mainsubcard .f-page-main{margin:.5rem}.f-page-is-mainsubcard .f-page-header+.f-page-main,.f-page-is-mainsubcard .farris-header+.f-page-main{margin-top:0}.f-page-is-mainsubcard .f-page-main,.f-page-is-mainsubcard.f-page-is-sidescrollspy .f-page-main .f-scrollspy-content{padding:0}.f-page-is-listnav-with-header .f-page-main{background:0 0}.f-page-is-listnav-with-header .f-page-content-main{background:var(--f-neutral-18)}.f-page-is-listnav .f-page-content,.f-page-is-listnav .f-page-content .f-page-content-main .f-page-card,.f-page-is-listnav .f-page-content .f-page-content-main .f-page-is-managelist,.f-page-is-listnav .f-page-content .f-page-content-nav .f-page{background:0 0}.f-page-is-listnav>.f-page-main{margin:.5rem}.f-page-is-listnav .f-page-content .f-page-content-nav{padding:0;box-shadow:0 0 8px 0 rgba(0,28,64,.08);border-right:none}.f-page-is-listnav .f-page-content .f-page-content-nav .f-page::before{top:0;left:0;right:0;bottom:0;border-radius:0;display:block}.f-page-is-listnav .f-page-content .f-page-content-main{margin:0}.f-page-is-listnav .f-page-content .f-page-content-main .f-page-card::before,.f-page-is-listnav .f-page-content .f-page-content-main .f-page-is-managelist::before{top:0;left:0;right:0;bottom:0;border-radius:0;display:block}.f-page .f-list-nav .f-list-nav-in{background:0 0!important;box-shadow:none!important}.f-page.f-page-is-midcard{overflow-y:auto;display:block}.f-page.f-page-is-midcard::-webkit-scrollbar-track{background-color:#EFF2F4}.f-page-layout{background:var(--f-neutral-19);box-shadow:0 2px 8px 0 rgba(var(--f-neutral-16),.1);border-radius:12px;margin:1rem}.f-page-layout .f-page-header{box-shadow:none}.f-page-layout .f-page-header .f-page-header-base{padding-top:1rem;padding-bottom:1rem}.f-page-container{margin:0 auto}@media (min-width:888px){.f-page-container{width:80%}.farris-form .farris-group-wrap{max-width:26.625rem}.farris-form .farris-group-auto .farris-group-wrap,.farris-form-auto .farris-group-wrap{max-width:none}}@media (min-width:1200px){.f-page-container{width:80%}}@media (min-width:1690px){.f-page-container{width:60%}}.f-btn-wrapper{padding-top:18px;padding-bottom:16px;text-align:center}.f-btn-wrapper .btn-lg{margin:0 6px}.f-tmpl-staticinfo-top{font-size:12px;color:rgba(0,0,0,.45);padding:0 0 40px}.f-tmpl-staticinfo-wrapper{background:rgba(42,135,255,.05);border:1px solid rgba(42,135,255,.2);border-radius:3px;padding:14px 20px 6px;margin:0 0 6px}.f-tmpl-staticinfo-wrapper .staticinfo--header .f-title .f-title-icon{margin:0 0 0 12px;border:1px solid #80B8FF;background:#D8E9FF;color:#4796FF;text-align:center;border-radius:2px}.f-tmpl-staticinfo-wrapper .staticinfo--header .f-title .f-title-icon:before{font-size:12px;line-height:14px;display:block}.f-tmpl-staticinfo-wrapper .staticinfo--header .f-title .f-title-icon.f-icon-woman{color:#FF7E7E;border-color:#FCABAB;background:#FFE9E9}.f-tmpl-staticinfo-wrapper .staticinfo--header .f-title .f-title-text{font-size:17px;color:#2D2F33;line-height:30px;margin:0}.f-tmpl-staticinfo-wrapper .staticinfo--content{padding:12px 0 0}.f-tmpl-staticinfo-wrapper .staticinfo--list{display:flex;margin:0 -14px 0 0;flex-wrap:wrap}.f-tmpl-staticinfo-wrapper .staticinfo--list .staticinfo--list-item{position:relative;padding:0 14px 0 0;margin:0 14px 8px 0;color:#36434D;font-size:14px;display:flex;align-items:center}.f-tmpl-staticinfo-wrapper .staticinfo--list .staticinfo--list-item:last-child::after,.f-tmpl-subgrid-by-card-list .f-list-view-multiple .f-list-select .custom-control{display:none}.f-tmpl-staticinfo-wrapper .staticinfo--list .staticinfo--list-item .f-icon{color:#878D99;font-size:13px;margin:0 4px 0 0}.f-tmpl-staticinfo-wrapper .staticinfo--list .staticinfo--list-item .f-title{margin:0 4px 0 0}.f-tmpl-staticinfo-wrapper .staticinfo--list .staticinfo--list-item::after{content:"";height:10px;width:1px;background:#E4E7EF;top:50%;margin-top:-5px;right:0;position:absolute}.f-section-scheme.f-section{background:0 0;margin:.5rem .5rem 0;padding:.625rem .875rem .25rem;box-shadow:none;border-radius:6px 6px 0 0}.f-section-like-query.f-section,.f-section-query.f-section{background:var(--f-neutral-19);margin:.5rem .5rem 0;padding:.625rem .875rem .25rem}.f-section-like-query .f-list-filter.list-filter-autolabel,.f-section-query .f-list-filter.list-filter-autolabel{padding-bottom:0!important}.f-section-like-query.f-section-form{margin:0!important;padding:.625rem 0 .25rem!important}.f-section-scheme{padding:0!important}.f-page-child-fill{flex-direction:column;flex:1 1 0;display:flex!important}.f-page-child-fill .f-struct-like-card-child-fill{display:flex;flex-direction:column;flex:1 1 0;overflow-y:auto}.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child{flex:1 1 0;flex-direction:column;display:flex;min-height:26.875rem}.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child:has(>.f-section-accordion.f-state-collapse){min-height:unset;display:block;flex:initial}.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child .f-section .f-component-tabs{flex:1 1 0;display:flex!important;flex-direction:column!important;overflow:hidden}.f-page-child-fill .f-struct-wrapper-child .f-struct-is-subgrid{flex:1 1 0;flex-direction:column;display:flex}.f-page-child-fill .f-struct-wrapper-child .f-grid-is-sub{height:auto;flex:1 1 0;flex-direction:column;display:flex}.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child .f-section .f-multiview-fill,.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child .f-section .f-multiview-fill .f-viewchange-content-item{display:flex;flex-direction:column;flex:1 1 0}.f-page-child-fill .f-struct-wrapper-child .f-section.f-section-fill .f-section-content{overflow:auto}.f-tmpl-subgrid-by-card{position:relative}.f-tmpl-subgrid-by-card .subgrid-by-card-item{padding:12px 12px 10px 40px;border-bottom:1px solid #E9E9E9;position:relative}.f-tmpl-subgrid-by-card .subgrid-by-card-item .card-item--order{position:absolute;top:16px;left:14px;border-radius:2px;background:#51BD78;line-height:1rem;color:#fff;font-size:12px;text-align:center;padding:0 2px;min-width:16px}.f-tmpl-subgrid-by-card .subgrid-by-card-item .card-item--header{padding:0;position:relative;margin:0 0 8px}.f-tmpl-subgrid-by-card .subgrid-by-card-item .card-item--header .card-item--toolbar{position:absolute;right:0;top:0}.f-tmpl-subgrid-by-card .subgrid-by-card-item .card-item--detail,.f-tmpl-subgrid-by-card .subgrid-by-card-item .card-item--title{font-size:1rem}.f-tmpl-subgrid-by-card .subgrid-by-card-item .card-item--detail{font-size:14px;padding:0;color:rgba(0,0,0,.75)}.f-tmpl-subgrid-by-card .subgrid-by-card-item .card-item--detail .card-item--item{margin-bottom:4px}.f-tmpl-subgrid-by-card-list .f-list-view-multiple .f-list-select{position:absolute;width:20px;height:20px;right:0;bottom:0}.f-tmpl-subgrid-by-card-list .f-list-view-multiple .f-list-select::before{position:absolute;font-size:12px;content:"\e118";color:#fff;font-family:FarrisIcons;z-index:100;right:0;bottom:-3px}.f-tmpl-subgrid-by-card-list .f-list-view-multiple .f-list-select::after{content:"";width:20px;height:20px;border:10px solid #fff;border-color:#fff #E6E6E6 #e6e6e6 #fff;position:absolute;bottom:0;right:0}.f-tmpl-subgrid-by-card-list .f-list-view-multiple .f-listview-active .subgrid-by-card-item{background:linear-gradient(270deg,rgba(235,244,255,.6) 0,#EBF4FF 100%)}.f-tmpl-subgrid-by-card-list .f-list-view-multiple .f-listview-active .f-list-select::after{border-color:#fff #63B7FF #63B7FF #fff}.f-tmpl-subgrid-by-card-list .f-list-view-multiple .f-tmpl-subgrid-by-card:hover .f-list-select::after{border-color:#fff #2A87FF #2A87FF #fff}.f-tmpl-subgrid-by-card-list .subgrid-by-card-footer{margin:8px 0 0;border:1px dashed #D9D9D9;height:28px}.f-tmpl-subgrid-by-card-list .subgrid-by-card-footer .btn{display:block;text-align:center;width:100%;height:100%}.farris-split-section{background:var(--f-neutral-19);box-shadow:0 2px 20px 0 rgba(3,18,51,.05);border-radius:8px;margin:.5rem;overflow:hidden;flex-wrap:nowrap}.farris-split-section .farris-lsection{padding:.875rem;box-shadow:1px 1px 4px 0 rgba(0,28,64,.1)}.farris-header,.farris-header+.farris-header{box-shadow:none}.farris-split-section .farris-rsection{padding:.875rem}.f-form-next-tab{margin-bottom:.3125rem!important}.farris-header{min-height:2.875rem;padding:.75rem .875rem;flex-shrink:0;background:var(--f-neutral-00)}.farris-form-title{margin:0;color:var(--f-text-01);font-size:1.0625rem;line-height:1.625rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.farris-card-content-bg .farris-panel .card-body{padding:.9375rem 0 0;background:var(--f-neutral-00)}.farris-card-section{padding:.875rem 0 .5rem}.farris-main-area{top:0;bottom:0;position:absolute;right:0;left:0;margin:0 auto;display:flex;background:#EFF2F4;overflow:hidden}.farris-cardpart-title{font-size:1rem;line-height:1.375rem;color:var(--f-text-01);margin:0 0 .75rem}.farris-grid-toolbar{display:flex;margin:0 0 .5rem;flex-shrink:0}.farris-grid-toolbar .farris-grid-title{padding:0;margin:0;font-size:1rem;line-height:1.375rem;color:var(--f-text-01)}.f-header-navbar{padding:0}.form-control{display:block;width:100%;height:calc(1.5357375rem + 2px);padding:.1875rem .5rem;font-size:.8125rem;line-height:1.4286;color:var(--f-text-02);background-color:var(--f-neutral-12);background-clip:padding-box;border:1px solid var(--f-neutral-04);border-radius:6px;box-shadow:0 0 0;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:var(--f-text-02);background-color:var(--f-neutral-12);border-color:var(--f-theme-08);outline:0;box-shadow:0 0 0,0 0 4px 2px rgba(99,136,255,.12)}.form-control::-moz-placeholder{color:var(--f-text-09);opacity:1}.form-control::placeholder{color:var(--f-text-09);opacity:1}.form-control:disabled,.form-control[readonly]{background-color:var(--f-neutral-12);opacity:1}select.form-control:focus::-ms-value{color:var(--f-text-02);background-color:var(--f-neutral-12)}.form-control-file,.form-control-range{display:block;width:100%}.form-control-plaintext{display:block;width:100%;padding-top:.1875rem;padding-bottom:.1875rem;margin-bottom:0;line-height:1.4286;color:var(--f-text-01);background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.32145rem + 2px);padding:.125rem .4375rem;font-size:.75rem;line-height:1.4286;border-radius:6px}.form-control-lg{height:calc(1.750025rem + 2px);padding:.25rem .3125rem;font-size:.875rem;line-height:1.4286;border-radius:6px}select.form-control[multiple],select.form-control[size],textarea.form-control{height:auto}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:var(--f-text-08)}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.col-form-label{font-size:inherit;line-height:1.4286}.col-form-label-lg{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.4286}.col-form-label-sm{padding-top:calc(.125rem + 1px);padding-bottom:calc(.125rem + 1px);font-size:.75rem;line-height:1.4286}.form-group{margin-bottom:.375rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex-grow:0;flex-shrink:0;flex-basis:auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.farris-form{flex-shrink:0}.farris-input-wrap{display:block;position:relative}.farris-input-wrap .form-control{width:100%;display:block}.farris-input-wrap .form-control.form-control-invalid{border-color:var(--f-semantic-danger-01)}.farris-input-wrap .form-control.form-control-invalid:focus{box-shadow:0 0 2px 1px rgba(244,97,96,.3)}.farris-input-wrap .input-group .form-control{width:1%}.farris-input-wrap .farris-feedback{position:absolute;top:100%;left:0;padding:.1875rem .5rem;z-index:122;display:none;border-radius:6px;transition:all .2s linear;cursor:pointer}.farris-input-wrap .farris-feedback .f-feedback-message{font-size:.8125rem;line-height:1.4286}.farris-input-wrap .farris-feedback .f-feedback-icon{font-size:14px}.farris-input-wrap .farris-feedback.f-state-invalid,.farris-input-wrap .farris-feedback.f-state-valid{display:block}.farris-input-wrap .farris-feedback.f-state-invalid{background:var(--f-semantic-danger-03);color:var(--f-semantic-danger-01)}.farris-input-wrap .farris-feedback.f-state-valid{background:var(--f-semantic-success-03);color:var(--f-semantic-success-01)}.farris-form-group{flex-wrap:nowrap!important}.farris-form-group .col-form-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%}.farris-form-group .farris-input-wrap .custom-control-label{display:inline}.farris-form-group .farris-input-wrap .custom-checkbox,.farris-form-group .farris-input-wrap .custom-radio{margin-bottom:0;margin-top:.125rem}.farris-label-info{padding:0 .25rem 0 0;flex-shrink:0}.farris-form-controls-inline .farris-group-wrap .farris-input-wrap,.form-inline .farris-input-wrap{flex-shrink:1;flex-grow:1;flex-basis:auto;min-width:1px}.farris-form-controls-inline .farris-group-wrap .col-form-label,.form-inline .col-form-label{display:flex;align-items:center;justify-content:flex-end!important;flex-direction:row!important}.farris-form-controls-inline .farris-group-wrap,.farris-form-inline{display:block}.farris-form-controls-inline .farris-group-wrap .col-form-label,.farris-form-inline .col-form-label{width:6rem;flex-shrink:0;margin-right:.625rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;justify-content:flex-end!important;flex-direction:row!important;align-self:start}.farris-form-controls-inline .farris-group-wrap .col-form-label>*,.farris-form-inline .col-form-label>*{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.farris-form-controls-inline .farris-group-wrap .col-form-label.col-form-label-multi,.farris-form-inline .col-form-label.col-form-label-multi{word-break:break-all;white-space:initial}.farris-form-controls-inline .farris-group-wrap .col-form-label.col-form-label-multi .farris-label-info,.farris-form-inline .col-form-label.col-form-label-multi .farris-label-info{align-self:flex-start;line-height:1.4286}.farris-form-controls-inline .farris-group-wrap .col-form-label.col-form-label-multi .farris-label-text,.farris-form-inline .col-form-label.col-form-label-multi .farris-label-text{white-space:initial;text-align:right;max-height:2.321475rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.farris-form-controls-inline .farris-group-wrap .form-group,.farris-form-inline .form-group{margin-bottom:.5rem;flex-wrap:nowrap!important}.farris-form-controls-inline .farris-group-multi-label .farris-group-wrap,.form-inline .farris-group-multi-label .farris-group-wrap{margin-bottom:0}.farris-form-controls-inline .farris-group-multi-label .farris-group-wrap .col-form-label,.form-inline .farris-group-multi-label .farris-group-wrap .col-form-label{padding-top:0;padding-bottom:0;word-break:break-all;white-space:initial}.farris-form-controls-inline .farris-group-multi-label .farris-group-wrap .col-form-label .farris-label-info,.form-inline .farris-group-multi-label .farris-group-wrap .col-form-label .farris-label-info{align-self:flex-start;line-height:1.4286}.farris-form-controls-inline .farris-group-multi-label .farris-group-wrap .col-form-label .farris-label-text,.form-inline .farris-group-multi-label .farris-group-wrap .col-form-label .farris-label-text{white-space:pre-wrap;text-align:right;max-height:2.321475rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.farris-form-controls-inline .farris-group-multi-label .farris-group-wrap .farris-input-wrap,.form-inline .farris-group-multi-label .farris-group-wrap .farris-input-wrap{align-self:flex-start}.farris-form-controls-inline.f-form-label-sm .farris-group-wrap .col-form-label,.farris-form-inline.f-form-label-sm .col-form-label{width:4.25rem}.farris-form-controls-inline.f-form-label-lg .farris-group-wrap .col-form-label,.farris-form-inline.f-form-label-lg .col-form-label{width:7.75rem}.farris-form-controls-inline.f-form-label-xl .farris-group-wrap .col-form-label,.farris-form-inline.f-form-label-xl .col-form-label{width:9.5rem}.farris-form-controls-inline.f-form-label-el .farris-group-wrap .col-form-label,.farris-form-inline.f-form-label-el .col-form-label{width:13rem}.farris-form-controls-inline .f-empty-input-placeholder,.farris-form-inline .f-empty-input-placeholder{padding-top:0;margin-top:0;margin-bottom:.5rem}.farris-form-controls-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.farris-form-controls-inline .farris-group-ver .col-form-label,.farris-form-controls-inline .farris-group-ver .form-group{display:block}.f-checkradio-no-label .farris-form-controls-inline .col-form-label,.f-checkradio-no-label .farris-form-inline .col-form-label{width:1px;overflow:hidden;height:calc(1.5357375rem + 1px * 2)}.f-checkradio-no-label .farris-form-controls-inline .custom-checkbox,.f-checkradio-no-label .farris-form-controls-inline .custom-radio,.f-checkradio-no-label .farris-form-inline .custom-checkbox,.f-checkradio-no-label .farris-form-inline .custom-radio{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.f-form-lable-auto .col-form-label{width:auto!important}.farris-form-controls-inline .f-checkradio-no-label .col-form-label,.farris-form-inline .f-checkradio-no-label .col-form-label{width:1px;overflow:hidden;height:calc(1.4286 * 1.4286 + .1875rem * 2 + 1px * 2)}.custom-control-label{margin-left:0}.f-input-underline .form-control{border-radius:0;background:0 0;border-width:0 0 1px;border-color:var(--f-neutral-02);border-style:solid}.f-input-underline .form-control:focus{background:0 0;border-color:var(--f-theme-08);color:var(--f-text-02);box-shadow:none}.f-input-underline .form-control:disabled,.f-input-underline .form-control:disabled:hover{background:0 0;border-color:var(--f-neutral-04);border-style:dashed;color:var(--f-text-02)}.f-input-underline .form-control:disabled::-moz-placeholder,.f-input-underline .form-control[readonly]::-moz-placeholder{color:var(--f-text-09)}.f-input-underline .form-control:disabled::placeholder,.f-input-underline .form-control[readonly]::placeholder{color:var(--f-text-09)}.f-input-underline .form-control[readonly],.f-input-underline .form-control[readonly]:hover{background:0 0;border-color:var(--f-neutral-04);border-style:dashed;color:var(--f-text-02)}.f-input-underline .f-cmp-inputgroup.actived .input-group{box-shadow:none}.f-input-underline .input-group{border-radius:0;border-width:0 0 1px;border-color:var(--f-neutral-02);border-style:solid}.f-input-underline .input-group .form-control{border:0}.f-input-underline .input-group.f-state-disabled,.f-input-underline .input-group.f-state-readonly{border-color:var(--f-neutral-04);border-style:dashed}.f-input-underline .input-group.f-state-focus{box-shadow:none}.f-state-form-view .farris-group-wrap .farris-label-text{color:var(--f-text-02)}.f-state-form-view .form-control:focus{background:var(--f-neutral-12);border-color:transparent;color:var(--f-text-02);box-shadow:none}.f-state-form-view .form-control:disabled,.f-state-form-view .form-control:disabled:hover,.f-state-form-view .form-control[readonly],.f-state-form-view .form-control[readonly]:hover{background:var(--f-neutral-12);border-color:transparent;color:var(--f-text-02)}.f-state-form-view .input-group,.f-state-form-view .input-group.f-state-disabled,.f-state-form-view .input-group.f-state-readonly{border-color:transparent}.farris-input-wrap .f-cmp-inputgroup.ng-invalid.ng-dirty .input-group,.farris-input-wrap .f-cmp-inputgroup.ng-invalid.ng-dirty .input-group:hover,.farris-input-wrap .f-cmp-inputgroup.ng-invalid.ng-touched .input-group,.farris-input-wrap .f-cmp-inputgroup.ng-invalid.ng-touched .input-group:hover,.farris-input-wrap .form-control.ng-invalid.ng-dirty,.farris-input-wrap .form-control.ng-invalid.ng-touched{border-color:#dc3545}.f-form-controls-fixed-with .farris-input-wrap{width:3.75rem}.f-checkradio-single{margin:0;padding:0;width:1rem;height:1rem;min-height:1rem;display:inline-flex}.f-checkradio-single .custom-control-label::after,.f-checkradio-single .custom-control-label::before{top:0;left:0}.f-form-table{width:100%;table-layout:fixed}.f-form-table td{padding-left:14px;padding-right:14px}.farris-input-wrap .form-control.ng-invalid.ng-dirty:focus,.farris-input-wrap .form-control.ng-invalid.ng-touched:focus{box-shadow:0 0 2px 1px rgba(220,53,69,.3)}.f-form-state-default .farris-input-wrap .form-control:disabled,.f-form-state-default .farris-input-wrap .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-default .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-default .farris-input-wrap .form-control[readonly]+.input-append-wrapper{background:var(--f-neutral-12)}.f-form-state-default .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-component-timepicker .input-group .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-component-timepicker .input-group.f-state-readonly{background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-default .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-default .f-component-timepicker .input-group.f-state-readonly .form-control{color:var(--f-text-02);background:var(--f-neutral-12)!important}.f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-component-timepicker .input-group.f-state-readonly .input-group-append{background:var(--f-neutral-12)}.f-form-state-default .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-default .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-default .f-component-timepicker .input-group.f-state-editable .form-control{color:var(--f-text-02);border-color:var(--f-neutral-04);background:var(--f-neutral-12)}.f-form-state-default .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-default .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-default .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-default .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-default .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-default .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-default .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-default .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-default .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-default .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-default .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-default .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-default .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-default .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-default .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-default .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-default .farris-editor.farris-editor-readonly .mce-container{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-default .farris-html-editor .ql-container.ql-disabled{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)!important}.f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly]{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly]+.input-append-wrapper{background:var(--f-neutral-10)}.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly{background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .form-control{color:var(--f-text-07);background:var(--f-neutral-10)!important}.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .input-group-append{background:var(--f-neutral-10)}.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-editable .form-control{color:var(--f-text-02);border-color:var(--f-neutral-04);background:var(--f-neutral-12)}.f-form-state-default .f-form-pretend-lines .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-pretend-lines .farris-editor.farris-editor-readonly .mce-container{color:var(--f-text-07);background:var(--f-neutral-10)}.f-form-state-default .f-form-pretend-lines .farris-html-editor .ql-container.ql-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)!important}.f-form-state-create .farris-input-wrap .form-control:disabled,.f-form-state-create .farris-input-wrap .form-control[readonly],.f-form-state-edit .farris-input-wrap .form-control:disabled,.f-form-state-edit .farris-input-wrap .form-control[readonly],.f-input-text-light .farris-input-wrap .form-control:disabled,.f-input-text-light .farris-input-wrap .form-control[readonly]{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-create .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-form-state-edit .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-edit .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-input-text-light .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-input-text-light .farris-input-wrap .form-control[readonly]+.input-append-wrapper{background:var(--f-neutral-10)}.f-form-state-create .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-component-timepicker .input-group .form-control[readonly],.f-input-text-light .f-cmp-inputgroup .input-group .form-control:disabled,.f-input-text-light .f-cmp-inputgroup .input-group .form-control[readonly],.f-input-text-light .f-cmp-number-spinner .input-group .form-control:disabled,.f-input-text-light .f-cmp-number-spinner .input-group .form-control[readonly],.f-input-text-light .f-component-timepicker .input-group .form-control:disabled,.f-input-text-light .f-component-timepicker .input-group .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-create .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-component-timepicker .input-group.f-state-readonly,.f-input-text-light .f-cmp-inputgroup .input-group.f-state-disabled,.f-input-text-light .f-cmp-inputgroup .input-group.f-state-readonly,.f-input-text-light .f-cmp-number-spinner .input-group.f-state-disabled,.f-input-text-light .f-cmp-number-spinner .input-group.f-state-readonly,.f-input-text-light .f-component-timepicker .input-group.f-state-disabled,.f-input-text-light .f-component-timepicker .input-group.f-state-readonly{background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-create .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-create .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-create .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-create .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-create .f-component-timepicker .input-group.f-state-readonly .form-control,.f-form-state-edit .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-edit .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-edit .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-edit .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-edit .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-edit .f-component-timepicker .input-group.f-state-readonly .form-control,.f-input-text-light .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-input-text-light .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-input-text-light .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-input-text-light .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-input-text-light .f-component-timepicker .input-group.f-state-disabled .form-control,.f-input-text-light .f-component-timepicker .input-group.f-state-readonly .form-control{color:var(--f-text-07);background:var(--f-neutral-10)!important}.f-form-state-create .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-create .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-create .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-component-timepicker .input-group.f-state-readonly .input-group-append{background:var(--f-neutral-10)}.f-form-state-create .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-create .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-create .f-component-timepicker .input-group.f-state-editable .form-control,.f-form-state-edit .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-edit .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-edit .f-component-timepicker .input-group.f-state-editable .form-control,.f-input-text-light .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-input-text-light .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-input-text-light .f-component-timepicker .input-group.f-state-editable .form-control{color:var(--f-text-02);border-color:var(--f-neutral-04);background:var(--f-neutral-12)}.f-form-state-create .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-create .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-create .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-create .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-create .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-create .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-create .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-create .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-create .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-create .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-edit .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .f-state-readonly.k-datepicker .k-picker-wrap,.f-input-text-light .farris-input-wrap .k-autocomplete.k-state-disabled,.f-input-text-light .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-input-text-light .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-input-text-light .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-input-text-light .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-input-text-light .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-input-text-light .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-create .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-create .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-create .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-create .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-create .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-create .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-create .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-create .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-create .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-edit .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-autocomplete,.f-input-text-light .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-input-text-light .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .farris-editor.farris-editor-readonly .mce-container,.f-form-state-edit .farris-editor.farris-editor-readonly .mce-container,.f-input-text-light .farris-editor.farris-editor-readonly .mce-container{color:var(--f-text-07);background:var(--f-neutral-10)}.f-form-state-create .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .farris-html-editor .ql-container.ql-disabled,.f-input-text-light .farris-html-editor .ql-container.ql-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)!important}.f-form-state-create .f-form-state-default .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .form-control[readonly],.f-input-text-light .f-form-state-default .farris-input-wrap .form-control:disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-create .f-form-state-default .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-create .f-form-state-default .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-form-state-edit .f-form-state-default .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-edit .f-form-state-default .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-input-text-light .f-form-state-default .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-input-text-light .f-form-state-default .farris-input-wrap .form-control[readonly]+.input-append-wrapper{background:var(--f-neutral-12)}.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group .form-control[readonly],.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group .form-control:disabled,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group .form-control[readonly],.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group .form-control:disabled,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group .form-control[readonly],.f-input-text-light .f-form-state-default .f-component-timepicker .input-group .form-control:disabled,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group.f-state-readonly,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group.f-state-disabled,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group.f-state-readonly{background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group.f-state-readonly .form-control,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group.f-state-readonly .form-control,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group.f-state-disabled .form-control,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group.f-state-readonly .form-control{color:var(--f-text-02);background:var(--f-neutral-12)!important}.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group.f-state-readonly .input-group-append{background:var(--f-neutral-12)}.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group.f-state-editable .form-control,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group.f-state-editable .form-control,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group.f-state-editable .form-control{color:var(--f-text-02);border-color:var(--f-neutral-04);background:var(--f-neutral-12)}.f-form-state-create .f-form-state-default .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-state-readonly.k-datepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .k-autocomplete.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-autocomplete,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-create .f-form-state-default .farris-editor.farris-editor-readonly .mce-container,.f-form-state-edit .f-form-state-default .farris-editor.farris-editor-readonly .mce-container,.f-input-text-light .f-form-state-default .farris-editor.farris-editor-readonly .mce-container{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-create .f-form-state-default .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .farris-html-editor .ql-container.ql-disabled,.f-input-text-light .f-form-state-default .farris-html-editor .ql-container.ql-disabled{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)!important}.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly]{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly]+.input-append-wrapper{background:var(--f-neutral-10)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control[readonly],.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control:disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control[readonly],.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control:disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control[readonly],.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control:disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly{background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .form-control{color:var(--f-text-07);background:var(--f-neutral-10)!important}.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .input-group-append{background:var(--f-neutral-10)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-editable .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-editable .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-editable .form-control{color:var(--f-text-02);border-color:var(--f-neutral-04);background:var(--f-neutral-12)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-state-readonly.k-datepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-autocomplete.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-autocomplete,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-editor.farris-editor-readonly .mce-container,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-editor.farris-editor-readonly .mce-container,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-editor.farris-editor-readonly .mce-container{color:var(--f-text-07);background:var(--f-neutral-10)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-html-editor .ql-container.ql-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-html-editor .ql-container.ql-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)!important}.f-form-state-default .f-form-state-create .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .form-control[readonly],.f-form-state-default .f-input-text-light .farris-input-wrap .form-control:disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .form-control[readonly]{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-state-create .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-default .f-form-state-create .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-form-state-default .f-form-state-edit .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-default .f-form-state-edit .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-form-state-default .f-input-text-light .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-default .f-input-text-light .farris-input-wrap .form-control[readonly]+.input-append-wrapper{background:var(--f-neutral-10)}.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-input-text-light .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group.f-state-readonly{background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group.f-state-readonly .form-control,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group.f-state-readonly .form-control,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group.f-state-readonly .form-control{color:var(--f-text-07);background:var(--f-neutral-10)!important}.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group.f-state-readonly .input-group-append{background:var(--f-neutral-10)}.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group.f-state-editable .form-control,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group.f-state-editable .form-control,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group.f-state-editable .form-control{color:var(--f-text-02);border-color:var(--f-neutral-04);background:var(--f-neutral-12)}.f-form-state-default .f-form-state-create .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-state-create .farris-editor.farris-editor-readonly .mce-container,.f-form-state-default .f-form-state-edit .farris-editor.farris-editor-readonly .mce-container,.f-form-state-default .f-input-text-light .farris-editor.farris-editor-readonly .mce-container{color:var(--f-text-07);background:var(--f-neutral-10)}.f-form-state-default .f-form-state-create .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-edit .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-input-text-light .farris-html-editor .ql-container.ql-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)!important}.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control:disabled,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control[readonly],.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .form-control:disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .form-control[readonly],.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-create .farris-card-content-bg .farris-input-wrap .form-control:disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .form-control[readonly],.f-form-state-create .farris-card-section .farris-input-wrap .form-control:disabled,.f-form-state-create .farris-card-section .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-edit .farris-card-content-bg .farris-input-wrap .form-control:disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .form-control[readonly],.f-form-state-edit .farris-card-section .farris-input-wrap .form-control:disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .form-control[readonly]{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .farris-card-content-bg .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .farris-card-section .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .farris-card-section .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .farris-card-section .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .farris-card-section .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .farris-card-section .farris-input-wrap .farris-html-editor .ql-container.ql-disabled{border-width:1px!important;border-color:var(--f-neutral-06)}.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly]{border:0}.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-editable{border-width:1px;border-color:var(--f-neutral-04)}.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-focus{border-color:var(--f-theme-08);color:var(--f-text-02)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .form-control[readonly]{border-width:0 0 1px;border-radius:0;border-style:solid;border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .farris-html-editor .ql-container.ql-disabled{border-width:0 0 1px!important;border-radius:0;border-style:solid;border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly]{border:0}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus{border-width:0 0 1px;border-radius:0;border-style:solid;border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-editable{border-width:1px;border-color:var(--f-neutral-04)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-focus{border-color:var(--f-theme-08);color:var(--f-text-02)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .form-control[readonly]{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled{border-width:1px!important;border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly]{border:0}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable{border-width:1px;border-color:var(--f-neutral-04)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus{border-color:var(--f-theme-08);color:var(--f-text-02)}.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control[readonly],.f-form-state-default .f-section-form .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-default .farris-card-content-bg .farris-input-wrap .form-control:disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .form-control[readonly],.f-form-state-default .farris-card-section .farris-input-wrap .form-control:disabled,.f-form-state-default .farris-card-section .farris-input-wrap .form-control[readonly]{border-width:0 0 1px;border-radius:0;border-style:solid;border-color:var(--f-neutral-06)}.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .farris-card-section .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .farris-card-section .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .farris-card-section .farris-input-wrap .farris-html-editor .ql-container.ql-disabled{border-width:0 0 1px!important;border-radius:0;border-style:solid;border-color:var(--f-neutral-06)}.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly]{border:0}.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus{border-width:0 0 1px;border-radius:0;border-style:solid;border-color:var(--f-neutral-06)}.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-editable{border-width:1px;border-color:var(--f-neutral-04)}.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-focus{border-color:var(--f-theme-08);color:var(--f-text-02)}.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .form-control[readonly]{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled{border-width:1px!important;border-color:var(--f-neutral-06)}.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly]{border:0}.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable{border-width:1px;border-color:var(--f-neutral-04)}.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus{border-color:var(--f-theme-08);color:var(--f-text-02)}.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .form-control[readonly]{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .farris-html-editor .ql-container.ql-disabled{border-width:1px!important;border-color:var(--f-neutral-06)}.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly]{border:0}.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-editable{border-width:1px;border-color:var(--f-neutral-04)}.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-focus{border-color:var(--f-theme-08);color:var(--f-text-02)}.f-form-pretend-lines .f-form-control-text,.f-form-pretend-lines .f-form-control-textarea{border-width:1px!important;color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.form-group--has-tips{position:relative}.form-group--has-tips .farris-label-tips{position:absolute;right:0;bottom:calc(.75rem + 1px);margin-bottom:-7px}.farris-label-tips,.farris-label-tips--highlight{display:inline-block;width:14px;height:14px;border:1px solid var(--f-theme-03);background:var(--f-aid-04);color:var(--f-theme-03);border-radius:7px;line-height:1;text-align:center}.farris-label-tips .f-icon,.farris-label-tips--highlight .f-icon{font-size:13px;vertical-align:top;transform:scale(.7)}.badge,.farris-label-tips--highlight .f-icon{vertical-align:baseline}.farris-label-tips--highlight:has(.f-icon-question),.farris-label-tips:has(.f-icon-question){border-color:var(--f-semantic-warning-01)}.farris-label-tips--highlight{border:none;color:#fff;background-image:linear-gradient(225deg,#FFB362 0,#FF8538 100%)}.form-label-plaintext .farris-label-text{color:var(--f-text-08)}.form-row{margin-right:-.5rem;margin-left:-.5rem}.form-row>.col,.form-row>[class*=col-]{padding-right:.5rem;padding-left:.5rem}.col-form-label{padding-top:0;padding-bottom:0;margin-bottom:.375rem;margin-left:0}.farris-form-controls-inline .farris-group-wrap .col-form-label,.farris-form-inline .col-form-label{padding-top:calc(.1875rem + 1px);padding-bottom:calc(.1875rem + 1px);margin-bottom:0}.f-list-view-content .f-list-view-group .f-list-content .f-tmpl-card--header-multicontent01 .header-multicontent01--content .header-multicontent01--footer{min-height:31px}.f-component-wizard-page-detail-footer{border-top:1px solid var(--f-neutral-08);padding:.75rem .875rem .875rem}.f-tmpl-card--header-multicontent01{background:#FEFEFF;border:1px solid #E4E7EF;border-radius:4px;width:19.375rem;margin:0 1rem 1rem 0;box-shadow:0 2px 10px 0 rgba(0,25,58,.1)}.f-tmpl-card--header-multicontent01 .header-multicontent01--header{color:#fff;border-radius:4px;height:2.5rem;padding:0 1.375rem;position:relative;background:linear-gradient(225deg,var(--f-aid-01),var(--f-theme-03))}.f-tmpl-card--header-multicontent01 .header-multicontent01--header .f-title{font-size:1rem;line-height:2.5rem;margin:0}.f-tmpl-card--header-multicontent01 .header-multicontent01--header .f-state{text-align:center;position:absolute;top:-1px;right:-1px;width:3.75rem;height:1.5rem;line-height:1.5rem;color:#fff;font-size:.75rem}.f-tmpl-card--header-multicontent01 .header-multicontent01--header .f-state span{display:block;border-radius:0 0 0 6px}.f-tmpl-card--header-multicontent01 .header-multicontent01--content{padding:1rem 1.375rem;position:relative}.f-tmpl-card--header-multicontent01 .header-multicontent01--content .f-title{font-size:1rem;height:22px}.f-tmpl-card--header-multicontent01 .header-multicontent01--content p{margin:0 0 .5rem}.f-tmpl-card--header-multicontent01 .header-multicontent01--content .f-state{position:absolute;right:0;top:13px}.f-tmpl-card--header-multicontent01 .header-multicontent01--content .f-state span{border-radius:4px 0 0 4px;padding-top:4px;padding-bottom:4px}.f-tmpl-card--header-multicontent01 .header-multicontent01--footer .f-emphasize{font-size:1.375rem;color:#F7962A}.f-tmpl-card--header-multicontent01 .header-multicontent01--footer .f-toolbar{margin:0}.f-tmpl-card--header-multicontent01 .header-multicontent01--footer .f-toolbar span{cursor:pointer;margin:0 1rem 0 0}.f-tmpl-list--columns01{display:flex;flex-wrap:no-wrap;border:1px solid #ddd;position:relative;margin:-1px 8px 0;flex-direction:row;padding:20px 8px 12px;align-items:center}.f-tmpl-list--columns01 p{margin-bottom:4px}.f-tmpl-list--columns01 .f-state{position:absolute;top:-1px;left:0}.f-tmpl-list--columns01 .f-state span{border-radius:0 0 4px 4px;padding-left:12px;padding-right:11px}.f-tmpl-list--columns01 .f-emphasize{font-size:1.375rem;color:#F7962A}.f-template-common-row{padding:12px 16px;align-items:center}.f-template-common-row .item-action-primary{display:inline-block;margin-right:16px;width:60px;height:60px;border-radius:50%;overflow:hidden}.f-template-common-row .item-action-primary .ap-img{display:block;width:60px;height:60px;border-radius:50%}.f-template-common-row .listview-item-content{border-bottom:1px solid #d9d9d9;flex:1 1 auto}.f-template-common-row .listview-item-content .listview-item-main{flex-grow:1;flex-shrink:1;flex-basis:0}.f-template-common-row .listview-item-content .listview-item-title{font-size:16px;color:rgba(0,0,0,.85)}.f-template-common-row .listview-item-content .listview-item-subtitle{font-size:14px;color:rgba(0,0,0,.45)}.badge-pill-success,.badge-success{color:#fff}.f-template-common-row .listview-item-content .listview-item-btns .btn{margin-left:6px;margin-right:6px}.f-listview-active .f-tmpl-list--columns01{box-shadow:0 2px 10px 0 rgba(0,25,58,.1)}.badge-arrow-left-success,.badge-arrow-right-success,.badge-pill-success,.badge-round-success,.badge-success{background:var(--f-semantic-success-01)}.f-listview-active .f-template-common-row .listview-item-content{border-color:var(--f-theme-03)}.f-page-is-onepage .f-onepage-tabs{margin:0 .5rem}.f-onepage-content{overflow-y:auto}.badge{display:inline-block;padding:.1875rem .5rem;font-size:.75rem;line-height:1;text-align:center;white-space:nowrap;border-radius:6px}.badge-pill,.badge-pill-border-success,.badge-pill-success{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-border-arrow-left-success,.badge-border-success,.badge-pill-border-success{color:var(--f-semantic-success-01);background:var(--f-semantic-success-03)}.badge-pill-border-success{border:1px solid var(--f-semantic-success-01)}.badge-border-success{padding:.125rem .4375rem;border:1px solid var(--f-semantic-success-02);border-radius:2px}.badge-border-arrow-left-success{border:1px solid var(--f-semantic-success-02);position:relative;margin-left:12px}.badge-border-arrow-left-success::after,.badge-border-arrow-left-success::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-left-success::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-success-02);border-width:6px 12px 6px 0}.badge-border-arrow-left-success::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-success-03);border-width:5px 10px 5px 0}.badge-border-arrow-right-success{position:relative;margin-right:12px}.badge-border-arrow-right-success::after,.badge-border-arrow-right-success::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-right-success::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-success-02);border-width:6px 0 6px 12px}.badge-border-arrow-right-success::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-success-03);border-width:5px 0 5px 10px}.badge-arrow-left-success::before,.badge-arrow-right-success::before{margin-top:-8px;border-top:8px solid transparent;border-bottom:8px solid transparent;content:"";top:50%}.badge-arrow-left-success{position:relative;color:#fff;margin-left:8px}.badge-arrow-left-success::before{position:absolute;border-right:8px solid transparent;border-left:0 solid transparent;left:-8px;border-right-color:var(--f-semantic-success-01)}.badge-arrow-right-success{position:relative;color:#fff;margin-right:8px}.badge-arrow-right-success::before{position:absolute;border-left:8px solid transparent;border-right:0 solid transparent;right:-8px;border-left-color:var(--f-semantic-success-01)}.badge-round-success{width:6px;height:6px;border-radius:3px;line-height:1;overflow:hidden;padding:0}.badge-round-outer-success{position:relative;width:14px;height:14px;display:block;background:rgba(var(--f-semantic-success-01),.18);border-radius:7px}.badge-round-outer-success::after{content:"";width:8px;height:8px;position:absolute;top:50%;left:50%;margin:-4px 0 0 -4px;border-radius:4px;background:var(--f-semantic-success-01)}.badge-pill-border-info,.badge-pill-info{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-info,.badge-pill-info{color:#fff;background:var(--f-semantic-info-01)}.badge-border-arrow-left-info,.badge-border-info,.badge-pill-border-info{color:var(--f-semantic-info-01);background:var(--f-semantic-info-03)}.badge-pill-border-info{border:1px solid var(--f-semantic-info-01)}.badge-border-info{padding:.125rem .4375rem;border:1px solid var(--f-semantic-info-02);border-radius:2px}.badge-border-arrow-left-info{border:1px solid var(--f-semantic-info-02);position:relative;margin-left:12px}.badge-arrow-left-info,.badge-arrow-right-info,.badge-round-info{background:var(--f-semantic-info-01)}.badge-border-arrow-left-info::after,.badge-border-arrow-left-info::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-left-info::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-info-02);border-width:6px 12px 6px 0}.badge-border-arrow-left-info::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-info-03);border-width:5px 10px 5px 0}.badge-border-arrow-right-info{position:relative;margin-right:12px}.badge-border-arrow-right-info::after,.badge-border-arrow-right-info::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-round-info,.badge-round-warning{width:6px;border-radius:3px;padding:0;display:inline-block!important;line-height:1;overflow:hidden;height:6px}.badge-border-arrow-right-info::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-info-02);border-width:6px 0 6px 12px}.badge-border-arrow-right-info::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-info-03);border-width:5px 0 5px 10px}.badge-arrow-left-info::before,.badge-arrow-right-info::before{margin-top:-8px;border-top:8px solid transparent;border-bottom:8px solid transparent}.badge-arrow-left-info{position:relative;color:#fff;margin-left:8px}.badge-arrow-left-info::before{content:"";position:absolute;top:50%;border-right:8px solid transparent;border-left:0 solid transparent;left:-8px;border-right-color:var(--f-semantic-info-01)}.badge-arrow-right-info{position:relative;color:#fff;margin-right:8px}.badge-arrow-right-info::before,.badge-round-outer-info::after{position:absolute;content:"";top:50%}.badge-arrow-right-info::before{border-left:8px solid transparent;border-right:0 solid transparent;right:-8px;border-left-color:var(--f-semantic-info-01)}.badge-round-outer-info{position:relative;width:14px;height:14px;display:block;background:rgba(var(--f-semantic-info-01),.18);border-radius:7px}.badge-round-outer-info::after{width:8px;height:8px;left:50%;margin:-4px 0 0 -4px;border-radius:4px;background:var(--f-semantic-info-01)}.badge-pill-border-warning,.badge-pill-warning{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-arrow-left-warning,.badge-arrow-right-warning,.badge-pill-warning,.badge-round-outer-warning::after,.badge-round-warning,.badge-warning{background:var(--f-semantic-warning-01)}.badge-pill-warning,.badge-warning{color:#fff}.badge-border-arrow-left-warning,.badge-border-warning,.badge-pill-border-warning{color:var(--f-semantic-warning-01);background:var(--f-semantic-warning-03)}.badge-pill-border-warning{border:1px solid var(--f-semantic-warning-01)}.badge-border-warning{padding:.125rem .4375rem;border:1px solid var(--f-semantic-warning-02);border-radius:2px}.badge-border-arrow-left-warning{border:1px solid var(--f-semantic-warning-02);position:relative;margin-left:12px}.badge-border-arrow-left-warning::after,.badge-border-arrow-left-warning::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-left-warning::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-warning-02);border-width:6px 12px 6px 0}.badge-border-arrow-left-warning::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-warning-03);border-width:5px 10px 5px 0}.badge-border-arrow-right-warning{position:relative;margin-right:12px}.badge-border-arrow-right-warning::after,.badge-border-arrow-right-warning::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-right-warning::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-warning-02);border-width:6px 0 6px 12px}.badge-border-arrow-right-warning::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-warning-03);border-width:5px 0 5px 10px}.badge-arrow-left-warning::before,.badge-arrow-right-warning::before{margin-top:-8px;border-top:8px solid transparent;border-bottom:8px solid transparent;content:"";top:50%}.badge-arrow-left-warning{position:relative;color:#fff;margin-left:8px}.badge-arrow-left-warning::before{position:absolute;border-right:8px solid transparent;border-left:0 solid transparent;left:-8px;border-right-color:var(--f-semantic-warning-01)}.badge-arrow-right-warning{position:relative;color:#fff;margin-right:8px}.badge-arrow-right-warning::before{position:absolute;border-left:8px solid transparent;border-right:0 solid transparent;right:-8px;border-left-color:var(--f-semantic-warning-01)}.badge-round-outer-warning{position:relative;width:14px;height:14px;display:block;background:rgba(var(--f-semantic-warning-01),.18);border-radius:7px}.badge-round-outer-warning::after{content:"";width:8px;height:8px;position:absolute;top:50%;left:50%;margin:-4px 0 0 -4px;border-radius:4px}.badge-pill-border-danger,.badge-pill-danger{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-danger,.badge-pill-danger{color:#fff;background:#F46160}.badge-border-arrow-left-danger,.badge-border-danger,.badge-pill-border-danger{color:#F46160;background:var(--f-semantic-danger-03)}.badge-pill-border-danger{border:1px solid #F46160}.badge-border-danger{padding:.125rem .4375rem;border:1px solid var(--f-semantic-danger-02);border-radius:2px}.badge-border-arrow-left-danger{border:1px solid var(--f-semantic-danger-02);position:relative;margin-left:12px}.badge-border-arrow-left-danger::after,.badge-border-arrow-left-danger::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-left-danger::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-danger-02);border-width:6px 12px 6px 0}.badge-border-arrow-left-danger::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-danger-03);border-width:5px 10px 5px 0}.badge-border-arrow-right-danger{position:relative;margin-right:12px}.badge-border-arrow-right-danger::after,.badge-border-arrow-right-danger::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-right-danger::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-danger-02);border-width:6px 0 6px 12px}.badge-border-arrow-right-danger::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-danger-03);border-width:5px 0 5px 10px}.badge-arrow-left-danger::before,.badge-arrow-right-danger::before{margin-top:-8px;border-top:8px solid transparent;border-bottom:8px solid transparent}.badge-arrow-left-danger{background:#F46160;position:relative;color:#fff;margin-left:8px}.badge-arrow-left-danger::before{content:"";position:absolute;top:50%;border-right:8px solid transparent;border-left:0 solid transparent;left:-8px;border-right-color:#F46160}.badge-arrow-right-danger{background:#F46160;position:relative;color:#fff;margin-right:8px}.badge-arrow-right-danger::before,.badge-round-outer-danger::after{position:absolute;content:"";top:50%}.badge-arrow-right-danger::before{border-left:8px solid transparent;border-right:0 solid transparent;right:-8px;border-left-color:#F46160}.badge-round-danger{width:6px;height:6px;border-radius:3px;display:inline-block!important;line-height:1;overflow:hidden;padding:0;background:#F46160}.badge-round-outer-danger{position:relative;width:14px;height:14px;display:block;background:rgba(244,97,96,.18);border-radius:7px}.badge-round-outer-danger::after{width:8px;height:8px;left:50%;margin:-4px 0 0 -4px;border-radius:4px;background:#F46160}.badge-pill-border-primary,.badge-pill-primary{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-arrow-left-primary,.badge-arrow-right-primary,.badge-pill-primary,.badge-primary,.badge-round-primary{background:var(--f-theme-03)}.badge-pill-primary,.badge-primary{color:#fff}.badge-border-arrow-left-primary,.badge-border-primary,.badge-pill-border-primary{color:var(--f-theme-03);background:var(--f-semantic-info-03)}.badge-pill-border-primary{border:1px solid var(--f-theme-03)}.badge-border-primary{padding:.125rem .4375rem;border:1px solid var(--f-theme-05);border-radius:2px}.badge-border-arrow-left-primary{border:1px solid var(--f-theme-05);position:relative;margin-left:12px}.badge-border-arrow-left-primary::after,.badge-border-arrow-left-primary::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-left-primary::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-theme-05);border-width:6px 12px 6px 0}.badge-border-arrow-left-primary::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-info-03);border-width:5px 10px 5px 0}.badge-border-arrow-right-primary{position:relative;margin-right:12px}.badge-border-arrow-right-primary::after,.badge-border-arrow-right-primary::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-round-continue,.badge-round-primary{border-radius:3px;display:inline-block!important;line-height:1;overflow:hidden}.badge-border-arrow-right-primary::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-theme-05);border-width:6px 0 6px 12px}.badge-border-arrow-right-primary::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-info-03);border-width:5px 0 5px 10px}.badge-arrow-left-primary::before,.badge-arrow-right-primary::before{margin-top:-8px;border-top:8px solid transparent;border-bottom:8px solid transparent;content:"";top:50%}.badge-arrow-left-primary{position:relative;color:#fff;margin-left:8px}.badge-arrow-left-primary::before{position:absolute;border-right:8px solid transparent;border-left:0 solid transparent;left:-8px;border-right-color:var(--f-theme-03)}.badge-arrow-right-primary{position:relative;color:#fff;margin-right:8px}.badge-arrow-right-primary::before{position:absolute;border-left:8px solid transparent;border-right:0 solid transparent;right:-8px;border-left-color:var(--f-theme-03)}.badge-round-primary{width:6px;height:6px;padding:0}.badge-round-outer-primary{position:relative;width:14px;height:14px;display:block;background:rgba(var(--f-theme-03),.18);border-radius:7px}.badge-round-outer-primary::after{content:"";width:8px;height:8px;position:absolute;top:50%;left:50%;margin:-4px 0 0 -4px;border-radius:4px;background:var(--f-theme-03)}.badge-pill-border-continue,.badge-pill-continue{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-continue,.badge-pill-continue{color:#fff;background:var(--f-semantic-submit-01)}.badge-border-arrow-left-continue,.badge-border-continue,.badge-pill-border-continue{color:var(--f-semantic-submit-01);background:var(--f-semantic-submit-03)}.badge-pill-border-continue{border:1px solid var(--f-semantic-submit-01)}.badge-border-continue{padding:.125rem .4375rem;border:1px solid var(--f-semantic-submit-02);border-radius:2px}.badge-border-arrow-left-continue{border:1px solid var(--f-semantic-submit-02);position:relative;margin-left:12px}.badge-arrow-left-continue,.badge-arrow-right-continue,.badge-round-continue{background:var(--f-semantic-submit-01)}.badge-border-arrow-left-continue::after,.badge-border-arrow-left-continue::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-left-continue::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-submit-02);border-width:6px 12px 6px 0}.badge-border-arrow-left-continue::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-submit-03);border-width:5px 10px 5px 0}.badge-border-arrow-right-continue{position:relative;margin-right:12px}.badge-border-arrow-right-continue::after,.badge-border-arrow-right-continue::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-right-continue::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-submit-02);border-width:6px 0 6px 12px}.badge-border-arrow-right-continue::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-submit-03);border-width:5px 0 5px 10px}.badge-arrow-left-continue::before,.badge-arrow-right-continue::before{margin-top:-8px;border-top:8px solid transparent;border-bottom:8px solid transparent;content:"";top:50%}.badge-arrow-left-continue{position:relative;color:#fff;margin-left:8px}.badge-arrow-left-continue::before{position:absolute;border-right:8px solid transparent;border-left:0 solid transparent;left:-8px;border-right-color:var(--f-semantic-submit-01)}.badge-arrow-right-continue{position:relative;color:#fff;margin-right:8px}.badge-arrow-right-continue::before{position:absolute;border-left:8px solid transparent;border-right:0 solid transparent;right:-8px;border-left-color:var(--f-semantic-submit-01)}.badge-round-continue{width:6px;height:6px;padding:0}.badge-round-outer-continue{position:relative;width:14px;height:14px;display:block;background:rgba(var(--f-semantic-submit-01),.18);border-radius:7px}.badge-round-outer-continue::after{content:"";width:8px;height:8px;position:absolute;top:50%;left:50%;margin:-4px 0 0 -4px;border-radius:4px;background:var(--f-semantic-submit-01)}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:6px}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:6px;border-top-right-radius:6px}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:6px;border-bottom-left-radius:6px}.card-body{flex-grow:1;flex-shrink:1;flex-basis:auto;padding:1.25rem}.card-footer,.card-header{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03)}.card-title{margin-bottom:.75rem}.card-header,.card-subtitle,.card-text:last-child{margin-bottom:0}.card-subtitle{margin-top:-.375rem}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header-pills,.card-header-tabs{margin-right:-.625rem;margin-left:-.625rem}.card-header{border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(6px - 1px) calc(6px - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(6px - 1px) calc(6px - 1px)}.card-header-tabs{margin-bottom:-.75rem;border-bottom:0}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(6px - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(6px - 1px);border-top-right-radius:calc(6px - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(6px - 1px);border-bottom-left-radius:calc(6px - 1px)}.card-deck{display:flex;flex-direction:column}.card-deck .card{margin-bottom:14px}@media (min-width:576px){.card-deck{flex-flow:row wrap;margin-right:-14px;margin-left:-14px}.card-deck .card{display:flex;flex-grow:1;flex-shrink:0;flex-basis:0%;flex-direction:column;margin-right:14px;margin-bottom:0;margin-left:14px}}.card-group{display:flex;flex-direction:column}.card-group>.card{margin-bottom:14px}@media (min-width:576px){.card-group{flex-flow:row wrap}.card-group>.card{flex-grow:1;flex-shrink:0;flex-basis:0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:6px}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:6px;border-top-right-radius:6px}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:6px;border-bottom-left-radius:6px}.card-group>.card:not(:first-child):not(:last-child):not(:only-child),.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}.card-columns{-moz-column-count:3;column-count:3;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.card-columns .card{margin-bottom:.75rem}.accordion .card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion .card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion .card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion .card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.f-form-is-table{box-shadow:0 2px 10px 0 rgba(0,0,0,.04)}.table.table-bordered.f-table-has-form td:first-child{border-left:unset}.table.table-bordered.f-table-has-form td:last-child{border-right:unset}.table.table-bordered.f-table-has-form>:first-child td{border-top:unset}.f-table-has-form{overflow:hidden;box-shadow:0 0 0 1px var(--f-neutral-07);border-radius:10px;margin:0}.f-table-has-form td{padding:0;height:43px;border:1px solid var(--f-neutral-07)}.f-table-has-form .farris-group-wrap--label{padding:.75rem 1rem;width:124px}.f-table-has-form .farris-group-wrap--label .farris-label-wrap{height:100%}.f-table-has-form .farris-group-wrap--label .form-group--has-tips{display:flex}.f-table-has-form .farris-group-wrap--label .form-group--has-tips .farris-label-tips{position:relative;bottom:auto;margin:1px 0 0 4px;flex-shrink:0}.f-table-has-form .farris-group-wrap--label .form-group--has-tips .col-form-label{flex:1 1 0}.f-table-has-form .farris-group-wrap--label .col-form-label{display:flex;margin:0;align-items:center;flex-shrink:0;justify-content:flex-end!important;flex-direction:row!important;align-self:start;word-break:break-all;min-width:82px;height:100%}.f-table-has-form .farris-group-wrap--label .farris-label-text{text-align:right;white-space:pre-wrap}.f-table-has-form .farris-group-wrap--label .farris-label-info{padding:0 .25rem 0 0;flex-shrink:0;line-height:1.4286;white-space:nowrap}.f-table-has-form .farris-group-wrap--input{position:relative;overflow:initial}.f-table-has-form .farris-group-wrap--input .farris-input-wrap{height:100%}.f-table-has-form .farris-group-wrap--input .farris-input-wrap.farris-textarea-wrap{min-height:60px}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .form-control{height:100%;border:none;border-radius:0;padding-left:1rem}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .form-control.form-control-invalid,.f-table-has-form .farris-group-wrap--input .farris-input-wrap .form-control.form-control-invalid:focus{box-shadow:inset 0 0 0 1pxvar --f-semantic-danger-01}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-cmp-inputgroup,.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-component-timepicker{height:100%}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-cmp-inputgroup .input-group,.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-cmp-number-spinner .input-group,.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-component-timepicker .input-group{height:100%;border:none}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-cmp-number-spinner .input-group .btn-group-number{height:100%}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-cmp-number-spinner .input-group .btn-group-number .btn-number-flag,.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-cmp-number-spinner .input-group .btn-group-number .btn-number-flag:nth-child(2){border:none}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-cmp-number-spinner .number-arrow-chevron,.f-table-has-form .farris-group-wrap--input .farris-input-wrap .input-group .input-group-append.f-cmp-iconbtn-wrapper .f-cmp-iconbtn .f-icon{font-size:1rem}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .lookupbox .input-group-append .f-icon-lookup{font-size:1.125rem}.f-table-has-form .farris-group-wrap--input .farris-input-wrap farris-checkboxgroup .farris-input-wrap,.f-table-has-form .farris-group-wrap--input .farris-input-wrap farris-radiogroup .farris-input-wrap{padding:.75rem 1rem}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .farris-checkradio-hor{align-items:center}.f-table-has-form .farris-group-wrap--input .farris-html-editor{border:none}.f-table-has-form .farris-group-wrap--input .farris-html-editor-border .ql-container.ql-disabled{border:none!important;padding:.75rem 1rem}.f-table-has-form .farris-group-wrap--input .farris-switch-outlayer{height:100%;display:flex;align-items:center;margin-left:1rem}.f-table-has-form .farris-group-wrap--input>.farris-input-wrap>.custom-control{height:100%;display:flex;align-items:center;padding:.75rem 1rem}.f-table-has-form .farris-group-wrap--input .f-component-text{height:100%;display:flex;align-items:center}.f-table-has-form .farris-group-wrap--input .f-component-text .f-form-control-text,.f-table-has-form .farris-group-wrap--input .f-component-text .f-form-control-textarea{border-color:transparent;padding-left:1rem}.f-table-has-form .input-group .input-group-append{padding-right:.5rem}.f-table-has-form .input-group .input-append-wrapper{padding-right:0}.f-table-has-form .input-group .input-group-append.f-cmp-iconbtn-wrapper{padding-right:.5rem}.f-table-has-form .input-group .input-group-append.f-cmp-iconbtn-wrapper .datepicker-clear{right:.5rem!important}.f-table-has-form .input-append-wrapper .input-group-text{padding-left:1rem;padding-right:1rem}.f-table-has-form .input-append-button{border-left:1px solid var(--f-neutral-07);margin-left:1px}.f-table-has-form .f-cmp-static-text-input-append .input-append-button,.f-table-has-form .f-cmp-text-input-append .input-append-button,.f-table-has-form .f-cmp-textarea-input-append .input-append-button{margin-left:0}.f-table-has-form .farris-editor .farris-editor-placeholder,.f-table-has-form .farris-editor .mce-tinymce{border:none}.f-table-has-form .farris-input-wrap .f-cmp-text-is-textarea{flex-direction:row}.f-table-has-form .farris-input-wrap .f-cmp-text-is-textarea .f-form-control-textarea{flex:1 1 0;width:100%}.f-table-has-form .farris-input-wrap .f-personnel-selector,.f-table-has-form .farris-input-wrap .f-personnel-selector .s-select-help{height:100%}.f-table-has-form .farris-input-wrap .f-personnel-selector .s-input-group{border:none!important}.f-table-has-form .farris-input-wrap .farris-tags{white-space:pre-wrap;height:100%;display:flex;align-items:center;margin-left:1rem}.f-table-has-form .farris-input-wrap .farris-tags .farris-tags-item-container{word-break:break-all;padding-left:4px}.f-table-has-form .farris-input-wrap .farris-tags .farris-tags-item-container .farris-tag-item{margin-top:4px;margin-bottom:4px;white-space:pre-wrap}@-moz-document url-prefix(){.f-table-has-form tr{height:43px}.f-table-has-form td{height:100%}} +/**2025-04-07 11:56:19**/ +@charset "UTF-8";.rtv-container .toolbar button:active,.rtv-container .toolbar button:focus,[tabindex="-1"]:focus{outline:0!important}body,caption{text-align:left}.f-calendar-month-view td,.f-icon::before,.ngx-pagination .f-icon,.page-item .page-link .f-icon,progress,sub,sup{vertical-align:baseline}.f-page-header-base>.col,.f-page-header-base>[class*=col-],.f-utils-nogutters>.col,.f-utils-nogutters>[class*=col-]{padding-left:0;padding-right:0}.f-utils-fill-auto{flex-shrink:1;flex-grow:1;flex-basis:0;overflow-x:hidden;overflow-y:auto}.f-cmp-footer-hasgap,.f-page-is-managelist .f-section+.f-section,.f-page-is-managelist .f-struct-wrapper+.f-struct-wrapper>.f-section,.f-section-hasgap{margin:.5rem 0 0}.f-cmp-footer-hasgap::before,.f-page-is-managelist .f-section+.f-section::before,.f-page-is-managelist .f-struct-wrapper+.f-struct-wrapper>.f-section::before,.f-section-hasgap::before{content:"";position:absolute;height:.5rem;background:#EFF2F4;left:0;right:0;top:-.5rem}.f-section-header .f-title,.f-tmpl-for-title-withline{color:var(--f-text-01);display:inline-flex;align-items:center;line-height:1.375rem;position:relative;overflow:hidden;padding:0 0 0 .75rem}article,aside,figcaption,figure,footer,header,hgroup,legend,main,nav,section{display:block}label,output{display:inline-block}.f-section-header .f-title>*,.f-tmpl-for-title-withline>*{margin:0 .625rem 0 0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn,.custom-control-label,dl,ol,ol ol,ol ul,ul,ul ol,ul ul{margin-bottom:0}dd,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem}.rtv-container.rtv-container-week .header-cell>span,dd{margin-left:0}.f-section-header .f-title .f-title-text,.f-tmpl-for-title-withline .f-title-text{font-size:.9375rem;line-height:1.375rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.f-section-header .f-title .f-title-subtitle,.f-tmpl-for-title-withline .f-title-subtitle{font-size:.8125rem;color:var(--f-text-08);line-height:1.375rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.f-section-header .f-title::before,.f-tmpl-for-title-withline::before{content:"";width:.25rem;height:1rem;background:var(--f-theme-03);border-radius:2px;position:absolute;top:50%;left:0;margin-top:-.5rem}dl,h1,h2,h3,h4,h5,h6,ol,p,pre,ul{margin-top:0}:root{--f-theme-01:#0E6DED;--f-theme-02:linear-gradient(135deg, #0E6DED 0%, #1B75EF 100%);--f-theme-03:#2A87FF;--f-theme-04:linear-gradient(135deg, #2A87FF 0%, #328BFF 100%);--f-theme-05:#529DFF;--f-theme-06:linear-gradient(135deg, #529DFF 0%, #559FFF 100%);--f-theme-07:linear-gradient(214deg, #3F65FF 0%, #4D9AFF 100%);--f-theme-08:#6388FF;--f-theme-09:linear-gradient(46deg, #2E77FF 0%, #2A87FF 100%);--f-theme-10:#2A62AB;--f-theme-11:linear-gradient(135deg, #2A87FF 0%, #328BFF 100%);--f-theme-12:linear-gradient(135deg, #2A87FF 0%, #328BFF 100%);--f-theme-13:linear-gradient(135deg, rgba(42, 135, 255, 0.1) 0%, rgba(50, 139, 255, 0.1) 100%);--f-theme-more-02:#2E77FF;--f-aid-01:#95BEF1;--f-aid-02:#DBE9FF;--f-aid-03:#E8F2FF;--f-aid-04:#EFF5FF;--f-aid-05:#CFEDFF;--f-aid-06:#EFF2F4;--f-aid-07:linear-gradient(195deg, #FFFBEB 0%, #EFF8F8 100%);--f-aid-08:#F0F6FF;--f-aid-09:#F7FAFF;--f-aid-10:#95C3FF;--f-ornament-01:linear-gradient(135deg, #FC8249 0%, #FE9539 100%);--f-ornament-02:linear-gradient(135deg, #1FC8DC 0%, #41D2BD 100%);--f-ornament-03:linear-gradient(135deg, #4190FF 0%, #657CFF 100%);--f-ornament-04:linear-gradient(135deg, #8B82FF 0%, #A082FF 100%);--f-ornament-05:linear-gradient(135deg, #4EC87A 0%, #52D389 100%);--f-ornament-01-start:#FC8249;--f-ornament-02-start:#1FC8DC;--f-ornament-03-start:#4190FF;--f-ornament-04-start:#8B82FF;--f-ornament-05-start:#4EC87A;--f-neutral-00:#fff;--f-neutral-00-rgb:255,255,255;--f-neutral-01:#303C53;--f-neutral-02:#AEB5C6;--f-neutral-03:#CCD1DD;--f-neutral-04:#D9DEE7;--f-neutral-05:#DEE4ED;--f-neutral-06:#E6E9F0;--f-neutral-07:#E9ECF3;--f-neutral-08:#E8EBF2;--f-neutral-09:#F1F3F7;--f-neutral-10:#F5F6F9;--f-neutral-11:#F7F8FB;--f-neutral-12:#FFFFFF;--f-neutral-13:#E4E7EF;--f-neutral-14:#FAFAFC;--f-neutral-15:#1F2329;--f-neutral-15-rgb:31,35,41;--f-neutral-16:#013364;--f-neutral-17:#031233;--f-neutral-18:rgba(255, 255, 255, 0.7);--f-neutral-19:rgba(255, 255, 255, 0.85);--f-neutral-20:#ffffff;--f-neutral-21:#334052;--f-text-00:#fff;--f-text-01:#000;--f-text-02:#2D2F33;--f-text-03:#424347;--f-text-04:#5A5E66;--f-text-05:#6080AD;--f-text-06:#747B8B;--f-text-07:#848C9A;--f-text-08:#A8ADB8;--f-text-09:#B4BCCC;--f-text-10:#C7CFDD;--f-text-11:#ffffff;--f-text-12:#C7D4EE;--f-text-13:rgba(255, 255, 255, 0.85);--f-semantic-info-01:#4D9AFF;--f-semantic-info-02:#AED1FF;--f-semantic-info-03:#EEF5FF;--f-semantic-info-04:linear-gradient(135deg, #657CFF 0%, #4190FF 100%);--f-semantic-submit-01:#62CBCD;--f-semantic-submit-02:#A7E0E1;--f-semantic-submit-03:#F3FBFB;--f-semantic-submit-04:linear-gradient(135deg, #12BFD3 0%, #41D5B9 100%);--f-semantic-success-01:#6CC77F;--f-semantic-success-02:#B5E3BF;--f-semantic-success-03:#F0FAF4;--f-semantic-success-04:linear-gradient(135deg, #3CA78D 0%, #7BCA8B 100%);--f-semantic-warning-01:#F5A144;--f-semantic-warning-02:#FAD0A1;--f-semantic-warning-03:#FEF5EC;--f-semantic-warning-04:linear-gradient(135deg, #FC8249 0%, #FE9539 100%);--f-semantic-warning-06:#F7B500;--f-semantic-danger-01:#F46160;--f-semantic-danger-02:#F9B0AF;--f-semantic-danger-03:#FDEFEF;--f-semantic-danger-04:linear-gradient(135deg, #E55875 0%, #FF7878 100%)}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}.popover,.tooltip,body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei","Helvetica Neue",Helvetica,Arial,sans-serif}body{margin:0;font-size:.8125rem;font-weight:400;line-height:1.4286;color:var(--f-text-02);background-color:#fff}.text-monospace,code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}p{margin-bottom:1rem}abbr[data-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{padding:0}li{list-style:none}dt{font-weight:700}blockquote,figure{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--f-theme-03);text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:var(--f-theme-05);text-decoration:none}a:not([href]):not([tabindex]),a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-size:1em}pre{margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:var(--f-text-08);caption-side:bottom}th{text-align:inherit}label{margin-bottom:.3125rem}button{border-radius:0}button:focus{outline:dotted 1px;outline:-webkit-focus-ring-color auto 5px}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}.display-1,.display-2,.display-3,.display-4{line-height:1.2}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:400;color:inherit}.blockquote,.table,hr{margin-bottom:1rem}.display-1,.display-2,.display-3,.display-4,.lead{font-weight:300}.h1,h1{font-size:1.625rem}.h2,h2{font-size:1.5rem}.h3,h3{font-size:1.375rem}.h4,h4{font-size:1.25rem}.accordion .card .card-header .panel-item-title,.farris-panel .card .card-header .panel-item-title,.h5,h5{font-size:1rem;line-height:1.375rem}.h5,h5{font-size:1rem}.btn-lg,.h6,h6{font-size:.875rem}.lead{font-size:1.015625rem}.display-1{font-size:6rem}.display-2{font-size:5.5rem}.display-3{font-size:4.5rem}.display-4{font-size:3.5rem}hr{box-sizing:content-box;height:0;overflow:visible;margin-top:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-inline,.list-unstyled{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{font-size:1.015625rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"— "}.clearfix::after,.custom-control-label::after,.custom-control-label::before{content:""}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:var(--f-theme-03)!important}.bg-secondary{background-color:#6c757d!important}.bg-success{background-color:var(--f-semantic-success-01)!important}.bg-info{background-color:var(--f-semantic-info-01)!important}.bg-warning{background-color:var(--f-semantic-warning-01)!important}.bg-danger{background-color:#dc3545!important}.bg-light{background-color:#f8f9fa!important}.bg-dark{background-color:#343a40!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid var(--f-neutral-06)!important}.border-top{border-top:1px solid var(--f-neutral-06)!important}.border-right{border-right:1px solid var(--f-neutral-06)!important}.border-bottom{border-bottom:1px solid var(--f-neutral-06)!important}.border-left{border-left:1px solid var(--f-neutral-06)!important}.border-0{border:0!important}.rounded-right,.rounded-top{border-top-right-radius:6px!important}.rounded-bottom,.rounded-right{border-bottom-right-radius:6px!important}.rounded-left,.rounded-top{border-top-left-radius:6px!important}.rounded-bottom,.rounded-left{border-bottom-left-radius:6px!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:var(--f-theme-03)!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:var(--f-semantic-success-01)!important}.border-info{border-color:var(--f-semantic-info-01)!important}.border-warning{border-color:var(--f-semantic-warning-01)!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded{border-radius:6px!important}.rounded-circle{border-radius:50%!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width:888px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media (min-width:1690px){.d-el-none{display:none!important}.d-el-inline{display:inline!important}.d-el-inline-block{display:inline-block!important}.d-el-block{display:block!important}.d-el-table{display:table!important}.d-el-table-row{display:table-row!important}.d-el-table-cell{display:table-cell!important}.d-el-flex{display:flex!important}.d-el-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.flex-row{flex-direction:row!important}.f-utils-flex-column,.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex-grow:1!important;flex-shrink:1!important;flex-basis:auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width:576px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex-grow:1!important;flex-shrink:1!important;flex-basis:auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width:768px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex-grow:1!important;flex-shrink:1!important;flex-basis:auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width:888px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex-grow:1!important;flex-shrink:1!important;flex-basis:auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:888px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.fixed-bottom,.fixed-top{position:fixed;z-index:1030;left:0;right:0}.fixed-top{top:0}.fixed-bottom{bottom:0}@supports (position:sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.f-max-width-auto,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link .farris-title-auto{max-width:none!important}.mh-100{max-height:100%!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:888px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex-grow:1!important;flex-shrink:1!important;flex-basis:auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}@media (min-width:1690px){.flex-el-row{flex-direction:row!important}.flex-el-column{flex-direction:column!important}.flex-el-row-reverse{flex-direction:row-reverse!important}.flex-el-column-reverse{flex-direction:column-reverse!important}.flex-el-wrap{flex-wrap:wrap!important}.flex-el-nowrap{flex-wrap:nowrap!important}.flex-el-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-el-fill{flex-grow:1!important;flex-shrink:1!important;flex-basis:auto!important}.flex-el-grow-0{flex-grow:0!important}.flex-el-grow-1{flex-grow:1!important}.flex-el-shrink-0{flex-shrink:0!important}.flex-el-shrink-1{flex-shrink:1!important}.justify-content-el-start{justify-content:flex-start!important}.justify-content-el-end{justify-content:flex-end!important}.justify-content-el-center{justify-content:center!important}.justify-content-el-between{justify-content:space-between!important}.justify-content-el-around{justify-content:space-around!important}.align-items-el-start{align-items:flex-start!important}.align-items-el-end{align-items:flex-end!important}.align-items-el-center{align-items:center!important}.align-items-el-baseline{align-items:baseline!important}.align-items-el-stretch{align-items:stretch!important}.align-content-el-start{align-content:flex-start!important}.align-content-el-end{align-content:flex-end!important}.align-content-el-center{align-content:center!important}.align-content-el-between{align-content:space-between!important}.align-content-el-around{align-content:space-around!important}.align-content-el-stretch{align-content:stretch!important}.align-self-el-auto{align-self:auto!important}.align-self-el-start{align-self:flex-start!important}.align-self-el-end{align-self:flex-end!important}.align-self-el-center{align-self:center!important}.align-self-el-baseline{align-self:baseline!important}.align-self-el-stretch{align-self:stretch!important}.float-el-left{float:left!important}.float-el-right{float:right!important}.float-el-none{float:none!important}.m-el-0{margin:0!important}.mt-el-0,.my-el-0{margin-top:0!important}.mr-el-0,.mx-el-0{margin-right:0!important}.mb-el-0,.my-el-0{margin-bottom:0!important}.ml-el-0,.mx-el-0{margin-left:0!important}.m-el-1{margin:.25rem!important}.mt-el-1,.my-el-1{margin-top:.25rem!important}.mr-el-1,.mx-el-1{margin-right:.25rem!important}.mb-el-1,.my-el-1{margin-bottom:.25rem!important}.ml-el-1,.mx-el-1{margin-left:.25rem!important}.m-el-2{margin:.5rem!important}.mt-el-2,.my-el-2{margin-top:.5rem!important}.mr-el-2,.mx-el-2{margin-right:.5rem!important}.mb-el-2,.my-el-2{margin-bottom:.5rem!important}.ml-el-2,.mx-el-2{margin-left:.5rem!important}.m-el-3{margin:1rem!important}.mt-el-3,.my-el-3{margin-top:1rem!important}.mr-el-3,.mx-el-3{margin-right:1rem!important}.mb-el-3,.my-el-3{margin-bottom:1rem!important}.ml-el-3,.mx-el-3{margin-left:1rem!important}.m-el-4{margin:1.5rem!important}.mt-el-4,.my-el-4{margin-top:1.5rem!important}.mr-el-4,.mx-el-4{margin-right:1.5rem!important}.mb-el-4,.my-el-4{margin-bottom:1.5rem!important}.ml-el-4,.mx-el-4{margin-left:1.5rem!important}.m-el-5{margin:3rem!important}.mt-el-5,.my-el-5{margin-top:3rem!important}.mr-el-5,.mx-el-5{margin-right:3rem!important}.mb-el-5,.my-el-5{margin-bottom:3rem!important}.ml-el-5,.mx-el-5{margin-left:3rem!important}.p-el-0{padding:0!important}.pt-el-0,.py-el-0{padding-top:0!important}.pr-el-0,.px-el-0{padding-right:0!important}.pb-el-0,.py-el-0{padding-bottom:0!important}.pl-el-0,.px-el-0{padding-left:0!important}.p-el-1{padding:.25rem!important}.pt-el-1,.py-el-1{padding-top:.25rem!important}.pr-el-1,.px-el-1{padding-right:.25rem!important}.pb-el-1,.py-el-1{padding-bottom:.25rem!important}.pl-el-1,.px-el-1{padding-left:.25rem!important}.p-el-2{padding:.5rem!important}.pt-el-2,.py-el-2{padding-top:.5rem!important}.pr-el-2,.px-el-2{padding-right:.5rem!important}.pb-el-2,.py-el-2{padding-bottom:.5rem!important}.pl-el-2,.px-el-2{padding-left:.5rem!important}.p-el-3{padding:1rem!important}.pt-el-3,.py-el-3{padding-top:1rem!important}.pr-el-3,.px-el-3{padding-right:1rem!important}.pb-el-3,.py-el-3{padding-bottom:1rem!important}.pl-el-3,.px-el-3{padding-left:1rem!important}.p-el-4{padding:1.5rem!important}.pt-el-4,.py-el-4{padding-top:1.5rem!important}.pr-el-4,.px-el-4{padding-right:1.5rem!important}.pb-el-4,.py-el-4{padding-bottom:1.5rem!important}.pl-el-4,.px-el-4{padding-left:1.5rem!important}.p-el-5{padding:3rem!important}.pt-el-5,.py-el-5{padding-top:3rem!important}.pr-el-5,.px-el-5{padding-right:3rem!important}.pb-el-5,.py-el-5{padding-bottom:3rem!important}.pl-el-5,.px-el-5{padding-left:3rem!important}.m-el-auto{margin:auto!important}.mt-el-auto,.my-el-auto{margin-top:auto!important}.mr-el-auto,.mx-el-auto{margin-right:auto!important}.mb-el-auto,.my-el-auto{margin-bottom:auto!important}.ml-el-auto,.mx-el-auto{margin-left:auto!important}}.f-cmp-pt,.f-cmp-py{padding-top:.875rem!important}.f-cmp-pb,.f-cmp-py{padding-bottom:.875rem!important}.f-cmp-mr,.f-cmp-mx{margin-right:.875rem!important}.f-cmp-ml,.f-cmp-mx{margin-left:.875rem!important}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:888px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:var(--f-theme-03)!important}.text-secondary{color:#6c757d!important}.text-success{color:var(--f-semantic-success-01)!important}.text-warning{color:var(--f-semantic-warning-01)!important}.text-danger{color:#dc3545!important}.text-light{color:#f8f9fa!important}.text-dark{color:#343a40!important}.text-body{color:var(--f-text-02)!important}.text-muted{color:var(--f-text-08)!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.visible{visibility:visible!important}.invisible{visibility:hidden!important}body{background:#f0f3f6}input::-ms-clear{display:none}input::-webkit-contacts-auto-fill-button{visibility:hidden;display:none!important;pointer-events:none;position:absolute;right:0}.f-utils-fill-flex-column,.f-utils-flex-column,.f-utils-flex-row,.f-utils-flex-row-wrap{display:flex!important;overflow:hidden}.h1,h1{line-height:2.125rem}.h2,h2{line-height:2}.h3,h3{line-height:1.875rem}.h4,h4{line-height:1.75rem}.btn-link,.dropdown-item,.h6,h6{line-height:1.25rem}.text-dark{color:var(--f-text-01)}.text-danger{color:var(--f-semantic-danger-01)!important}.text-info{color:var(--f-theme-05)!important}::-webkit-scrollbar{width:7px;height:7px;background-color:var(--f-neutral-14)}::-webkit-scrollbar-track{border-radius:0;background-color:var(--f-neutral-14);border:none;background-clip:padding-box}::-webkit-scrollbar-thumb{background-color:var(--f-neutral-03);border:none;background-clip:content-box;opacity:.6;border-radius:7px}::-webkit-scrollbar-thumb:hover{background:var(--f-text-06)}.f-cmp-mt{margin-top:.875rem!important}.f-cmp-mb{margin-bottom:.875rem!important}.f-cmp-mx-minus{margin-left:-.875rem!important;margin-right:-.875rem!important}.f-cmp-px{padding-left:.875rem!important;padding-right:.875rem!important}.f-cmp-p{padding:.875rem!important}.f-cmp-gutter{border-bottom:10px solid #EFF2F4}.f-split-border-b{border-bottom:1px solid var(--f-neutral-08)}.f-common-px{padding-left:.875rem;padding-right:.875rem}.f-col-h1,.f-col-h10,.f-col-h11,.f-col-h12,.f-col-h2,.f-col-h3,.f-col-h4,.f-col-h5,.f-col-h6,.f-col-h7,.f-col-h8,.f-col-h9,.f-col-w1,.f-col-w10,.f-col-w11,.f-col-w12,.f-col-w2,.f-col-w3,.f-col-w4,.f-col-w5,.f-col-w6,.f-col-w7,.f-col-w8,.f-col-w9{padding-right:14px;padding-left:14px}.f-common-py{padding-top:.875rem;padding-bottom:.875rem}.f-common-py-form{padding-top:.875rem;padding-bottom:.5rem}.f-utils-absolute-all{top:0;bottom:0;position:absolute;right:0;left:0}.accordion .card .card-header,.f-col-h1,.f-col-h10,.f-col-h11,.f-col-h12,.f-col-h2,.f-col-h3,.f-col-h4,.f-col-h5,.f-col-h6,.f-col-h7,.f-col-h8,.f-col-h9,.f-col-w1,.f-col-w10,.f-col-w11,.f-col-w12,.f-col-w2,.f-col-w3,.f-col-w4,.f-col-w5,.f-col-w6,.f-col-w7,.f-col-w8,.f-col-w9,.farris-panel .card .card-header,.rtv-container .toolbar .btns .btn-group button i.f-icon{position:relative}.f-utils-fill-flex-column{flex-shrink:1;flex-grow:1;flex-basis:0;flex-direction:column!important}.f-utils-flex-row{flex-direction:row!important;flex-wrap:nowrap}.f-utils-flex-row-wrap{flex-direction:row!important;flex-wrap:wrap!important}.f-utils-fill-flex-row,.f-utils-fill-flex-row-wrap{flex-shrink:1;display:flex!important;overflow:hidden}.f-utils-fill-flex-row{flex-grow:1;flex-basis:0;flex-direction:row!important;flex-wrap:nowrap!important}.f-utils-fill-flex-row-wrap{flex-grow:1;flex-basis:0;flex-direction:row!important;flex-wrap:wrap!important}.f-utils-fill{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.f-utils-overflow-xhya{overflow-x:hidden!important;overflow-y:auto!important}.f-utils-overflow-xayh{overflow-y:hidden!important;overflow-x:auto!important}.f-utils-overflow-xaya{overflow:auto!important}.f-utils-overflow-hidden{overflow:hidden!important}.f-utils-overflow-auto{overflow:auto!important}.f-utils-hcenter-vcenter{display:flex;align-items:center;justify-content:center}.f-overflow-y-auto{overflow-y:auto!important}.f-overflow-y-hidden{overflow-y:hidden!important}.f-overflow-x-auto{overflow-x:auto!important}.f-overflow-x-hidden{overflow-x:hidden!important}@media (min-width:576px){.f-overflow-sm-y-auto{overflow-y:auto!important}.f-overflow-sm-y-hidden{overflow-y:hidden!important}.f-overflow-sm-x-auto{overflow-x:auto!important}.f-overflow-sm-x-hidden{overflow-x:hidden!important}}@media (min-width:768px){.f-overflow-md-y-auto{overflow-y:auto!important}.f-overflow-md-y-hidden{overflow-y:hidden!important}.f-overflow-md-x-auto{overflow-x:auto!important}.f-overflow-md-x-hidden{overflow-x:hidden!important}}@media (min-width:888px){.f-overflow-lg-y-auto{overflow-y:auto!important}.f-overflow-lg-y-hidden{overflow-y:hidden!important}.f-overflow-lg-x-auto{overflow-x:auto!important}.f-overflow-lg-x-hidden{overflow-x:hidden!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}.f-overflow-xl-y-auto{overflow-y:auto!important}.f-overflow-xl-y-hidden{overflow-y:hidden!important}.f-overflow-xl-x-auto{overflow-x:auto!important}.f-overflow-xl-x-hidden{overflow-x:hidden!important}}@media (min-width:1690px){.text-el-left{text-align:left!important}.text-el-right{text-align:right!important}.text-el-center{text-align:center!important}.f-overflow-el-y-auto{overflow-y:auto!important}.f-overflow-el-y-hidden{overflow-y:hidden!important}.f-overflow-el-x-auto{overflow-x:auto!important}.f-overflow-el-x-hidden{overflow-x:hidden!important}}.farris-overflow-y-auto{overflow-x:hidden!important;overflow-y:auto!important}.farris-overflow-y-hidden{overflow-x:hidden!important;overflow-y:hidden!important}.farris-overflow-hidden{overflow:hidden!important}.f-col-w1{min-height:1px;width:8.3333333333%}.f-col-w2{min-height:1px;width:16.6666666667%}.f-col-w3{min-height:1px;width:25%}.f-col-w4{min-height:1px;width:33.3333333333%}.f-col-w5{min-height:1px;width:41.6666666667%}.f-col-w6{min-height:1px;width:50%}.f-col-w7{min-height:1px;width:58.3333333333%}.f-col-w8{min-height:1px;width:66.6666666667%}.f-col-w9{min-height:1px;width:75%}.f-col-w10{min-height:1px;width:83.3333333333%}.f-col-w11{min-height:1px;width:91.6666666667%}.f-col-w12{min-height:1px;width:100%}.f-col-h1{min-height:1px;height:8.3333333333%}.f-col-h2{min-height:1px;height:16.6666666667%}.f-col-h3{min-height:1px;height:25%}.f-col-h4{min-height:1px;height:33.3333333333%}.f-col-h5{min-height:1px;height:41.6666666667%}.f-col-h6{min-height:1px;height:50%}.f-col-h7{min-height:1px;height:58.3333333333%}.f-col-h8{min-height:1px;height:66.6666666667%}.f-col-h9{min-height:1px;height:75%}.f-col-h10{min-height:1px;height:83.3333333333%}.f-col-h11{min-height:1px;height:91.6666666667%}.f-col-h12{min-height:1px;height:100%}.f-utils-text-break{white-space:normal!important;word-break:break-all!important}.f-text-emphasize{color:var(--f-text-01)!important}.f-text-light{color:var(--f-text-04)!important}.f-text-lighter{color:var(--f-text-08)!important}.f-text-mute{color:var(--f-text-09)!important}.f-text-two-line{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;max-height:2.5rem}.f-min-width-auto{min-width:auto!important}.win11Scroll{overflow:overlay;scroll-behavior:smooth}.win11Scroll::-webkit-scrollbar{width:14px;height:14px;border-radius:7px}.win11Scroll::-webkit-scrollbar-thumb{display:none;background-clip:padding-box;border:6px solid transparent;border-radius:14px}.win11Scroll::-webkit-scrollbar-thumb:hover{border:4px solid transparent}.win11Scroll::-webkit-scrollbar-button:single-button{height:14px}.win11Scroll:hover::-webkit-scrollbar-thumb{display:block}.win11Scroll.show::-webkit-scrollbar-thumb{display:block}.win11Scroll::-webkit-scrollbar-corner{background:rgba(0,0,0,0)}.win11Scroll::-webkit-scrollbar-track{background-color:transparent}.win11Scroll.nobtn::-webkit-scrollbar:vertical{background:0 0}.win11Scroll.nobtn::-webkit-scrollbar:horizontal{background:0 0}.win11Scroll.nobtn::-webkit-scrollbar-button:single-button{height:0;width:0}.accordion,.farris-panel{border:1px solid var(--f-neutral-13)}.accordion .card,.farris-panel .card{border-top:0;background:var(--f-neutral-00);border-color:var(--f-neutral-13)}.accordion .card .card-header,.farris-panel .card .card-header{border-width:0;background-color:var(--f-neutral-00);color:var(--f-text-02);padding:.5265rem .875rem}.accordion .card .card-header:hover,.accordion .card.f-state-hover,.farris-panel .card .card-header:hover,.farris-panel .card.f-state-hover{color:var(--f-theme-05);border-color:var(--f-neutral-13);background-color:var(--f-neutral-00)}.accordion .card .card-body,.farris-panel .card .card-body{padding:.9375rem}.accordion .card.f-state-disabled .card-header,.farris-panel .card.f-state-disabled .card-header{color:var(--f-text-07);background-color:var(--f-neutral-00);border-color:var(--f-neutral-02)}.accordion .card.f-state-disabled .f-icon,.farris-panel .card.f-state-disabled .f-icon{display:none}.accordion .card.f-state-disabled .accordion-title,.farris-panel .card.f-state-disabled .accordion-title{color:var(--f-text-07)}.accordion .card.f-state-selected .card-header,.farris-panel .card.f-state-selected .card-header{color:var(--f-theme-01);background-color:var(--f-neutral-00);border-color:var(--f-neutral-13)}.accordion .accordion-title,.farris-panel .accordion-title{color:var(--f-text-02)}.accordion .f-accordion-collapse,.accordion .f-accordion-expand,.farris-panel .f-accordion-collapse,.farris-panel .f-accordion-expand{margin-top:-.3125rem;color:var(--f-neutral-01);font-size:1.25rem;width:1.25rem;height:1.25rem;vertical-align:middle}.accordion .f-accordion-collapse::before,.farris-panel .f-accordion-collapse::before{font-family:FarrisIcons;content:"\e013"}.accordion .f-accordion-expand::before,.f-btn-collapse-expand::after,.farris-panel .f-accordion-expand::before{content:"\e015";font-family:FarrisIcons}.accordion .card-header,.farris-panel .card-header{cursor:pointer}.accordion .panel-item-title,.farris-panel .panel-item-title{float:left}.accordion .panel-item-tool,.farris-panel .panel-item-tool{float:right}.accordion .panel-item-clear,.farris-panel .panel-item-clear{clear:both}.accordion .f-state-disabled,.farris-panel .f-state-disabled{pointer-events:none}.accordion .card,.farris-panel .card{border-left:0;border-right:0}.accordion .active,.farris-panel .active{height:initial;transition:height .35s ease}.accordion .inactive,.farris-panel .inactive{height:0;overflow:hidden;transition:height .35s ease}.farris-panel .card:not(:first-of-type) .card-header:first-child,.farris-panel .card:not(:first-of-type):not(:last-of-type){border-radius:0}.farris-panel .card:first-of-type{border-bottom-right-radius:0;border-bottom-left-radius:0}.farris-panel .card:last-of-type{border-bottom:0;border-top-left-radius:0;border-top-right-radius:0}.f-cmp-panel-pt-card-subgrid .card,.farris-panel-dividing-line .card{border-width:0}.f-cmp-panel-pt-card-subgrid .card .card-header,.farris-panel-dividing-line .card .card-header{border-width:0 0 1px;background:var(--f-neutral-00);border-color:var(--f-neutral-13)}.f-cmp-panel-pt-card-subgrid .card.f-state-selected .card-header,.farris-panel-dividing-line .card.f-state-selected .card-header{background-color:var(--f-neutral-00);border-color:var(--f-neutral-13);color:var(--f-theme-01)}.accordion .card .card-header .f-icon,.btn-secondary,.farris-panel .card .card-header .f-icon{color:var(--f-text-02)}.f-cmp-panel-pt-card-subgrid{margin:0}.f-cmp-panel-has-form .card .card-body{padding:0}.accordion .card .card-header:hover .f-icon,.farris-panel .card .card-header:hover .f-icon{color:var(--f-theme-05)}.accordion .card.f-state-selected .card-header .f-icon,.farris-panel .card.f-state-selected .card-header .f-icon{color:var(--f-theme-01)}.rtv-container{width:100%;height:100%;display:flex;flex-direction:column;background:#fff}.rtv-container .room-subject{border-radius:2px}.rtv-container .room-subject dt{font-size:13px;text-overflow:ellipsis;overflow:hidden}.rtv-container .room-subject_category{padding:0 4px;border-radius:4px;margin-right:8px;font-size:12px;display:inline-block;line-height:20px;background:var(--f-aid-02);border:1px solid var(--f-theme-01)}.rtv-container .room-subject dd.other-info{margin:0;line-height:18px;color:var(--f-text-07);text-overflow:ellipsis;overflow:hidden;padding-top:3px}.rtv-container .text-center{align-items:center;justify-content:center}.rtv-container .toolbar{height:50px;width:100%;border-bottom:1px solid var(--f-neutral-07);display:flex;align-items:center;padding-left:20px}.rtv-container .toolbar .view-type{width:131px;height:32px;line-height:32px;background:var(--f-aid-04);border-radius:32px;display:flex;align-items:center}.rtv-container .toolbar .view-type .btn-day,.rtv-container .toolbar .view-type .btn-week{width:64px;height:30px;border-radius:32px;background:0 0;border:0;font-weight:400;cursor:pointer}.rtv-container .toolbar .view-type .btn-active{background:rgba(255,255,255,.75);box-shadow:0 4px 18px 0 rgba(2,75,193,.2);color:var(--f-theme-03);cursor:default}.rtv-container .toolbar .line{height:20px;width:20px;display:inline-block;border-right:1px solid var(--f-neutral-06);margin-right:20px}.rtv-container .toolbar .btns{display:flex;width:112px;margin-right:20px}.rtv-container .toolbar .btns button{height:26px;background:#FFF;border:1px solid #e8ebf2;box-shadow:0 2px 6px 0 rgba(31,35,41,.06);border-radius:6px;outline:0;cursor:pointer}.rtv-container .toolbar .btns .btn-today{width:50px;margin-right:5px}.rtv-container .toolbar .btns .btn-group{width:53px;flex-grow:1;display:flex}.rtv-container .toolbar .btns .btn-group button{width:26px}.rtv-container .toolbar .btns .btn-group button i.f-icon{left:-2px;top:2px}.rtv-container .toolbar .btns .btn-prev{border-radius:6px 0 0 6px}.rtv-container .toolbar .btns .btn-next{border-radius:0 6px 6px 0}.rtv-container .main{flex-grow:1;display:flex;flex-direction:column;overflow:hidden}.rtv-container .main .fixed-left{position:sticky!important;left:0;z-index:9;flex:none!important;width:300px}.rtv-container .main .roomname{align-items:center;justify-content:start;background-color:#fff!important}.rtv-container .main .header{height:40px;overflow:hidden;border-bottom:1px solid #E6E9F0}.rtv-container .main .body .room-cell,.rtv-container .main .header-cell{height:100%;border-right:1px solid var(--f-neutral-06);border-bottom:1px solid var(--f-neutral-06);display:flex}.rtv-container .main .header-row{display:flex;flex-direction:row;width:2700px;height:100%}.rtv-container .main .header-cell>span.time{margin-left:-20px;font-size:14px;color:var(--f-text-04);font-weight:500}.rtv-container .main .time-cell{width:100px;align-items:center}.rtv-container .main .body{flex-grow:1;height:100%}.rtv-container .main .body .room-row{min-height:62px;display:flex;flex-direction:row;width:2700px}.rtv-container .main .body .room-cell{position:relative}.rtv-container .main .body .room-cell .item-content{width:100px;position:absolute;left:0;flex-wrap:nowrap;display:flex;flex-direction:column;line-height:20px;justify-content:center;z-index:1;word-break:normal;white-space:nowrap;overflow:hidden;height:calc(100% - 4px);cursor:pointer}.rtv-container .main .body .room-cell .item-content:hover{box-shadow:2px 2px 7px #bebebe}.rtv-container .main .body .room-cell .item-content .item-content-wrap{border-radius:6px;background:var(--f-aid-02);width:100%;height:100%}.rtv-container .main .body .room-cell .item-content .item-content-wrap.gray{background-color:#f0f0f0}.rtv-container .main .body .room-cell .item-content .item-content-wrap.gray .room-subject_category{border:1px solid #ccc;background:#F2F3F5;color:#878d99}.rtv-container .main .body .room-cell .item-content .item-content-wrap.blue{background:#dae9ff}.rtv-container .main .body .room-cell .item-content .item-content-wrap.blue .room-subject_category{border:1px solid #9bf;background:#9bf;color:#fff}.rtv-container .main .body .room-cell .item-content .item-content-wrap.orange{background:#ffedda}.rtv-container .main .body .room-cell .item-content .item-content-wrap.orange .room-subject_category{border:1px solid #ff772e;background:#ff772e;color:#fff5ea}.rtv-container .main .body .room-cell .item-content .item-content-wrap.mintgreen{background:#daffe0}.rtv-container .main .body .room-cell .item-content .item-content-wrap.mintgreen .room-subject_category{border:1px solid #42fc57;background:#42fc57;color:#449e00}.rtv-container .main .body .room-cell .item-content .item-content-wrap.red{background:#ffdada}.rtv-container .main .body .room-cell .item-content .item-content-wrap.red .room-subject_category{border:1px solid #ff8383;background:#ffa4a4;color:#ae0000}.rtv-container .main .body .room-cell .item-content .item-content-wrap.pink{background:#f6daff}.rtv-container .main .body .room-cell .item-content .item-content-wrap.pink .room-subject_category{border:1px solid #f867d6;background:#f867d6;color:#ffe2ef}.rtv-container .main .body .room-cell .item-content .item-content-wrap.bluegreen{background:#dafffe}.rtv-container .main .body .room-cell .item-content .item-content-wrap.bluegreen .room-subject_category{border:1px solid #2ac3ac;background:#2ac3ac;color:#efffe5}.rtv-container .main .body .room-cell .item-content .selected{outline:var(--f-theme-05) solid 2px;outline-offset:-2px;border-radius:6px}.rtv-container.rtv-container-week .header-cell,.rtv-container.rtv-container-week .room-cell{flex:1}.rtv-container.rtv-container-week .header-row,.rtv-container.rtv-container-week .room-row{width:auto!important}.rtv-container.rtv-container-week .time-cell{line-height:20px;width:150px}.rtv-container.rtv-container-week .time-cell .week-day-subject{cursor:pointer;transition:all .1s ease}.rtv-container.rtv-container-week .time-cell .week-day-subject:hover{background-color:var(--f-aid-02)}.rtv-container.rtv-container-week .time-cell li.selected{border:1px solid var(--f-theme-01);border-radius:4px;background:var(--f-aid-02)}.rtv-container.rtv-container-week .time-cell .rtv-week-day{text-align:center;border-radius:10px;width:20px;margin:0 5px;font-size:13px}.rtv-container.rtv-container-week .time-cell .rtv-week-day.active{background-image:linear-gradient(135deg,var(--f-aid-10) 0,var(--f-theme-05) 100%);color:#fff}.rtv-container.rtv-container-week .time-cell .rtv-week-day-item:before{content:"●";margin-right:3px;top:-2px;position:relative}.reserve-detail-container{display:flex;flex-direction:column;background:#FFF;box-shadow:0 4px 12px 2px rgba(31,35,41,.1);border-radius:16px;width:368px;height:436px;transition:all .12s ease}.reserve-detail-container .detail-header{height:185px;background-image:linear-gradient(116deg,var(--f-aid-10) 0,var(--f-theme-05) 100%);border-radius:16px 16px 0 0}.reserve-detail-container .detail-header.gray{color:#fff;background-image:linear-gradient(116deg,#bcbebf 0,#909293 100%)}.reserve-detail-container .detail-header.blue{color:#fff;background-image:linear-gradient(116deg,#09F 0,#0AF 100%)}.reserve-detail-container .detail-header.orange{color:#fff;background-image:linear-gradient(116deg,#ffc78c 0,#ffab58 100%)}.reserve-detail-container .detail-header.mintgreen{color:#fff;background-image:linear-gradient(116deg,#72cc89 0,#00a804 100%)}.reserve-detail-container .detail-header.red{color:#fff;background-image:linear-gradient(116deg,#ff9797 0,#ff3939 100%)}.reserve-detail-container .detail-header.pink{color:#fff;background-image:linear-gradient(116deg,#f1b9fb 0,#d458ff 100%)}.reserve-detail-container .detail-header.bluegreen{color:#fff;background-image:linear-gradient(116deg,#59ddc9 0,#1694c5 100%)}.reserve-detail-container .detail-header .detail-toolbar{height:44px;justify-content:flex-end;align-items:center;padding-right:15px;display:flex}.reserve-detail-container .detail-header .detail-toolbar span.f-icon{font-size:14px;cursor:pointer;width:32px;height:32px;text-align:center;line-height:32px;border-radius:6px}.reserve-detail-container .detail-header .detail-toolbar span.f-icon:hover{background:rgba(255,255,255,.2)}.reserve-detail-container .detail-header .detail-title{flex:1;padding:0 24px;overflow:hidden}.reserve-detail-container .detail-header .detail-title .detail-place{font-size:16px}.reserve-detail-container .detail-header .detail-title div.title-content{margin:6px 0 16px;font-size:20px;line-height:28px}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge{height:18px;border-radius:4px;display:inline-block;font-size:12px;text-align:center;line-height:18px;padding:0 5px}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge.gray{border:1px solid #ccc;background:#F2F3F5;color:#878d99}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge.blue{border:1px solid #9bf;background:#9bf;color:#fff}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge.pink{border:1px solid #f867d6;background:#f867d6;color:#ffe2ef}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge.red{border:1px solid #ff8383;background:#ffa4a4;color:#ae0000}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge.mintgreen{border:1px solid #42fc57;background:#42fc57;color:#449e00}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge.orange{border:1px solid #ff772e;background:#ff772e;color:#fff5ea}.reserve-detail-container .detail-header .detail-title div.title-content span.detail-badge.bluegreen{border:1px solid #48fce0;background:#5efee6;color:#00b8bd}.reserve-detail-container .detail-header .detail-title .detail-timer{height:30px;font-size:14px;line-height:30px}.reserve-detail-container .detail-info-content{flex:1;padding:2px 2px 10px;color:#666;border-radius:0 0 16px 16px}.reserve-detail-container .detail-info-content ul{list-style:none;margin:0;padding:16px;font-size:14px}.reserve-detail-container .detail-info-content ul li{line-height:28px;display:flex;flex-direction:row}.f-calendar-day-view-header-primary,.reserve-detail-container .detail-info-content ul li span.detail-content{flex:1}.reserve-detail-container .detail-info-content ul li span.detail-subtitle{width:70px;display:inline-block}.shading-border-top{border-top:1px solid #fff!important}.f-avatar{position:relative;cursor:pointer;overflow:hidden}.f-avatar.f-avatar-readonly{cursor:default}.f-avatar.f-avatar-circle{border-radius:100%;overflow:hidden}.f-avatar.f-avatar-square{border-radius:0}.f-avatar .f-avatar-defult,.f-avatar .f-avatar-image{display:inline-block;width:100%;height:100%}.f-avatar .f-avatar-icon{display:none;position:absolute;left:0;right:0;top:0;bottom:0;align-items:center;justify-content:center;background:rgba(0,0,0,.3)}.f-avatar .f-avatar-icon .f-icon{font-size:24px;color:#fff}.f-avatar.f-avatar-circle .f-avatar-icon{border-radius:100%}.f-avatar.f-avatar-square .f-avatar-icon{border-radius:0}.f-avatar .f-avatar-upload-loading{position:absolute;left:0;top:0;display:inline-block;width:100%;height:100%;background-color:rgba(0,0,0,.15)}.f-avatar .f-avatar-upload-loading .loading-inner{position:absolute;width:100%;left:0;top:50%;margin-top:-25px;height:50px;line-height:50px;text-align:center;font-size:16px;color:#fff}.f-avatar:hover .f-avatar-icon{display:flex}.btn{display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:1px solid transparent;padding:.1875rem .875rem;font-size:.8125rem;line-height:1.4286;border-radius:6px;transition:none}@media screen and (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:focus,.btn:hover{text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn.disabled,.btn:disabled{opacity:1;box-shadow:none}.btn:not(:disabled):not(.disabled){cursor:pointer}.btn:not(:disabled):not(.disabled).active,.btn:not(:disabled):not(.disabled).active:focus,.btn:not(:disabled):not(.disabled):active,.btn:not(:disabled):not(.disabled):active:focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:var(--f-text-00);background:var(--f-theme-04);border-color:var(--f-theme-03);box-shadow:0 4px 10px 0 rgba(var(--f-theme-03),.2);position:relative;z-index:20}.btn-primary:hover,.btn-primary:not(:disabled):not(.disabled).focus,.btn-primary:not(:disabled):not(.disabled):focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-primary:hover{color:var(--f-text-00);background:linear-gradient(135deg,#529DFF 0,#559FFF 100%);border-color:var(--f-theme-05)}.btn-primary.disabled,.btn-primary:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:var(--f-text-00);background:var(--f-theme-02);border-color:var(--f-theme-01);box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-secondary{background:var(--f-neutral-12);border-color:var(--f-neutral-08);box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-secondary:hover{color:var(--f-theme-05);background:var(--f-neutral-12);border-color:var(--f-theme-05);box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-secondary:not(:disabled):not(.disabled).focus,.btn-secondary:not(:disabled):not(.disabled):focus{box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-secondary.disabled,.btn-secondary:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:var(--f-theme-01);background:var(--f-neutral-12);border-color:var(--f-theme-01);box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-danger,.btn-danger:hover{color:var(--f-semantic-danger-01);box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-danger,.f-btn-icon::before,.f-cmp-inputgroup .input-append-button,.f-cmp-text-input-append .input-append-button,.f-component-text .input-append-button,.input-append-button{background:var(--f-neutral-00)}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-danger{border-color:#F9B0AF}.btn-danger:hover{background:rgba(var(--f-semantic-danger-01),.06);border-color:var(--f-semantic-danger-01)}.btn-danger:not(:disabled):not(.disabled).focus,.btn-danger:not(:disabled):not(.disabled):focus{box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-danger.disabled,.btn-danger:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:var(--f-semantic-danger-01);background:rgba(var(--f-semantic-danger-01),.1);border-color:var(--f-semantic-danger-01);box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.btn-success,.btn-success:hover,.btn-success:not(:disabled):not(.disabled).focus,.btn-success:not(:disabled):not(.disabled):focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-success,.btn-success:hover{color:var(--f-text-00);background:var(--f-semantic-success-01);border-color:var(--f-semantic-success-01)}.btn-success.disabled,.btn-success:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:var(--f-text-00);background:var(--f-semantic-success-01);border-color:var(--f-semantic-success-01);box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-warning,.btn-warning:hover{color:var(--f-text-00);background:var(--f-semantic-warning-01);border-color:var(--f-semantic-warning-01);box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-warning:not(:disabled):not(.disabled).focus,.btn-warning:not(:disabled):not(.disabled):focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-warning.disabled,.btn-warning:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-dark,.btn-dark:hover,.btn-dark:not(:disabled):not(.disabled).focus,.btn-dark:not(:disabled):not(.disabled):focus,.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:var(--f-text-00);background:var(--f-semantic-warning-01);border-color:var(--f-semantic-warning-01)}.btn-dark{color:var(--f-text-00);background:#343a40;border-color:#343a40}.btn-dark:hover{color:var(--f-text-00);background:#23272b;border-color:#23272b}.btn-dark.disabled,.btn-dark:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:var(--f-text-00);background:#1d2124;border-color:#171a1d;box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-light,.btn-light:hover{color:#212529;box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-light{background:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{background:#e2e6ea;border-color:#dae0e5}.btn-light:not(:disabled):not(.disabled).focus,.btn-light:not(:disabled):not(.disabled):focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-light.disabled,.btn-light:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-info,.btn-info:hover,.btn-info:not(:disabled):not(.disabled).focus,.btn-info:not(:disabled):not(.disabled):focus,.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background:#dae0e5;border-color:#d3d9df}.btn-info{background:var(--f-theme-03);border-color:var(--f-theme-03)}.btn-info:hover{color:var(--f-text-00);background:linear-gradient(135deg,#529DFF 0,#559FFF 100%);border-color:var(--f-theme-05)}.btn-info.disabled,.btn-info:disabled{color:var(--f-text-07);background:var(--f-neutral-08);border-color:var(--f-neutral-05);box-shadow:none}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:var(--f-text-00);background:var(--f-theme-02);border-color:var(--f-theme-02);box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-link,.btn-link:hover{background-color:transparent}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-link{font-weight:400;color:var(--f-theme-03);padding:0;border:0}.btn-lg,.btn-sm{line-height:1.4286;border-radius:6px}.btn-link:hover{color:var(--f-theme-05);text-decoration:none;border-color:transparent}.btn-link.focus,.btn-link:focus{text-decoration:none;border-color:transparent;color:var(--f-theme-01);box-shadow:none}.btn-link.active,.btn-link:active{box-shadow:none!important;color:var(--f-theme-01)}.btn-link.disabled,.btn-link:disabled{color:var(--f-text-07);pointer-events:none}.btn-link+.btn-link{margin-right:.875rem}.btn-lg{padding:.25rem 1.125rem}.btn-sm{padding:.125rem .5rem;font-size:.75rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.btn-warning{color:var(--f-text-00)}.btn-outline-danger.disabled,.btn-outline-danger:disabled,.btn-outline-dark.disabled,.btn-outline-dark:disabled,.btn-outline-info.disabled,.btn-outline-info:disabled,.btn-outline-light.disabled,.btn-outline-light:disabled,.btn-outline-link.disabled,.btn-outline-link:disabled,.btn-outline-primary.disabled,.btn-outline-primary:disabled,.btn-outline-secondary.disabled,.btn-outline-secondary:disabled,.btn-outline-success.disabled,.btn-outline-success:disabled,.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:var(--f-text-07);border-color:var(--f-neutral-05);background:0 0}.btn-info{color:var(--f-text-00)}.f-cursor-pointer{cursor:pointer!important}.f-btn-collapse-expand{color:var(--f-text-03);background-color:transparent;box-shadow:none}.dropdown-submenu .dropdown-toggle,.f-btn-collapse-expand:active,.f-btn-collapse-expand:focus,.f-btn-icon.f-bare,.f-layout-pane.f-page-content-nav,.f-response-content .dropdown-item{box-shadow:none!important}.f-btn-collapse-expand:hover{color:var(--f-theme-05)}.f-btn-collapse-expand:active{color:var(--f-theme-01)}.f-btn-collapse-expand::after{width:1em;height:1em;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-size:1rem;font-style:normal;font-variant:normal;font-weight:400;line-height:1;speak:none;text-transform:none;display:inline-block;vertical-align:middle;margin-left:.25rem}.f-btn-collapse-expand.f-state-expand::after{content:"\e013"}.f-toolbar .f-btn-collapse-expand{padding-right:0}.f-pretend-link{color:var(--f-theme-03)!important;cursor:pointer;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}.f-pretend-link:hover{color:var(--f-theme-05);text-decoration:none}.btn.btn-px{padding-left:2.25rem;padding-right:2.25rem}.f-btn-ml{margin-left:.5rem!important}.f-btn-link-ml,.f-btn-link-mr{margin-left:.875rem!important}.f-btn-mr{margin-right:.625rem!important}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex-grow:0;flex-shrink:1;flex-basis:auto}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group-sm>.btn{padding:.125rem .5rem;font-size:.75rem;line-height:1.4286;border-radius:6px}.btn-group-lg>.btn{padding:.25rem 1.125rem;font-size:.875rem;line-height:1.4286;border-radius:6px}.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropright-top .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropup-left .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before,.dropleft-up .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-lg+.dropdown-toggle-split{padding-right:.84375rem;padding-left:.84375rem}.btn-group.show .dropdown-toggle{box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06)}.btn-group.show .dropdown-toggle.btn-link{box-shadow:none}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.f-btn-group .f-btn-group-links .btn-link{margin-left:.375rem;margin-right:.375rem}.f-btn-group .f-btn-group-links .btn-link:first-child{margin-left:0}.f-btn-group .f-btn-group-links .btn-link:last-child{margin-right:.1875rem}.f-btn-group .f-btn-group-links .btn-icontext{color:var(--f-theme-03);padding:0 3px;margin:0 0 0 .375rem}.f-btn-group .f-btn-group-links .btn-icontext .f-icon{margin:0}.f-btn-group .f-btn-group-links .btn-icontext:last-child{margin-right:0}.f-btn-group .f-btn-group-dropdown{padding:0 3px;margin-left:.375rem}.f-btn-group .f-btn-group-dropdown .f-btn-dropdown{display:inline-block;border:none;outline:0;background:var(--f-aid-04);color:var(--f-theme-03);width:1rem;height:1rem;line-height:1rem;text-align:center;border-radius:100%;padding:0}.f-btn-group .f-btn-group-dropdown .f-btn-dropdown:hover{cursor:pointer;color:var(--f-theme-03);background:var(--f-aid-03)}.f-btn-group .f-btn-group-dropdown .f-btn-dropdown:focus{color:var(--f-text-00);background:var(--f-theme-02)}.f-btn-group .f-btn-group-dropdown .f-btn-dropdown .f-icon{font-size:.75rem}.f-btn-group .f-btn-group-dropdown .dropdown-menu{min-width:5rem}.f-btn-group-dropdown-menu{z-index:1300!important}.f-btn-group-dropdown-menu .dropdown-item .dropdown-item-icon{margin:0 8px 0 0}.f-button-edit .farris-tags.form-control{padding:0}.f-button-edit .farris-tag-input-box,.f-button-edit .farris-tag-item{line-height:17px!important;margin:2px 6px 2px 0!important}.f-button-edit .farris-tag-input-box .form-control{height:inherit!important;padding:1px 0!important}.f-button-edit-nowrap .input-group{flex-wrap:nowrap!important}.f-button-edit-nowrap .farris-tags{overflow:hidden}.f-button-edit-nowrap .farris-tags-item-container{display:flex;flex-wrap:nowrap;overflow:hidden}.f-button-edit .input-group:not(.f-state-disabled,.f-state-readonly) .form-control,.f-cmp-number-spinner:not(.f-state-disabled,.f-state-readonly,.number-range) .form-control{border-top-right-radius:0;border-bottom-right-radius:0}.fv-calculator-standard-main{background-color:#f1f1f1;margin:0 auto;box-shadow:0 0 15px #4d4d4d}.fv-calculator-standard-main ul{list-style:none;margin:0;padding:0}.fv-calculator-standard-main li{float:left;text-align:center;cursor:pointer}.fv-calculator-standard-main li img{height:14px}.fv-calculator-standard-main .fv-calculator-title{padding:5px 0;height:30px;line-height:30px;font-size:18px;margin-left:10px}.fv-calculator-standard-main .fv-calculator-result{height:140px;text-align:right;width:100%}.fv-calculator-standard-main .fv-calculator-result-out{margin:0 5px;height:48px;overflow:hidden}.fv-calculator-standard-main .fv-calculator-second{font-size:42px;font-weight:700;overflow-y:auto;white-space:nowrap;text-align:right}.fv-calculator-standard-main .fv-calculator-pre{color:#A7A7A7;padding:0 20px;font-size:16px;height:24px;width:100%;overflow:hidden;position:relative;z-index:99}.fv-calculator-standard-main .fv-calculator-pre .fv-calculator-pre-left{width:16px;text-align:center;line-height:20px;height:24px;position:absolute;z-index:101;left:0;top:0;font-weight:600;cursor:pointer;background:#f1f1f1}.fv-calculator-standard-main .fv-calculator-pre .fv-calculator-pre-right{width:16px;text-align:center;line-height:20px;height:24px;position:absolute;z-index:101;right:0;top:0;font-weight:600;cursor:pointer;background:#f1f1f1}.fv-calculator-pre .fv-calculator-pre-content{text-align:right;height:24px;line-height:24px;white-space:nowrap;overflow-y:auto;overflow-x:hidden}.fv-calculator-pre-left:hover,.fv-calculator-pre-right:hover{color:#1853d1;background:#9b9b9b}.fv-calculator-standard-main .fv-calculator-type{height:auto;text-align:left;font-weight:700;margin:10px 0 20px 10px;font-size:22px}.fv-calculator-standard-main .fv-calculator-type-bar{height:90px;width:100px;position:absolute;top:110px;background-color:#E6E6E6}.fv-calculator-standard-main .fv-calculator-type-bar li{float:left;width:100px;text-align:center;line-height:30px}.fv-calculator-standard-main .active{background-color:#CFCFCF}.fv-calculator-standard-main .fv-calculator-number{font-weight:700;border:1px solid #fff!important;background:#fff!important}.fv-calculator-standard-main .fv-calculator-number:hover{border:1px solid #f1f1f1!important;background:#c6c6c6!important}.fv-calculator-standard-main .fv-calculator-operator:hover{border:1px solid #f1f1f1!important;background:#82bceb!important;color:#fff}.fv-calculator-standard-main .fv-calculator-letter{font-size:16px}.fv-calculator-standard-main{width:500px;height:460px}#fv-calculator-num-symbol{height:270px;font-size:20px;display:flex;flex-wrap:wrap;justify-content:center}#fv-calculator-num-symbol li{line-height:48px;width:23%;margin:5px 0 0 5px;background:#dedede;border:1px solid #dedede;list-style-type:none}#fv-calculator-num-symbol li:hover{background:#c6c6c6;border:1px solid #f1f1f1}.f-calendar-day-view-header,.f-calendar-day-view-item{border-bottom:1px solid #e9e9e9;display:flex}.f-calendar-day-view-item,.f-calendar-day-view-item-lower,.f-calendar-day-view-item-upper,.f-calendar-day-view-item-upper:first-child,.f-calendar-day-view-item:first-child{border-top:1px solid transparent}.f-calendar-day-view{background-color:#fff;display:flex;flex-direction:column;min-width:860px;height:530px}.f-calendar-day-view-header-corner{width:44px;height:24px}.f-calendar-day-view-header-columns{display:flex}.f-calendar-day-view-header-cell{display:flex;flex:1;padding:4px 4px 8px;font-size:14px;color:rgba(0,0,0,.75);line-height:22px;font-weight:500}.f-calendar-day-view-header-cell .f-calendar-day-view-date{border-radius:20px;width:24px;height:24px;text-align:center;margin-right:4px}.f-calendar-day-view-header-cell .f-calendar-day-view-current{background:#0093f5;color:#fff}.f-calendar-day-view-content{display:flex;flex:1;overflow-y:scroll}.f-calendar-day-view-content-side{width:44px}.f-calendar-day-view-item{height:22px}.f-calendar-day-view-item-upper{border-bottom:1px solid transparent}.f-calendar-day-view-item-lower{border-bottom:1px solid #e9e9e9}.f-calendar-day-view-item-cell{flex:1;height:22px;border-left:1px solid transparent;border-right:1px solid #e9e9e9}.f-calendar-day-view-item-cell:first-child{border-left:1px solid #e9e9e9;border-right:1px solid #e9e9e9}.f-calendar-day-view-item-cell:last-child{border-left:1px solid transparent;border-right:1px solid transparent}.f-calendar-header{display:flex;background-color:#fff}.f-calendar-header>.f-calendar-title{font-weight:600;font-size:24px;line-height:32px;margin:14px 0;padding:0 14px;border-right:1px solid #e9e9e9;width:144px}.f-calendar-header>.f-calendar-navigator{flex:1;display:flex}.f-calendar-header .f-calendar-view-switch{margin:16px 14px;position:relative}.f-calendar-header .f-calendar-view-switch-panel{background-color:#eff5ff;width:200px;height:28px;border-radius:28px;display:flex;font-weight:500}.f-calendar-header .f-calendar-view-switch-panel>span{flex:1;line-height:28px;text-align:center}.f-calendar-header .f-calendar-view-switch>.f-calendar-view-switch-active-view{height:24px;width:62px;position:absolute;background:#fff;box-shadow:0 4px 18px 0 rgba(2,75,193,.2);border-radius:24px;line-height:24px;text-align:center;color:#0091da;font-weight:500;transition:.3s ease-out all}.f-calendar-header>.f-calendar-navigator>.f-calendar-navigator-today{background:#fff;border:1px solid #e8ebf2;box-shadow:0 2px 6px 0 rgba(31,35,41,.06);border-radius:6px;font-size:13px;color:#2d2f33;font-weight:400;margin:auto 6px auto 14px}.f-calendar-header>.f-calendar-navigator>.f-calendar-navigator-button-group{box-shadow:0 2px 6px 0 rgba(31,35,41,.06);border-radius:6px;font-size:13px;color:#2d2f33;font-weight:400;margin:auto 14px auto 0}.f-calendar-header>.f-calendar-navigator>.f-calendar-navigator-button-group>.f-calendar-navigator-previous{background:#fff;border:1px solid #e8ebf2;border-right-color:transparent;border-radius:6px 0 0 6px;padding:.1875rem .375rem}.f-calendar-header>.f-calendar-navigator>.f-calendar-navigator-button-group>.f-calendar-navigator-next{background:#fff;border:1px solid #e8ebf2;border-radius:0 6px 6px 0;padding:.1875rem .375rem}.f-calendar-month-view{min-width:860px;display:flex}.f-calendar-month-view table{display:table!important;margin:initial!important;flex:1;table-layout:fixed;width:-moz-fit-content;width:fit-content}.f-calendar-month-view tr{border-top:initial!important;transition:initial!important}.f-calendar-month-view th{border:initial!important;background-color:initial!important;font-size:14px!important;color:rgba(0,0,0,.75);line-height:22px;font-weight:500!important}.f-calendar-month-view{background-color:#fff}.f-calendar-month-view td{border:1px solid #e9e9e9!important;padding:4px!important;height:100px}.f-calendar-week-view-header,.f-calendar-week-view-item{display:flex;border-bottom:1px solid #e9e9e9}.f-calendar-month-view .f-calendar-month-view-title{display:flex}.f-calendar-month-view .f-calendar-month-view-title>.f-calendar-month-view-date{border-radius:20px;width:24px;height:24px;line-height:24px;text-align:center;font-size:14px}.f-calendar-month-view .f-calendar-month-view-title>.f-calendar-month-view-date-month{flex:1;border-radius:20px;width:24px;height:24px;line-height:24px;text-align:right;font-size:14px}.f-calendar-month-view .f-calendar-month-view-current{background:#0093f5;color:#fff}.f-calendar-month-view .f-calendar-month-view-event-item{background-color:#ebf3ff;font-size:12px;color:#0e6ded;line-height:18px;margin:2px 0;padding:2px 4px}.f-calendar-week-view{background-color:#fff;display:flex;flex-direction:column;min-width:860px;height:530px}.f-calendar-week-view-header-corner{width:44px;height:24px}.f-calendar-week-view-header-primary{flex:1}.f-calendar-week-view-header-columns{display:flex}.f-calendar-week-view-header-cell{flex:1;padding:4px 4px 8px;display:flex;font-size:14px;color:rgba(0,0,0,.75);line-height:22px;font-weight:500}.f-calendar-week-view-header-cell .f-calendar-week-view-date{border-radius:20px;width:24px;height:24px;text-align:center;margin-right:4px}.f-calendar-week-view-header-cell .f-calendar-week-view-current{background:#0093f5;color:#fff}.f-calendar-week-view-content{display:flex;flex:1;overflow-y:scroll}.f-calendar-week-view-content-side{width:44px}.f-calendar-content-primary{flex:1}.f-calendar-side{margin-top:-11px}.f-calendar-side-row{height:22px;padding-right:4px;text-align:end}.f-calendar-side-row-number{height:22px;line-height:22px}.f-calendar-week-view-item{height:22px;border-top:1px solid transparent}.f-calendar-week-view-item:first-child{border-top:1px solid #e9e9e9}.f-calendar-week-view-item-lower,.f-calendar-week-view-item-upper,.f-calendar-week-view-item-upper:first-child{border-top:1px solid transparent}.f-calendar-week-view-item-upper{border-bottom:1px solid transparent}.f-calendar-week-view-item-lower{border-bottom:1px solid #e9e9e9}.f-calendar-week-view-item-cell{flex:1;height:22px;border-left:1px solid transparent;border-right:1px solid #e9e9e9}.f-calendar-week-view-item-cell:first-child{border-left:1px solid #e9e9e9;border-right:1px solid #e9e9e9}.f-calendar-week-view-item-cell:last-child{border-left:1px solid transparent;border-right:1px solid transparent}.f-calendar-event{background:#ebf3ff;border-radius:2px;margin:2px;font-size:12px;color:#0e6ded;padding:2px 4px}.f-capsule-container{color:#6080AD;position:relative;display:inline-block;box-sizing:content-box;padding:0;margin:0;cursor:pointer;white-space:nowrap;min-width:2.5rem;height:1.8rem;overflow:hidden}.f-capsule-container.primary .f-capsule-board{background-color:#eff5ff}.f-capsule-container.secondary .f-capsule-board{background-color:#f2f4f8}.f-capsule-container .f-capsule-pane{display:flex;height:100%;min-height:100%;justify-content:flex-start;align-items:center;top:0;position:relative}.f-capsule-container .f-capsule-pane .f-capsule-item{opacity:1;display:inline-block;font-size:12px;line-height:1.8rem;padding-left:24px;padding-right:24px;z-index:2}.f-capsule-container .f-capsule-pane .f-capsule-item.f-capsule-active-item{font-weight:700}.f-capsule-container.primary .f-capsule-pane .f-capsule-item.f-capsule-active-item{color:#2a87ff}.f-capsule-container .f-capsule-pane .f-capsule-item>i{margin-right:2px;font-size:12px}.f-capsule-container .f-capsule-board{background-color:#f2f4f8;border-radius:1.8rem;height:1.8rem;position:absolute;top:0;z-index:0}.f-capsule{height:calc(100% - 4px);border-radius:1.8rem;position:absolute;background:#fff;left:2px;top:2px;opacity:1;display:inline-block;font-size:12px;padding-left:22px;padding-right:22px;z-index:1}.custom-checkbox .custom-control-input:checked~.custom-control-label::after,.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:none}.custom-control{position:relative;display:block;min-height:1.1607375rem;padding-left:0}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;clip:rect(0,0,0,0);overflow:hidden;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:var(--f-theme-03);background-color:var(--f-neutral-00);box-shadow:none}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 4px 2px rgba(99,136,255,.12);color:var(--f-theme-03)}.custom-control-input:active~.custom-control-label::before{color:var(--f-text-00);background-color:var(--f-theme-03);box-shadow:none}.custom-checkbox .custom-control-input:checked~.custom-control-label::before,.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before,.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before,.custom-control-input:disabled~.custom-control-label::before,.custom-control-label::before,.custom-radio .custom-control-input:checked~.custom-control-label::before,.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:var(--f-neutral-00)}.custom-control-input:disabled~.custom-control-label{color:var(--f-neutral-06)}.custom-control-label{position:relative}.custom-control-label::before{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;box-shadow:0 0 0;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.custom-control-label::after{position:absolute;top:.08036875rem;left:-1.5rem;width:1rem;height:1rem;background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{top:1px;border-radius:0}@media screen and (prefers-reduced-motion:reduce){.custom-control-label::before{transition:none}}.custom-control.custom-checkbox,.custom-control.custom-radio{padding-right:.8125rem;margin-bottom:.25rem}.custom-control .custom-control-label::before{color:var(--f-neutral-02)}.custom-control .custom-control-label:hover{cursor:pointer}.custom-control .custom-control-input:disabled~.custom-control-label:hover,.custom-control .custom-control-input[readonly]~.custom-control-label:hover{cursor:default}.custom-control .custom-control-label:hover::before{color:var(--f-theme-05)}.custom-control .custom-control-input:checked~.custom-control-label::before{color:var(--f-theme-03)}.custom-control .custom-control-input[readonly]~.custom-control-label{color:var(--f-text-02)}.custom-control .custom-control-input[readonly]~.custom-control-label::before{color:var(--f-neutral-06)}.custom-control .custom-control-input:disabled~.custom-control-label{color:var(--f-text-02)}.custom-control .custom-control-input:disabled~.custom-control-label::before{color:var(--f-neutral-06)}.custom-control .custom-control-input[disabled]:checked~.custom-control-label::before,.custom-control .custom-control-input[readonly]:checked~.custom-control-label::before{color:rgba(var(--f-theme-03),.2)}.custom-control-label{padding-left:1.5rem;color:var(--f-text-02);display:inline}.custom-control-label::before{width:1em;height:1em;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:FarrisIcons;font-style:normal;font-variant:normal;font-weight:400;speak:none;text-transform:none;display:inline-block;vertical-align:middle;color:var(--f-neutral-02);font-size:14px;line-height:1;top:3px;left:0;position:absolute}.custom-control-label::after{display:none}.custom-checkbox .custom-control-label::before{content:"\e304"}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{box-shadow:none;font-family:FarrisIcons;content:"\e306";color:var(--f-theme-03)}.custom-checkbox .custom-control-input:checked~.custom-control-label::before,.custom-radio .custom-control-input:checked~.custom-control-label::before{content:"";background-repeat:no-repeat;background-size:contain;background-position:center center;box-shadow:0 2px 6px 0 rgba(var(--f-theme-03),.2)}.custom-checkbox .custom-control-input[disabled]:checked~.custom-control-label::before,.custom-checkbox .custom-control-input[readonly]:checked~.custom-control-label::before,.custom-radio .custom-control-input[disabled]:checked~.custom-control-label::before,.custom-radio .custom-control-input[readonly]:checked~.custom-control-label::before{box-shadow:none;opacity:.4}.f-radio-button-danger:hover,.f-radio-button-primary:hover,.f-radio-button-success:hover,.f-radio-button-warning:hover{box-shadow:0 2px 6px 0 rgba(31,35,41,.06)}.custom-checkbox .custom-control-input:checked~.custom-control-label::before{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjE0cHgiIGhlaWdodD0iMTRweCIgdmlld0JveD0iMCAwIDE0IDE0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgIDx0aXRsZT7nvJbnu4QgMjc8L3RpdGxlPg0KICAgIDxkZWZzPg0KICAgICAgICA8bGluZWFyR3JhZGllbnQgeDE9Ijg3LjE4OTcwNjUlIiB5MT0iMCUiIHgyPSIxOC4yNDA0NDkyJSIgeTI9IjEwMCUiIGlkPSJsaW5lYXJHcmFkaWVudC0xIj4NCiAgICAgICAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiMzRjY1RkYiIG9mZnNldD0iMCUiPjwvc3RvcD4NCiAgICAgICAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiM0RDlBRkYiIG9mZnNldD0iMTAwJSI+PC9zdG9wPg0KICAgICAgICA8L2xpbmVhckdyYWRpZW50Pg0KICAgIDwvZGVmcz4NCiAgICA8ZyBpZD0i5paw54mIIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4NCiAgICAgICAgPGcgaWQ9Iue8lue7hC0yNyI+DQogICAgICAgICAgICA8cmVjdCBpZD0i55+p5b2i5aSH5Lu9LTE0IiBmaWxsPSJ1cmwoI2xpbmVhckdyYWRpZW50LTEpIiB4PSIwIiB5PSIwIiB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHJ4PSIzIj48L3JlY3Q+DQogICAgICAgICAgICA8cGF0aCBkPSJNMTAuNjkwOTE2NCw0LjEzNjA2NjY0IEwxMS4zNTMzNzY5LDQuNzU0MDk0OTIgQzExLjQzNDE0MzMsNC44Mjk0NDQyNCAxMS40Mzg1MzQ3LDQuOTU2MDAxMDcgMTEuMzYzMTg1NCw1LjAzNjc2NzUxIEMxMS4zNjMwNjY2LDUuMDM2ODk0ODYgMTEuMzYyOTQ3Niw1LjAzNzAyMjA2IDExLjM2MjgyODUsNS4wMzcxNDkxMSBMNi42MTYzOTg1OSwxMC4wOTgyNDI1IEM2LjU0MDgzODUyLDEwLjE3ODgxMTggNi40MTQyNzA2NSwxMC4xODI4NzI2IDYuMzMzNzAxMzQsMTAuMTA3MzEyNSBDNi4zMzE3ODIyMSwxMC4xMDU1MTI3IDYuMzI5ODk4NzgsMTAuMTAzNjc1MiA2LjMyODA1MjE1LDEwLjEwMTgwMSBMMy4xNDA3NDAxNiw2Ljg2NzAxODkyIEMzLjA2MzIxNDc1LDYuNzg4MzM4ODggMy4wNjQxNTA3NSw2LjY2MTcwOTM0IDMuMTQyODMwNzksNi41ODQxODM5MyBDMy4xNDI5NTUxMSw2LjU4NDA2MTQzIDMuMTQzMDc5Niw2LjU4MzkzOTA5IDMuMTQzMjA0MjQsNi41ODM4MTY5MiBMMy43OTAxMjUxOCw1Ljk0OTcxODg4IEMzLjg2ODg2OTM1LDUuODcyNTM1NTQgMy45OTUyMjY2Myw1Ljg3MzY0MzM2IDQuMDcyNjA1NCw1Ljk1MjE5NTQ5IEw2LjQ1MDE0NjI0LDguMzY1Nzg4ODIgTDYuNDUwMTQ2MjQsOC4zNjU3ODg4MiBMMTAuNDA4NjEwMiw0LjE0NTQ4MzUzIEMxMC40ODQwMzI2LDQuMDY1MDcyMTYgMTAuNjEwMzAzLDQuMDYwODYwMTYgMTAuNjkwOTE2NCw0LjEzNjA2NjY0IFoiIGlkPSLot6/lvoQtMTPlpIfku70iIGZpbGw9IiNGRkZGRkYiIGZpbGwtcnVsZT0ibm9uemVybyI+PC9wYXRoPg0KICAgICAgICA8L2c+DQogICAgPC9nPg0KPC9zdmc+)}.farris-checkradio-ver{display:flex!important;flex-direction:column}.farris-checkradio-hor{flex-wrap:wrap;display:inline-flex}.farris-input-wrap.farris-checkradio-hor{display:inline-flex}.custom-radio .custom-control-label::before{border-radius:50%;content:"\e309"}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:none}.custom-radio .custom-control-input:checked~.custom-control-label::before{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjE0cHgiIGhlaWdodD0iMTRweCIgdmlld0JveD0iMCAwIDE0IDE0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgIDx0aXRsZT5SZWN0YW5nbGUgMjcxIENvcHkgMTHlpIfku70gMjwvdGl0bGU+DQogICAgPGRlZnM+DQogICAgICAgIDxsaW5lYXJHcmFkaWVudCB4MT0iODcuMTg5NzA2NSUiIHkxPSIwJSIgeDI9IjE4LjI0MDQ0OTIlIiB5Mj0iMTAwJSIgaWQ9ImxpbmVhckdyYWRpZW50LTEiPg0KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzNGNjVGRiIgb2Zmc2V0PSIwJSI+PC9zdG9wPg0KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzREOUFGRiIgb2Zmc2V0PSIxMDAlIj48L3N0b3A+DQogICAgICAgIDwvbGluZWFyR3JhZGllbnQ+DQogICAgPC9kZWZzPg0KICAgIDxnIGlkPSLmlrDniYgiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPg0KICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlLTI3MS1Db3B5LTEx5aSH5Lu9LTIiIHN0cm9rZT0idXJsKCNsaW5lYXJHcmFkaWVudC0xKSIgc3Ryb2tlLXdpZHRoPSI0IiB4PSIyIiB5PSIyIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIHJ4PSI1Ij48L3JlY3Q+DQogICAgPC9nPg0KPC9zdmc+)}.farris-checkradio-hor .farris-radio-button .btn{border-radius:0}.farris-checkradio-hor .farris-radio-button:first-child .btn{border-top-left-radius:6px;border-bottom-left-radius:6px}.farris-checkradio-hor .farris-radio-button:last-child .btn{border-top-right-radius:6px;border-bottom-right-radius:6px}.f-radio-button,.f-radio-tag{color:#2d2f33;background:#fff;border:1px solid #e8ebf2}.f-radio-button-success:hover{color:#6cc77f;background:#fff;border-color:#6cc77f}.f-radio-button-warning:hover{color:#f5a144;background:#fff;border-color:#f5a144}.f-radio-button-danger:hover{color:#f46160;background:#fff;border-color:#f46160}.f-radio-button-primary:hover{color:#2a87ff;background:#fff;border-color:#2a87ff}.f-radio-button-success.active{color:#fff;background:#6cc77f;border-color:#6cc77f}.f-radio-button-warning.active{color:#fff;background:#f5a144;border-color:#f5a144}.f-radio-button-danger.active{color:#fff;background:#f46160;border-color:#f46160}.f-radio-button-primary.active{color:#fff;background:#2a87ff;border-color:#2a87ff}.f-radio-tag{display:inline-block;position:relative;margin-right:8px;padding:3px 16px;border:1px solid rgba(0,0,0,.15);border-radius:2px;overflow:hidden;cursor:pointer;margin-bottom:0}.f-radio-icon,.f-radio-tag>.tip{position:absolute;display:block}.f-radio-icon{right:-4px;bottom:-3px;font-size:12px;color:#fff}.f-radio-tag>.tip{right:0;bottom:0;width:14px;height:14px;border:7px solid #dadada;border-top:7px solid transparent;border-left:7px solid transparent}.f-radio-tag-success.active{color:#6cc77f;border-color:#6cc77f;background:rgba(108,199,127,.05)}.f-radio-tag-warning.active{color:#f5a144;border-color:#f5a144;background:rgba(245,161,68,.05)}.f-radio-tag-danger.active{color:#f46160;border-color:#f56161;background:rgba(245,97,97,.05)}.f-radio-tag-primary.active{color:#2a87ff;border-color:#2a87ff;background:rgba(42,135,255,.05)}.f-radio-tag-success.active>.tip{border-right-color:#6cc77f;border-bottom-color:#6cc77f}.f-radio-tag-warning.active>.tip{border-right-color:#f5a144;border-bottom-color:#f5a144}.f-radio-tag-danger.active>.tip{border-right-color:#f46160;border-bottom-color:#f46160}.f-radio-tag-primary.active>.tip{border-right-color:#2a87ff;border-bottom-color:#2a87ff}.f-color-picker-component{display:inline-block;position:relative;line-height:normal}.f-color-picker-component .color-picker-wrapper{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.f-color-picker-component .color-picker-wrapper .color-picker-input{border-top-right-radius:0;border-bottom-right-radius:0;flex:1 1 auto;width:1%;min-width:200px}.f-color-picker-component .color-picker-wrapper .color-picker-trigger{display:inline-block;box-sizing:border-box;height:calc(1.62503rem + 2px);width:calc(1.62503rem + 2px);padding:.1875rem;border:1px solid #e6e6e6;border-left:none;border-top-right-radius:4px;border-bottom-right-radius:4px;font-size:0;position:relative;cursor:pointer}.f-color-picker-component .color-picker-wrapper .color-picker-trigger .color-picker-trigger-inner{position:relative;display:block;box-sizing:border-box;border:1px solid #999;border-radius:2px;width:100%;height:100%;text-align:center}.f-color-picker-component .color-picker-wrapper .color-picker-trigger .color-picker-trigger-inner.is-alpha{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.f-color-picker-component .color-picker-wrapper .color-picker-trigger .color-picker-trigger-inner div{width:100%;height:100%}.f-color-picker-component .color-picker-panel{display:block;position:absolute;width:300px;z-index:3000;padding:6px;box-sizing:content-box;background-color:#fff;border:1px solid #ebeef5;border-radius:4px;box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.f-color-picker-component .color-picker-panel.disabled{display:none}.f-color-picker-component .color-picker-panel .color-picker-main{padding-bottom:6px}.f-color-picker-component .color-picker-panel .input-btn{margin-top:6px;text-align:right}.f-color-picker-component .color-picker-panel .input-btn input{float:left;width:180px;height:28px;line-height:28px;cursor:pointer;-webkit-appearance:none;background-color:#fff;border-radius:4px;border:1px solid #dcdfe6;box-sizing:border-box;color:#606266;font-size:inherit;outline:0;padding:0 7px;transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.f-color-picker-component .color-picker-panel .input-btn input:focus{border-color:#409eff}.f-color-picker-component .color-picker-panel .input-btn .btn-clear{background-color:#fff;border:none;outline:0;color:#409eff}.color-picker-wrapper .color-picker-trigger{border-color:var(--f-neutral-04)!important;height:calc(1.5rem + .125rem)!important}.f-alpha-component{display:flex;flex-direction:column;position:relative;box-sizing:border-box;width:280px;height:12px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.f-alpha-component .color-alpha-slider__bar{position:relative;background:linear-gradient(to right,rgba(255,69,0,0) 0,#ff4500 100%);height:100%}.f-alpha-component .color-alpha-slider__thumb{position:absolute;cursor:pointer;box-sizing:border-box;left:189px;top:0;width:4px;height:100%;border-radius:1px;background:#fff;border:1px solid #f0f0f0;box-shadow:0 0 2px rgba(0,0,0,.6);z-index:1}.f-hue-component{position:relative;box-sizing:border-box;width:12px;height:180px;background-color:red;padding:2px 0;float:right}.f-hue-component .color-hue-slider__bar{position:relative;background:linear-gradient(red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red);height:100%}.f-hue-component .color-hue-slider__thumb{position:absolute;cursor:pointer;box-sizing:border-box;top:10px;left:0;width:100%;height:4px;border-radius:1px;background:#fff;border:1px solid #f0f0f0;box-shadow:0 0 2px rgba(0,0,0,.6);z-index:1}.f-preset-component{display:flex;font-size:12px;margin-top:8px;width:280px}.f-preset-component .color-preset__colors{display:flex;flex:1;flex-wrap:wrap}.f-preset-component .color-preset__colors .color-preset__color-selector{margin:0 0 8px 8px;width:20px;height:20px;border-radius:4px;cursor:pointer}.f-preset-component .color-preset__colors .color-preset__color-selector:nth-child(10n+1){margin-left:0}.f-preset-component .color-preset__colors .color-preset__color-selector.selected{box-shadow:0 0 3px 2px #409eff}.f-preset-component .color-preset__colors .color-preset__color-selector div{display:flex;height:100%;border-radius:3px}.f-sv-panel-component{display:inline-block;position:relative;width:280px;height:180px}.f-sv-panel-component .color-svpanel__white{position:absolute;top:0;left:0;right:0;bottom:0;background:linear-gradient(90deg,#fff,hsla(0,0%,100%,0))}.f-sv-panel-component .color-svpanel__black{position:absolute;top:0;left:0;right:0;bottom:0;background:linear-gradient(0deg,#000,transparent)}.f-sv-panel-component .color-svpanel__cursor{position:absolute}.f-sv-panel-component .color-svpanel__cursor div{cursor:pointer;width:6px;height:6px;box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px rgba(0,0,0,.3),0 0 1px 2px rgba(0,0,0,.4);border-radius:50%;transform:translate(-3px,-3px)}input-group.actived .input-group{box-shadow:0 0 4px 2px rgba(99,136,255,.12);border-color:var(--f-theme-08)}.popover.f-combo-list-wrapper{background:var(--f-neutral-20)}.f-combo-list-container{overflow:auto;z-index:9;padding:.25rem}.f-combo-list-container .f-empty-title,.f-combo-list-container .f-list-view-group{margin:0}.f-combo-list-container .f-combo-list-search-box{margin:.25rem .5rem}.f-combo-list-container .f-combo-list-search-box .f-combo-list-item{padding:.125rem .5rem}.f-combo-list-item{position:relative;display:block;padding:.3125rem .5rem;background-color:#fff;border-radius:6px}.f-combo-list-item.f-un-select{color:var(--f-text-09)}.f-combo-list-item:not(.f-un-select):hover{background:var(--f-neutral-11);color:var(--f-text-02)}.f-combo-list-item.f-listview-active{color:var(--f-text-02);background:var(--f-neutral-10)}.f-combo-tree-container .fv-tree,.f-combo-tree-container .fv-tree-content{overflow:auto}.condition-list{width:100%;display:flex;flex-direction:column;overflow-y:hidden;resize:vertical;min-height:50px}.condition-list .condition-list-body{height:calc(100% - 32px);overflow-y:auto}.condition-list .condition-list-body-maxh{max-height:380px}.condition-list .condition-list-bottom{position:relative;margin:14px 0 14px 6px}.condition-list .condition-list-reset{position:absolute;right:32px;bottom:4px}.condition-list .add-group-btn{width:100%;background:rgba(239,245,255,.65);border:1px solid #dbe9ff;border-radius:6px;color:#2a87ff;font-size:13px}.condition-list .add-condition-btn{color:#2A87FF;font-size:13px;display:inline-block}.condition-list .add-condition-btn:hover{cursor:pointer}.condition-list .add-condition-btn .f-icon{vertical-align:text-bottom;position:relative;width:16px;height:16px;border-radius:50%}.condition-list .add-condition-btn .f-icon-filter-add::before{position:relative;bottom:3px;left:2px;font-size:12px}.condition-list .add-condition-btn .f-icon-filter-grouping::before{position:relative;bottom:3px;left:1px;font-size:12px}.condition-list .condition-list-content{display:flex}.condition-list .condition-list-content-group{flex:0 0 auto}.condition-list .condition-list-item{padding:4px;display:flex;height:40px}.condition-list .condition-list-item-type{width:200px}.condition-list .condition-list-type button{text-align:left;position:relative;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.condition-list .condition-list-item-compare{width:134px}.condition-list .condition-list-compare button{text-align:left;position:relative}.condition-list .condition-list-compare .f-icon-arrow-chevron-down::before,.condition-list .condition-list-compare .f-icon-arrowhead-s::before,.condition-list .condition-list-type .f-icon-arrow-chevron-down::before,.condition-list .condition-list-type .f-icon-arrowhead-s::before{position:absolute;right:8px;bottom:4px}.condition-list .condition-list-content .dropdown-toggle::after{display:none}.condition-list .condition-list-item-control{line-height:26px;width:200px}.condition-list .condition-list-item-extend .f-icon{vertical-align:text-bottom}.condition-list .condition-list-item-extend .f-icon:hover{cursor:pointer}.condition-list .condition-list-item-extend .f-icon-plus-sm::before,.condition-list .condition-list-item-extend .f-icon-splus::before{font-size:14px;color:#2a87ff;background-color:#e8f2ff;border-radius:50%;position:relative;top:1px}.condition-list .condition-list-item-extend .f-icon-minus-sm::before,.condition-list .condition-list-item-extend .f-icon-sminus::before{font-size:14px;color:#f46160;background-color:#fadcdd;border-radius:50%;position:relative;top:1px}.condition-list .condition-list-relation{margin:2px 0 2px 12px;border-left:1px solid #dee3f0;position:relative;display:flex;align-items:center;padding-left:12px;font-size:13px;color:#2a87ff;text-align:center;cursor:pointer}.condition-list .condition-list-relation:hover .condition-list-relation-close{display:inline}.condition-list .condition-list-relation-close{position:absolute;top:-4px;display:none}.fv-grid,.fv-grid-header,.fv-grid-header-cell{display:flex;overflow:hidden}.condition-list .condition-list-relation:hover .condition-list-relation-text{text-decoration:underline}.condition-list .condition-list-item .custom-control-label:before{position:relative;top:2px}.condition-list .condition-list-relation button{width:20px}.fv-grid{position:relative;flex-direction:column;border-style:solid;border-width:1px;border-color:transparent;flex:1;color:#424347}.fv-grid-header{position:relative;z-index:2;color:#5a5e66;font-weight:400;border-bottom:1px solid #e4e7ef;background-color:#f4f5f9}.fv-grid-header-corner{background-color:#f4f5f9;border-style:solid;border-width:1px;border-color:transparent;padding:.375rem 0}.fv-grid-header-left-fixed,.fv-grid-header-right-fixed{position:relative;overflow:hidden;background-color:#f4f5f9;z-index:1}.fv-grid-header-left-fixed{box-shadow:4px 0 10px 0 rgba(31,35,41,.06)}.fv-grid-header-right-fixed{box-shadow:-4px 0 10px 0 rgba(31,35,41,.06)}.fv-grid-header-primary{flex:1;position:relative;overflow:hidden;background-color:#f4f5f9}.fv-grid-header-columns{position:relative}.fv-grid-header-cell{position:absolute;border:1px solid transparent;top:0;padding:.4375rem .75rem;line-height:18px;color:#2d2f33;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle}.fv-grid-header-cell::after{content:"";position:absolute;left:0;top:50%;margin-top:-.5625rem;display:block;height:1.125rem;width:1px;background-color:#e6e9f0}.fv-grid-header-group-columns .fv-grid-header-cell{border-bottom-color:#eaecf3;border-right-color:#eaecf3;padding:0 .75rem;text-align:center}.fv-grid-header-group-columns .fv-grid-header-cell::after{display:none}.fv-grid-content{flex:1;display:flex;position:relative;overflow:hidden;z-index:0;background:#fff}.fv-grid-content-hover{cursor:pointer}.fv-grid-content-side{position:relative}.fv-grid-content-primary{flex:1;position:relative;overflow:hidden}.fv-grid-content-left-fixed,.fv-grid-content-right-fixed{position:relative;overflow:hidden;z-index:1}.fv-grid-content-left-fixed{box-shadow:4px 0 10px 0 rgba(31,35,41,.06);background-color:#fff}.fv-grid-content-right-fixed{box-shadow:-6px 0 6px -4px rgba(0,0,0,.12);background-color:#fff}.fv-grid-data{height:100%}.fv-grid-merge-date{position:absolute;top:0}.fv-grid-row{left:0;position:absolute}.fv-datagrid-strip .fv-grid-row-odd{background-color:#fff}.fv-datagrid-strip .fv-grid-row-even{background-color:#f7f8fb}.fv-grid-row-hover{cursor:pointer;color:#424347;background:#edf5ff!important;border-color:#eaecf3}.fv-grid-row-selected{color:#424347!important;border-color:#95bef1;background-color:#dae9ff!important}.fv-grid-cell,.fv-grid-group-row,.fv-grid-summary-row{border-color:transparent;background-color:transparent;border-style:solid;border-width:1px;position:absolute}.fv-grid-group-row,.fv-grid-summary-row{left:0;font-weight:600}.fv-grid-group-row-icon{width:28px;height:28px;flex-shrink:0;color:rgba(0,0,0,.45);line-height:24px;padding:.25rem .75rem}@keyframes rotate-group-collapse{0%{transform:rotate(0)}100%{transform:rotate(-90deg)}}.fv-grid-group-row-icon-collapse{transform:rotate(-90deg)}.fv-grid-cell{line-height:26px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;top:0;padding:0 .75rem}.fv-grid-wrap-content .fv-grid-cell{text-overflow:initial;overflow:initial;white-space:initial}.fv-grid-cell .f-form-control-textarea,.fv-grid-cell textarea.form-control{min-height:initial}.fv-grid-merged-cell{border-left-color:#eaecf3;background-color:#fff;text-align:center}.fv-grid-sidebar-row{left:0;position:absolute;line-height:24px;border-style:solid;border-width:1px;border-color:transparent;background-color:transparent}.fv-datagrid-strip .fv-grid-sidebar-row-odd{background-color:#fff}.fv-datagrid-strip .fv-grid-sidebar-row-even{background-color:#f7f8fb}.fv-grid-sidebar-row-hover{cursor:pointer;color:#424347;background:#edf5ff!important}.fv-grid-sidebar-row-selected{color:#424347!important;background-color:#dae9ff!important}.fv-grid-sidebar-row-checkbox{vertical-align:middle;margin:.25rem .5rem .25rem 1rem}.fv-grid-sidebar-row-number{display:inline-flex;width:32px;padding:0 .25rem}.fv-grid-content-hover .fv-grid-vertical-scroll{opacity:1}.fv-grid-vertical-scroll{opacity:0;position:absolute;background-color:transparent;right:0;left:auto!important;width:10px;cursor:default;transition:width .2s linear,opacity .2s linear,background-color .2s linear;height:288px;z-index:1}.fv-grid-vertical-scroll-thumb{transition:background-color .2s linear,width .2s ease-in-out;width:10px;right:0;background-color:rgba(0,0,0,.25);border-radius:10px;position:absolute}.fv-grid-content-hover .fv-grid-horizontal-scroll{opacity:1}.fv-grid-horizontal-scroll{opacity:0;position:absolute;background-color:transparent;bottom:0;top:auto!important;height:10px;cursor:default;transition:width .2s linear,opacity .2s linear,background-color .2s linear;width:812px;z-index:1}.fv-grid-horizontal-scroll-thumb{transition:background-color .2s linear,width .2s ease-in-out;height:10px;bottom:0;background-color:rgba(0,0,0,.25);border-radius:10px;position:absolute}.fv-grid-header-cell>.fv-column-title{flex:1;text-overflow:ellipsis;overflow:hidden;word-break:break-all;white-space:nowrap}.fv-grid-header-cell>.fv-column-resize-bar{display:block;position:absolute!important;top:-2px;bottom:-2px;right:0;margin:0;width:5px;padding:0;cursor:e-resize;border:1px solid transparent}.fv-grid-header-cell:hover>.fv-column-resize-bar{border-right:3px solid #2a87ff;border-top:none}.fv-grid-header-cell:hover>.fv-column-handler{display:block}.fv-grid-header-cell>.fv-column-handler{float:right;cursor:pointer;display:none;color:#2a87ff}.fv-grid-header-cell>.fv-column-handler.fv-column-handler-active{display:block!important;color:#2a87ff}.fv-grid-header-cell>.fv-column-handler:hover{color:#2a87ff}.fv-grid-header-cell>.fv-grid-settings-icon{display:block;cursor:pointer;margin-left:8px}.fv-datagrid-resize-overlay{z-index:98;width:100%;height:100%;cursor:e-resize;background:0 0;position:absolute}.fv-datagrid-resize-proxy{width:1px;border-left:1px dashed #2a87ff;left:0;display:none;position:absolute;height:100%;z-index:99}.fv-datagrid-summary{padding:3px;background-color:#fff}.fv-datagrid-summary .fv-datagird-summary-panel{height:40px;background:linear-gradient(90deg,#eff8f8 0,#fffbeb 100%);border-radius:8px;display:flex;justify-content:space-between}.fv-datagrid-summary-title{line-height:40px;width:100px;padding:0 16px;font-size:14px;font-weight:500}.fv-datagrid-summary-content{display:flex;line-height:40px}.fv-datagrid-summary-field{line-height:40px;margin-right:10px}.fv-datagrid-summary-field-title{font-size:14px;margin:0 16px}.fv-datagrid-summary-field-value{color:#ff6c29;font-size:18px;font-weight:700}.fv-datagrid-pagination{display:flex;flex-direction:row-reverse;background-color:#fff}.fv-column-handler-popover .popover-body{max-width:none}.fv-column-sort-filter-container{width:300px}.fv-column-sort-filter-container .fv-column-filter-section .fv-column-filter-section-title{font-size:15px;margin:10px 0}.fv-column-sort-filter-container .fv-column-filter-section .fv-column-filter-section-editor{margin-bottom:10px;max-height:240px;overflow:hidden;display:flex;flex-direction:column}.fv-column-sort-filter-container .fv-column-sort-filter-footer{display:flex}.fv-column-sort-filter-container .fv-column-sort-filter-footer .fv-column-confirm-section{flex:1;display:flex;flex-direction:row-reverse}.fv-grid-filter-panel{padding:0 6px 4px}.fv-grid-settings{min-width:800px;min-height:480px}.fv-grid-settings .f-btn-icon{color:#878d99!important}.fv-grid-settings .f-btn-icon:hover{color:#529dff!important}.fv-grid-settings .farris-tabs-header-pre{color:#000;font-weight:500}.fv-grid-settings .farris-tabs-header-post,.fv-grid-settings .farris-tabs-header-pre{padding:.75rem .5rem .75rem 1.125rem}.fv-grid-settings .farris-tabs-header{margin:0!important}.fv-grid-settings .container{padding-left:24px;padding-right:24px}.fv-grid-group-panel{border-bottom:1px solid #e4e7ef;background-color:#f4f5f9;height:40px}.fv-grid-bordered{border:1px solid #EAECF3}.fv-grid-bordered .fv-grid-cell{border-right-color:#EAECF3}.fv-grid-bordered .fv-grid-cell:last-child{border-right-color:transparent}.fv-grid-horizontal-bordered .fv-grid-cell,.fv-grid-horizontal-bordered .fv-grid-group-row,.fv-grid-horizontal-bordered .fv-grid-merged-cell,.fv-grid-horizontal-bordered .fv-grid-sidebar-row,.fv-grid-horizontal-bordered .fv-grid-summary-row{border-bottom-color:#eaecf3}.fv-grid-hierarchy-cell .custom-checkbox{display:flex;padding-right:0!important;margin:auto 0}.fv-grid-hierarchy-cell .fv-tree-node-toggle,.fv-grid-hierarchy-cell .fv-tree-node-toggle-minus{padding-right:6px}.fv-grid-hierarchy-cell .custom-label{padding-left:1.2rem}.fv-grid-hierarchy-cell div#treeNodeIcons{margin:auto 5px auto 0;color:#a5a6ab}.fv-grid-hierarchy-cell .fv-tree-node-toggle::before{font-family:FarrisIcons;color:#2D2F33;content:"\e11f"}.fv-grid-hierarchy-cell .fv-tree-node-toggle-minus::before{font-family:FarrisIcons;color:#2D2F33;content:"\e122"}.fv-grid-hierarchy-cell .fv-tree-node-toggle:hover::before{color:#59a1ff}.f-datepicker-container{display:flex;position:absolute;margin:.25rem 0 0;padding:0;box-shadow:0 2px 20px 0 rgba(3,18,51,.12);background:var(--f-neutral-20);border-radius:10px;z-index:9999;animation:selectorfadein 60ms;box-sizing:border-box;color:var(--f-text-01);flex-wrap:wrap;font-family:PingFangSC-Regular,Arial}.f-datepicker-container:focus{border:none;outline:0}.f-datepicker-container .arrow{display:none;width:1rem;height:6px;margin:0;position:absolute;left:8px}.f-datepicker-container .arrow::after,.f-datepicker-container .arrow::before{content:"";border-color:transparent;border-style:solid;position:absolute;display:block;border-width:0 6px 6px}.f-datepicker-container .arrow::after{top:1px}.f-datepicker-container .arrow::before{top:0}.f-datepicker-container.container-position-bottom .arrow{top:-6px}.f-datepicker-container.container-position-bottom .arrow::after,.f-datepicker-container.container-position-bottom .arrow::before{border-width:0 6px 6px;border-bottom-color:#fff}.f-datepicker-container.container-position-top{margin:-6px}.f-datepicker-container.container-position-top .arrow{top:auto;bottom:-6px}.f-datepicker-container.container-position-top .arrow::after,.f-datepicker-container.container-position-top .arrow::before{border-width:6px 6px 0;border-top-color:#fff}.f-datepicker-container .f-datepicker-sidebar{position:absolute;top:0;bottom:0;width:100px;border-right:1px solid var(--f-neutral-13);box-sizing:border-box;padding-top:6px;background-color:#fff;overflow:auto}.f-datepicker-container .f-datepicker-sidebar button{display:block;width:100%;border:0;background-color:transparent;line-height:28px;font-size:14px;color:#606266;padding-left:12px;text-align:left;outline:0;cursor:pointer}.f-datepicker-container .f-datepicker-sidebar button:hover{color:#409eff}.f-datepicker-container .f-datepicker-content{width:287px}.f-datepicker-container .f-datepicker-content .f-datepicker-header{display:flex;justify-content:space-between;border-bottom:1px solid var(--f-neutral-13)}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-prev-btn{padding-left:1rem}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-prev-btn .f-datepicker-header-btn{color:var(--f-text-02);padding:1px 8px 1px 0}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-next-btn{padding-right:1rem}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-next-btn .f-datepicker-header-btn{color:var(--f-text-02);padding:1px 0 1px 8px}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-header-btn{height:40px;outline:0;border:0;background:var(--f-neutral-20);line-height:35px;font-size:14px;padding:1px 4px;cursor:pointer}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-header-btn:hover{color:var(--f-theme-05)}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-header-btn:active{color:var(--f-theme-01)}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-header-btn.f-datepicker-header-btn-disabled,.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-header-btn.f-datepicker-header-btn-disabled:active,.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-header-btn.f-datepicker-header-btn-disabled:hover{color:var(--f-text-07)}.f-datepicker-container .f-datepicker-content .f-datepicker-header .f-datepicker-monthYearText .f-datepicker-header-btn{color:var(--f-text-02)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper{width:100%;height:254px;padding:8px 12px}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table{width:100%;height:100%;max-width:100%;background-color:transparent;border-collapse:collapse;text-align:center;border:0}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table th{font-weight:400;color:var(--f-text-08)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table tr.f-datepicker-selectWeek{cursor:pointer;transition:all .3s}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table tr.f-datepicker-selectWeek:not(.f-datepicker-selectedWeek):hover{background:var(--f-neutral-10)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table tr.f-datepicker-selectedWeek{background:var(--f-neutral-09)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td{padding:0;position:relative}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td:focus{border:0;outline:0;box-shadow:none}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td.f-datepicker-weeknbr{color:f-text-05}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-date:hover,.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-month:hover,.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-year:hover,.f-datepicker-container .f-datepicker-select-btn:hover{color:var(--f-theme-05)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td.f-datepicker-range::before{position:absolute;top:3px;right:0;bottom:3px;left:0;display:block;background:var(--f-neutral-10);border:0;border-radius:0;content:""}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-markdate{position:absolute;top:5px;left:5px;width:4px;height:4px;border-radius:50%}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-date,.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-month,.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-year{display:block;padding:0;margin:0 auto;text-align:center;background:0 0;border-radius:2px;transition:all .3s ease;cursor:pointer}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-date:active,.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-month:active,.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-year:active{color:var(--f-theme-01)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-date{width:28px;height:28px;line-height:28px;position:relative;z-index:1;border:1px solid transparent;border-radius:100%}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-month-cell,.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-year-cell{display:inline-block;padding:3px 8px;line-height:20px;border-radius:100%;border:1px solid transparent}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-current{border:1px solid var(--f-theme-03);color:var(--f-theme-03);background:#fff;box-shadow:0 0 4px 2px rgba(var(--f-theme-03),.12)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-range{color:var(--f-theme-03);border:1px solid var(--f-aid-02);background:var(--f-aid-02)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-selected{border:1px solid transparent;background:linear-gradient(214deg,#3F65FF 0,#4D9AFF 100%);color:#fff;border-radius:100%;box-shadow:0 2px 6px 0 rgba(var(--f-theme-03),.4)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-selected:hover{color:#fff}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-highlight{background:#75abf2;color:#fff}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-highlight:hover{color:#fff}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td.f-datepicker-no-currmonth{color:var(--f-text-07)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-disabled{background-color:var(--f-neutral-09);color:var(--f-text-07)}.f-datepicker-container .f-datepicker-content .f-datepicker-table-wrapper .f-datepicker-table td .f-datepicker-disabled:hover{color:var(--f-text-07)}.f-datepicker-container .datepicker-content-has-timer .time-picker-panel{display:flex;bottom:0}.f-datepicker-container .datepicker-content-has-timer .time-picker-panel .farris-timer-picker{display:flex;flex:1 1 0}.f-datepicker-container .datepicker-content-has-timer .time-picker-panel .farris-timer-picker .time-picker-panel-inner{box-shadow:none;display:flex;flex:1 1 0}.f-datepicker-container .datepicker-content-has-timer .time-picker-panel .farris-timer-picker .time-picker-panel-inner .time-picker-panel-combobox{flex:1 1 0;overflow:hidden}.f-datepicker-container .datepicker-content-has-timer .time-picker-panel .farris-timer-picker .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select{height:100%;max-height:none}.f-datepicker-container .f-datepicker-commitBtn-wrapper{width:100%;text-align:right;height:2.8125rem;display:flex;align-items:center;padding:0 1.5rem;border-top:1px solid var(--f-neutral-13)}.f-datepicker-container .f-datepicker-select-btn{outline:0;border:0;cursor:pointer;flex-shrink:1;flex-grow:1;flex-basis:0}.f-datepicker-container .datepicker-multi-days-wrapper{border-left:1px solid var(--f-neutral-13)}.f-datepicker-multi-selectdays-header{border-bottom:1px solid var(--f-neutral-13)}.f-datepicker-multi-selectdays-clear{color:var(--f-text-09)}.f-datepicker-multi-selectdays-clear:hover{color:var(--f-theme-05)}.f-datepicker-multi-selectdays{color:var(--f-text-02)}.f-datepicker-multi-selectdays:hover{background:var(--f-neutral-10);color:var(--f-text-02)}.f-datepicker-multi-selectdays .remove{color:var(--f-text-09)}.f-datepicker-multi-selectdays .remove:hover{color:var(--f-theme-05)}.f-cmp-datepicker .date-range-wrapper{display:flex;padding-top:0;padding-bottom:0;align-items:center;flex-shrink:1;flex-grow:1;flex-basis:0%;background:0 0}.f-cmp-datepicker .date-range-wrapper .sub-input{outline:0;border:0;height:100%;display:block;width:100%}.f-cmp-datepicker .date-range-wrapper .sub-input.form-control{width:100%;padding:0}.f-cmp-datepicker .date-range-wrapper .sub-input-wrapper-end{flex:1 1 auto}.f-cmp-datepicker .date-range-wrapper .sub-input-wrapper{position:relative}.f-cmp-datepicker .date-range-wrapper .sub-input-wrapper::after{content:"";position:absolute;height:1px;background:var(--f-theme-04);left:0;bottom:0;width:0;transition:all .3s linear}.dropdown,.dropdown-left,.dropdown-submenu,.dropleft,.dropleft-up,.dropright,.dropright-up,.dropup,.dropup-left,.f-filter-wrapper{position:relative}.f-cmp-datepicker .date-range-wrapper .sub-input-spliter{margin:0 4px;flex-shrink:0;line-height:1;font-size:12px;color:var(--f-text-04)}.f-cmp-datepicker .date-range-wrapper .sub-input-wrapper.f-state-focus::after{width:100%}.f-cmp-datepicker .input-group{display:flex}.f-cmp-datepicker .input-group.f-state-focus{border-color:var(--f-theme-08);box-shadow:0 0 0 2px rgba(var(--f-theme-03),.14)}.f-cmp-datepicker .input-group.f-state-disabled,.f-cmp-datepicker .input-group.f-state-readonly{box-shadow:none}@keyframes selectorfadein{from{opacity:0}to{opacity:1}}.f-datepicker-footer{display:flex;justify-content:space-between;border-top:1px solid #e4e7ef}.f-datepicker-footer .f-datepicker-redirect{margin:4px auto;line-height:32px;font-size:1rem}.dropdown-toggle::after,.dropup .dropdown-toggle::after{margin-left:.125rem;content:""}.f-datepicker-footer .f-datepicker-redirect>button{font-size:14px;font-weight:800}.f-dial .f-dial-range,.f-dial .f-dial-value{fill:none}.f-dial .f-dial-text{font-size:1.3rem;text-align:center}.f-discussion-group-edit{border:1px solid var(--f-neutral-04)!important;background:var(--f-neutral-12)!important}.f-discussion-group-edit .f-discussion-group-edit-container .textarea-editor a{color:var(--f-theme-03)}.f-discussion-group-edit .f-discussion-group-edit-footer{background:var(--f-neutral-09)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-item{color:var(--f-text-06)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-item .toolbar-icon{color:var(--f-text-08)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown{background:var(--f-neutral-20)!important;box-shadow:0 2px 20px 0 rgba(3,18,51,.12)!important}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item .f-discussion-group-about-dropdown-list-detail .about-list-detail-text{color:var(--f-text-02)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item .f-discussion-group-about-dropdown-list-detail .about-list-detail-subtext{color:var(--f-text-06)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item .f-icon-check,.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item .f-icon-tick::before{border:1px solid var(--f-neutral-02);color:#fff}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item.active .f-icon-check,.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item.active .f-icon-tick::before{background:linear-gradient(214deg,#3F65FF 0,#4D9AFF 100%)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item .about-list-item-avatar-tip{background-color:linear-gradient(214deg,#3F65FF 0,#4D9AFF 100%);color:#fff}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-discussion-group-about-dropdown-list-item:not(.about-dropdown-list-item-empty):hover{background:var(--f-neutral-11)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-about .f-discussion-group-about-dropdown .f-about-list-btns{border-top:1px solid var(--f-neutral-06)!important;background:var(--f-neutral-09)!important}.f-discussion-dialog-content-left .f-discussion-tab-content,.f-discussion-dialog-content-right{border:1px solid var(--f-neutral-04)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-dropdown .toolbar-icon{color:var(--f-text-09)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-dropdown .toolbar-dropdown-list{background:0 2px 20px 0 rgba(3,18,51,.12);box-shadow:var(--f-neutral-20)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-toolbar .f-discussion-group-edit-toolbar-dropdown .toolbar-dropdown-list ul li:hover{background:var(--f-neutral-11)}.f-discussion-group-edit .f-discussion-group-edit-footer .f-discussion-group-edit-btns .f-discussion-cancel,.farris-discussion-group-reply-tip{color:var(--f-text-04)}.f-discussion-dialog-content-left .f-discussion-tab-content .f-discussion-personnel-content .f-discussion-personnel-crumbs .crumbs-list-item{color:var(--f-text-02)}.f-discussion-dialog-content-left .f-discussion-tab-content .f-discussion-personnel-content .f-discussion-personnel-crumbs .crumbs-list-item.crumbs-list-item-disabled{color:var(--f-text-07)}.f-discussion-dialog-content-right .f-discussion-selected-personnel-header{background:var(--f-neutral-09)}.f-discussion-dialog-content-right .f-discussion-selected-personnel-content .f-discussion-selected-list .f-discussion-selected-item-text .f-discussion-selected-name{color:var(--f-text-02)}.f-discussion-dialog-content-right .f-discussion-selected-personnel-content .f-discussion-selected-list .f-discussion-selected-item-tip{color:var(--f-text-09)}.f-discussion-dialog-content-right .f-discussion-selected-personnel-content .f-discussion-selected-list .f-discussion-selected-item-remove{color:var(--f-theme-05)}.f-discussion-dialog-content-right .f-discussion-selected-personnel-content .f-discussion-selected-list .f-discussion-selected-item:hover{background:var(--f-neutral-11)}.f-discussion-dialog-content .f-discussion-personnel-item:hover,.f-listview-active .f-tmpl-card--header-multicontent01,.f-listview-active .f-tmpl-list--columns01{background:var(--f-aid-03)}.f-discussion-dialog-content .f-discussion-personnel-item-text .f-discussion-personnel-name{color:var(--f-text-01)}.f-discussion-dialog-content .f-discussion-personnel-item-text .f-discussion-personnel-mail{color:var(--f-text-06)}.f-discussion-dialog-content .f-discussion-personnel-item.active,.f-discussion-dialog-content .f-discussion-personnel-item.selected{background:var(--f-aid-02)}.f-discussion-dialog-content .f-discussion-personnel-item.selected .f-discussion-personnel-mail,.f-discussion-dialog-content .f-discussion-personnel-item.selected .f-discussion-personnel-name{color:#c1c1c1}.f-discussion-dialog-content .f-discussion-section-list-empty .f-icon{color:var(--f-text-08)}.f-discussion-dialog-content .f-discussion-section-list-empty .section-list-empty-text{color:var(--f-text-09)}.f-discussion-dialog-content .f-discussion-personnel-item-tip{color:#fff;background-color:#4796FF}.f-discussion-dialog-content .f-discussion-section-list .section-list-item-name{color:var(--f-text-02);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.f-discussion-dialog-content .f-discussion-section-list .section-list-item-next{color:var(--f-theme-03)}.f-discussion-dialog-content .f-discussion-section-list .section-list-item-next::before{background:var(--f-neutral-06)}.f-discussion-dialog-content .f-discussion-section-list .section-list-item:hover{background:var(--f-neutral-11)}.f-discussion-dialog-content .f-discussion-section-list .person-list-item-content .section-list-item-name{color:var(--f-text-02)}.f-discussion-dialog-content .f-discussion-section-list .person-list-item-content .section-list-item-tip{color:var(--f-text-09)}.f-discussion-person-list-page .section-page-text{color:var(--f-text-05)}.f-discussion-person-list-page:hover .section-page-text{color:var(--f-text-02)}.f-discussion-group-content-item .discussion-item-avatar-tip{color:var(--f-text-00);background-color:var(--f-theme-05)}.f-discussion-group-content-item .discussion-item-inner{border-bottom:1px solid var(--f-neutral-06)}.f-discussion-group-content-item .discussion-item-inner .discussion-item-username{color:var(--f-text-02)}.f-discussion-group-content-item .discussion-item-inner .discussion-item-text,.f-discussion-group-content-item .discussion-item-inner .discussion-item-text-reply-content,.f-discussion-group-content-item .discussion-item-inner .discussion-item-text-reply-title{color:var(--f-text-04)}.f-discussion-group-content-item .discussion-item-inner .discussion-item-text-reply{background:var(--f-neutral-09)!important;border-radius:6px!important}.f-discussion-group-content-item .discussion-item-inner .discussion-item-text-reply-title .discussion-item-text-reply-name{color:rgba(var(--f-theme-05),.8)}.f-discussion-group-content-item .discussion-item-inner .discussion-item-footer .discussion-item-time{color:var(--f-text-09)}.f-discussion-group-content-item .discussion-item-inner .discussion-item-footer .discussion-item-btns .discussion-item-btns-start .discussion-item-btns-start-text,.f-discussion-group-content-item .discussion-item-inner .discussion-item-footer .discussion-item-btns .discussion-item-btns-start .f-icon{color:var(--f-text-12)!important}.f-discussion-group-content-item .discussion-item-inner .discussion-item-footer .discussion-item-btns .discussion-item-btns-start:hover .discussion-item-btns-start-text,.f-discussion-group-content-item .discussion-item-inner .discussion-item-footer .discussion-item-btns .discussion-item-btns-start:hover .f-icon{color:var(--f-theme-05)!important}.f-discussion-group-content-item .discussion-item-inner .discussion-item-footer .discussion-item-btns .discussion-item-btns-start:active .discussion-item-btns-start-text,.f-discussion-group-content-item .discussion-item-inner .discussion-item-footer .discussion-item-btns .discussion-item-btns-start:active .f-icon{color:var(--f-theme-01)!important}.f-discussion-group-content-item .discussion-item-inner .discussion-item-text .discussion-item-text-message a{color:var(--f-theme-03)!important}.f-discussion-group-content-item .discussion-item-inner .discussion-item-text .discussion-item-text-message a:hover{color:var(--f-theme-05)!important}.f-discussion-group-content-item .discussion-item-inner .discussion-item-text .discussion-item-text-message a:active{color:var(--f-theme-01)!important}.dropdown-toggle::after{display:inline-block;width:0;height:0;vertical-align:.125rem;border-top:.25rem solid;border-right:.25rem solid transparent;border-bottom:0;border-left:.25rem solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:300;display:none;float:left;min-width:10rem;padding:.25rem;margin:.25rem 0;font-size:.8125rem;color:var(--f-text-02);text-align:left;list-style:none;background-color:var(--f-neutral-20);background-clip:padding-box;border:0 solid rgba(0,0,0,.15);border-radius:6px;box-shadow:0 2px 20px 0 rgba(3,18,51,.12)}.dropup .dropdown-toggle::after,.dropup-left .dropdown-toggle::after{display:inline-block;width:0;height:0;vertical-align:.125rem;border-right:.25rem solid transparent;border-bottom:.25rem solid;border-left:.25rem solid transparent;border-top:0}.dropdown-menu-right{right:0;left:auto}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.25rem}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropup-left .dropdown-menu{top:auto;right:0;left:auto;bottom:100%;margin-top:0;margin-bottom:.25rem}.dropup-left .dropdown-toggle::after{margin-left:.125rem;content:""}.dropright .dropdown-toggle::after,.dropright-up .dropdown-toggle::after{display:inline-block;border-bottom:.25rem solid transparent;border-left:.25rem solid;vertical-align:0;height:0;content:"";width:0;border-right:0}.dropup-left .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.25rem}.dropright .dropdown-toggle::after{margin-left:.125rem;border-top:.25rem solid transparent}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright-up .dropdown-menu{top:auto;right:auto;left:100%;bottom:0;margin-top:0;margin-left:.25rem}.dropright-up .dropdown-toggle::after{margin-left:.125rem;border-top:.25rem solid transparent}.dropright-up .dropdown-toggle:empty::after{margin-left:0}.dropleft-up .dropdown-menu{top:auto;right:100%;left:auto;bottom:0;margin-top:0;margin-bottom:.25rem}.dropleft-up .dropdown-toggle::after{width:0;height:0;margin-left:.125rem;vertical-align:.125rem;content:"";display:none}.dropleft .dropdown-toggle::before,.dropleft-up .dropdown-toggle::before{display:inline-block;border-top:.25rem solid transparent;border-right:.25rem solid;border-bottom:.25rem solid transparent;height:0;content:""}.dropleft-up .dropdown-toggle::before{width:0;margin-right:.125rem;vertical-align:0}.dropleft-up .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.25rem}.dropleft .dropdown-toggle::after{width:0;height:0;margin-left:.125rem;vertical-align:.125rem;content:"";display:none}.dropleft .dropdown-toggle::before{width:0;margin-right:.125rem;vertical-align:0}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;overflow:hidden;border-top:1px solid var(--f-neutral-06)}.dropdown-item{display:block;clear:both;font-weight:400;color:var(--f-text-04);text-align:inherit;white-space:nowrap;background-color:transparent;border:0;cursor:pointer;border-radius:6px}.dropdown-item:focus,.dropdown-item:hover{color:var(--f-text-02);text-decoration:none;background-color:var(--f-neutral-11)}.dropdown-item.active,.dropdown-item:active{color:var(--f-text-02);text-decoration:none;background-color:var(--f-neutral-10)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--f-text-09);background-color:transparent;cursor:default}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.25rem .5rem;margin-bottom:0;font-size:.75rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.3125rem .5rem;color:var(--f-text-04)}.dropdown-divider{margin:.25rem 0}.btn-group .btn+.dropdown-toggle-split{margin-left:-1px}.btn-group .btn-primary+.dropdown-toggle-split{margin-left:-1px;border-left-color:var(--f-neutral-06)}.dropdown-item{padding:.25rem .5rem}.dropdown-left>.dropdown-menu{right:0;left:auto}.dropleft>.dropdown-menu{top:0;right:100%;left:auto!important;margin-right:-1px}.dropdown-submenu .dropdown-item.dropdown-toggle{padding-right:1rem}.dropdown-submenu>.dropdown-toggle.dropdown-toggle-split{position:absolute;width:24px;height:24px;top:50%;right:0;left:auto;margin-top:-12px;cursor:pointer;border-radius:4px;text-align:center}.dropdown-submenu>.dropdown-toggle.dropdown-toggle-split:hover{color:var(--f-text-04);background:var(--f-aid-02)}.dropdown-item .btn-link,.dropdown-item .btn-link:hover,.f-btn-icon.f-bare,.f-btn-icon.f-bare.f-state-active,.f-btn-icon.f-bare.f-state-hover,.f-btn-icon.f-bare:active,.f-btn-icon.f-bare:hover,.f-btn-icon.f-bare:hover.f-state-active,.f-btn-icon.f-bare:hover:active{color:inherit}.dropdown-submenu>.dropdown-item.dropdown-toggle::after,.dropdown-submenu>.dropdown-item.dropdown-toggle::before{position:absolute;top:50%;right:9px;left:auto;margin-top:-4px}.dropdown-submenu.dropleft>.dropdown-item.dropdown-toggle::before,.dropdown-submenu.dropright>.dropdown-item.dropdown-toggle::before{margin-top:-.25rem}.btn-group .btn-secondary+.dropdown-toggle-split,.dropright>.dropdown-menu{margin-left:-1px}.f-response-content .dropdown-item.f-rt-btn,.f-response-content .dropdown-item.f-rt-toggle{cursor:pointer}.f-response-content .dropdown-item.f-rt-btn.disabled,.f-response-content .dropdown-item.f-rt-toggle.disabled{cursor:default}.farris-dropdown.btn-group .dropdown-menu{max-height:unset!important;width:unset!important}.f-filter-footer .footer-container,.f-sort-editor .footer-container{height:2rem;min-height:2rem;background-color:var(--f-neutral-07);line-height:2rem;flex-shrink:0}.f-list-filter .filter-expand{color:var(--f-text-07);cursor:pointer}.f-list-filter .filter-expand:hover{color:var(--f-theme-05)}.f-list-filter .filter-expand.active{color:var(--f-theme-03);background:rgba(var(--f-theme-05),.1)}.f-list-filter .filter-expand .filter-expand-tag{background-color:var(--f-semantic-danger-01)}.f-list-filter .filter-inputs-extend{border:none;background:var(--f-neutral-20)}.f-filter-wrapper .f-filter-inputs-extend .f-filter-typelist-arrow,.f-list-filter .filter-inputs-extend .filter-typelist-arrow{border-top-color:var(--f-neutral-20);border-right-color:transparent;border-bottom-color:transparent;border-left-color:var(--f-neutral-20)}.f-list-filter .filter-inputs-extend .filter-typelist-arrow{background:0 0;box-shadow:-2px -2px 5px rgba(0,0,0,.08)}.f-list-filter .filter-inputs-extend .filter-form-btns .filter-form-btn-reset::after{background:var(--f-neutral-06)}.f-list-filter .filter-search-btn-reset{color:var(--f-text-04)}.f-list-filter .filter-search-btn-reset:hover{color:var(--f-theme-05)}.f-list-filter .filter-inputs-extend{box-shadow:0 0 5px 0 rgba(0,0,0,.15)!important;border-radius:10px}.f-filter{display:block;flex-grow:1;flex-shrink:1;flex-basis:0;max-width:100%}.f-filter-wrapper,.f-filter-wrapper .f-filter-wrapper-inner{display:flex;align-items:flex-start}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn{display:flex;align-items:center;flex-shrink:0;height:26px;line-height:26px;padding-left:10px}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn .extend-btn-text{margin-right:2px}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn .extend-btn-arrow{margin-left:8px}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn-advanced{flex-shrink:0;width:24px;height:24px;margin-left:21px;line-height:24px;color:var(--f-text-07);cursor:pointer}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn-advanced:hover{color:var(--f-theme-05)}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn-advanced.active{box-shadow:0 2px 5px 0 rgba(0,0,0,.15);color:var(--f-theme-01);background:rgba(var(--f-theme-03),.1);border-radius:2px}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn-advanced .f-icon{display:block;line-height:24px;margin:0 auto;font-size:18px}.f-filter-wrapper .f-filter-wrapper-inner .f-filter-extend-btn-advanced .filter-expand-tag{position:absolute;right:0;top:0;display:block;width:6px;height:6px;background-color:#f5222d;border-radius:50%}.f-filter-wrapper .f-filter-inputs-extend{width:429px;right:0;top:38px;border-radius:10px;background-color:var(--f-neutral-20);box-shadow:0 0 5px 0 rgba(0,0,0,.15);z-index:101;padding:20px 0}.f-filter-wrapper .f-filter-inputs-extend .f-filter-typelist-arrow{display:block;position:absolute;right:7px;top:-4px;width:8.49px;height:8.49px;background:0 0;border-style:solid;border-width:4.24px;box-shadow:-2px -2px 5px rgba(0,0,0,.08);transform:translateX(-50%) rotate(45deg)}.f-filter-wrapper .f-filter-inputs-extend .f-filter-form-btns{margin-top:6px;padding:0 14px}.f-filter-wrapper .f-filter-inputs-extend .f-filter-form-btns .btn{margin-left:6px}.f-filter-wrapper .f-filter-inputs-extend .f-filter-form-btns .filter-form-btn-reset{position:relative;padding-right:10px;margin-right:4px}.f-filter-wrapper .f-filter-inputs-extend .f-filter-form-btns .filter-form-btn-reset::after{content:"";position:absolute;right:0;top:50%;width:1px;height:16px;margin-top:-8px;background:#d9d9d9}.f-filter-wrapper .f-filter-main{display:flex;justify-content:space-between}.f-filter-wrapper .f-filter-main .f-filter-list-wrapper{max-width:100%;margin-right:26px;overflow:hidden}.f-filter-wrapper .f-filter-list{display:flex;align-items:center;flex-wrap:nowrap;height:26px}.f-filter-wrapper .f-filter-list .f-filter-item{display:flex;align-items:center;flex-shrink:0;position:relative;height:26px;line-height:26px;margin-right:8px;font-size:13px;color:var(--f-text-02);border:1px solid #fff;border-radius:3px;cursor:pointer}.f-filter-wrapper .f-filter-list .f-filter-item-text{flex-shrink:0;color:var(--f-text-04)}.f-filter-wrapper .f-filter-list .f-filter-item-content{margin-left:4px;color:var(--f-text-02);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.f-filter-wrapper .f-filter-list .f-filter-item-arrow{flex-shrink:0;margin-left:8px;color:var(--f-text-04)}.f-filter-wrapper .f-filter-list .f-filter-item.f-filter-item-edit,.f-filter-wrapper .f-filter-list .f-filter-item:hover{background:rgba(var(--f-aid-05),.35);border-color:var(--f-aid-05)}.f-filter-wrapper .f-filter-list .f-filter-item.f-filter-item-actived{background:rgba(var(--f-aid-05),.35);border:1px solid var(--f-aid-05);border-radius:3px}.f-filter-wrapper .f-filter-list .f-filter-item.f-filter-item-actived:hover .f-filter-item-clear{display:flex}.f-filter-wrapper .f-filter-list .f-filter-item.f-filter-item-actived:hover .f-filter-item-arrow{opacity:0}.f-filter-wrapper .f-filter-list .f-filter-item-clear{display:none;flex-direction:column;justify-content:center;position:absolute;right:2px;top:0;bottom:0;cursor:pointer}.f-filter-wrapper .f-filter-list .f-filter-item-clear .f-icon{font-size:12px;color:#6388FF}.f-filter-wrapper .f-filter-list .f-filter-item-required{flex-shrink:0;margin-right:2px}.f-filter-wrapper .f-filter-list.f-filter-list-extend .f-filter-item-last,.f-filter-wrapper .f-filter-toolbars .btn,.form-group--has-tips .farris-input-wrap{margin-right:18px}.f-filter-wrapper .f-filter-list .f-filter-item-inner{display:flex;align-items:center;max-width:286px}.f-filter-wrapper .f-filter-list.f-filter-list-extend{height:auto;flex-wrap:wrap}.f-filter-wrapper .f-filter-list.f-filter-list-extend .f-filter-item{margin-bottom:6px}.f-filter-wrapper .f-filter-list-ellipsis{flex-shrink:0;width:48px;height:26px;line-height:20px;padding-right:18px;text-align:center;cursor:pointer}.f-filter-wrapper .f-filter-toolbars{flex-shrink:0;display:flex;align-items:center;padding:3px 0}.f-filter-wrapper .f-filter-list-extend .f-filter-toolbars{margin-bottom:8px}.f-filter-wrapper .f-filter-item-reminder{position:absolute;top:calc(100% - 6px);left:0;padding-top:11px;z-index:100}.f-filter-wrapper .f-filter-item-reminder .reminder-arrow{position:absolute;top:2px;left:10%}.f-filter-wrapper .f-filter-item-reminder .reminder-arrow::after{position:absolute;top:2px;display:block;content:"";border-color:transparent;border-style:solid;border-width:0 6px 8px;border-bottom-color:var(--f-theme-03)}.f-filter-wrapper .f-filter-item-reminder .reminder-inner{padding:8px 12px;font-size:13px;color:#fff;white-space:nowrap;background:linear-gradient(46deg,#2E77FF 0,#2A87FF 100%);box-shadow:2px 2px 8px 0 rgba(0,0,0,.14);border-radius:10px}.f-filter-wrapper .f-filter-item-reminder .reminder-inner .f-icon{margin-right:6px;font-size:13px}.f-filter-panel-form .filter-type-checkboxgroup .farris-form-group .farris-input-wrap .custom-checkbox,.f-filter-panel-form .filter-type-radio .farris-form-group .farris-input-wrap .custom-radio{margin-bottom:0;margin-top:0}.f-filter-panel-form .filter-type-checkboxgroup .farris-form-group .farris-input-wrap .custom-checkbox:last-child,.f-filter-panel-form .filter-type-radio .farris-form-group .farris-input-wrap .custom-radio:last-child{margin-bottom:0}.f-filter-panel-form .filter-type-checkboxgroup .farris-form-group .farris-input-wrap .custom-checkbox .custom-control-label,.f-filter-panel-form .filter-type-radio .farris-form-group .farris-input-wrap .custom-radio .custom-control-label{display:block;width:100%;line-height:30px}.f-filter-panel-form .filter-type-checkboxgroup .farris-form-group .farris-input-wrap .custom-checkbox .custom-control-label::before,.f-filter-panel-form .filter-type-radio .farris-form-group .farris-input-wrap .custom-radio .custom-control-label::before{top:8px}.f-filter-panel-form .filter-type-checkboxgroup .farris-form-group .farris-input-wrap .custom-checkbox:hover,.f-filter-panel-form .filter-type-radio .farris-form-group .farris-input-wrap .custom-radio:hover{background-color:var(--f-neutral-11)}.f-sidebar-filter-main .f-sidebar-filter-footer{display:flex;align-items:center;justify-content:space-between!important;height:72px!important;padding:10px 24px!important;border-top:1px dashed #eaedf3!important;background:var(--f-neutral-00)!important}.f-sidebar-filter-main .f-sidebar-header .f-tmpl-for-title-withline::before{display:none}.f-sidebar-filter-main .f-sidebar-filter-content{padding:24px 48px 24px 12px!important}.f-sidebar-filter-main .f-sidebar-filter-content .farris-form-controls-inline .farris-group-wrap .form-group{margin-bottom:10px}.f-sidebar-filter-main .f-sidebar-filter-btns .btn{height:32px;margin-right:12px}.f-sidebar-filter-main .f-sidebar-filter-btns .f-sidebar-filter-btn-confirm{padding-left:66px;padding-right:66px;margin-right:0}.f-filter-inputs-extend-list .form-group,.f-sidebar-filter-list .form-group{display:block}.f-filter-inputs-extend-list.farris-form-controls-inline .form-group,.f-sidebar-filter-list.farris-form-controls-inline .form-group{display:flex}.f-filter-panel-flexible-icon{flex-shrink:0;margin:0 6px;font-size:14px;color:#999}.f-filter-panel-wrapper{position:fixed;z-index:1050;top:0;left:0;height:100%;width:100%;pointer-events:auto}.f-filter-panel{position:absolute;z-index:100;padding-top:14px}.f-filter-panel-header{display:flex;justify-content:space-between;align-items:center}.f-filter-panel-header .panel-header-title{line-height:22px;font-size:15px;color:rgba(0,0,0,.85);font-weight:600}.f-filter-panel-content{padding-top:8px}.f-filter-panel-content .filter-type-checkboxgroup{max-height:216px;padding:6px 8px 6px 0;border-radius:2px;overflow-y:auto}.f-filter-panel-content .filter-type-checkboxgroup .custom-checkbox{padding-left:14px}.f-filter-panel-footer{display:flex;justify-content:space-between;padding-top:16px;align-items:center}.f-filter-panel-footer .filter-panel-submit{padding-left:22px;padding-right:22px;margin-left:8px}.f-filter-panel-footer .btn-link{padding-right:8px}.f-filter-panel-footer .btn-empty{position:relative;padding-left:8px}.f-filter-panel-footer .btn-empty::before{position:absolute;left:0;top:50%;width:1px;height:16px;margin-top:-8px;background-color:var(--f-neutral-08);content:""}.f-filter-panel .f-filter-panel-inner{position:relative;min-width:380px;padding:14px 24px 18px;background:var(--f-neutral-20);box-shadow:0 2px 12px 0 rgba(31,35,41,.1);border-radius:10px}.f-filter-panel .f-filter-panel-inner.f-filter-panel-inner-xs{padding:10px 4px 16px}.f-filter-panel .f-filter-panel-inner.f-filter-panel-inner-auto{min-width:auto;padding:0}.f-filter-panel-arrow{position:absolute;top:-12px;left:26px}.f-filter-panel-arrow::after{position:absolute;top:2px;display:block;content:"";border-color:transparent;border-style:solid;border-width:0 8px 10px;border-bottom-color:var(--f-neutral-20)}.f-filter-panel.f-filter-panel-radio .f-filter-panel-inner{min-width:230px}.f-filter-panel .f-panel-filter-tip{display:flex;align-items:center;margin-bottom:12px}.f-filter-panel .f-panel-filter-tip .panel-filter-tip-text{margin-right:8px}.f-filter-panel .panel-flexible-range-wrapper{align-items:center}.f-filter-panel .panel-flexible-range-wrapper .f-icon{flex-shrink:0;margin:0 8px;font-size:14px;color:#999}.f-filter-panel .panel-flexible-range-wrapper .f-cmp-datepicker,.f-filter-panel .panel-flexible-range-wrapper .f-cmp-number-spinner{width:150px}.f-filter-panel-date-tags{display:flex;flex-direction:row;align-items:center;padding-top:12px}.f-filter-panel-date-tags .panel-date-tag{height:24px;line-height:22px;padding:0 14px;margin-right:8px;font-size:12px;background-color:var(--f-neutral-00);border:1px solid var(--f-neutral-08);border-radius:13px;cursor:pointer}.f-filter-panel-date-tags .panel-date-tag.active{background:rgba(var(--f-theme-03),.09);border:1px solid}.filter-panel-checkbox{width:100%;height:30px;line-height:30px;margin:0;padding-right:0;background:var(--f-neutral-09)}.filter-panel-checkbox .custom-control-label{display:block;cursor:pointer;width:100%}.filter-panel-checkbox .custom-control-label::before{top:50%;transform:translateY(-50%)}.f-filter-panel-radiogroup .panel-radiogroup-item{display:flex;align-items:center;padding:.5rem 1.375rem;border:0;cursor:pointer}.f-filter-panel-radiogroup .panel-radiogroup-item.panel-radiogroup-item-active{color:var(--f-text-02);background:var(--f-neutral-10);border-radius:3px}.f-filter-panel-radiogroup .panel-radiogroup-item-text{font-size:14px;line-height:18px}.f-filter-panel-radiogroup .panel-radiogroup-item:hover{color:var(--f-text-02);background-color:var(--f-neutral-11)}.f-filter-search-result-panel{position:absolute;left:0;top:26px;z-index:100;width:200px;padding:8px;color:rgba(0,0,0,.85);background-color:#fff;box-shadow:0 2px 12px 0 rgba(31,35,41,.1);border-radius:4px}.f-filter-search-result-panel .search-result-title{line-height:22px;font-size:14px;font-weight:600}.f-filter-search-result-panel .search-result-list .search-result-item{line-height:26px;font-size:14px;cursor:pointer;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.f-filter-search-result-panel .search-result-list .search-result-item:hover{background:rgba(42,135,255,.06)}.f-filter-panel-search-tags{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap;max-width:320px;padding-top:12px}.f-filter-panel-search-tags .panel-search-tag{display:flex;align-items:center;height:24px;line-height:22px;margin-right:8px;margin-bottom:8px;font-size:12px;color:#333;background-color:#fff;border:1px solid rgba(216,220,230,.6);border-radius:2px;cursor:pointer}.f-filter-panel-search-tags .panel-search-tag:last-child{margin-right:0}.f-filter-panel-search-tags .panel-search-tag .panel-search-tag-text{max-width:72px;padding-left:8px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.f-filter-panel-search-tags .panel-search-tag .panel-search-tag-remove{height:22px;line-height:22px;margin-left:6px;margin-right:8px;font-size:14px;color:#999;cursor:pointer}.f-filter-panel-search-tags .panel-search-tag:active{background:rgba(42,135,255,.06);border:1px solid rgba(42,135,255,.16)}.f-filter-container{padding-bottom:12px}.f-filter-wrapper .f-filter-list .f-filter-item{padding:0 20px 0 12px!important}.f-filter-wrapper .f-filter-list .f-filter-item-clear{padding:0 2px!important}.container,.container-fluid{padding-right:14px;padding-left:14px;margin-right:auto;margin-left:auto;width:100%}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:888px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.row{display:flex;flex-wrap:wrap;margin-right:-14px;margin-left:-14px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-el,.col-el-1,.col-el-10,.col-el-11,.col-el-12,.col-el-2,.col-el-3,.col-el-4,.col-el-5,.col-el-6,.col-el-7,.col-el-8,.col-el-9,.col-el-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:14px;padding-left:14px}.col{flex-basis:0;flex-grow:1;max-width:100%}.col-auto{flex-grow:0;flex-shrink:0;flex-basis:auto;width:auto;max-width:none}.col-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.col-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.col-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.col-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.col-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.col-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.col-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.col-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.col-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.col-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.col-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.col-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.3333333333%}.offset-2{margin-left:16.6666666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.3333333333%}.offset-5{margin-left:41.6666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.3333333333%}.offset-8{margin-left:66.6666666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.3333333333%}.offset-11{margin-left:91.6666666667%}.f-area-response [class*=col-xs]{flex:none;max-width:none}.f-area-response.f-area-response--xs .col-xs-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.f-area-response.f-area-response--xs .col-xs-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.f-area-response.f-area-response--xs .col-xs-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.f-area-response.f-area-response--xs .col-xs-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.f-area-response.f-area-response--xs .col-xs-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.f-area-response.f-area-response--xs .col-xs-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.f-area-response.f-area-response--xs .col-xs-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.f-area-response.f-area-response--xs .col-xs-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.f-area-response.f-area-response--xs .col-xs-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.f-area-response.f-area-response--xs .col-xs-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.f-area-response.f-area-response--xs .col-xs-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.f-area-response.f-area-response--xs .col-xs-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}@media (min-width:576px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.col-sm-auto{flex-grow:0;flex-shrink:0;flex-basis:auto;width:auto;max-width:none}.col-sm-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.col-sm-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.col-sm-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.col-sm-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.col-sm-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.col-sm-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.col-sm-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.col-sm-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.col-sm-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.col-sm-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.col-sm-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.col-sm-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.3333333333%}.offset-sm-2{margin-left:16.6666666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.3333333333%}.offset-sm-5{margin-left:41.6666666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.3333333333%}.offset-sm-8{margin-left:66.6666666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.3333333333%}.offset-sm-11{margin-left:91.6666666667%}}.f-area-response [class*=col-sm]{flex:none;max-width:none}.f-area-response.f-area-response--sm .col-sm-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.f-area-response.f-area-response--sm .col-sm-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.f-area-response.f-area-response--sm .col-sm-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.f-area-response.f-area-response--sm .col-sm-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.f-area-response.f-area-response--sm .col-sm-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.f-area-response.f-area-response--sm .col-sm-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.f-area-response.f-area-response--sm .col-sm-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.f-area-response.f-area-response--sm .col-sm-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.f-area-response.f-area-response--sm .col-sm-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.f-area-response.f-area-response--sm .col-sm-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.f-area-response.f-area-response--sm .col-sm-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.f-area-response.f-area-response--sm .col-sm-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}@media (min-width:768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.col-md-auto{flex-grow:0;flex-shrink:0;flex-basis:auto;width:auto;max-width:none}.col-md-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.col-md-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.col-md-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.col-md-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.col-md-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.col-md-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.col-md-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.col-md-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.col-md-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.col-md-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.col-md-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.col-md-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.3333333333%}.offset-md-2{margin-left:16.6666666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.3333333333%}.offset-md-5{margin-left:41.6666666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.3333333333%}.offset-md-8{margin-left:66.6666666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.3333333333%}.offset-md-11{margin-left:91.6666666667%}}.f-area-response [class*=col-md]{flex:none;max-width:none}.f-area-response.f-area-response--md .col-md-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.f-area-response.f-area-response--md .col-md-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.f-area-response.f-area-response--md .col-md-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.f-area-response.f-area-response--md .col-md-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.f-area-response.f-area-response--md .col-md-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.f-area-response.f-area-response--md .col-md-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.f-area-response.f-area-response--md .col-md-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.f-area-response.f-area-response--md .col-md-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.f-area-response.f-area-response--md .col-md-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.f-area-response.f-area-response--md .col-md-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.f-area-response.f-area-response--md .col-md-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.f-area-response.f-area-response--md .col-md-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}@media (min-width:888px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.col-lg-auto{flex-grow:0;flex-shrink:0;flex-basis:auto;width:auto;max-width:none}.col-lg-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.col-lg-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.col-lg-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.col-lg-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.col-lg-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.col-lg-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.col-lg-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.col-lg-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.col-lg-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.col-lg-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.col-lg-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.col-lg-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.3333333333%}.offset-lg-2{margin-left:16.6666666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.3333333333%}.offset-lg-5{margin-left:41.6666666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.3333333333%}.offset-lg-8{margin-left:66.6666666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.3333333333%}.offset-lg-11{margin-left:91.6666666667%}}.f-area-response [class*=col-lg]{flex:none;max-width:none}.f-area-response.f-area-response--lg .col-lg-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.f-area-response.f-area-response--lg .col-lg-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.f-area-response.f-area-response--lg .col-lg-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.f-area-response.f-area-response--lg .col-lg-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.f-area-response.f-area-response--lg .col-lg-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.f-area-response.f-area-response--lg .col-lg-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.f-area-response.f-area-response--lg .col-lg-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.f-area-response.f-area-response--lg .col-lg-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.f-area-response.f-area-response--lg .col-lg-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.f-area-response.f-area-response--lg .col-lg-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.f-area-response.f-area-response--lg .col-lg-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.f-area-response.f-area-response--lg .col-lg-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}@media (min-width:1200px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.col-xl-auto{flex-grow:0;flex-shrink:0;flex-basis:auto;width:auto;max-width:none}.col-xl-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.col-xl-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.col-xl-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.col-xl-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.col-xl-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.col-xl-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.col-xl-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.col-xl-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.col-xl-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.col-xl-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.col-xl-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.col-xl-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.3333333333%}.offset-xl-2{margin-left:16.6666666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.3333333333%}.offset-xl-5{margin-left:41.6666666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.3333333333%}.offset-xl-8{margin-left:66.6666666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.3333333333%}.offset-xl-11{margin-left:91.6666666667%}}.f-area-response [class*=col-xl]{flex:none;max-width:none}.f-area-response.f-area-response--xl .col-xl-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.f-area-response.f-area-response--xl .col-xl-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.f-area-response.f-area-response--xl .col-xl-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.f-area-response.f-area-response--xl .col-xl-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.f-area-response.f-area-response--xl .col-xl-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.f-area-response.f-area-response--xl .col-xl-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.f-area-response.f-area-response--xl .col-xl-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.f-area-response.f-area-response--xl .col-xl-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.f-area-response.f-area-response--xl .col-xl-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.f-area-response.f-area-response--xl .col-xl-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.f-area-response.f-area-response--xl .col-xl-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.f-area-response.f-area-response--xl .col-xl-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}@media (min-width:1690px){.col-el{flex-basis:0;flex-grow:1;max-width:100%}.col-el-auto{flex-grow:0;flex-shrink:0;flex-basis:auto;width:auto;max-width:none}.col-el-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.col-el-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.col-el-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.col-el-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.col-el-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.col-el-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.col-el-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.col-el-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.col-el-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.col-el-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.col-el-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.col-el-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}.order-el-first{order:-1}.order-el-last{order:13}.order-el-0{order:0}.order-el-1{order:1}.order-el-2{order:2}.order-el-3{order:3}.order-el-4{order:4}.order-el-5{order:5}.order-el-6{order:6}.order-el-7{order:7}.order-el-8{order:8}.order-el-9{order:9}.order-el-10{order:10}.order-el-11{order:11}.order-el-12{order:12}.offset-el-0{margin-left:0}.offset-el-1{margin-left:8.3333333333%}.offset-el-2{margin-left:16.6666666667%}.offset-el-3{margin-left:25%}.offset-el-4{margin-left:33.3333333333%}.offset-el-5{margin-left:41.6666666667%}.offset-el-6{margin-left:50%}.offset-el-7{margin-left:58.3333333333%}.offset-el-8{margin-left:66.6666666667%}.offset-el-9{margin-left:75%}.offset-el-10{margin-left:83.3333333333%}.offset-el-11{margin-left:91.6666666667%}}.f-area-response [class*=col-el]{flex:none;max-width:none}.f-area-response.f-area-response--el .col-el-1{flex-grow:0;flex-shrink:0;flex-basis:8.3333333333%;max-width:8.3333333333%}.f-area-response.f-area-response--el .col-el-2{flex-grow:0;flex-shrink:0;flex-basis:16.6666666667%;max-width:16.6666666667%}.f-area-response.f-area-response--el .col-el-3{flex-grow:0;flex-shrink:0;flex-basis:25%;max-width:25%}.f-area-response.f-area-response--el .col-el-4{flex-grow:0;flex-shrink:0;flex-basis:33.3333333333%;max-width:33.3333333333%}.f-area-response.f-area-response--el .col-el-5{flex-grow:0;flex-shrink:0;flex-basis:41.6666666667%;max-width:41.6666666667%}.f-area-response.f-area-response--el .col-el-6{flex-grow:0;flex-shrink:0;flex-basis:50%;max-width:50%}.f-area-response.f-area-response--el .col-el-7{flex-grow:0;flex-shrink:0;flex-basis:58.3333333333%;max-width:58.3333333333%}.f-area-response.f-area-response--el .col-el-8{flex-grow:0;flex-shrink:0;flex-basis:66.6666666667%;max-width:66.6666666667%}.f-area-response.f-area-response--el .col-el-9{flex-grow:0;flex-shrink:0;flex-basis:75%;max-width:75%}.f-area-response.f-area-response--el .col-el-10{flex-grow:0;flex-shrink:0;flex-basis:83.3333333333%;max-width:83.3333333333%}.f-area-response.f-area-response--el .col-el-11{flex-grow:0;flex-shrink:0;flex-basis:91.6666666667%;max-width:91.6666666667%}.f-area-response.f-area-response--el .col-el-12{flex-grow:0;flex-shrink:0;flex-basis:100%;max-width:100%}@font-face{font-family:FarrisIcons;font-style:normal;font-weight:400;src:url(data:font/ttf;base64,AAEAAAALAIAAAwAwR1NVQiCLJXoAAAE4AAAAVE9TLzI2JE+JAAABjAAAAGBjbWFwTohH7gAAC/AAACWUZ2x5ZqfrFDEAADaIAAH0DGhlYWQnvvaKAAAA4AAAADZoaGVhCNUHTgAAALwAAAAkaG10eApz/50AAAHsAAAKBGxvY2GWVxNEAAAxhAAABQRtYXhwA6wBEAAAARgAAAAgbmFtZchH0mwAAiqUAAACi3Bvc3QSpDltAAItIAAAK3cAAQAAA4D/gABcBVX/9v/3BQAAAQAAAAAAAAAAAAAAAAAAAoEAAQAAAAEAAGP+/t1fDzz1AAsEAAAAAADh1NlIAAAAAOHU2Uj/9v9xBQADjAAAAAgAAgAAAAAAAAABAAACgQEEACEAAAAAAAIAAAAKAAoAAAD/AAAAAAAAAAEAAAAKADAAPgACREZMVAAObGF0bgAaAAQAAAAAAAAAAQAAAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAQEAgGQAAUAAAKJAswAAACPAokCzAAAAesAMgEIAAACAAUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBmRWQAwOAA7LcDgP+AAAAD3ACPAAAAAQAAAAAAAAAAAAAAAAACBAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAD//wQA//8EAP//BAD//wQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAQAABAD/+QQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP/5BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP/2BAD/9gQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//kEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAP//BAD//wQA//8EAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEVQAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABEQAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEkgAABJIAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAASSAAAEAAAABJIAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAD//wQAAAAEAAAABAAAAAQAAAAEAP/9BAAAAAQAAAAEAAAABAD//wQA//8EAP/9BAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAREAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQB//8EAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQ8AAAENf/+BAAAAAQA//8EAAAABAD//wQAAAAEAP//BAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQB//4ETgAABAAAAAVVAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAE/wAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAAAAAFAAAAAwAAACwAAAAEAAAHMAABAAAAAAYqAAMAAQAAACwAAwAKAAAHMAAEBf4AAAA4ACAABAAY4DLhSeIO4wrlKuYr5kPmmua85tfnBegs6SLrGOs/60/rb+t/64nrqeu568nr2evp6/nsqey3//8AAOAA4QDiAOMA5QDmAOYt5kXmvObX5wDoAOkA6wTrGutB61HrceuB65rrsOvA69Dr4evw7KDssP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAOACcAS4BSgFeAbICCAI0At4C3gLeAugDQAOEA6wD9gQSBE4EagR6BJgEqgS8BM4E3gTwBQIAAAGPAGsAZgBhAoACfgJ/An0AZwBlAGIAZAJzAnECcgJwAngAYwBsAnwCegJ7AnkAbQBoAGkAagBeAA8AEQAVABMAEgBYAFMCdgJ3AnUBrwBSAFYAUQBZAF0AXwBgAFoCbwBOAFUCXgAEAE8AWwA5ABQAOgA9AAMBrwA/AFwASwJ0AEYAQgBKADwANwA7ADgAPgAKAAgABwBAACECawJsAEgCagHpAm0AKgHoAm4AIwAkACkAJgAWAA0AJQBBAEUATABJAEQARwAoACcAIAAiADYALgAvADIBsAA1Ak4ATQBDAAkCaQBXADQAFwAMADEALQAsADMAMAArAB0AGgAZAAsAHwAbABwAGAAeAAYABQAQAFAAVAGOAYUBiQGMAmgCZwHnAkkCQAGHAYsCSAJHAY0BiAGGAYoBfAGDAX8BgQGCAYABewGEAX4BfQF1AXMBcQFyAXkBdwF6AXQBeAF2AWoBbQFvAWcBaQFsAW4BcAFoAWsBZgFiAV0BZAFfAWEBYwFeAWUBYAFDAUgBSQFAAUIBRgFHAUUBQQFPAVABTQFLAU4BTAFEAVwBWgFbAVYBVAFXAVgBVQFZAVIBUwFKAVEBAAECAQEA/wD6ASYBPQEsATsBOQEvAPsBKgE0APwBBwEJAREBCgEIAQ0BBgEFAQ4BAwEQATMBIQEgAPUAkAE3ARkBMgD4AI4AigEkAI8AiwEXAP0BOgE+AT8BMQD+ARUBEwESAR8A+QEbARQBGAEaATUBIgDzASMBKwELARwBHgEoAScBJQEtATgBNgEEAQwBFgD3APIBKQD0AS4BMAE8AR0BDwCMAI0AngCXAJ8AkQCTAJ0AqACmAKAApwClAKsAnACWAJIAlACbAJoAlQCYAH4AfACjAKQAqgCtAK4AoQB9AIEAiQCHAIQAiACAAIYAhQB7AKkB5wD2AIIAfwCDAG4AegB5AHgAdwB2AHMAdAB1AHIAcQBvAHAArACiAJkA5gDsAOsA7gDpAOoA7wDnAOMA5ADwAO0A5QDoAPEA2QDbANoA4gDcAN4A3QDfAOAA4QDXANAA0wDRANYA1QDUANIAzwDYAMYAzADIAMkAxQDOAMoAxwDNAMsAwQDAAMMAvADCALsAxAC/AL0AvgCwALkArwC1ALQAtgCyALgAsQC6ALcAswJfAlwCYAJmAmUCZAJjAmICYQJdAlsCWgJZAlMCVgJRAlICVAJVAlcCWAJQAk8CTgJNAkwBsAJLAkoCRQJGAkECQgJDAkQCMQIwAj8CPgI9AjwCOwI4AjkCOgIzAjQCNQI2AjcCMgIvAi4CLQIsAisCKgIpAigCJwImAiUCJAIjAiICIAIhAh8CHgIdAhwCGwIaAhkCGAIXAhYCFQIUAhMCEgIRAhACDwIOAg0CDAILAgoCCQIIAgcCBgIFAgQCAwICAgECAAH/Af4B/QH8AfsB+gH5AfgB9wH2AfUB9AHzAfIB8QHwAe8B7gHtAewBrwHrAeoB5gHlAeQB4wHiAeEB4AHfAd4B3QHcAdsB2gHZAdgB1wHWAdUB1AHTAdIB0QHQAc8BzgHNAcwBywHKAckByAHHAcYBxQHEAcMBwgHBAcABvwG+Ab0BvAG7AboBuQG4AbcBtgG1AbQBswGyAbEBsAGvAa4BrQGsAasBqgGpAagBpwGmAaUBpAGjAaIBoQGgAZ8BngGdAZwBmwGWAZUBlAGTAZIBkQGQAZcBmAGZAZoAAgAOAAEAAAEGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAHmQAAAAAAAAChwAA4AAAAOAAAAABjwAA4AEAAOABAAAAawAA4AIAAOACAAAAZgAA4AMAAOADAAAAYQAA4AQAAOAEAAACgAAA4AUAAOAFAAACfgAA4AYAAOAGAAACfwAA4AcAAOAHAAACfQAA4AgAAOAIAAAAZwAA4AkAAOAJAAAAZQAA4AoAAOAKAAAAYgAA4AsAAOALAAAAZAAA4AwAAOAMAAACcwAA4A0AAOANAAACcQAA4A4AAOAOAAACcgAA4A8AAOAPAAACcAAA4BAAAOAQAAACeAAA4BEAAOARAAAAYwAA4BIAAOASAAAAbAAA4BMAAOATAAACfAAA4BQAAOAUAAACegAA4BUAAOAVAAACewAA4BYAAOAWAAACeQAA4BcAAOAXAAAAbQAA4BgAAOAYAAAAaAAA4BkAAOAZAAAAaQAA4BoAAOAaAAAAagAA4BsAAOAbAAAAXgAA4BwAAOAcAAAADwAA4B0AAOAdAAAAEQAA4B4AAOAeAAAAFQAA4B8AAOAfAAAAEwAA4CAAAOAgAAAAEgAA4CEAAOAhAAAAWAAA4CIAAOAiAAAAUwAA4CMAAOAjAAACdgAA4CQAAOAkAAACdwAA4CUAAOAlAAACdQAA4CYAAOAmAAABrwAA4CcAAOAnAAAAUgAA4CgAAOAoAAAAVgAA4CkAAOApAAAAUQAA4CoAAOAqAAAAWQAA4CsAAOArAAAAXQAA4CwAAOAsAAAAXwAA4C0AAOAtAAAAYAAA4C4AAOAuAAAAWgAA4C8AAOAvAAACbwAA4DAAAOAwAAAATgAA4DEAAOAxAAAAVQAA4DIAAOAyAAACXgAA4QAAAOEAAAAABAAA4QEAAOEBAAAATwAA4QIAAOECAAAAWwAA4QMAAOEDAAAAOQAA4QQAAOEEAAAAFAAA4QUAAOEFAAAAOgAA4QYAAOEGAAAAPQAA4QcAAOEHAAAAAwAA4QgAAOEIAAABrwAA4QkAAOEJAAAAPwAA4QoAAOEKAAAAXAAA4QsAAOELAAAASwAA4QwAAOEMAAACdAAA4Q0AAOENAAAARgAA4Q4AAOEOAAAAQgAA4Q8AAOEPAAAASgAA4RAAAOEQAAAAPAAA4REAAOERAAAANwAA4RIAAOESAAAAOwAA4RMAAOETAAAAOAAA4RQAAOEUAAAAPgAA4RUAAOEVAAAACgAA4RYAAOEWAAAACAAA4RcAAOEXAAAABwAA4RgAAOEYAAAAQAAA4RkAAOEZAAAAIQAA4RoAAOEaAAACawAA4RsAAOEbAAACbAAA4RwAAOEcAAAASAAA4R0AAOEdAAACagAA4R4AAOEeAAAB6QAA4R8AAOEfAAACbQAA4SAAAOEgAAAAKgAA4SEAAOEhAAAB6AAA4SIAAOEiAAACbgAA4SMAAOEjAAAAIwAA4SQAAOEkAAAAJAAA4SUAAOElAAAAKQAA4SYAAOEmAAAAJgAA4ScAAOEnAAAAFgAA4SgAAOEoAAAADQAA4SkAAOEpAAAAJQAA4SoAAOEqAAAAQQAA4SsAAOErAAAARQAA4SwAAOEsAAAATAAA4S0AAOEtAAAASQAA4S4AAOEuAAAARAAA4S8AAOEvAAAARwAA4TAAAOEwAAAAKAAA4TEAAOExAAAAJwAA4TIAAOEyAAAAIAAA4TMAAOEzAAAAIgAA4TQAAOE0AAAANgAA4TUAAOE1AAAALgAA4TYAAOE2AAAALwAA4TcAAOE3AAAAMgAA4TgAAOE4AAABsAAA4TkAAOE5AAAANQAA4ToAAOE6AAACTgAA4TsAAOE7AAAATQAA4TwAAOE8AAAAQwAA4T0AAOE9AAAACQAA4T4AAOE+AAACaQAA4T8AAOE/AAAAVwAA4UAAAOFAAAAANAAA4UEAAOFBAAAAFwAA4UIAAOFCAAAADAAA4UMAAOFDAAAAMQAA4UQAAOFEAAAALQAA4UUAAOFFAAAALAAA4UYAAOFGAAAAMwAA4UcAAOFHAAAAMAAA4UgAAOFIAAAAKwAA4UkAAOFJAAAAHQAA4gAAAOIAAAAAGgAA4gEAAOIBAAAAGQAA4gIAAOICAAAACwAA4gMAAOIDAAAAHwAA4gQAAOIEAAAAGwAA4gUAAOIFAAAAHAAA4gYAAOIGAAAAGAAA4gcAAOIHAAAAHgAA4ggAAOIIAAAABgAA4gkAAOIJAAAABQAA4goAAOIKAAAAEAAA4gsAAOILAAAAUAAA4gwAAOIMAAAAVAAA4g0AAOINAAABjgAA4g4AAOIOAAABhQAA4wAAAOMAAAABiQAA4wEAAOMBAAABjAAA4wIAAOMCAAACaAAA4wMAAOMDAAACZwAA4wQAAOMEAAAB5wAA4wUAAOMFAAACSQAA4wYAAOMGAAACQAAA4wcAAOMHAAABhwAA4wgAAOMIAAABiwAA4wkAAOMJAAACSAAA4woAAOMKAAACRwAA5QAAAOUAAAABjQAA5QEAAOUBAAABiAAA5QIAAOUCAAABhgAA5QMAAOUDAAABigAA5QQAAOUEAAABfAAA5QUAAOUFAAABgwAA5QYAAOUGAAABfwAA5QcAAOUHAAABgQAA5QgAAOUIAAABggAA5QkAAOUJAAABgAAA5QoAAOUKAAABewAA5QsAAOULAAABhAAA5QwAAOUMAAABfgAA5Q0AAOUNAAABfQAA5Q4AAOUOAAABdQAA5Q8AAOUPAAABcwAA5RAAAOUQAAABcQAA5REAAOURAAABcgAA5RIAAOUSAAABeQAA5RMAAOUTAAABdwAA5RQAAOUUAAABegAA5RUAAOUVAAABdAAA5RYAAOUWAAABeAAA5RcAAOUXAAABdgAA5RgAAOUYAAABagAA5RkAAOUZAAABbQAA5RoAAOUaAAABbwAA5RsAAOUbAAABZwAA5RwAAOUcAAABaQAA5R0AAOUdAAABbAAA5R4AAOUeAAABbgAA5R8AAOUfAAABcAAA5SAAAOUgAAABaAAA5SEAAOUhAAABawAA5SIAAOUiAAABZgAA5SMAAOUjAAABYgAA5SQAAOUkAAABXQAA5SUAAOUlAAABZAAA5SYAAOUmAAABXwAA5ScAAOUnAAABYQAA5SgAAOUoAAABYwAA5SkAAOUpAAABXgAA5SoAAOUqAAABZQAA5gAAAOYAAAABYAAA5gEAAOYBAAABQwAA5gIAAOYCAAABSAAA5gMAAOYDAAABSQAA5gQAAOYEAAABQAAA5gUAAOYFAAABQgAA5gYAAOYGAAABRgAA5gcAAOYHAAABRwAA5ggAAOYIAAABRQAA5gkAAOYJAAABQQAA5goAAOYKAAABTwAA5gsAAOYLAAABUAAA5gwAAOYMAAABTQAA5g0AAOYNAAABSwAA5g4AAOYOAAABTgAA5g8AAOYPAAABTAAA5hAAAOYQAAABRAAA5hEAAOYRAAABXAAA5hIAAOYSAAABWgAA5hMAAOYTAAABWwAA5hQAAOYUAAABVgAA5hUAAOYVAAABVAAA5hYAAOYWAAABVwAA5hcAAOYXAAABWAAA5hgAAOYYAAABVQAA5hkAAOYZAAABWQAA5hoAAOYaAAABUgAA5hsAAOYbAAABUwAA5hwAAOYcAAABSgAA5h0AAOYdAAABUQAA5h4AAOYeAAABAAAA5h8AAOYfAAABAgAA5iAAAOYgAAABAQAA5iEAAOYhAAAA/wAA5iIAAOYiAAAA+gAA5iMAAOYjAAABJgAA5iQAAOYkAAABPQAA5iUAAOYlAAABLAAA5iYAAOYmAAABOwAA5icAAOYnAAABOQAA5igAAOYoAAABLwAA5ikAAOYpAAAA+wAA5ioAAOYqAAABKgAA5isAAOYrAAABNAAA5i0AAOYtAAAA/AAA5i4AAOYuAAABBwAA5i8AAOYvAAABCQAA5jAAAOYwAAABEQAA5jEAAOYxAAABCgAA5jIAAOYyAAABCAAA5jMAAOYzAAABDQAA5jQAAOY0AAABBgAA5jUAAOY1AAABBQAA5jYAAOY2AAABDgAA5jcAAOY3AAABAwAA5jgAAOY4AAABEAAA5jkAAOY5AAABMwAA5joAAOY6AAABIQAA5jsAAOY7AAABIAAA5jwAAOY8AAAA9QAA5j0AAOY9AAAAkAAA5j4AAOY+AAABNwAA5j8AAOY/AAABGQAA5kAAAOZAAAABMgAA5kEAAOZBAAAA+AAA5kIAAOZCAAAAjgAA5kMAAOZDAAAAigAA5kUAAOZFAAABJAAA5kYAAOZGAAAAjwAA5kcAAOZHAAAAiwAA5kgAAOZIAAABFwAA5kkAAOZJAAAA/QAA5koAAOZKAAABOgAA5ksAAOZLAAABPgAA5kwAAOZMAAABPwAA5k0AAOZNAAABMQAA5k4AAOZOAAAA/gAA5k8AAOZPAAABFQAA5lAAAOZQAAABEwAA5lEAAOZRAAABEgAA5lIAAOZSAAABHwAA5lMAAOZTAAAA+QAA5lQAAOZUAAABGwAA5lUAAOZVAAABFAAA5lYAAOZWAAABGAAA5lcAAOZXAAABGgAA5lgAAOZYAAABNQAA5lkAAOZZAAABIgAA5loAAOZaAAAA8wAA5lsAAOZbAAABIwAA5lwAAOZcAAABKwAA5l0AAOZdAAABCwAA5l4AAOZeAAABHAAA5l8AAOZfAAABHgAA5mAAAOZgAAABKAAA5mEAAOZhAAABJwAA5mIAAOZiAAABJQAA5mMAAOZjAAABLQAA5mQAAOZkAAABOAAA5mUAAOZlAAABNgAA5mYAAOZmAAABBAAA5mcAAOZnAAABDAAA5mgAAOZoAAABFgAA5mkAAOZpAAAA9wAA5moAAOZqAAAA8gAA5msAAOZrAAABKQAA5mwAAOZsAAAA9AAA5m0AAOZtAAABLgAA5m4AAOZuAAABMAAA5m8AAOZvAAABPAAA5nAAAOZwAAABHQAA5nEAAOZxAAABDwAA5nIAAOZyAAAAjAAA5nMAAOZzAAAAjQAA5nQAAOZ0AAAAngAA5nUAAOZ1AAAAlwAA5nYAAOZ2AAAAnwAA5ncAAOZ3AAAAkQAA5ngAAOZ4AAAAkwAA5nkAAOZ5AAAAnQAA5noAAOZ6AAAAqAAA5nsAAOZ7AAAApgAA5nwAAOZ8AAAAoAAA5n0AAOZ9AAAApwAA5n4AAOZ+AAAApQAA5n8AAOZ/AAAAqwAA5oAAAOaAAAAAnAAA5oEAAOaBAAAAlgAA5oIAAOaCAAAAkgAA5oMAAOaDAAAAlAAA5oQAAOaEAAAAmwAA5oUAAOaFAAAAmgAA5oYAAOaGAAAAlQAA5ocAAOaHAAAAmAAA5ogAAOaIAAAAfgAA5okAAOaJAAAAfAAA5ooAAOaKAAAAowAA5osAAOaLAAAApAAA5owAAOaMAAAAqgAA5o0AAOaNAAAArQAA5o4AAOaOAAAArgAA5o8AAOaPAAAAoQAA5pAAAOaQAAAAfQAA5pEAAOaRAAAAgQAA5pIAAOaSAAAAiQAA5pMAAOaTAAAAhwAA5pQAAOaUAAAAhAAA5pUAAOaVAAAAiAAA5pYAAOaWAAAAgAAA5pcAAOaXAAAAhgAA5pgAAOaYAAAAhQAA5pkAAOaZAAAAewAA5poAAOaaAAAAqQAA5rwAAOa8AAAB5wAA5tcAAObXAAAA9gAA5wAAAOcAAAAAggAA5wEAAOcBAAAAfwAA5wIAAOcCAAAAgwAA5wMAAOcDAAAAbgAA5wQAAOcEAAAAegAA5wUAAOcFAAAAeQAA6AAAAOgAAAAAeAAA6AEAAOgBAAAAdwAA6AIAAOgCAAAAdgAA6AMAAOgDAAAAcwAA6AQAAOgEAAAAdAAA6AUAAOgFAAAAdQAA6AYAAOgGAAAAcgAA6AcAAOgHAAAAcQAA6AgAAOgIAAAAbwAA6AkAAOgJAAAAcAAA6AoAAOgKAAAArAAA6AsAAOgLAAAAogAA6AwAAOgMAAAAmQAA6A0AAOgNAAAA5gAA6A4AAOgOAAAA7AAA6A8AAOgPAAAA6wAA6BAAAOgQAAAA7gAA6BEAAOgRAAAA6QAA6BIAAOgSAAAA6gAA6BMAAOgTAAAA7wAA6BQAAOgUAAAA5wAA6BUAAOgVAAAA4wAA6BYAAOgWAAAA5AAA6BcAAOgXAAAA8AAA6BgAAOgYAAAA7QAA6BkAAOgZAAAA5QAA6BoAAOgaAAAA6AAA6BsAAOgbAAAA8QAA6BwAAOgcAAAA2QAA6B0AAOgdAAAA2wAA6B4AAOgeAAAA2gAA6B8AAOgfAAAA4gAA6CAAAOggAAAA3AAA6CEAAOghAAAA3gAA6CIAAOgiAAAA3QAA6CMAAOgjAAAA3wAA6CQAAOgkAAAA4AAA6CUAAOglAAAA4QAA6CYAAOgmAAAA1wAA6CcAAOgnAAAA0AAA6CgAAOgoAAAA0wAA6CkAAOgpAAAA0QAA6CoAAOgqAAAA1gAA6CsAAOgrAAAA1QAA6CwAAOgsAAAA1AAA6QAAAOkAAAAA0gAA6QEAAOkBAAAAzwAA6QIAAOkCAAAA2AAA6QMAAOkDAAAAxgAA6QQAAOkEAAAAzAAA6QUAAOkFAAAAyAAA6QYAAOkGAAAAyQAA6QcAAOkHAAAAxQAA6QgAAOkIAAAAzgAA6QkAAOkJAAAAygAA6QoAAOkKAAAAxwAA6QsAAOkLAAAAzQAA6QwAAOkMAAAAywAA6Q0AAOkNAAAAwQAA6Q4AAOkOAAAAwAAA6Q8AAOkPAAAAwwAA6RAAAOkQAAAAvAAA6REAAOkRAAAAwgAA6RIAAOkSAAAAuwAA6RMAAOkTAAAAxAAA6RQAAOkUAAAAvwAA6RUAAOkVAAAAvQAA6RYAAOkWAAAAvgAA6RcAAOkXAAAAsAAA6RgAAOkYAAAAuQAA6RkAAOkZAAAArwAA6RoAAOkaAAAAtQAA6RsAAOkbAAAAtAAA6RwAAOkcAAAAtgAA6R0AAOkdAAAAsgAA6R4AAOkeAAAAuAAA6R8AAOkfAAAAsQAA6SAAAOkgAAAAugAA6SEAAOkhAAAAtwAA6SIAAOkiAAAAswAA6wQAAOsEAAACXwAA6wUAAOsFAAACXAAA6wYAAOsGAAACYAAA6wcAAOsHAAACZgAA6wgAAOsIAAACZQAA6wkAAOsJAAACZAAA6woAAOsKAAACYwAA6wsAAOsLAAACYgAA6wwAAOsMAAACYQAA6w0AAOsNAAACXQAA6w4AAOsOAAACWwAA6w8AAOsPAAACWgAA6xAAAOsQAAACWQAA6xEAAOsRAAACUwAA6xIAAOsSAAACVgAA6xMAAOsTAAACUQAA6xQAAOsUAAACUgAA6xUAAOsVAAACVAAA6xYAAOsWAAACVQAA6xcAAOsXAAACVwAA6xgAAOsYAAACWAAA6xoAAOsaAAACUAAA6xsAAOsbAAACTwAA6xwAAOscAAACTgAA6x0AAOsdAAACTQAA6x4AAOseAAACTAAA6x8AAOsfAAABsAAA6yAAAOsgAAACSwAA6yEAAOshAAACSgAA6yIAAOsiAAACRQAA6yMAAOsjAAACRgAA6yQAAOskAAACQQAA6yUAAOslAAACQgAA6yYAAOsmAAACQwAA6ycAAOsnAAACRAAA6ygAAOsoAAACMQAA6ykAAOspAAACMAAA6yoAAOsqAAACPwAA6ysAAOsrAAACPgAA6ywAAOssAAACPQAA6y0AAOstAAACPAAA6y4AAOsuAAACOwAA6y8AAOsvAAACOAAA6zAAAOswAAACOQAA6zEAAOsxAAACOgAA6zIAAOsyAAACMwAA6zMAAOszAAACNAAA6zQAAOs0AAACNQAA6zUAAOs1AAACNgAA6zYAAOs2AAACNwAA6zcAAOs3AAACMgAA6zgAAOs4AAACLwAA6zkAAOs5AAACLgAA6zoAAOs6AAACLQAA6zsAAOs7AAACLAAA6zwAAOs8AAACKwAA6z0AAOs9AAACKgAA6z4AAOs+AAACKQAA6z8AAOs/AAACKAAA60EAAOtBAAACJwAA60IAAOtCAAACJgAA60MAAOtDAAACJQAA60QAAOtEAAACJAAA60UAAOtFAAACIwAA60YAAOtGAAACIgAA60cAAOtHAAACIAAA60gAAOtIAAACIQAA60kAAOtJAAACHwAA60oAAOtKAAACHgAA60sAAOtLAAACHQAA60wAAOtMAAACHAAA600AAOtNAAACGwAA604AAOtOAAACGgAA608AAOtPAAACGQAA61EAAOtRAAACGAAA61IAAOtSAAACFwAA61MAAOtTAAACFgAA61QAAOtUAAACFQAA61UAAOtVAAACFAAA61YAAOtWAAACEwAA61cAAOtXAAACEgAA61gAAOtYAAACEQAA61kAAOtZAAACEAAA61oAAOtaAAACDwAA61sAAOtbAAACDgAA61wAAOtcAAACDQAA610AAOtdAAACDAAA614AAOteAAACCwAA618AAOtfAAACCgAA62AAAOtgAAACCQAA62EAAOthAAACCAAA62IAAOtiAAACBwAA62MAAOtjAAACBgAA62QAAOtkAAACBQAA62UAAOtlAAACBAAA62YAAOtmAAACAwAA62cAAOtnAAACAgAA62gAAOtoAAACAQAA62kAAOtpAAACAAAA62oAAOtqAAAB/wAA62sAAOtrAAAB/gAA62wAAOtsAAAB/QAA620AAOttAAAB/AAA624AAOtuAAAB+wAA628AAOtvAAAB+gAA63EAAOtxAAAB+QAA63IAAOtyAAAB+AAA63MAAOtzAAAB9wAA63QAAOt0AAAB9gAA63UAAOt1AAAB9QAA63YAAOt2AAAB9AAA63cAAOt3AAAB8wAA63gAAOt4AAAB8gAA63kAAOt5AAAB8QAA63oAAOt6AAAB8AAA63sAAOt7AAAB7wAA63wAAOt8AAAB7gAA630AAOt9AAAB7QAA634AAOt+AAAB7AAA638AAOt/AAABrwAA64EAAOuBAAAB6wAA64IAAOuCAAAB6gAA64MAAOuDAAAB5gAA64QAAOuEAAAB5QAA64UAAOuFAAAB5AAA64YAAOuGAAAB4wAA64cAAOuHAAAB4gAA64gAAOuIAAAB4QAA64kAAOuJAAAB4AAA65oAAOuaAAAB3wAA65sAAOubAAAB3gAA65wAAOucAAAB3QAA650AAOudAAAB3AAA654AAOueAAAB2wAA658AAOufAAAB2gAA66AAAOugAAAB2QAA66EAAOuhAAAB2AAA66IAAOuiAAAB1wAA66MAAOujAAAB1gAA66QAAOukAAAB1QAA66UAAOulAAAB1AAA66YAAOumAAAB0wAA66cAAOunAAAB0gAA66gAAOuoAAAB0QAA66kAAOupAAAB0AAA67AAAOuwAAABzwAA67EAAOuxAAABzgAA67IAAOuyAAABzQAA67MAAOuzAAABzAAA67QAAOu0AAABywAA67UAAOu1AAABygAA67YAAOu2AAAByQAA67cAAOu3AAAByAAA67gAAOu4AAABxwAA67kAAOu5AAABxgAA68AAAOvAAAABxQAA68EAAOvBAAABxAAA68IAAOvCAAABwwAA68MAAOvDAAABwgAA68QAAOvEAAABwQAA68UAAOvFAAABwAAA68YAAOvGAAABvwAA68cAAOvHAAABvgAA68gAAOvIAAABvQAA68kAAOvJAAABvAAA69AAAOvQAAABuwAA69EAAOvRAAABugAA69IAAOvSAAABuQAA69MAAOvTAAABuAAA69QAAOvUAAABtwAA69UAAOvVAAABtgAA69YAAOvWAAABtQAA69cAAOvXAAABtAAA69gAAOvYAAABswAA69kAAOvZAAABsgAA6+EAAOvhAAABsQAA6+IAAOviAAABsAAA6+MAAOvjAAABrwAA6+QAAOvkAAABrgAA6+UAAOvlAAABrQAA6+YAAOvmAAABrAAA6+cAAOvnAAABqwAA6+gAAOvoAAABqgAA6+kAAOvpAAABqQAA6/AAAOvwAAABqAAA6/EAAOvxAAABpwAA6/IAAOvyAAABpgAA6/MAAOvzAAABpQAA6/QAAOv0AAABpAAA6/UAAOv1AAABowAA6/YAAOv2AAABogAA6/cAAOv3AAABoQAA6/gAAOv4AAABoAAA6/kAAOv5AAABnwAA7KAAAOygAAABngAA7KEAAOyhAAABnQAA7KIAAOyiAAABnAAA7KMAAOyjAAABmwAA7KQAAOykAAABlgAA7KUAAOylAAABlQAA7KYAAOymAAABlAAA7KcAAOynAAABkwAA7KgAAOyoAAABkgAA7KkAAOypAAABkQAA7LAAAOywAAABkAAA7LEAAOyx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Ad8B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AgACAQICAgMCBAIFAgYCBwIIAgkCCgILAgwCDQIOAg8CEAIRAhICEwIUAhUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIgIjAiQCJQImAicCKAIpAioCKwIsAi0CLgIvAjACMQIyAjMCNAI1AjYCNwI4AjkCOgI7AjwCPQI+Aj8CQAJBAkICQwJEAkUCRgJHAkgCSQJKAksCTAJNAk4CTwJQAlECUgJTAlQCVQJWAlcCWAJZAloCWwJcAl0CXgJfAmACYQJiAmMCZAJlAmYCZwJoAmkCagJrAmwCbQJuAm8CcAJxAnICcwJ0AnUCdgJ3AngCeQJ6AnsCfAJ9An4CfwKAAoECggKDAoQChQKGAocCiAKJAooCiwKMAo0CjgKPApACkQKSApMClAKVApYClwKYApkCmgKbApwCnQKeAp8CoAKhAqICowKkAqUCpgKnAqgCqQKqAqsCrAKtAq4CrwKwArECsgKzArQCtQK2ArcCuAK5AroCuwK8Ar0CvgK/AsACwQLCAsMCxALFAsYCxwLIAskCygLLAswCzQLOAs8C0ALRAtIC0wLUAtUC1gLXAtgC2QLaAtsC3ALdAt4C3wLgAuEC4gLjAuQC5QLmAucC6ALpAuoC6wLsAu0C7gLvAvAC8QLyAvMC9AL1AvYC9wL4AvkC+gL7AvwC/QL+Av8DAAMBAwIDAwMEAwUDBgMHAwgDCQMKAwsDDAMNAw4DDwMQAxEDEgMTAxQDFQMWAxcDGAMZAxoDGwMcAx0DHgMfAyADIQMiAyMDJAMlAyYDJwMoAykDKgMrAywDLQMuAy8DMAMxAzIDMwM0AzUDNgM3AzgDOQM6AzsDPAM9Az4DPwNAA0EDQgNDA0QDRQNGA0cDSANJA0oDSwNMA00DTgNPA1ADUQNSA1MDVANVA1YDVwNYA1kDWgNbA1wDXQNeA18DYANhA2IDYwNkA2UDZgNnA2gDaQNqA2sDbANtA24DbwNwA3EDcgNzA3QDdQN2A3cDeAN5A3oDewN8A30DfgN/A4ADgQOCAAphLWNodWxpcmVuCmNsb2NrLWVjYjUKY2xvY2stZTEwNwllMTAwLXVuZG8OZTIwOS1zdWJ0aXRsZXMHZTIwOC1oZBJlMTE3LWNhbmNlbC1jaXJjbGUTZTExNi1jYW5jZWwtb3V0bGluZQxlMTNkLXByZXZpZXcLZTExNS1jYW5jZWwEc3RvcApjYWxjdWxhdG9yDHNvcnQtZGVzYy1zbQ5lbmNsb3N1cmVfZWRpdBJlMDFjLWFycm93LXBhcmVudDENZTIwYS1wbGF5bGlzdBBlMDFkLWFycm93LXJvb3QxEWUwMjAtYXJyb3dzLXN3YXAxF2UwMWYtYXJyb3dzLWRpbWVuc2lvbnMxE2UxMDQtbm9uLXJlY3VycmVuY2UVZTAxZS1hcnJvd3MtcmVzaXppbmcxEGUxMjctc29ydC1hc2Mtc20IZTE0MS1wYW4OZTIwNi12b2x1bWUtdXAKZTIwMS1wYXVzZQllMjAwLXBsYXkMZTIwNC1mb3J3YXJkEGUyMDUtdm9sdW1lLWRvd24UZTE0OS1rcGktc3RhdHVzLW9wZW4PZTIwNy12b2x1bWUtb2ZmC2UyMDMtcmV3aW5kDWUxMzItZG93bmxvYWQSZTExOS1jaGVjay1vdXRsaW5lC2UxMzMtdXBsb2FkEmUxMjMtbWludXMtY2lyY2xlMQ1lMTI0LXNvcnQtYXNjC2UxMjktZmlsdGVyC2UxMjYtdW5zb3J0C2UxMzEtbG9nb3V0CmUxMzAtbG9naW4OZTEyNS1zb3J0LWRlc2MQZTEyMC1wbHVzLWNpcmNsZRRlMTQ4LWtwaS1zdGF0dXMtaG9sZAxlMTQ1LXBsdXMtc20OZTE0NC1jb25uZWN0b3IWZTEzNS1oeXBlcmxpbmstb3Blbi1zbQtlMTM2LWxhdW5jaBRlMTQ3LWtwaS1zdGF0dXMtZGVueQllMTQzLWNhcnQLZTEzNy13aW5kb3cNZTE0Ni1taW51cy1zbQ1lMTQwLXpvb20tb3V0FGUxMzktd2luZG93LW1pbmltaXplE2UxMzQtaHlwZXJsaW5rLW9wZW4SZTExMS1saW5rLXZlcnRpY2FsCWUxMTMtbG9jawtlMTAzLXJlbG9hZA1lMTA1LXJlc2V0LXNtFGUxMTItdW5saW5rLXZlcnRpY2FsFmUxMTAtdW5saW5rLWhvcml6b250YWwOZTEwNi1yZWxvYWQtc20LZTExNC11bmxvY2sLZTEwOS1mbG9wcHkKZTExOC1jaGVjaxFlMTJhLWZpbHRlci1jbGVhchJlMTBlLWF0dGFjaG1lbnQtNDULZTEzYy13cmVuY2gaZTEyZS1maWx0ZXItYWRkLWV4cHJlc3Npb24OZTEyYi1maWx0ZXItc20PZTEwZC1hdHRhY2htZW50FWUxMmYtZmlsdGVyLWFkZC1ncm91cBJlMTFjLWNsb3NlLW91dGxpbmUYZTEyZC1maWx0ZXItc29ydC1kZXNjLXNtFGUxMGYtbGluay1ob3Jpem9udGFsCGUxMGItZGl0F2UxMmMtZmlsdGVyLXNvcnQtYXNjLXNtCmUxM2ItZ2VhcnMJZTAzMC1tZW51CWUxMDEtcmVkbwplMjBiLWF1ZGlvEmUwMjktbGF5b3V0LTEtYnktNBFlMDI3LWhhbmRsZXItZHJhZw9lMDIyLWNhdGVnb3JpemUMZTIwYy1wbGF5LXNtEmUwMzEtbW9yZS12ZXJ0aWNhbAtlMDI4LWxheW91dAxlMTNmLXpvb20taW4SZTAyMS1kcmFnLWFuZC1kcm9wEmUwMmEtbGF5b3V0LTItYnktMgllMDJlLXJvd3MKZTEwMi1yZXNldAplMTBhLXByaW50GGUwMmItbGF5b3V0LXNpZGUtYnktc2lkZRBlMDFiLWFycm93LWRyaWxsE2UwMmMtbGF5b3V0LXN0YWNrZWQMZTAyZC1jb2x1bW5zFWUwMDMtYXJyb3ctNDUtdXAtbGVmdBNlMDBhLWFycm93LWVuZC1kb3duFWUwMTEtYXJyb3dzLW5vLWNoYW5nZQtlMDBiLXNlZWstdxRlMDA5LWFycm93LWVuZC1yaWdodBdlMDAyLWFycm93LTQ1LWRvd24tbGVmdBFlMDA4LWFycm93LWVuZC11cBBlMDE4LWFycm93LXJpZ2h0D2UwMTktYXJyb3ctZG93bg9lMDFhLWFycm93LWxlZnQYZTAwMS1hcnJvdy00NS1kb3duLXJpZ2h0GGUwMTItYXJyb3ctb3ZlcmZsb3ctZG93bg1lMDE3LWFycm93LXVwFmU3MDMtbWFya2VyLXBpbi10YXJnZXQNZTgwOC1kaWdnLWJveAplODA5LWVtYWlsCWU4MDctZGlnZxJlODA2LWRlbGljaW91cy1ib3gMZTgwMy1ibG9nZ2VyEGU4MDQtYmxvZ2dlci1ib3gOZTgwNS1kZWxpY2lvdXMKZTgwMi1pbmJveAllODAxLXVzZXIKZTgwMC1zaGFyZQplNzA1LXVucGluCGU3MDQtcGluDmU2OTktZm9udC1zaXplEGU2ODktcGFuZS1mcmVlemUcZTY5MC10b2dnbGUtZnVsbC1zY3JlZW4tbW9kZRJlNjg4LXRhYmxlLXVubWVyZ2UKZTcwMS1nbG9iZRJlNjk2LWN1c3RvbS1mb3JtYXQPZTY5MS1mb3JtdWxhLWZ4EmU3MDAtZ2xvYmUtb3V0bGluZQ9lNzAyLW1hcmtlci1waW4LZTY5NC1kb2xsYXIVZTY5OC1kZWNpbWFsLWRlY3JlYXNlFWU2OTctZGVjaW1hbC1pbmNyZWFzZQtlNjkzLXN5bWJvbAxlNjk1LXBlcmNlbnQIZTY5Mi1zdW0TZTY0My10ZXh0Ym94LWhpZGRlbhVlNjQ3LXRlbXBsYXRlLW1hbmFnZXIUZTY3Mi1oeXBlcmxpbmstZ2xvYmUbZTY3My1oeXBlcmxpbmstZ2xvYmUtcmVtb3ZlDGU2NDItdGV4dGJveA9lNjQ2LWVkaXQtdG9vbHMLZTYzZC1idXR0b24KZTY3Ny10YWJsZRFlNjgyLXRhYmxlLWRlbGV0ZRVlNjc4LXRhYmxlLXByb3BlcnRpZXMQZTY4My1jZWxscy1tZXJnZRxlNjg2LWNlbGwtc3BsaXQtaG9yaXpvbnRhbGx5FmU2ODEtdGFibGUtY2VsbC1kZWxldGULZTY3NS1hbmNob3IbZTY4Ny1jY2VsbC1zcGxpdC12ZXJ0aWNhbGx5EWU4MGMtZmFjZWJvb2stYm94G2U2ODUtY2VsbHMtbWVyZ2UtdmVydGljYWxseR1lNjg0LWNlbGxzLW1lcmdlLWhvcml6b250YWxseRVlNjgwLXRhYmxlLXJvdy1kZWxldGUPZTY3OS10YWJsZS1jZWxsFGU2NzQtaHlwZXJsaW5rLWVtYWlsF2U2NzYtdGFibGUtbGlnaHQtZGlhbG9nHmU2N2MtdGFibGUtY29sdW1uLWluc2VydC1yaWdodBRlNjhmLXZhbGlkYXRpb24tZGF0YQ1lODBiLWZjYWVib29rD2U2OGEtcm93LWZyZWV6ZRJlNjhiLWNvbHVtbi1mcmVlemUbZTY3ZS10YWJsZS1yb3ctaW5zZXJ0LWJlbG93HWU2N2ItdGFibGUtY29sdW1uLWluc2VydC1sZWZ0G2U2N2QtdGFibGUtcm93LWluc2VydC1hYm92ZRplNjdhLXRhYmxlLWNlbGwtcHJvcGVydGllcxxlNjlhLWltYWdlLWFic29sdXRlLXBvc2l0aW9uEmU2OGMtdG9vbGJhci1mbG9hdBhlNjdmLXRhYmxlLWNvbHVtbi1kZWxldGUOZTgwYS1lbWFpbC1ib3gSZTY4ZC1zcGVsbC1jaGVja2VyFWU2OGUtdmFsaWRhdGlvbi14aHRtbAhlOTE5LWNzcwplOTE3LWh0bWw1B2U5MWYtdmILZTkxZC12YnByb2oUZTkyMi1maWxlLWhvcml6b250YWwIZTkxYi1leGUHZTkxYS1qcwtlOTFjLWNzcHJvagplOTIxLWNsb3VkB2U5MWUtY3MJZTkxOC1odG1sCGU5MjAtc2xuDmU5MTItZmlsZS1hc2N4D2U5MTAtZmlsZS1mbGFzaAllOTE1LWZpbG0JZTkxNi1jc3MzDWU5MTQtZmlsZS16aXANZTkwZS1maWxlLXBkZg1lOTBkLWZpbGUtcHB0EGU5MTEtZmlsZS1jb25maWcNZTkwZi1maWxlLXBzZA1lOTEzLWZpbGUtYmFjDWU5MDctZmlsZS1hZGQOZTkwMy1mb2xkZXItdXAPZTkwYS1maWxlLWV4Y2VsFWU5MDUtYWdncmVnYXRlLWZpZWxkcwllOTA2LWZpbGUIZTkwOS1jc3YIZTkwYy1tZGIQZTkwNC1mb2xkZXItbW9yZQ5lOTBiLWZpbGUtd29yZA1lOTA4LWZpbGUtdHh0EGU5MDEtZm9sZGVyLW9wZW4IZTgyNy1yc3MKZTgyOS12aW1lbwtlOTAwLWZvbGRlcgxlODI4LXJzcy1ib3gQZTgyYy15b3V0dWJlLWJveAxlODJiLXlvdXR1YmUOZTgyYS12aW1lby1ib3gRZTgyNi1kcmliYmJsZS1ib3gPZTkwMi1mb2xkZXItYWRkFmU4MWMtdGVsbC1hLWZyaWVuZC1ib3gPZTgxZS10dW1ibHItYm94C2U4MWQtdHVtYmxyEGU4MjAtdHdpdHRlci1ib3gPZTgyMi15YW1tZXItYm94C2U4MjEteWFtbWVyDGU4MjMtYmVoYW5jZRBlODI0LWJlaGFuY2UtYm94DWU4MjUtZHJpYmJibGUMZTgxZi10d2l0dGVyDmU4MTUtcGludGVyZXN0EmU4MTYtcGludGVyZXN0LWJveBFlODE5LXN0dW1ibGUtdXBvbgtlODBkLWdvb2dsZRBlODE0LW15c3BhY2UtYm94FWU4MWEtc3R1bWJsZS11cG9uLWJveA1lODExLWxpbmtlZGluEWU4MTItbGlua2VkaW4tYm94EGU4MGYtZ29vZ2xlLXBsdXMPZTgwZS1nb29nbGUtYm94D2U4MTgtcmVkZGl0LWJveBRlODEwLWdvb2dsZS1wbHVzLWJveAxlODEzLW15c3BhY2ULZTgxNy1yZWRkaXQSZTgxYi10ZWxsLWEtZnJpZW5kEHN0cmlwLWNzcy1mb3JtYXQOdmlkZW8tZXh0ZXJuYWwTc3RyaXAtc3Bhbi1lbGVtZW50cwpzZWxlY3QtYWxsGHRhYmxlLWFsaWduLWJvdHRvbS1yaWdodBNzdHJpcC1hbGwtZm9ybWF0aW5nCHRleHRhcmVhCmltYWdlLWVkaXQJdGV4dC13cmFwGHRhYmxlLWFsaWduLW1pZGRsZS1yaWdodBJ0YWJsZS1hbGlnbi1yZW1vdmUNdHJhY2stY2hhbmdlcxh0cmFjay1jaGFuZ2VzLXJlamVjdC1hbGwMYWxpZ24tcmVtb3ZlDGFsaWduLWNlbnRlcg1hbGlnbi1qdXN0aWZ5C2FsaWduLXJpZ2h0CWJvcmRlci1ubwxhcHBseS1mb3JtYXQLYm9yZGVyLWxlZnQNYm9yZGVyLWJvdHRvbQtib3JkZXJzLWFsbBdib3JkZXJzLWluc2lkZS12ZXJ0aWNhbA9ib3JkZXJzLW91dHNpZGUZYm9yZGVycy1pbnNpZGUtaG9yaXpvbnRhbARjb3B5CWNsZWFyLWNzcwpib3JkZXItdG9wDGJvcmRlci1yaWdodBtlNjcxLWh5cGVybGluay1saWdodC1kaWFsb2cRYm9yZGVycy1zaG93LWhpZGUOYm9yZGVycy1pbnNpZGUOZGljdGlvbmFyeS1hZGQLY3VzdG9tLWljb24HY29tbWVudBBkb2N1bWVudC1tYW5hZ2VyC2NvcHktZm9ybWF0D2NoYW5nZS1tYW51YWxseQ5jb21tZW50LXJlbW92ZQ1jYWxlbmRhci1kYXRlE2NvbW1lbnRzLXJlbW92ZS1hbGwQaW1hZ2UtbWFwLWVkaXRvcgNjdXQObW9kdWxlLW1hbmFnZXIFcGFzdGUSaW1hZ2UtbGlnaHQtZGlhbG9nDGNvZGUtc25pcHBldAxmb3JtLWVsZW1lbnQNbWVkaWEtbWFuYWdlcg1mbGFzaC1tYW5hZ2VyDXBhcmFncmFwaC1hZGQacGFzdGUtZnJvbS13b3JkLXN0cmlwLWZpbGUPcnVsZS1ob3Jpem9udGFsD3Bhc3RlLWZyb20td29yZA1wYXN0ZS1hcy1odG1sE3N0cmlwLWZvbnQtZWxlbWVudHMXdGFibGUtYWxpZ24tYm90dG9tLWxlZnQQZmluZC1hbmQtcmVwbGFjZRZ0YWJsZS1hbGlnbi10b3AtY2VudGVyCnBhc3RlLWh0bWwVc3RyaXAtd29yZC1mb3JtYXR0aW5nGXRhYmxlLWFsaWduLW1pZGRsZS1jZW50ZXIRZm9ybWF0LWNvZGUtYmxvY2sUdHJhY2stY2hhbmdlcy1yZWplY3QJZ3JvdXAtYm94BGZvcm0ZdGFibGUtYWxpZ24tYm90dG9tLWNlbnRlcgtzaWx2ZXJsaWdodBBwYXN0ZS1wbGFpbi10ZXh0CnNlbGVjdC1ib3gOcGFzdGUtbWFya2Rvd24XdGFibGUtYWxpZ24tbWlkZGxlLWxlZnQUdHJhY2stY2hhbmdlcy1lbmFibGUVdGFibGUtYWxpZ24tdG9wLXJpZ2h0DXN0eWxlLWJ1aWxkZXIUdGFibGUtYWxpZ24tdG9wLWxlZnQUdHJhY2stY2hhbmdlcy1hY2NlcHQYdHJhY2stY2hhbmdlcy1hY2NlcHQtYWxsEWEtZTYwNGZvbnQtZmFtaWx5EGEtZTYwOXN1Yi1zY3JpcHQWYS1lNjA1Zm9yZWdyb3VuZC1jb2xvcgphLWU2MDFib2xkCGEtZTYxMGg0E2EtZTYwOHN0cmlrZXRocm91Z2gXYS1lNjA2Y29udmVydC1sb3dlcmNhc2UXYS1lNjA3Y29udmVydC11cHBlcmNhc2UMYS1lNjAyaXRhbGljD2EtZTYwM3VuZGVybGluZRJhLWU2MWNhbGlnbi1ib3R0b20IYS1lNjBkaDEIYS1lNjBmaDMJYS1lNjBjYWxsCGEtZTYwZWgyEGEtZTYwYXN1cC1zY3JpcHQJYS1lNjBiZGl2EGEtZTYxZGFsaWduLWxlZnQPYS1lNjFhYWxpZ24tdG9wEmEtZTYxYmFsaWduLW1pZGRsZRVhLWU2MTVpbmRlbnQtaW5jcmVhc2UTYS1lNjE4aW5zZXJ0LW1pZGRsZRRhLWU2MTRsaXN0LXVub3JkZXJlZBVhLWU2MTZpbmRlbnQtZGVjcmVhc2UPYS1lNjE3aW5zZXJ0LXVwEWEtZTYxOWluc2VydC1kb3duCGEtZTYxMmg2EmEtZTYxM2xpc3Qtb3JkZXJlZAhhLWU2MTFoNRNhLWU1MjR0aHVtYm5haWxzLXVwFmEtZTUyOWZ1bGwtc2NyZWVuLWV4aXQVYS1lNTI2dGh1bWJuYWlscy1kb3duFWEtZTYwMHBhZ2UtcHJvcGVydGllcxVhLWU1Mjd0aHVtYm5haWxzLWxlZnQaYS1lNTIzYWxpZ24tYm90dG9tLWVsZW1lbnQRYS1lNTI4ZnVsbC1zY3JlZW4WYS1lNTI1dGh1bWJuYWlscy1yaWdodBFhLWU1MmFyZXNldC1jb2xvchphLWU1MjJhbGlnbi1taWRkbGUtZWxlbWVudBJhLWU1MWJiYWNrLWVsZW1lbnQZYS1lNTIwYWxpZ24tcmlnaHQtZWxlbWVudBVhLWU1MWNmb3J3YXJkLWVsZW1lbnQLYS1lNTE4c2hhcGUXYS1lNTIxYWxpZ24tdG9wLWVsZW1lbnQWYS1lNTFkYmFja3dhcmQtZWxlbWVudBNhLWU1MTlyb3VuZC1jb3JuZXJzGGEtZTUxZWFsaWduLWxlZnQtZWxlbWVudBNhLWU1MWFmcm9udC1lbGVtZW50GmEtZTUxZmFsaWduLWNlbnRlci1lbGVtZW50CmEtZTUxMGxpbmUZYS1lNTExYnJpZ2h0bmVzcy1jb250cmFzdAthLWU1MGZwYWludA9hLWU1MTVncmV5c2NhbGUNYS1lNTBlcGFsZXR0ZQ1hLWU1MTdzaGFycGVuE2EtZTUxM2ludmVydC1jb2xvcnMKYS1lNTE2Ymx1chBhLWU1MTJzYXR1cmF0aW9uEmEtZTUxNHRyYW5zcGVyYW5jeQxhLWU1MGFyb3RhdGUTYS1lNTA0em9vbS1iZXN0LWZpdAthLWU1MGRicnVzaBFhLWU1MGNyb3RhdGUtbGVmdAphLWU1MDZjcm9wE2EtZTUwOWZsaXAtdmVydGljYWwMYS1lNTA3bWlycm9yFWEtZTUwOGZsaXAtaG9yaXpvbnRhbBJhLWU1MDVpbWFnZS1yZXNpemUSYS1lNTBicm90YXRlLXJpZ2h0DWEtZTIwZXN0b3Atc20SYS1lNTAyaW1hZ2UtZXhwb3J0FGEtZTMwN3RyaS1zdGF0ZS1udWxsC2EtZTUwMWltYWdlE2EtZTMwMGhlYXJ0LW91dGxpbmUWYS1lNTAzem9vbS1hY3R1YWwtc2l6ZQxhLWUzMDhjaXJjbGULYS1lMzAxaGVhcnQSYS1lNTAwcGhvdG8tY2FtZXJhDmEtZTIwZHBhdXNlLXNtC2NvbGxhcHNlLW5lCXRodW1idGFjawtzLXRodW1idGFjawZtb3ZldG8NZmlsdGVyX2RlbGV0ZQ9maWx0ZXJfZ3JvdXBpbmcKZmlsdGVyX2FkZBNmaWx0ZXJfY2FuY2VsbGF0aW9uBnZlcm5hdgpjdy1hcnJvd2RlCGN3LWhvdGVsB2N3LXRyaXAFemhhZ2UHZGVuZ2hhbw10aXNoaXNodW9taW5nBERyYWcGYmlhbmppBmNoYWthbgJiZwRsaGp0CGR1bGltaW1hEXFpYW5taW5ncWlhbnpoYW5nBmZhbmt1aRRhLUNGX0Rlc2NlbmRpbmdPcmRlchNhLUNGX0FzY2VuZGluZ09yZGVyBWFib3V0CXl1bnhpYW94aRBlbmNsb3N1cmVfZGVsZXRlEmVuY2xvc3VyZV9kb3dubG9hZBBlbmNsb3N1cmVfdXBsb2FkEGVuY2xvc3VyZV9icm93c2UKdXBsb2FkX2JpZw9jYWxlbmRhcnNfbGluZTEJbW9yZV9saW5lDmRyb3AtZG93bl9saW5lEHBlcnNwZWN0aXZlX3ZpZXcKY2hhcnRfdmlldwlmb3JtX3ZpZXcJbGlzdF92aWV3CWNhcmRfdmlldwtyZW1vdmVfZmFjZQtkdWl6aGFuZ2Rhbg1kaXpoaXNoZW5xaW5nDWppbmd4aWFvcmVud3UHYmFpZmFuZwprZWh1Z3VhbnhpCGZheXVuZGFuCWxpYW54aXJlbg1mdWt1YW50b25nemhpD2thaXBpYW9zaGVucWluZw94aWFvc2hvdWRhY2hlbmcOeGlhb3Nob3VxaWFubGkOeGlhb3Nob3VtdWJpYW8Nc2h1anVzaGFuZ2Jhbwx4dWtlc2hhbmdwaW4Jemhlbmd6aGFvDHhpYW9zaG91eXVjZQ94aWFvc2hvdXR1YW5kdWkFaGVscDELaW5mby1jaXJjbGUKZGVwYXJ0bWVudARjb2RlBHBhdGgPZmxvd2xpbmUtbWFudWFsDWZsb3dsaW5lLW1vcmUSZmxvd2xpbmUtc2NoZWR1bGVkEWZsb3dsaW5lLWNhbmNlbGVkEGZsb3dsaW5lLXBlbmRpbmcMZmxvd2xpbmUtcnVuEGZsb3dsaW5lLWNyZWF0ZWQQZmxvd2xpbmUtcnVubmluZxBmbG93bGluZS13YWl0aW5nEGZsb3dsaW5lLXNraXBwZWQNZmxvd2xpbmUtdmlldxBmbG93bGluZS13YXJuaW5nC29yaWVudGF0aW9uBGxhc3QFZmlyc3QOeXVuaGFuZ3NoaWljb24aQ29sdW1uLWZpbHRlcmFuZGRlc2NlbmRpbmcZQ29sdW1uLWZpbHRlcmFuZGFzY2VuZGluZxxDb2x1bW5zLURlZmF1bHRmaWx0ZXJhbmRzb3J0DUNvbHVtbi1maWx0ZXISQ29sdW1ucy1kZXNjZW5kaW5nEUNvbHVtbnMtYXNjZW5kaW5nE0NvbHVtbnMtRGVmYXVsdHNvcnQPbGF1bmNocGFkLWZhY2UyCmxhdW5jaHBhZDIPZi1pY29uLWNoZWNrYm94DGYtaWNvbi1taW51cwpmLWljb24tYWRkCGRyb3Bkb3duCm5hdmlnYXRpb24Ray1pLW1lc3NhZ2VfZXJyb3ITay1pLW1lc3NhZ2Vfc3VjY2VzcwpzdWRva3UtbmV3CGxpc3QtbmV3CXRpbGVkLW5ldwxxaWVodWFuenV6aGkHcmFkaW8tMgZ0ZW5hbnQGc3Vkb2t1BXRpbGVkBWxpc3QxC3Nob3VjYW5namlhCmNvbGxlY3Rpb24DaWRlDG9jY2x1ZGUtZmFjZQdvY2NsdWRlDmxhdW5jaHBhZC1mYWNlCWxhdW5jaHBhZAtpbmZvcm1hdGlvbgdiYWNrbG9nB21lc3NhZ2UJbWF4aW1pemUxBnNlYXJjaAppbmRleC1mYWNlBWluZGV4CHl4c190ZXh0DXl4c19jb250YWluZXILeXhzX2NvbHVtbnMIeXhzX21vdmUIeXhzX2NvcHkKeXhzX2RlbGV0ZQl5eHNfbGV2ZWwJeXhzX2VhcnRoDXl4c19jdXN0b21pemUIc2lnbl9vdXQLdXNlcl9jZW50ZXIGcmVtb3ZlBnBhY2t1cAZjYW1lcmEGbmFycm93DWFtcGxpZmljYXRpb24JY2xvY2t3aXNlEGNvdW50ZXJjbG9ja3dpc2UGZWRpdG9yBHNraW4EYXJlYQhwYXNzd29yZAhsYW5ndWFnZQViYXNpYwhtaW5pbWl6ZQxtYXhpbWl6YXRpb24NbmV3LWRpbWVuc2lvbhFmaWxlLWZvbGRlci1jbG9zZRBmaWxlLWZvbGRlci1vcGVuCG5ldy1lZGl0CG5ldy1mb3JtBXdvbWFuA21hbgZyZWNvcmQEbW9yZQRsaXN0CXRlbGVwaG9uZQhmdW5jdGlvbgtwcm9kdWN0bGlzdA5hdHRhY2htZW50bGlzdBNkb2N1bWVudGluZm9ybWF0aW9uDG5ldy1maWx0cmF0ZQ5uZXctZnVsbHNjcmVlbgdyb29maW5nDUJvdHRvbXNldHRpbmcPcGFnZS10aXRsZS10YXNrEXBhZ2UtdGl0bGUtcmV2aWV3EHBhZ2UtdGl0bGUtc3RhcnQPcGFnZS10aXRsZS10eXBlEXBhZ2UtdGl0bGUtcmVjb3JkEnBhZ2UtdGl0bGUtdm91Y2hlchBwYWdlLXRpdGxlLXF1ZXJ5EXBhZ2UtdGl0bGUtbnVtYmVyEXBhZ2UtdGl0bGUtbWFuYWdlFnBhZ2UtdGl0bGUtbWFpbnRlbmFuY2UVcGFnZS10aXRsZS1kaWN0aW9uYXJ5GHBhZ2UtdGl0bGUtY29uZmlndXJhdGlvbhVwYWdlLXRpdGxlLWFkbWluaXN0ZXIRcGFnZS10aXRsZS1kZWZpbmUXdHJpLXN0YXRlLWluZGV0ZXJtaW5hdGUQcGFuZWwtcmV0cmFjdGlvbgtlZGl0LWJ1dHRvbg5pbnB1dC1sYW5ndWFnZRdhdHRyaWJ1dGUtY29uZmlndXJhdGlvbgtFbmdpbmVlcmluZwNnaXQTcmFkaW9idXR0b24tY2hlY2tlZAxzaGFwZS1jaXJjbGUQY2hlY2tib3gtY2hlY2tlZBVrLWktaG9tZS13ZWF0aGVyLWxlYWYNay1pLWhvbWUtbW9yZQ1rLWktaG9tZS1yaW5nDGstaS1ob21lLWFkZA5rLWktaG9tZS1zZXR1cA5rLWktaG9tZS13b21hbgxrLWktaG9tZS1tYW4Oay1pLXRvcF9hZ2VuY3kMay1pLXRvcF9uZXdzDGstaS10b3BfaG9tZRJrLWktdG9wX2ltX2RlZmF1bHQXay1pLXRvcF9kZXZlbG9wbWVudHRvb2wMay1pLXRvcF9tZW51DmstaS10b3Bfc2VhcmNoCmstaS10b3BfbXkPay1pLWZsYWdfdXJnZW50DGstaS1uZXh0cGFnZRBrLWktcHJldmlvdXNwYWdlE2staS1tZXNzYWdlX3JvdXRpbmUTay1pLUV4aGFsZS1EaXNjb3VudBNrLWktbW9yZS1ob3Jpem9udGFsEGstaS1tZXNzYWdlX2hlbHATay1pLW1lc3NhZ2Vfd2FybmluZxZrLWktc3RlcHMtZGVsaXZlcmdvb2RzFWstaS1zdGVwcy1yZWNlaXZhYmxlcxFrLWktc3RlcHMtaW52b2ljZRRrLWktc3RlcHMtb3V0b2ZzdG9jaxRrLWktc3RlcHMtc2V0dGxlbWVudBNrLWktc3RlcHMtdHJhbnNwb3J0DGstaS1ib29rbWFyaxBrLWktc3Rhci1vdXRsaW5lCGstaS16b29tEGstaS1jbG9zZS1jaXJjbGUQay1pLWNoZWNrLWNpcmNsZQlrLWktY2xvc2UQay1pLXBsdXMtb3V0bGluZRFrLWktbWludXMtb3V0bGluZQtrLWktcmVvcmRlcg1rLWktcmV3aW5kLXNtDmstaS1mb3J3YXJkLXNtE2staS1hcnJvdy1zZWVrLWRvd24Ray1pLWFycm93LXNlZWstdXAKay1pLWRlbGV0ZQlrLWktZ3JvdXAIay1pLWdyaWQPay1pLWdyaWQtbGF5b3V0DmstaS1hcnJvd3Mta3BpFmstaS1hcnJvdy1jaGV2cm9uLWxlZnQXay1pLWFycm93LWNoZXZyb24tcmlnaHQWay1pLWFycm93LWNoZXZyb24tZG93bhRrLWktYXJyb3ctY2hldnJvbi11cBFrLWktYXJyb3ctNjAtbGVmdAtrLWktYXJyb3ctZRFrLWktYXJyb3ctNjAtZG93bg9rLWktYXJyb3ctNjAtdXAAAAA=) format("truetype")}.f-icon{width:1em;height:1em;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-size:1rem;font-family:FarrisIcons;font-style:normal;font-variant:normal;font-weight:400;line-height:1;speak:none;text-transform:none;text-decoration:none;display:inline-block}.f-icon:focus,.f-icon:hover{text-decoration:none}.f-icon-sm{font-size:.75rem}.f-icon-lg{font-size:1.5rem}.f-icon-none::before{content:"";display:none}.f-icon-arrow-45-up-right::before,.f-icon-collapse-ne::before,.f-icon-resize-ne::before{content:"\e000"}.f-icon-arrow-45-down-right::before,.f-icon-collapse-se::before,.f-icon-resize-se::before{content:"\e001"}.f-icon-arrow-45-down-left::before,.f-icon-collapse-sw::before,.f-icon-resize-sw::before{content:"\e002"}.f-icon-arrow-45-up-left::before,.f-icon-collapse-nw::before,.f-icon-resize-new::before,.f-icon-resize-nw::before{content:"\e003"}.f-icon-arrow-60-up::before,.f-icon-arrow-n::before,.f-icon-expand-n::before,.f-icon-kpi-trend-increase::before,.f-icon-sarrow-n::before{content:"\e004"}.f-icon-arrow-60-right::before,.f-icon-arrow-e::before,.f-icon-expand-e::before,.f-icon-expand::before,.f-icon-sarrow-e::before{content:"\e005"}.f-icon-arrow-60-down::before,.f-icon-arrow-s::before,.f-icon-collapse::before,.f-icon-expand-s::before,.f-icon-kpi-trend-decrease::before,.f-icon-sarrow-s::before{content:"\e006"}.f-icon-arrow-60-left::before,.f-icon-arrow-w::before,.f-icon-expand-w::before,.f-icon-sarrow-w::before{content:"\e007"}.f-icon-arrow-end-up::before{content:"\e008"}.f-icon-arrow-end-right::before,.f-icon-seek-e::before{content:"\e009"}.f-icon-arrow-end-down::before{content:"\e00a"}.f-icon-arrow-end-left::before,.f-icon-seek-w::before{content:"\e00b"}.f-icon-arrow-double-60-up::before,.f-icon-arrow-seek-up::before,.f-icon-seek-n::before{content:"\e00c"}.f-icon-arrow-double-60-right::before,.f-icon-arrow-seek-right::before,.f-icon-forward-sm::before{content:"\e00d"}.f-icon-arrow-double-60-down::before,.f-icon-arrow-seek-down::before,.f-icon-seek-s::before,.f-list-nav.f-list-nav-bottom .f-list-nav-toggle-sidebar .triangle::before{content:"\e00e"}.f-icon-arrow-double-60-left::before{content:"\e00f"}.f-icon-arrow-chevron-up::before,.f-icon-arrowhead-n::before{content:"\e013"}.f-icon-arrow-chevron-right::before,.f-icon-arrowhead-e::before{content:"\e014"}.f-icon-arrow-chevron-down::before,.f-icon-arrowhead-s::before{content:"\e015"}.f-icon-arrow-chevron-left::before,.f-icon-arrowhead-w::before{content:"\e016"}.f-icon-grid::before{content:"\e023"}.f-icon-grid-layout::before{content:"\e024"}.f-icon-group::before{content:"\e025"}.f-icon-ungroup::before{content:"\e026"}.f-icon-undo-large::before,.f-icon-undo::before{content:"\e100"}.f-icon-redo-large::before,.f-icon-redo::before{content:"\e101"}.f-icon-reset::before{content:"\e102"}.f-icon-refresh::before,.f-icon-reload::before{content:"\e103"}.f-icon-clock::before{content:"\ecb5"}.f-icon-calendar::before{content:"\e108"}.f-icon-save::before{content:"\e109"}.f-icon-edit::before,.f-icon-pencil::before{content:"\e10b"}.f-icon-delete::before,.f-icon-trash::before{content:"\e10c"}.f-icon-attachment::before,.f-icon-clip::before{content:"\e10d"}.f-icon-attachment-45::before,.f-icon-clip-45::before{content:"\e10e"}.f-icon-lock::before{content:"\e113"}.f-icon-unlock::before{content:"\e114"}.f-icon-cancel::before{content:"\e115"}.f-icon-cancel-outline::before,.f-icon-deny::before{content:"\e116"}.f-icon-cancel-circle::before{content:"\e117"}.f-icon-check::before,.f-icon-checkmark::before,.f-icon-tick::before{content:"\e118"}.f-icon-check-outline::before,.f-icon-checkmark-outline::before{content:"\e119"}.f-icon-success::before{content:"\eb7d"}.f-icon-check-circle::before,.f-icon-checkmark-circle::before{content:"\e11a"}.f-icon-x::before{content:"\e11b"}.f-icon-close-outline::before,.f-icon-x-outline::before{content:"\e11c"}.f-icon-error::before{content:"\eb7e"}.f-icon-close-circle::before,.f-icon-x-circle::before,.input-group .input-group-append>.input-group-clear .modal_close::before,.input-group .input-group-prepend>.input-group-clear .modal_close::before{content:"\e11d"}.f-icon-add::before,.f-icon-plus::before{content:"\e11e"}.f-icon-plus-outline::before{content:"\e11f"}.f-icon-plus-circle::before{content:"\e120"}.f-icon-kpi-trend-equal::before,.f-icon-minus::before,.k-minus::before{content:"\e121"}.f-icon-minus-outline::before{content:"\e122"}.f-icon-minus-circle::before{content:"\e123"}.f-icon-filter::before{content:"\e129"}.f-icon-filter-clear::before{content:"\e12a"}.f-icon-filter-sort-asc-sm::before{content:"\e12c"}.f-icon-filter-sort-desc-sm::before{content:"\e12d"}.f-icon-download::before{content:"\e132"}.f-icon-upload::before{content:"\e133"}.f-icon-minimize::before,.f-icon-window-minimize::before{content:"\e139"}.f-icon-cog::before,.f-icon-gear::before{content:"\e13a"}.f-icon-cogs::before,.f-icon-gears::before{content:"\e13b"}.f-icon-eye::before,.f-icon-preview::before{content:"\e13d"}.f-icon-search::before,.f-icon-zoom::before{content:"\e13e"}.f-icon-fav-outline::before,.f-icon-favorite-outline::before{content:"\e300"}.f-icon-fav::before,.f-icon-favorite::before,.f-icon-heart::before{content:"\e301"}.f-icon-bookmark-outline::before,.f-icon-star-outline::before{content:"\e302"}.f-icon-bookmark::before,.f-icon-star::before{content:"\e303"}.f-icon-checkbox::before,.f-icon-shape-rect::before{content:"\e304"}.f-icon-checkbox-checked::before{content:"\e305"}.f-icon-radiobutton::before,.f-icon-shape-circle::before{content:"\e309"}.f-icon-radiobutton-checked::before{content:"\e30a"}.f-icon-folder::before{content:"\e900"}.f-icon-folder-open::before{content:"\e901"}.f-icon-file::before{content:"\e906"}.f-icon-message_help::before{content:"\eb04"}.f-icon-message_routine::before{content:"\eb05"}.f-icon-message_warning::before{content:"\eb06"}.f-icon-previouspage::before{content:"\eb0e"}.f-icon-nextpage::before{content:"\eb0f"}.f-icon-top_menu::before{content:"\eb12"}.f-icon-edit-button::before{content:"\eb25"}.f-icon-file-folder-close::before{content:"\eb47"}.f-icon-file-folder-open::before{content:"\eb48"}.f-icon-maximization::before{content:"\eb4a"}.f-icon-minimize::before{content:"\eb4b"}.f-icon-editor::before{content:"\eb52"}.f-icon-occlude::before{content:"\eb6e"}.f-icon-occlude-face::before{content:"\eb6f"}.f-icon-camera::before{content:"\eb57"}.f-icon-date::before{content:"\eb7f"}.f-icon-dropdown::before{content:"\eb82"}.f-icon-timepicker::before{content:"\e107"}.f-icon-info::before,.f-icon-note::before{content:"\eb05"}.f-icon-question::before{content:"\eb04"}.f-icon-help::before{content:"\e402"}.f-icon-warning::before{content:"\eb06"}.f-icon-drag-vertical::before{content:"\eca0"}.f-icon-page-title-define::before{content:"\eb2a"}.f-icon-page-title-administer::before{content:"\eb2b"}.f-icon-page-title-configuration::before{content:"\eb2c"}.f-icon-page-title-dictionary::before{content:"\eb2d"}.f-icon-page-title-maintenance::before{content:"\eb2e"}.f-icon-page-title-query::before{content:"\eb2f"}.f-icon-page-title-number::before{content:"\eb30"}.f-icon-page-title-manage::before{content:"\eb31"}.f-icon-page-title-review::before{content:"\eb32"}.f-icon-page-title-start::before{content:"\eb33"}.f-icon-page-title-type::before{content:"\eb34"}.f-icon-page-title-record::before{content:"\eb35"}.f-icon-page-title-voucher::before{content:"\eb36"}.f-icon-page-title-task::before{content:"\eb37"}.f-icon-remove_face::before{content:"\ebd4"}.f-icon-enclosure_delete::before{content:"\ebe8"}.f-icon-enclosure_download::before{content:"\ebe7"}.f-icon-enclosure_upload::before{content:"\ebe6"}.f-icon-enclosure_browse::before{content:"\ebe5"}.f-icon-upload_big::before{content:"\ebe4"}.f-icon-arrow-seek-left::before,.f-icon-rewind-sm::before,.f-list-nav.f-list-nav-left .f-list-nav-toggle-sidebar .triangle::before{content:"\e00f"}.f-icon-spin{animation:spinicon 2s infinite linear}@keyframes spinicon{0%{transform:rotate(0)}100%{transform:rotate(359deg)}}.f-icon-with-modifier{position:relative;margin:.25em}.f-icon-modifier{position:absolute;font-size:.5em;bottom:0;right:0;margin:0 -.5em -.5em 0}.f-icon-xs{font-size:.5rem}.f-icon-md,.f-legend-icon::after,.modal_close{font-size:1.25rem}.f-icon-xl{font-size:2rem}.f-btn-icon,.input-group-text{font-size:.8125rem;line-height:1.4286}.f-icon-arrows-kpi::before,.f-icon-kpi::before{content:"\e010"}.f-icon-arrows-no-change::before{content:"\e011"}.f-icon-arrow-overflow-down::before{content:"\e012"}.f-icon-arrow-up::before{content:"\e017"}.f-icon-arrow-right::before{content:"\e018"}.f-icon-arrow-down::before{content:"\e019"}.f-icon-arrow-left::before{content:"\e01a"}.f-icon-arrow-drill::before{content:"\e01b"}.f-icon-arrow-parent::before{content:"\e01c"}.f-icon-arrow-root::before{content:"\e01d"}.f-icon-arrows-resizing::before{content:"\e01e"}.f-icon-arrows-dimensions::before,.f-icon-dimension::before{content:"\e01f"}.f-icon-arrows-swap::before{content:"\e020"}.f-icon-drag-and-drop::before{content:"\e021"}.f-icon-categorize::before{content:"\e022"}.f-icon-handler-drag::before{content:"\e027"}.f-icon-layout::before{content:"\e028"}.f-icon-layout-1-by-4::before{content:"\e029"}.f-icon-layout-2-by-2::before,.f-icon-page-layout::before{content:"\e02a"}.f-icon-layout-side-by-side::before{content:"\e02b"}.f-icon-layout-stacked::before{content:"\e02c"}.f-icon-columns::before{content:"\e02d"}.f-icon-rows::before{content:"\e02e"}.f-icon-reorder::before{content:"\e02f"}.f-icon-hamburger::before,.f-icon-menu::before{content:"\e030"}.f-icon-more-vertical::before,.f-icon-vbars::before{content:"\e031"}.f-icon-hbars::before,.f-icon-more-horizontal::before{content:"\e032"}.f-icon-recurrence::before{content:"\e103"}.f-icon-non-recurrence::before,.f-icon-refresh-clear::before{content:"\e104"}.f-icon-reset-sm::before{content:"\e105"}.f-icon-recurrence-sm::before,.f-icon-refresh-sm::before,.f-icon-reload-sm::before{content:"\e106"}.f-icon-floppy::before{content:"\e109"}.f-icon-print::before,.f-icon-printer::before{content:"\e10a"}.f-icon-hyperlink::before,.f-icon-link-horizontal::before{content:"\e10f"}.f-icon-hyperlink-remove::before,.f-icon-unlink-horizontal::before{content:"\e110"}.f-icon-link-vertical::before{content:"\e111"}.f-icon-unlink-vertical::before{content:"\e112"}.f-icon-sort-asc::before{content:"\e124"}.f-icon-sort-desc::before{content:"\e125"}.f-icon-sort-clear::before,.f-icon-unsort::before{content:"\e126"}.f-icon-sort-asc-sm::before{content:"\e127"}.f-icon-sort-desc-sm::before{content:"\e128"}.f-icon-filter-sm::before{content:"\e12b"}.f-icon-filter-add-expression::before{content:"\e12e"}.f-icon-filter-add-group::before{content:"\e12f"}.f-icon-login::before{content:"\e130"}.f-icon-logout::before{content:"\e131"}.f-icon-hyperlink-open::before{content:"\e134"}.f-icon-hyperlink-open-sm::before{content:"\e135"}.f-icon-launch::before{content:"\e136"}.f-icon-maximize::before,.f-icon-window-maximize::before,.f-icon-window::before{content:"\e137"}.f-icon-restore::before,.f-icon-tiles::before,.f-icon-window-restore::before,.f-icon-windows::before{content:"\e138"}.f-icon-custom::before{content:"\e13a"}.f-icon-settings::before,.f-icon-wrench::before{content:"\e13c"}.f-icon-zoom-in::before{content:"\e13f"}.f-icon-zoom-out::before{content:"\e140"}.f-icon-move::before,.f-icon-pan::before{content:"\e141"}.f-icon-calculator::before{content:"\e142"}.f-icon-cart::before,.f-icon-shopping-cart::before{content:"\e143"}.f-icon-connector::before{content:"\e144"}.f-icon-plus-sm::before,.f-icon-splus::before{content:"\e145"}.f-icon-minus-sm::before,.f-icon-sminus::before{content:"\e146"}.f-icon-kpi-status-deny::before{content:"\e147"}.f-icon-kpi-status-hold::before{content:"\e148"}.f-icon-kpi-status-open::before{content:"\e149"}.f-icon-play::before{content:"\e200"}.f-icon-pause::before{content:"\e201"}.f-icon-stop::before{content:"\e202"}.f-icon-rewind::before{content:"\e203"}.f-icon-forward::before{content:"\e204"}.f-icon-volume-down::before,.f-icon-volume-low::before{content:"\e205"}.f-icon-volume-high::before,.f-icon-volume-up::before{content:"\e206"}.f-icon-volume-mute::before,.f-icon-volume-off::before{content:"\e207"}.f-icon-hd::before{content:"\e208"}.f-icon-subtitles::before{content:"\e209"}.f-icon-playlist::before{content:"\e20a"}.f-icon-audio::before{content:"\e20b"}.f-icon-play-sm::before{content:"\e20c"}.f-icon-pause-sm::before{content:"\e20d"}.f-icon-stop-sm::before{content:"\e20e"}.f-icon-heart-outline::before{content:"\e300"}.f-icon-tri-state-indeterminate::before{content:"\e306"}.f-icon-tri-state-null::before{content:"\e307"}.f-icon-circle::before{content:"\e308"}.f-icon-bell::before,.f-icon-notification::before{content:"\e400"}.f-icon-exception::before{content:"\e403"}.f-icon-photo-camera::before{content:"\e500"}.f-icon-image::before,.f-icon-photo::before{content:"\e501"}.f-icon-image-export::before,.f-icon-photo-export::before{content:"\e502"}.f-icon-zoom-actual-size::before{content:"\e503"}.f-icon-zoom-best-fit::before{content:"\e504"}.f-icon-image-resize::before{content:"\e505"}.f-icon-crop::before{content:"\e506"}.f-icon-mirror::before{content:"\e507"}.f-icon-flip-horizontal::before{content:"\e508"}.f-icon-flip-vertical::before{content:"\e509"}.f-icon-rotate::before{content:"\e50a"}.f-icon-rotate-cw::before,.f-icon-rotate-right::before{content:"\e50b"}.f-icon-rotate-ccw::before,.f-icon-rotate-left::before{content:"\e50c"}.f-icon-brush::before{content:"\e50d"}.f-icon-palette::before{content:"\e50e"}.f-icon-background::before,.f-icon-droplet::before,.f-icon-paint::before{content:"\e50f"}.f-icon-line::before,.f-icon-shape-line::before{content:"\e510"}.f-icon-brightness-contrast::before{content:"\e511"}.f-icon-saturation::before{content:"\e512"}.f-icon-invert-colors::before{content:"\e513"}.f-icon-opacity::before,.f-icon-transperancy::before{content:"\e514"}.f-icon-greyscale::before{content:"\e515"}.f-icon-blur::before{content:"\e516"}.f-icon-sharpen::before{content:"\e517"}.f-icon-shape::before{content:"\e518"}.f-icon-round-corners::before{content:"\e519"}.f-icon-front-element::before{content:"\e51a"}.f-icon-back-element::before{content:"\e51b"}.f-icon-forward-element::before{content:"\e51c"}.f-icon-backward-element::before{content:"\e51d"}.f-icon-align-left-element::before{content:"\e51e"}.f-icon-align-center-element::before{content:"\e51f"}.f-icon-align-right-element::before{content:"\e520"}.f-icon-align-top-element::before{content:"\e521"}.f-icon-align-middle-element::before{content:"\e522"}.f-icon-align-bottom-element::before{content:"\e523"}.f-icon-thumbnails-up::before{content:"\e524"}.f-icon-thumbnails-right::before{content:"\e525"}.f-icon-thumbnails-down::before{content:"\e526"}.f-icon-thumbnails-left::before{content:"\e527"}.f-icon-full-screen::before,.f-icon-fullscreen-enter::before,.f-icon-fullscreen::before{content:"\e528"}.f-icon-full-screen-exit::before,.f-icon-fullscreen-exit::before{content:"\e529"}.f-icon-background-remove::before,.f-icon-paint-remove::before,.f-icon-reset-color::before{content:"\e52a"}.f-icon-page-properties::before{content:"\e600"}.f-icon-bold::before{content:"\e601"}.f-icon-italic::before{content:"\e602"}.f-icon-underline::before{content:"\e603"}.f-icon-font-family::before{content:"\e604"}.f-icon-foreground-color::before,.f-icon-text::before{content:"\e605"}.f-icon-convert-lowercase::before{content:"\e606"}.f-icon-convert-uppercase::before{content:"\e607"}.f-icon-strike-through::before,.f-icon-strikethrough::before{content:"\e608"}.f-icon-sub-script::before,.f-icon-subscript::before{content:"\e609"}.f-icon-sup-script::before,.f-icon-superscript::before{content:"\e60a"}.f-icon-div::before{content:"\e60b"}.f-icon-all::before{content:"\e60c"}.f-icon-h1::before{content:"\e60d"}.f-icon-h2::before{content:"\e60e"}.f-icon-h3::before{content:"\e60f"}.f-icon-h4::before{content:"\e610"}.f-icon-h5::before{content:"\e611"}.f-icon-h6::before{content:"\e612"}.f-icon-insert-ordered-list::before,.f-icon-list-numbered::before,.f-icon-list-ordered::before{content:"\e613"}.f-icon-insert-unordered-list::before,.f-icon-list-bulleted::before,.f-icon-list-unordered::before{content:"\e614"}.f-icon-indent-increase::before,.f-icon-indent::before{content:"\e615"}.f-icon-indent-decrease::before,.f-icon-outdent::before{content:"\e616"}.f-icon-insert-n::before,.f-icon-insert-top::before,.f-icon-insert-up::before{content:"\e617"}.f-icon-insert-m::before,.f-icon-insert-middle::before{content:"\e618"}.f-icon-insert-bottom::before,.f-icon-insert-down::before,.f-icon-insert-s::before{content:"\e619"}.f-icon-align-top::before{content:"\e61a"}.f-icon-align-middle::before{content:"\e61b"}.f-icon-align-bottom::before{content:"\e61c"}.f-icon-align-left::before,.f-icon-justify-left::before{content:"\e61d"}.f-icon-align-center::before,.f-icon-justify-center::before{content:"\e61e"}.f-icon-align-right::before,.f-icon-justify-right::before{content:"\e61f"}.f-icon-align-justify::before,.f-icon-justify-full::before{content:"\e620"}.f-icon-align-remove::before,.f-icon-justify-clear::before{content:"\e621"}.f-icon-text-wrap::before{content:"\e622"}.f-icon-rule-horizontal::before{content:"\e623"}.f-icon-table-align-top-left::before{content:"\e624"}.f-icon-table-align-top-center::before{content:"\e625"}.f-icon-table-align-top-right::before{content:"\e626"}.f-icon-table-align-middle-left::before{content:"\e627"}.f-icon-table-align-middle-center::before{content:"\e628"}.f-icon-table-align-middle-right::before{content:"\e629"}.f-icon-table-align-bottom-left::before{content:"\e62a"}.f-icon-table-align-bottom-center::before{content:"\e62b"}.f-icon-table-align-bottom-right::before{content:"\e6d7"}.f-icon-table-align-remove::before{content:"\e62d"}.f-icon-all-borders::before,.f-icon-borders-all::before{content:"\e62e"}.f-icon-borders-outside::before,.f-icon-outside-borders::before{content:"\e62f"}.f-icon-borders-inside::before,.f-icon-inside-borders::before{content:"\e630"}.f-icon-borders-inside-horizontal::before,.f-icon-inside-horizontal-borders::before{content:"\e631"}.f-icon-borders-inside-vertical::before,.f-icon-inside-vertical-borders::before{content:"\e632"}.f-icon-border-top::before,.f-icon-top-border::before{content:"\e633"}.f-icon-border-bottom::before,.f-icon-bottom-border::before{content:"\e634"}.f-icon-border-left::before,.f-icon-left-border::before{content:"\e635"}.f-icon-border-right::before,.f-icon-right-border::before{content:"\e636"}.f-icon-border-no::before,.f-icon-no-borders::before{content:"\e637"}.f-icon-borders-show-hide::before{content:"\e638"}.f-icon-border::before,.f-icon-form::before{content:"\e639"}.f-icon-form-element::before{content:"\e63a"}.f-icon-code-snippet::before{content:"\e63b"}.f-icon-select-all::before{content:"\e63c"}.f-icon-button::before{content:"\e63d"}.f-icon-select-box::before{content:"\e63e"}.f-icon-calendar-date::before{content:"\e63f"}.f-icon-group-box::before{content:"\e640"}.f-icon-textarea::before{content:"\e641"}.f-icon-textbox::before{content:"\e642"}.f-icon-textbox-hidden::before{content:"\e643"}.f-icon-paragraph-add::before{content:"\e645"}.f-icon-edit-tools::before{content:"\e646"}.f-icon-template-manager::before{content:"\e647"}.f-icon-change-manually::before{content:"\e648"}.f-icon-track-changes::before{content:"\e649"}.f-icon-track-changes-enable::before{content:"\e64a"}.f-icon-track-changes-accept::before{content:"\e64b"}.f-icon-track-changes-accept-all::before{content:"\e64c"}.f-icon-track-changes-reject::before{content:"\e64d"}.f-icon-track-changes-reject-all::before{content:"\e64e"}.f-icon-document-manager::before{content:"\e64f"}.f-icon-custom-icon::before{content:"\e650"}.f-icon-dictionary-add::before{content:"\e651"}.f-icon-image-insert::before,.f-icon-image-light-dialog::before,.f-icon-insert-image::before{content:"\e652"}.f-icon-image-edit::before{content:"\e653"}.f-icon-image-map-editor::before{content:"\e654"}.f-icon-comment::before{content:"\e655"}.f-icon-comment-remove::before{content:"\e656"}.f-icon-comments-remove-all::before{content:"\e657"}.f-icon-silverlight::before{content:"\e658"}.f-icon-media-manager::before{content:"\e659"}.f-icon-video-external::before{content:"\e65a"}.f-icon-flash-manager::before{content:"\e65b"}.f-icon-find-and-replace::before,.f-icon-find::before{content:"\e65c"}.f-icon-copy::before,.f-icon-files::before{content:"\e65d"}.f-icon-cut::before{content:"\e65e"}.f-icon-paste::before{content:"\e65f"}.f-icon-paste-as-html::before{content:"\e660"}.f-icon-paste-from-word::before{content:"\e661"}.f-icon-paste-from-word-strip-file::before{content:"\e662"}.f-icon-paste-html::before{content:"\e663"}.f-icon-paste-markdown::before{content:"\e664"}.f-icon-paste-plain-text::before{content:"\e665"}.f-icon-apply-format::before{content:"\e666"}.f-icon-clear-css::before,.f-icon-clearformat::before{content:"\e667"}.f-icon-copy-format::before{content:"\e668"}.f-icon-strip-all-formating::before{content:"\e669"}.f-icon-strip-css-format::before{content:"\e66a"}.f-icon-strip-font-elements::before{content:"\e66b"}.f-icon-strip-span-elements::before{content:"\e66c"}.f-icon-strip-word-formatting::before{content:"\e66d"}.f-icon-format-code-block::before{content:"\e66e"}.f-icon-style-builder::before{content:"\e66f"}.f-icon-module-manager::before{content:"\e670"}.f-icon-hyperlink-insert::before,.f-icon-hyperlink-light-dialog::before{content:"\e671"}.f-icon-hyperlink-globe::before{content:"\e672"}.f-icon-hyperlink-globe-remove::before{content:"\e673"}.f-icon-hyperlink-email::before{content:"\e674"}.f-icon-anchor::before{content:"\e675"}.f-icon-create-table::before,.f-icon-table-insert::before,.f-icon-table-light-dialog::before{content:"\e676"}.f-icon-table::before{content:"\e677"}.f-icon-table-properties::before,.f-icon-table-wizard::before{content:"\e678"}.f-icon-table-cell::before{content:"\e679"}.f-icon-table-cell-properties::before{content:"\e67a"}.f-icon-add-column-left::before,.f-icon-table-column-insert-left::before{content:"\e67b"}.f-icon-add-column-right::before,.f-icon-table-column-insert-right::before{content:"\e67c"}.f-icon-add-row-above::before,.f-icon-table-row-insert-above::before{content:"\e67d"}.f-icon-add-row-below::before,.f-icon-table-row-insert-below::before{content:"\e67e"}.f-icon-delete-column::before,.f-icon-table-column-delete::before{content:"\e67f"}.f-icon-delete-row::before,.f-icon-table-row-delete::before{content:"\e680"}.f-icon-table-cell-delete::before{content:"\e681"}.f-icon-table-delete::before{content:"\e682"}.f-icon-cells-merge::before,.f-icon-merge-cells::before{content:"\e683"}.f-icon-cells-merge-horizontally::before,.f-icon-merge-horizontally::before{content:"\e684"}.f-icon-cells-merge-vertically::before,.f-icon-merge-vertically::before{content:"\e685"}.f-icon-cell-split-horizontally::before{content:"\e686"}.f-icon-cell-split-vertically::before{content:"\e687"}.f-icon-normal-layout::before,.f-icon-table-unmerge::before{content:"\e688"}.f-icon-freeze-panes::before,.f-icon-pane-freeze::before{content:"\e689"}.f-icon-freeze-row::before,.f-icon-row-freeze::before{content:"\e68a"}.f-icon-column-freeze::before,.f-icon-freeze-col::before{content:"\e68b"}.f-icon-toolbar-float::before{content:"\e68c"}.f-icon-spell-checker::before{content:"\e68d"}.f-icon-validation-xhtml::before{content:"\e68e"}.f-icon-validation-data::before{content:"\e68f"}.f-icon-toggle-full-screen-mode::before{content:"\e690"}.f-icon-formula-fx::before,.f-icon-fx::before{content:"\e691"}.f-icon-sum::before{content:"\e692"}.f-icon-symbol::before{content:"\e693"}.f-icon-currency::before,.f-icon-dollar::before{content:"\e694"}.f-icon-percent::before{content:"\e695"}.f-icon-custom-format::before,.f-icon-format-number::before{content:"\e696"}.f-icon-decimal-increase::before,.f-icon-increase-decimal::before{content:"\e697"}.f-icon-decimal-decrease::before,.f-icon-decrease-decimal::before{content:"\e698"}.f-icon-font-size::before{content:"\e699"}.f-icon-image-absolute-position::before{content:"\e69a"}.f-icon-globe-outline::before{content:"\e700"}.f-icon-globe::before{content:"\e701"}.f-icon-marker-pin::before{content:"\e702"}.f-icon-marker-pin-target::before{content:"\e703"}.f-icon-pin::before{content:"\e704"}.f-icon-unpin::before{content:"\e705"}.f-icon-share::before{content:"\e800"}.f-icon-user::before{content:"\e801"}.f-icon-inbox::before{content:"\e802"}.f-icon-blogger::before{content:"\e803"}.f-icon-blogger-box::before{content:"\e804"}.f-icon-delicious::before{content:"\e805"}.f-icon-delicious-box::before{content:"\e806"}.f-icon-digg::before{content:"\e807"}.f-icon-digg-box::before{content:"\e808"}.f-icon-email::before,.f-icon-envelop::before,.f-icon-letter::before{content:"\e809"}.f-icon-email-box::before,.f-icon-envelop-box::before,.f-icon-letter-box::before{content:"\e80a"}.f-icon-facebook::before{content:"\e80b"}.f-icon-facebook-box::before{content:"\e80c"}.f-icon-google::before{content:"\e80d"}.f-icon-google-box::before{content:"\e80e"}.f-icon-google-plus::before{content:"\e80f"}.f-icon-google-plus-box::before{content:"\e810"}.f-icon-linkedin::before{content:"\e811"}.f-icon-linkedin-box::before{content:"\e812"}.f-icon-myspace::before{content:"\e813"}.f-icon-myspace-box::before{content:"\e814"}.f-icon-pinterest::before{content:"\e815"}.f-icon-pinterest-box::before{content:"\e816"}.f-icon-reddit::before{content:"\e817"}.f-icon-reddit-box::before{content:"\e818"}.f-icon-stumble-upon::before{content:"\e819"}.f-icon-stumble-upon-box::before{content:"\e81a"}.f-icon-tell-a-friend::before{content:"\e81b"}.f-icon-tell-a-friend-box::before{content:"\e81c"}.f-icon-tumblr::before{content:"\e81d"}.f-icon-tumblr-box::before{content:"\e81e"}.f-icon-twitter::before{content:"\e81f"}.f-icon-twitter-box::before{content:"\e820"}.f-icon-yammer::before{content:"\e821"}.f-icon-yammer-box::before{content:"\e822"}.f-icon-behance::before{content:"\e823"}.f-icon-behance-box::before{content:"\e824"}.f-icon-dribbble::before{content:"\e825"}.f-icon-dribbble-box::before{content:"\e826"}.f-icon-rss::before{content:"\e827"}.f-icon-rss-box::before{content:"\e828"}.f-icon-vimeo::before{content:"\e829"}.f-icon-vimeo-box::before{content:"\e82a"}.f-icon-youtube::before{content:"\e82b"}.f-icon-youtube-box::before{content:"\e82c"}.f-icon-folder-add::before{content:"\e902"}.f-icon-folder-up::before{content:"\e903"}.f-icon-fields-more::before,.f-icon-folder-more::before{content:"\e904"}.f-icon-aggregate-fields::before{content:"\e905"}.f-icon-file-vertical::before,.f-icon-page-portrait::before{content:"\e906"}.f-icon-file-add::before,.f-icon-insert-file::before{content:"\e907"}.f-icon-file-txt::before,.f-icon-txt::before{content:"\e908"}.f-icon-csv::before,.f-icon-file-csv::before{content:"\e909"}.f-icon-excel::before,.f-icon-file-excel::before,.f-icon-file-xls::before,.f-icon-xls::before,.f-icon-xlsa::before{content:"\e90a"}.f-icon-doc::before,.f-icon-file-doc::before,.f-icon-file-word::before,.f-icon-word::before{content:"\e90b"}.f-icon-file-mdb::before,.f-icon-mdb::before{content:"\e90c"}.f-icon-file-ppt::before,.f-icon-ppt::before{content:"\e90d"}.f-icon-file-pdf::before,.f-icon-pdf::before,.f-icon-pdfa::before{content:"\e90e"}.f-icon-file-psd::before,.f-icon-psd::before{content:"\e90f"}.f-icon-file-flash::before,.f-icon-flash::before{content:"\e910"}.f-icon-config::before,.f-icon-file-config::before{content:"\e911"}.f-icon-ascx::before,.f-icon-file-ascx::before{content:"\e912"}.f-icon-bac::before,.f-icon-file-bac::before{content:"\e913"}.f-icon-file-zip::before,.f-icon-zip::before{content:"\e914"}.f-icon-film::before{content:"\e915"}.f-icon-css3::before{content:"\e916"}.f-icon-html5::before{content:"\e917"}.f-icon-html::before,.f-icon-source-code::before,.f-icon-view-source::before{content:"\e918"}.f-icon-css::before{content:"\e919"}.f-icon-js::before{content:"\e91a"}.f-icon-exe::before{content:"\e91b"}.f-icon-csproj::before{content:"\e91c"}.f-icon-vbproj::before{content:"\e91d"}.f-icon-cs::before{content:"\e91e"}.f-icon-vb::before{content:"\e91f"}.f-icon-sln::before{content:"\e920"}.f-icon-cloud::before{content:"\e921"}.f-icon-file-horizontal::before,.f-icon-page-landscape::before{content:"\e922"}.f-icon-steps-transport::before{content:"\eb07"}.f-icon-steps-settlement::before{content:"\eb08"}.f-icon-steps-outofstock::before{content:"\eb09"}.f-icon-steps-invoice::before{content:"\eb0a"}.f-icon-steps-receivables::before{content:"\eb0b"}.f-icon-steps-delivergoods::before{content:"\eb0c"}.f-icon-exhale-discount::before{content:"\eb0d"}.f-icon-flag_urgent::before{content:"\eb10"}.f-icon-top_home::before{content:"\eb11"}.f-icon-top_agency::before{content:"\eb13"}.f-icon-top_news::before{content:"\eb14"}.f-icon-top_im_default::before{content:"\eb15"}.f-icon-top_developmenttool::before{content:"\eb16"}.f-icon-top_search::before{content:"\eb17"}.f-icon-top_my::before{content:"\eb18"}.f-icon-home-man::before{content:"\eb1a"}.f-icon-home-woman::before{content:"\eb1b"}.f-icon-home-setup::before{content:"\eb1c"}.f-icon-home-add::before{content:"\eb1d"}.f-icon-home-ring::before{content:"\eb1e"}.f-icon-home-operation::before{content:"\eb1f"}.f-icon-home-more::before{content:"\eb20"}.f-icon-home-weather-leaf::before{content:"\eb21"}.f-icon-engineering::before{content:"\eb22"}.f-icon-git::before{content:"\eb23"}.f-icon-panel-retraction::before{content:"\eb24"}.f-icon-input-language::before{content:"\eb26"}.f-icon-attribute-configuration::before{content:"\eb27"}.f-icon-bottomsetting::before{content:"\eb28"}.f-icon-roofing::before{content:"\eb29"}.f-icon-new-fullscreen::before{content:"\eb38"}.f-icon-filtrate::before{content:"\eb39"}.f-icon-document-information::before{content:"\eb3a"}.f-icon-attachment-list::before{content:"\eb3b"}.f-icon-product-list::before{content:"\eb3c"}.f-icon-new-function::before{content:"\eb3d"}.f-icon-telephone::before{content:"\eb3e"}.f-icon-list::before{content:"\eb3f"}.f-icon-more::before{content:"\eb41"}.f-icon-record::before{content:"\eb42"}.f-icon-man::before{content:"\eb43"}.f-icon-woman::before{content:"\eb44"}.f-icon-new-form::before{content:"\eb45"}.f-icon-new-edit::before{content:"\eb46"}.f-icon-new-dimension::before{content:"\eb49"}.f-icon-basic::before{content:"\eb4c"}.f-icon-language::before{content:"\eb4d"}.f-icon-password::before{content:"\eb4e"}.f-icon-area::before{content:"\eb4f"}.f-icon-skin::before{content:"\eb51"}.f-icon-counterclockwise::before{content:"\eb53"}.f-icon-clockwise::before{content:"\eb54"}.f-icon-amplification::before{content:"\eb55"}.f-icon-narrow::before{content:"\eb56"}.f-cmp-footer .f-cmp-footer-header .f-toolbar .toolbar--collapse-icon::before,.f-icon-packup::before{content:"\eb58"}.f-icon-remove::before{content:"\eb59"}.f-icon-user_center::before{content:"\eb5a"}.f-icon-sign_out::before{content:"\eb5b"}.f-icon-yxs_customize::before{content:"\eb5c"}.f-icon-yxs_earth::before{content:"\eb5d"}.f-icon-yxs_level::before{content:"\eb5e"}.f-icon-yxs_delete::before{content:"\eb5f"}.f-icon-yxs_copy::before{content:"\eb60"}.f-icon-yxs_move::before{content:"\eb61"}.f-icon-index::before{content:"\eb65"}.f-icon-index-face::before{content:"\eb66"}.f-icon-search::before{content:"\eb67"}.f-icon-message::before{content:"\eb69"}.f-icon-backlog::before{content:"\eb6a"}.f-icon-information::before{content:"\eb6b"}.f-icon-launchpad::before{content:"\eb6c"}.f-icon-launchpad-face::before{content:"\eb6d"}.f-icon-ide::before{content:"\eb71"}.f-icon-collection::before{content:"\eb72"}.f-icon-shoucangjia::before{content:"\eb73"}.f-icon-list1::before{content:"\eb74"}.f-icon-tiled::before{content:"\eb75"}.f-icon-sudoku::before{content:"\eb76"}.f-icon-tenant::before{content:"\eb77"}.f-icon-radio-2::before{content:"\eb78"}.f-icon-qiehuanzuzhi::before{content:"\eb79"}.f-icon-tiled-new::before{content:"\eb7a"}.f-icon-list-new::before{content:"\eb7b"}.f-icon-sudoku-new::before{content:"\eb7c"}.f-icon-danger::before{content:"\eb7e"}.f-icon-default::before{content:"\eb14"}.f-icon-navigation::before{content:"\eb81"}.f-icon-launchpad-face2::before{content:"\eb84"}.f-icon-launchpad2::before{content:"\eb83"}.f-icon-col-filteranddescending::before{content:"\eb9b"}.f-icon-col-filterandascending::before{content:"\eb9a"}.f-icon-col-defaultfilterandsort::before{content:"\eb89"}.f-icon-col-filter::before{content:"\eb88"}.f-icon-col-descending::before{content:"\eb87"}.f-icon-col-ascending::before{content:"\eb86"}.f-icon-col-defaultsort::before{content:"\eb85"}.f-icon-runtime::before{content:"\eb9c"}.f-icon-page-last::before{content:"\eb9e"}.f-icon-page-first::before{content:"\eb9d"}.f-icon-orientation-arrow::before{content:"\eb9f"}.f-icon-flowline-scheduled:before{content:"\eba9"}.f-icon-flowline-canceled::before{content:"\eba8"}.f-icon-flowline-pending::before{content:"\eba7"}.f-icon-flowline-run::before{content:"\eba6"}.f-icon-flowline-created::before{content:"\eba5"}.f-icon-flowline-running::before{content:"\eba4"}.f-icon-flowline-waiting::before{content:"\eba3"}.f-icon-flowline-skipped::before{content:"\eba2"}.f-icon-flowline-view::before{content:"\eba1"}.f-icon-flowline-warning::before{content:"\eba0"}.f-icon-flowline-more::before{content:"\ebb0"}.f-icon-flowline-manual::before{content:"\ebb1"}.f-icon-path::before{content:"\ebb2"}.f-icon-code::before{content:"\ebb3"}.f-icon-department::before{content:"\ebb4"}.f-icon-info-circle::before{content:"\ebb5"}.f-icon-help-01::before{content:"\ebb6"}.f-icon-statement::before{content:"\ebd3"}.f-icon-address-location::before{content:"\ebd2"}.f-icon-task-record::before{content:"\ebd1"}.f-icon-visit:before{content:"\ebd0"}.f-icon-relationship::before{content:"\ebc9"}.f-icon-truck-delivery::before{content:"\ebc8"}.f-icon-concat-list::before{content:"\ebc7"}.f-icon-payment-notice::before{content:"\ebc6"}.f-icon-application-for-invoicing::before{content:"\ebc5"}.f-icon-accomplishment:before{content:"\ebc4"}.f-icon-potential:before{content:"\ebc3"}.f-icon-aim::before{content:"\ebc2"}.f-icon-declaration-form::before{content:"\ebc1"}.f-icon-licensed::before{content:"\ebc0"}.f-icon-profile-picture::before{content:"\ebb9"}.f-icon-forecast-of-completion::before{content:"\ebb8"}.f-icon-team::before{content:"\ebb7"}.f-icon-table_view::before{content:"\ebf7"}.f-icon-card_view::before{content:"\ebd5"}.f-icon-list_view::before{content:"\ebd6"}.f-icon-form_view::before{content:"\ebd7"}.f-icon-chart_view::before{content:"\ebd8"}.f-icon-perspective_view::before{content:"\ebd9"}.f-icon-drop-down_line::before{content:"\ebe1"}.f-icon-more_line::before{content:"\ebe2"}.f-icon-calendars_line1::before{content:"\ebe3"}.f-icon-message_round::before{content:"\ebe9"}.f-icon-col-descendingorder::before{content:"\ebf2"}.f-icon-col-ascendingorder::before{content:"\ebf1"}.f-icon-feedback::before{content:"\ebf3"}.f-icon-signature::before{content:"\ebf4"}.f-icon-indep-password::before{content:"\ebf5"}.f-icon-honor::before{content:"\ebf6"}.f-icon-view-cardview::before{content:"\ebf8"}.f-icon-edit-cardview::before{content:"\ebf9"}.f-icon-description-tips::before{content:"\eca1"}.f-icon-equalsign::before{content:"\eca2"}.f-icon-column-rectangle::before{content:"\eca3"}.f-icon-position::before{content:"\ecb4"}.f-icon-hotel::before{content:"\ecb3"}.f-icon-arrowwide::before{content:"\ecb2"}.f-icon-foldin::before{content:"\ecb1"}.f-icon-filter-cancel::before{content:"\eca4"}.f-icon-filter-add::before{content:"\eca5"}.f-icon-filter-grouping::before{content:"\eca6"}.f-icon-filter-delete::before{content:"\eca7"}.f-icon-moverto::before{content:"\eca8"}.f-icon-thumbtack-fill::before{content:"\eca9"}.f-icon-thumbtack::before{content:"\ecb0"}.f-icon-enclosure-edit::before{content:"\ecb6"}.f-icon-notifier::before{content:"\ecb7"}.f-iconmage{display:inline-block}.f-btn-icon{cursor:pointer;padding:.1875rem;border:1px solid var(--f-neutral-08);border-radius:6px;position:relative;display:flex;align-items:center;justify-content:center;width:1.6607375rem;height:1.6607375rem}.f-btn-icon.f-bare{border-color:transparent!important;background:0 0!important;transition:color .2s ease-in-out}.f-btn-icon::after,.f-btn-icon::before{border-radius:6px;content:"";position:absolute;left:-1px;right:-1px;top:-1px;bottom:-1px;z-index:0;transition:opacity .2s ease-in-out;pointer-events:none}.f-btn-icon.f-bare::before{display:block}.f-btn-icon::before{opacity:0;display:none}.f-btn-icon.f-state-hover::before,.f-btn-icon:hover::before{opacity:.08}.f-btn-icon::after{opacity:0;display:none}.farris-image-cropper-frame,.farris-image-cropper-frame .farris-image-cropper{position:relative;width:100%}.btn-icontext{display:inline-flex;align-items:center}.btn-icontext .f-icon{margin:0 .4375rem 0 0}.f-icon-danger,.f-icon-error{color:var(--f-semantic-danger-01)}.f-icon-info,.f-icon-note::before{color:var(--f-semantic-info-01)}.f-icon-question,.f-icon-warning{color:var(--f-semantic-warning-01)}.f-icon-success{color:var(--f-semantic-success-01)}.f-icon-default{color:var(--f-semantic-info-01)}.f-icon-lookup::before{content:"\e032"}.f-page-pre::before{content:"\e016"}.f-page-first::before{content:"\eb9d"}.f-page-last::before{content:"\eb9e"}.f-page-next::before{content:"\e014"}.modal_minimize{font-family:FarrisIcons}.modal_minimize::before{content:"\eb4b"}.modal_maximize{font-family:FarrisIcons}.modal_maximize::before{content:"\eb68"}.f-icon-close::before,.f-icon-group-delete::before,.modal_close::before{content:"\e11b"}.f-icon-close,.f-icon-group-delete::before{font-family:FarrisIcons}.modal_close{font-family:FarrisIcons}.modalrevert::before{content:"\eb4b"}.f-legend-icon::after{content:"";width:1.125rem;height:.875rem;overflow:hidden;display:inline-block;line-height:1.125rem;margin:0 .25rem 0 0;color:var(--f-neutral-01)}.f-legend-collapse::after,.f-legend-show::after{font-size:.875rem;font-family:FarrisIcons}.f-legend-collapse::after{content:"\e013"}.f-legend-show::after{content:"\e015"}.f-cmp-inputgroup .f-transfer-date .search-tag-item.search-field:hover.search-field-remove>.f-icon::before,.f-search-box .search-tag-item.search-field:hover.search-field-remove>.f-icon::before,.f-sidebar-close::before{content:"\e11b"}.f-sidebar-entry::before{content:"\e014"}.farris-image-cropper-frame{display:flex;max-width:100%;max-height:100%;overflow:hidden;text-align:center}.farris-image-cropper-frame .farris-image-cropper .farris-source-image{max-width:100%;max-height:100%;transform-origin:center}.farris-image-cropper-frame .farris-image-overlay{position:absolute;pointer-events:none;touch-action:none;outline:#fff solid 100vw;top:0;left:0}.farris-image-cropper-frame .farris-image-cropper-wrapper{position:absolute;display:flex;color:#53535C;background:0 0;outline:rgba(0,0,0,.3) solid 100vw;outline:solid var(--cropper-outline-color,rgba(0,0,0,.3));touch-action:none}.farris-image-cropper-frame .farris-image-cropper-wrapper:after{position:absolute;content:"";top:0;bottom:0;left:0;right:0;pointer-events:none;border:1px dashed;opacity:.75;color:inherit;z-index:1}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-move{width:100%;cursor:move;border-radius:100%;border:1px solid #388fff}.farris-image-cropper-frame .farris-image-cropper-wrapper:focus .farris-image-cropper-move{border-color:#1e90ff;border-width:2px}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize{position:absolute;display:inline-block;line-height:6px;padding:8px;opacity:.85;z-index:1}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize .farris-image-cropper-square{display:inline-block;background:#388fff;width:6px;height:6px;border:1px solid #59a1ff;box-sizing:content-box}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.topleft{top:-12px;left:-12px;cursor:nwse-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.top{top:-12px;left:calc(50% - 12px);cursor:ns-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.topright{top:-12px;right:-12px;cursor:nesw-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.right{top:calc(50% - 12px);right:-12px;cursor:ew-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.bottomright{bottom:-12px;right:-12px;cursor:nwse-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.bottom{bottom:-12px;left:calc(50% - 12px);cursor:ns-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.bottomleft{bottom:-12px;left:-12px;cursor:nesw-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize.left{top:calc(50% - 12px);left:-12px;cursor:ew-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize-bar{position:absolute;z-index:1}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize-bar.top{top:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize-bar.right{top:11px;right:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize-bar.bottom{bottom:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper .farris-image-cropper-resize-bar.left{top:11px;left:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}.farris-image-cropper-frame .farris-image-cropper-wrapper.farris-image-cropper-rounded{outline-color:transparent;width:161px;height:161px}.farris-image-cropper-frame .farris-image-cropper-wrapper.farris-image-cropper-rounded:after{border-radius:100%;box-shadow:0 0 0 100vw rgba(0,0,0,.3);box-shadow:0 0 0 100vw var(--cropper-outline-color,rgba(0,0,0,.3))}@media (orientation:portrait){.farris-image-cropper-frame .farris-image-cropper-wrapper{outline-width:100vh}.farris-image-cropper-frame .farris-image-cropper-wrapper.farris-image-cropper-rounded:after{box-shadow:0 0 0 100vh rgba(0,0,0,.3);box-shadow:0 0 0 100vh var(--cropper-outline-color,rgba(0,0,0,.3))}}.farris-image-cropper-frame .farris-image-cropper-wrapper.farris-image-cropper-rounded .farris-image-cropper-move{border-radius:100%}.farris-image-cropper-frame.farris-image-cropper-disabled .farris-image-cropper-wrapper .farris-image-cropper-move,.farris-image-cropper-frame.farris-image-cropper-disabled .farris-image-cropper-wrapper .farris-image-cropper-resize,.farris-image-cropper-frame.farris-image-cropper-disabled .farris-image-cropper-wrapper .farris-image-cropper-resize-bar{display:none}.farris-image-cropper-frame .farris-image-cropper-error{width:100%;text-align:center;font-size:14px}.farris-image-cropper-frame .farris-image-cropper-loading{position:absolute;top:0;left:0;width:100%;height:100%}.farris-image-cropper-frame .farris-image-cropper-loading .farris-image-cropper-loading-spinner{width:31px;height:31px;margin:0 auto;border:2px solid #388fff;border-radius:50%;border-left-color:transparent;border-right-color:transparent;-webkit-animation:cssload-spin 425ms infinite linear;position:absolute;top:calc(50% - 15px);left:calc(50% - 15px);animation:cssload-spin 425ms infinite linear}.input-group-append,.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text,.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control{margin-left:-1px}@keyframes cssload-spin{to{transform:rotate(360deg)}}.f-cmp-static-text-input-append,.f-cmp-text-input-append,.f-cmp-textarea-input-append{display:flex;height:100%}.f-cmp-static-text-input-append,.f-cmp-textarea-input-append{align-items:flex-start}.f-cmp-static-text-input-append .f-form-control-text,.f-cmp-static-text-input-append .f-form-control-textarea{flex:1 1 0}.f-cmp-static-text-input-append .input-append-wrapper,.f-cmp-text-input-append .input-append-wrapper,.f-cmp-textarea-input-append .input-append-wrapper{flex-shrink:0;height:100%}.input-append-text .input-group-text{color:var(--f-text-02);cursor:default}.input-append-button .input-group-text{color:var(--f-theme-03)}.f-cmp-inputgroup .input-append-text .input-group-text,.f-cmp-text-input-append .input-append-text .input-group-text,.f-component-text .input-append-text .input-group-text{color:var(--f-text-02)}.f-cmp-inputgroup .input-append-button .input-group-text,.f-cmp-text-input-append .input-append-button .input-group-text,.f-component-text .input-append-button .input-group-text{color:var(--f-theme-03)}.f-cmp-text-input-append .input-append-wrapper,.f-cmp-textarea-input-append .input-append-wrapper,.f-component-text .input-append-wrapper,.input-group .input-append-wrapper{background:var(--f-neutral-12)}.f-cmp-text-input-append .input-append-wrapper>.input-group-text,.f-cmp-textarea-input-append .input-append-wrapper>.input-group-text,.f-component-text .input-append-wrapper>.input-group-text,.input-group .input-append-wrapper>.input-group-text{border:0;background:0 0}.f-cmp-input-append-form .input-append-wrapper{position:absolute;right:1px;height:auto;top:1px;bottom:1px;border-radius:0 6px 6px 0;display:block}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after,.input-group>.custom-select:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-append-wrapper.f-state-disabled{display:none!important}.was-validated .farris-input-wrap .form-check-input:invalid~.invalid-feedback,.was-validated .farris-input-wrap .form-check-input:invalid~.invalid-tooltip,.was-validated .farris-input-wrap .form-check-input:valid~.valid-feedback,.was-validated .farris-input-wrap .form-check-input:valid~.valid-tooltip{display:block}.f-cmp-text-is-textarea.f-cmp-input-append-form .input-append-wrapper,.f-cmp-textarea-input-append.f-cmp-input-append-form .input-append-wrapper{bottom:auto}.form-control:disabled,.form-control:disabled:hover,.form-control[readonly],.form-control[readonly]:hover{border-color:var(--f-neutral-04);color:var(--f-text-02);background:var(--f-neutral-12);cursor:default}.form-control:hover{background-color:var(--f-neutral-12);color:var(--f-text-02);border-color:var(--f-theme-08);box-shadow:none}.was-validated .farris-input-wrap .custom-control-input:invalid~.custom-control-label,.was-validated .farris-input-wrap .custom-control-input:valid~.custom-control-label,.was-validated .farris-input-wrap .form-check-input:invalid~.form-check-label,.was-validated .farris-input-wrap .form-check-input:valid~.form-check-label{color:var(--f-neutral-04)}.form-control[readonly]:focus{box-shadow:none}.farris-input-wrap .custom-select.is-valid,.farris-input-wrap .form-control.is-valid,.was-validated .farris-input-wrap .custom-select:valid,.was-validated .farris-input-wrap .form-control:valid{border-color:var(--f-neutral-04)}.farris-input-wrap .custom-select.is-valid:focus,.farris-input-wrap .form-control.is-valid:focus,.was-validated .farris-input-wrap .custom-select:valid:focus,.was-validated .farris-input-wrap .form-control:valid:focus{border-color:var(--f-neutral-04);box-shadow:0 0 0 .2rem rgba(var(--f-neutral-04),.25)}.was-validated .farris-input-wrap .custom-control-input:valid~.custom-control-label::before{background-color:rgba(var(--f-neutral-04),.75)}.was-validated .farris-input-wrap .custom-control-input:valid:checked~.custom-control-label::before{background-color:rgba(var(--f-neutral-04),.9)}.was-validated .farris-input-wrap .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(var(--f-neutral-04),.25)}.was-validated .farris-input-wrap .custom-file-input:valid~.custom-file-label{border-color:var(--f-neutral-04)}.was-validated .farris-input-wrap .custom-file-input:valid~.custom-file-label::after{border-color:inherit}.was-validated .farris-input-wrap .custom-file-input:valid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(var(--f-neutral-04),.25)}.farris-input-wrap .custom-select.is-invalid,.farris-input-wrap .form-control.is-invalid,.was-validated .farris-input-wrap .custom-select:invalid,.was-validated .farris-input-wrap .form-control:invalid{border-color:var(--f-neutral-04)}.farris-input-wrap .custom-select.is-invalid:focus,.farris-input-wrap .form-control.is-invalid:focus,.was-validated .farris-input-wrap .custom-select:invalid:focus,.was-validated .farris-input-wrap .form-control:invalid:focus{border-color:var(--f-neutral-04);box-shadow:0 0 0 .2rem rgba(var(--f-neutral-04),.25)}.was-validated .farris-input-wrap .custom-control-input:invalid~.custom-control-label::before{background-color:rgba(var(--f-neutral-04),.75)}.was-validated .farris-input-wrap .custom-control-input:invalid:checked~.custom-control-label::before{background-color:rgba(var(--f-neutral-04),.9)}.was-validated .farris-input-wrap .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(var(--f-neutral-04),.25)}.was-validated .farris-input-wrap .custom-file-input:invalid~.custom-file-label{border-color:var(--f-neutral-04)}.was-validated .farris-input-wrap .custom-file-input:invalid~.custom-file-label::after{border-color:inherit}.was-validated .farris-input-wrap .custom-file-input:invalid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(var(--f-neutral-04),.25)}input:-internal-autofill-selected{background:var(--f-neutral-12)}.f-empty-input-placeholder{padding-top:1.1607375rem;margin-top:.375rem;height:calc(1.5rem + .125rem);margin-bottom:.375rem;box-sizing:content-box}textarea::-webkit-input-placeholder{color:var(--f-text-09)!important}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control{position:relative;flex-grow:1;flex-shrink:1;flex-basis:0;width:1%;margin-bottom:0}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-file{display:flex;align-items:center}.input-group-append,.input-group-prepend{display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-prepend{margin-right:-1px}.input-group-text{display:flex;align-items:center;padding:.1875rem .5rem;margin-bottom:0;font-weight:400;color:var(--f-text-02);text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid var(--f-neutral-04);border-radius:6px}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{height:calc(1.750025rem + 2px);padding:.25rem .3125rem;font-size:.875rem;line-height:1.4286;border-radius:6px}.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{height:calc(1.32145rem + 2px);padding:.125rem .4375rem;font-size:.75rem;line-height:1.4286;border-radius:6px}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.input-group.f-state-focus{outline:0;border-color:var(--f-theme-08);box-shadow:0 0 0,0 0 4px 2px rgba(99,136,255,.12)}.input-group{border:1px solid var(--f-neutral-04);border-radius:6px}.input-group .form-control{border:0;height:1.5rem;box-shadow:none}.input-group .form-control:focus{box-shadow:none}.input-group .input-group-prepend{border-radius:6px 0 0 6px}.input-group .input-group-append{border-radius:0 6px 6px 0}.input-group .input-group-append,.input-group .input-group-prepend{background:#e4e7eb}.input-group .input-group-append>.btn,.input-group .input-group-append>.dropdown,.input-group .input-group-append>.input-group-text,.input-group .input-group-prepend>.btn,.input-group .input-group-prepend>.dropdown,.input-group .input-group-prepend>.input-group-text{border:0}.input-group .input-group-append>.input-group-text,.input-group .input-group-prepend>.input-group-text{background:0 0}.input-group .input-group-append>.input-group-clear,.input-group .input-group-prepend>.input-group-clear{padding:0 8px;border-radius:6px!important;background:var(--f-neutral-12)}.input-group .input-group-append>.input-group-clear .modal_close,.input-group .input-group-prepend>.input-group-clear .modal_close{color:var(--f-text-10);font-size:.75rem}.input-group .input-group-append>.input-group-clear:hover .modal_close,.input-group .input-group-prepend>.input-group-clear:hover .modal_close{color:var(--f-text-08)}.input-group:not(.farris-input-group-readonly):not(.farris-input-group-disable):not(.f-state-readonly):not(.f-state-disabled):not(.f-state-focus):hover{border-color:var(--f-theme-08)}.f-cmp-inputgroup .input-group-before-tips{background:var(--f-neutral-04);border:none;border-right:1px solid var(--f-neutral-04);position:relative;border-radius:6px 0 0 6px;padding:0 8px;display:flex;align-items:center}.f-cmp-inputgroup .input-group-before-tips .f-icon{font-size:14px}.f-cmp-inputgroup .input-group-before-tips .tips-arrow{width:4px;height:4px;margin:-4px 0 0;position:absolute;top:50%;right:0}.f-cmp-inputgroup .input-group-before-tips .tips-arrow::after,.f-cmp-inputgroup .input-group-before-tips .tips-arrow::before{content:"";border-color:transparent;border-style:solid;border-width:4px 4px 4px 0;position:absolute}.f-cmp-inputgroup .input-group-before-tips .tips-arrow::before{left:0;border-right-color:var(--f-neutral-04)}.f-cmp-inputgroup .input-group-before-tips .tips-arrow::after{left:1px;border-right-color:var(--f-neutral-12)}.f-cmp-inputgroup .f-state-disabled,.f-cmp-inputgroup .f-state-editable{border-color:var(--f-neutral-04);background:var(--f-neutral-12)}.f-cmp-inputgroup.input-group{flex-wrap:nowrap}.f-cmp-inputgroup .input-group-append{margin-left:0;background:var(--f-neutral-12)}.f-cmp-inputgroup.input-group>.form-control:not(:last-child){border-radius:6px}.f-cmp-inputgroup.input-group--has-clear>.form-control:last-of-type{border-top-right-radius:0;border-bottom-right-radius:0}.f-cmp-inputgroup .input-group-text{justify-content:center;color:rgba(0,0,0,.25);padding-left:.26786875rem;padding-right:.26786875rem;cursor:pointer}.f-cmp-inputgroup .input-group-text:hover{color:var(--f-theme-05)}.f-cmp-inputgroup .f-state-disabled .input-group-append,.f-cmp-inputgroup .f-state-readonly .input-group-append,.f-cmp-inputgroup .farris-input-group-disable .input-group-append,.f-cmp-inputgroup .farris-input-group-readonly .input-group-append{background:var(--f-neutral-12)}.f-cmp-inputgroup .f-state-disabled .input-group-append:not(.input-append-wrapper),.f-cmp-inputgroup .f-state-readonly .input-group-append:not(.input-append-wrapper),.f-cmp-inputgroup .farris-input-group-disable .input-group-append:not(.input-append-wrapper),.f-cmp-inputgroup .farris-input-group-readonly .input-group-append:not(.input-append-wrapper){display:none}.f-cmp-inputgroup .f-state-disabled .input-append-wrapper,.f-cmp-inputgroup .f-state-readonly .input-append-wrapper,.f-cmp-inputgroup .farris-input-group-disable .input-append-wrapper,.f-cmp-inputgroup .farris-input-group-readonly .input-append-wrapper{color:var(--f-text-02)}.f-cmp-inputgroup .f-state-disabled .input-append-wrapper .input-append-text:hover,.f-cmp-inputgroup .f-state-readonly .input-append-wrapper .input-append-text:hover,.f-cmp-inputgroup .farris-input-group-disable .input-append-wrapper .input-append-text:hover,.f-cmp-inputgroup .farris-input-group-readonly .input-append-wrapper .input-append-text:hover{color:inherit}.f-cmp-inputgroup .f-state-disabled .append-force-show,.f-cmp-inputgroup .f-state-readonly .append-force-show,.f-cmp-inputgroup .farris-input-group-disable .append-force-show,.f-cmp-inputgroup .farris-input-group-readonly .append-force-show{display:flex}.f-cmp-inputgroup .f-state-disabled .input-group-text,.f-cmp-inputgroup .f-state-readonly .input-group-text,.f-cmp-inputgroup .farris-input-group-disable .input-group-text,.f-cmp-inputgroup .farris-input-group-readonly .input-group-text{cursor:default}.f-cmp-inputgroup .f-state-disabled .form-control{color:var(--f-text-02)}.f-cmp-inputgroup .f-state-editable .form-control{color:var(--f-text-02)!important}.f-cmp-inputgroup .f-state-focus{outline:0;border-color:var(--f-theme-08);box-shadow:0 0 0,0 0 4px 2px rgba(99,136,255,.12)}.f-cmp-inputgroup .f-state-readonly{box-shadow:none;background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-cmp-inputgroup .f-state-readonly .form-control{color:var(--f-text-02)}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper{display:flex;flex-direction:row;align-items:center}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--content{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden;height:100%;word-break:break-all}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--content .multi--close{color:var(--f-text-10);font-size:14px;cursor:pointer;margin-left:4px}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--content .multi--close::before{content:"\e11d"}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--item{display:inline-flex;align-items:center;border-radius:4px;margin:0 4px 0 0;padding:0 6px;background:var(--f-neutral-09)}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--item:last-child{margin:0}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--more{flex-shrink:0;font-size:13px;color:var(--f-theme-03);display:flex;align-items:center}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--more .multi--more-icon{font-size:13px}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi--more .multi--more-icon::before{content:"\e11e"}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi-date-display .multi--item{padding:0 14px 0 6px}.f-cmp-inputgroup .f-cmp-inputgroup--multi-wrapper .multi-date-display .multi-date-display-readonly{padding:0 6px}.language-textbox-panel{background:var(--f-neutral-20)!important;margin:.25rem 0 0;border-radius:10px;box-shadow:0 2px 20px 0 rgba(3,18,51,.12)!important}.f-layout-pane.f-page-content-main,.f-splitter-pane.f-splitter-pane-bottom,.f-splitter-pane.f-splitter-pane-left,.f-splitter-pane.f-splitter-pane-right,.f-splitter-pane.f-splitter-pane-top{box-shadow:0 0 8px 0 rgba(0,28,64,.08)}.language-textbox-panel .list-group-item{background:0 0}.f-layout{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:row;flex-wrap:nowrap;overflow:hidden;position:relative}.f-layout-pane.f-page-content-main{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:auto;display:flex}.f-layout-pane.f-page-content-nav{display:flex;flex-direction:column;padding:0;position:relative;z-index:100}.f-layout-pane>.f-layout-resize-bar.f-layout-resize-bar-e{cursor:e-resize;width:.4375rem;right:-.3125rem;height:100%;top:0}.f-layout-pane>.f-layout-resize-bar.f-layout-resize-bar-w{cursor:w-resize;width:.4375rem;left:-.3125rem;height:100%;top:0}.f-layout-pane>.f-layout-resize-bar.f-layout-resize-bar-s{cursor:s-resize;height:.4375rem;bottom:-.3125rem;width:100%;left:0}.f-layout-pane>.f-layout-resize-bar.f-layout-resize-bar-n{cursor:n-resize;height:.4375rem;top:-.3125rem;width:100%;left:0}.f-layout-pane>.f-layout-resize-bar{position:absolute;font-size:.1px;display:block;touch-action:none}.f-layout-pane>.f-layout-resize-bar:hover{background:rgba(42,135,255,.07)}.f-layout-resize-overlay{z-index:98;width:100%;height:100%;cursor:e-resize;background:0 0;position:absolute}.f-layout-horizontal-resize-proxy,.f-layout-vertical-resize-proxy{background:rgba(42,135,255,.07);display:none;z-index:100;position:absolute}.f-layout-horizontal-resize-proxy{width:.4375rem;left:0;height:100%}.f-layout-vertical-resize-proxy{height:.4375rem;top:0;width:100%}.f-list-nav{height:100%;min-height:200px}.f-list-nav .f-list-nav-in{position:relative;height:100%;background-color:#fff;box-shadow:1px 1px 8px 0 rgba(0,28,64,.08);z-index:100}.f-list-nav .f-list-nav-main{display:flex;flex-direction:column;height:100%;overflow-x:hidden}.f-list-nav .f-list-nav-main .f-list-nav-footer,.f-list-nav .f-list-nav-main .f-list-nav-header{flex-shrink:0}.f-list-nav .f-list-nav-main .f-list-nav-content{flex-grow:1;flex-shrink:1;flex-basis:0;overflow-y:auto;padding:.625rem 0}.f-list-nav .f-list-nav-main .f-list-nav-header .f-list-nav-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:.625rem .875rem .375rem!important;border:none!important;font-size:17px;color:var(--f-text-02);line-height:24px}.f-list-nav.f-list-nav-left{padding-right:0}.f-list-nav.f-list-nav-right{padding-left:0}.f-list-nav.f-list-nav-bottom,.f-list-nav.f-list-nav-top{width:100%;height:auto;min-height:auto}.f-list-nav .f-list-nav-in>.ng-resizable-handle{z-index:105}.splitter-pane-collapse-animate{transition:width .5s ease 0s}.f-template-listnav-row .list-nav-link{margin:4px 8px;border-radius:8px;color:var(--f-text-02);display:flex;align-items:center;padding:.5625rem 1.25rem}.f-template-listnav-row .list-nav-link.link-disable{background-color:#F9F9F9}.f-template-listnav-row .list-nav-link .nav-item-name{flex:1;font-size:.875rem;line-height:1.25rem;color:var(--f-text-02);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.f-template-listnav-row .list-nav-link .nav-item-counter{display:inline-block;padding:0 .3125rem;height:.875rem;line-height:.875rem;border-radius:.5rem;font-size:.625rem;color:var(--f-theme-03)}.f-template-listnav-row .list-nav-link:hover{background:var(--f-aid-02)}.f-listview-active .f-template-listnav-row .list-nav-link{border:none;background:var(--f-theme-04);box-shadow:0 4px 10px 0 rgba(var(--f-theme-03),.2)}.f-listview-active .f-template-listnav-row .list-nav-link .nav-item-name{color:#fff}.f-listview-active .f-template-listnav-row .list-nav-link .nav-item-counter{color:#fff;font-size:13px;background:0 0}.f-list-nav .f-list-nav-toggle-sidebar{width:22px;height:22px;background:#fff;border:1px solid var(--f-neutral-07);display:flex;align-items:center;position:absolute;z-index:120;margin:0;cursor:pointer}.f-list-nav .f-list-nav-toggle-sidebar .triangle{color:var(--f-text-02);border:none;font-family:FarrisIcons;width:14px;height:14px;-webkit-font-smoothing:antialiased;font-size:14px;font-weight:400;text-transform:none;display:block;line-height:14px;margin:0 auto}.f-list-nav .f-list-nav-toggle-sidebar .triangle::before{line-height:1}.f-list-nav .f-list-nav-toggle-sidebar .active,.f-list-nav .f-list-nav-toggle-sidebar:hover{border-color:var(--f-theme-03);color:#fff;background-image:linear-gradient(214deg,#3F65FF 0,#4D9AFF 100%);box-shadow:0 3px 8px 0 rgba(var(--f-semantic-info-01),.4)}.f-list-nav.f-list-nav-left .f-list-nav-toggle-sidebar{border-radius:12px;top:14px;right:-12px;left:auto}.f-list-nav.f-list-nav-left .f-list-nav-toggle-sidebar .triangle{border:none}.f-list-nav.f-list-nav-left .f-list-nav-toggle-sidebar.active{right:-12px;transform:rotateY(180deg)}.f-list-nav.f-list-nav-right .f-list-nav-toggle-sidebar{border-radius:12px;top:14px;left:-12px;right:auto}.f-list-nav.f-list-nav-right .f-list-nav-toggle-sidebar .triangle{border:none}.f-list-nav.f-list-nav-right .f-list-nav-toggle-sidebar .triangle::before{content:"\e00d"}.f-list-nav.f-list-nav-right .f-list-nav-toggle-sidebar.active{left:-12px;transform:rotateY(180deg)}.f-list-nav.f-list-nav-top .f-list-nav-toggle-sidebar{border-radius:12px;top:auto;bottom:-12px;right:14px;width:22px;height:22px;left:auto}.f-list-nav.f-list-nav-top .f-list-nav-toggle-sidebar .triangle{border:none}.f-list-nav.f-list-nav-top .f-list-nav-toggle-sidebar .triangle::before{content:"\e00c"}.f-list-nav.f-list-nav-top .f-list-nav-toggle-sidebar.active{top:auto;left:auto;right:14px;bottom:-12px;transform:rotateX(180deg)}.f-list-nav.f-list-nav-bottom .f-list-nav-toggle-sidebar{border-radius:12px;top:-12px;bottom:auto;right:14px;width:22px;height:22px;left:auto}.f-list-nav.f-list-nav-bottom .f-list-nav-toggle-sidebar .triangle{border:none}.f-list-nav.f-list-nav-bottom .f-list-nav-toggle-sidebar.active{right:14px;left:auto;top:-12px;bottom:auto;transform:rotateX(180deg)}.f-template-timeline-new-row .f-timeline{padding-right:26px}.f-template-timeline-new-row .f-timeline .timeline-date{position:relative;padding-bottom:16px;padding-left:18px;color:rgba(0,0,0,.45);font-size:14px;line-height:20px}.f-template-timeline-new-row .f-timeline .timeline-date::before{position:absolute;left:0;top:0;width:1px;height:35px;border-left:1px dotted #dcdcdc;content:"";z-index:9}.f-template-timeline-new-row .f-timeline .timeline-date::after{position:absolute;left:-3px;top:6.5px;display:block;width:7px;height:7px;background:#66B869;border-radius:100%;content:"";z-index:10}.f-template-timeline-new-row .f-timeline .timeline-content-wrapper{padding-left:18px;padding-bottom:13px;border-left:1px dotted #dcdcdc}.f-template-timeline-new-row .f-timeline .timeline-content-wrapper .timeline-content{padding:15px 14px;background:#F9F9F9;border:1px solid #F2F2F2}.f-template-timeline-new-row .f-timeline .timeline-content-wrapper .timeline-content-title{padding-bottom:12px;font-size:14px;line-height:20px;color:rgba(0,0,0,.65);border-bottom:1px solid rgba(220,220,220,.6)}.f-template-timeline-new-row .f-timeline .timeline-content-wrapper .timeline-content-title .title-sum{line-height:22px;font-size:16px;color:#F49730}.f-template-timeline-new-row .f-timeline .timeline-content-wrapper .timeline-content-main .content-data{font-size:0;margin-top:16px}.f-template-timeline-new-row .f-timeline .timeline-content-wrapper .timeline-content-main .content-data li{display:inline-block;padding-right:30px;margin-bottom:18px;font-size:14px;line-height:20px;color:rgba(0,0,0,.65)}.f-template-timeline-new-row .f-timeline.f-timeline-first .timeline-date::before{height:28px;top:7px}.f-template-timeline-new-row .f-timeline.f-timeline-success .timeline-date::after{background:var(--f-semantic-success-01)}.f-template-timeline-new-row .f-timeline.f-timeline-info .timeline-date::after{background-color:var(--f-semantic-info-01)}.f-template-timeline-new-row .f-timeline.f-timeline-error .timeline-date::after{background-color:var(--f-semantic-danger-01)}.f-template-timeline-new-row .f-timeline.f-timeline-warn .timeline-date::after{background-color:var(--f-semantic-warning-01)}.f-list-view .f-list-view-hover,.f-tmpl-subgrid-by-card .subgrid-by-card-item.f-state-edit{background:linear-gradient(270deg,rgba(235,244,255,.6) 0,#EBF4FF 100%)}.f-listview-fill{flex-grow:1;flex-shrink:1;flex-basis:0;overflow:hidden}.f-listview-fill .f-list-view{height:100%}.f-listview-fill .f-list-view .f-list-view-footer,.f-listview-fill .f-list-view .f-list-view-header{flex-shrink:0}.f-listview-fill .f-list-view .f-list-view-content{overflow-y:auto;flex-grow:1;flex-shrink:1;flex-basis:0}.f-list-view{display:flex;flex-direction:column;overflow:hidden}.f-list-view .f-list-view-content{flex:1;overflow:auto}.f-list-view .f-list-view-group{padding:0}.f-list-view .f-paging-wrapper{padding:14px 0}.f-list-view .f-list-view-group-item{display:flex;align-items:center;float:none;text-align:initial}.f-list-view .f-list-view-group-item.f-none-border{border-bottom:0}.f-list-view .f-list-view-group-item.f-listview-active,.f-list-view .f-list-view-group-item.f-listview-hover{cursor:pointer;color:#424347}.f-list-view .f-list-view-group-item.f-listview-active{border-color:#529dff}.f-list-view .f-list-view-group-item.f-un-select{color:#848c9a}.f-list-view .f-list-view-group-item .f-list-content{flex:1 1 auto;width:100%}.f-list-view .f-list-view-draggable-item{border:1px solid #e2e3e5;background-color:#fafbfd;border-radius:10px;margin:4px 2px}.f-list-view .f-list-view-draggable-item.f-listview-hover{cursor:pointer;color:#424347;background:#edf5ff!important}.f-list-view .f-list-view-draggable-item.f-listview-hover .f-list-remove-icon{display:initial}.f-list-view .f-list-view-draggable-item.f-listview-active{border-color:#529dff}.f-list-view .f-list-view-draggable-item.moving{opacity:0}.f-list-view .f-list-view-draggable-item.draggable-item--text-truncate .f-list-content{overflow:hidden}.f-list-view .f-list-view-draggable-item.draggable-item--text-truncate .f-list-content div{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.f-list-view .f-list-select{padding:0 0 0 14px}.f-list-view .f-list-select .listview-checkbox{margin:.25rem 0}.f-list-view .f-list-pin{color:#2986ff;padding:0 14px 0 0}.f-list-view .f-list-remove{width:30px;color:#f4625f;padding:0 14px 0 0}.f-list-view .f-list-remove-icon{display:none}.f-list-view .f-list-handle{padding:0 14px 0 0}.f-list-view .f-list-view-emptydata .f-empty-title{font-size:14px;line-height:22px;color:#999;padding:20px 0;text-align:center}.f-list-view.small-item .f-list-select{padding:initial}::highlight(search-result){background-color:#F7B500;color:#fff}.f-list-view-group-item .custom-control.listview-checkbox{margin-right:0;padding-right:4px}.f-listview-card-content-fill .f-list-content{height:100%;display:flex;flex-direction:column}.f-listview-card-content-fill .f-list-content>*{height:100%}.f-tmpl-card-listview--header-multicontent02 .f-list-view{margin:0}.f-tmpl-card-listview--header-multicontent02 .f-list-view-group{margin:0 -10px}.f-tmpl-card-listview--header-multicontent02 .f-list-view-content{overflow-x:hidden}.f-tmpl-card--header-multicontent02{position:relative;margin:0 10px 20px}.f-tmpl-card--header-multicontent02 .f-list-select{position:absolute;padding:0!important;top:10px;left:14px}.f-tmpl-card--header-multicontent02 .f-list-select .custom-checkbox{margin:0;padding:0}.f-tmpl-card--header-multicontent02 .f-list-select .custom-control-label::before{font-size:1rem}.f-tmpl-card--header-multicontent02 .header-multicontent02{background:#FEFEFF;border:1px solid #E9ECF3;border-radius:6px;width:310px;margin:0}.f-tmpl-card--header-multicontent02 .header-multicontent02 .text-label{color:#5A5E66}.f-tmpl-card--header-multicontent02 .header-multicontent02 .f-emphasize{font-size:16px;color:var(--f-semantic-warning-01)}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--header{padding:0 0 0 38px;height:40px;display:flex;align-items:center;border-bottom:1px solid #E9ECF3}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--header .f-title{margin:0;flex-shrink:1;flex-grow:1;flex-basis:0;font-size:16px;font-weight:600;color:#2D2F33;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--header .f-state{margin:0 0 0 8px}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--header .f-state .badge{border-radius:20px 0 0 20px;height:28px;line-height:28px;padding:0 13px}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--content{padding:14px 0 0 14px;color:#2D2F33;font-size:13px}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--content p{margin:0 0 10px}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer{padding:8px 14px 18px}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer p{margin:0}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer .footer--auxiliary{width:32px;border-radius:16px;margin:0 8px 0 0}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer .footer--auxiliary img{display:block;width:32px;height:32px}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer .text--name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:13px;color:#5A5E66}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer .icon-btn{padding:2px;margin:0 8px;cursor:pointer}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer .icon-btn.disabled{color:var(--f-text-07)}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer .icon-btn:hover{color:var(--f-theme-03)}.f-tmpl-card--header-multicontent02 .header-multicontent02 .header-multicontent02--footer .icon-btn .f-icon{font-size:14px}.f-tmpl-list01-container{border-top:1px solid rgba(0,0,0,.07);border-bottom:1px solid rgba(0,0,0,.07);margin-top:-1px}.f-tmpl-list01-container .f-list-select{padding-right:0!important}.f-tmpl-list01-container .gutter{margin:0 30px 0 0}.f-tmpl-list01-container .list01--header{font-size:13px;margin:0 0 3px}.f-tmpl-list01-container .list01--header .f-title{font-weight:600;margin:0 8px 0 0;vertical-align:top}.f-tmpl-list01-container .list01--header li{display:inline-block;margin:0 30px 3px 0}.f-tmpl-list01-container .list01--header li:last-child{margin-right:0}.f-tmpl-list01-container .list01--header .badge{border-radius:10px;line-height:20px;padding:0 8px}.f-tmpl-list01-container .list01--des{font-size:12px;color:rgba(0,0,0,.5)}.modal-header,.modal-header .close,.modal-header .close:not(:disabled):not(.disabled):focus,.modal-header .close:not(:disabled):not(.disabled):hover,.ng-busy-default-sign,.ng-busy-default-text{color:var(--f-text-02)}.f-tmpl-list01-container .list01--des span{display:inline-block;margin-bottom:3px}.f-tmpl-list01-container .list01--des span:last-child{margin-right:0}.f-tmpl-list01-container .list01--content{padding:16px 12px 16px 8px}.f-tmpl-list01-container .list01--toolbar{width:150px;padding:0 14px;text-align:right}.f-list-view-footer .f-paging-wrapper{padding:0!important}.f-list-view-footer .f-paging-wrapper .pagination-container{height:2.5rem}.f-list-view-footer .f-paging-wrapper .pagination{padding:.875rem 0 0}.f-component-loading{z-index:1060;top:0;left:0;right:0;bottom:0;position:absolute}.farris-loading-backdrop{position:absolute;top:0;left:0;right:0;bottom:0;z-index:1061;opacity:0;background-color:transparent}.farris-loading{position:absolute;top:50%;left:50%}.ng-busy-default-wrapper{text-align:center}.ng-busy-default-sign{position:relative;display:flex;align-items:center;z-index:1063;padding:8px 16px 8px 8px;border:0 solid #E5E9EF;border-radius:8px;box-shadow:0 6px 16px -8px rgba(0,0,0,.06),0 0 30px 12px rgba(0,0,0,.04);background:#fff}.ng-busy-default-text{display:inline-block;margin-left:.375rem;max-width:25rem;text-align:left;padding:0 4px;font-size:15px}.ng-busy-default-spinner{position:relative;display:inline-block;width:1.5625rem;height:1.5625rem;vertical-align:middle}.ng-busy-default-spinner div{position:absolute;left:44.5%;top:37%;width:10%;height:26%;background:#666;border-radius:3.125rem;box-shadow:0 0 3px rgba(0,0,0,.2);opacity:0;animation:busy-spinner-anim 1s linear infinite}.f-loading-round{font-size:10px;margin:0;width:100%;height:100%;border-radius:50%;position:relative;animation:loadingRountAnimation 1s infinite linear;transform:translateZ(0)}.f-loading-round::before{width:50%;height:50%;background:var(--f-theme-03);border-radius:100% 0 0;position:absolute;top:0;left:0;content:""}.f-loading-round::after{background:#fff;width:90%;height:90%;border-radius:50%;content:"";margin:auto;position:absolute;top:0;left:0;bottom:0;right:0}@keyframes loadingRountAnimation{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.f-loading-dot-wrapper .dot1{background:var(--f-semantic-danger-01)}.f-loading-dot-wrapper .dot2{background:var(--f-semantic-warning-01)}.f-loading-dot-wrapper .dot3{background:var(--f-semantic-success-01)}.f-loading-dot{position:absolute;margin:auto;top:0;bottom:0;left:0;right:0;width:100%;height:100%;animation:fLoadingDotRotate 1.8s linear infinite;overflow:hidden}.f-loading-dot-wrapper{overflow:hidden;position:relative;height:100%;width:100%}.f-loading-dot-wrapper .dot{position:absolute;margin:auto;width:25%;height:25%;border-radius:100%;transition:all 1s ease}.f-loading-dot-wrapper .dot1{top:0;bottom:0;left:0;animation:dotsY 1.8s linear infinite}.f-loading-dot-wrapper .dot2{left:0;right:0;top:0;animation:dotsX 1.8s linear infinite}.f-loading-dot-wrapper .dot3{top:0;bottom:0;right:0;animation:dotsY 1.8s linear infinite}.f-loading-dot-wrapper .dot4{background:var(--f-semantic-info-01);left:0;right:0;bottom:0;animation:dotsX 1.8s linear infinite}@keyframes fLoadingDotRotate{0%{transform:rotate(0)}10%{width:100%;height:100%}66%{width:25%;height:25%}100%{transform:rotate(360deg);width:100%;height:100%}}@keyframes dotsY{66%{opacity:.3;width:25%}77%{opacity:1;width:0}}@keyframes dotsX{66%{opacity:.3;height:25%}77%{opacity:1;height:0}}.modal-tips{padding:.5625rem .625rem .5625rem 1.25rem}.modal-tips .modal-tips-content{margin-top:0;margin-left:2.25rem;margin-right:1.75rem}.modal-tips .modal-tips-title{color:var(--f-text-04);font-size:.875rem;line-height:1.25rem;font-weight:400;margin:0}.modal-tips .toast-msg{margin:0;word-break:break-all;font-size:1rem;line-height:1.375rem}.modal-tips .only-toast-msg{color:var(--f-text-04);font-size:1rem;line-height:1.375rem}.modal-tips .toast-msg-title{margin:1px 0 0;word-break:break-all;font-size:1rem;line-height:1.375rem;color:var(--f-text-01)}.modal-tips .toast-msg-detail{word-break:break-all;color:var(--f-text-06);font-size:.875rem;margin:.625rem 0 0}.modal-tips .modal-tips-iconwrap .f-icon{font-size:1.625rem;margin-right:.75rem}.modal-footer .btn,.modal-footer .k-button{font-size:.8125rem;padding:.375rem 1.3125rem}.message-container{height:8.75rem;display:flex;flex-direction:column}.message-container .btn{min-width:3.75rem;margin:auto .3125rem}.farris-messager{display:flex}.farris-messager .icon{background-position:center .1875rem;background-size:4.375rem;background-repeat:no-repeat;width:4.375rem;height:4.375rem}.farris-messager .msg{flex:1 1 auto}.modal-message .modal-tips,.modal-message .modal-tips.messager-type-error{padding:1.875rem 1.5rem 1.75rem 1.875rem}.modal-message .modal-tips .modal-tips-content{padding:0}.modal-message .modal-tips .modal-tips-iconwrap{margin:0}.modal-message .modal-tips .modal-tips-iconwrap .f-icon{font-size:1.625rem}.modal-message .modal-footer{background:#fff!important;box-shadow:none;border:none;padding:0 1.5rem 1.25rem 1.875rem}.modal-message .modal-cotnent--has-header .modal-tips{padding:1.875rem 1.5rem 1.75rem 1.875rem}.modal.farris-modal .modal-message.model-dialog-maximize{width:60%!important;max-width:50rem!important;height:auto!important;max-height:60%!important;top:0!important;left:0!important;margin:0!important}.modal,.modal-backdrop{top:0;left:0;bottom:0;right:0}.modal.farris-modal .modal-message .modal-body{padding:0}.modal-open{overflow:hidden}.modal-open .modal{overflow-y:auto}.modal{position:fixed;z-index:1050;display:none;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-25%)}@media screen and (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:translate(0,0)}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - .5rem * 2)}.modal-dialog-centered::before{display:block;height:calc(100vh - .5rem * 2);content:""}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:0 solid #E5E9EF;border-radius:16px;box-shadow:0 2px 12px 0 rgba(0,0,0,.06);outline:0}.modal-backdrop{position:fixed;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.15}.modal-title{margin-bottom:0;line-height:1.375rem}.modal-body{position:relative;flex-grow:1;flex-shrink:1;flex-basis:auto;padding:.625rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:3.125rem;height:3.125rem;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:31.25rem;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - 1.75rem * 2)}.modal-dialog-centered::before{height:calc(100vh - 1.75rem * 2)}.modal-content{box-shadow:0 2px 12px 0 rgba(0,0,0,.06)}.modal-sm{max-width:18.75rem}}@media (min-width:888px){.modal-lg{max-width:50rem}}.modal-header{display:flex;justify-content:space-between;flex-shrink:0;padding:.75rem .5rem .75rem 1.125rem;background:#fff;align-items:center;border-top-left-radius:16px;border-top-right-radius:16px;border-bottom:none}.modal-header .close{opacity:1;padding:.1875rem;margin:-.25rem 0;border:1px solid transparent;font-size:1rem;width:1.6607375rem;height:1.6607375rem}.modal-title{font-size:1rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.modal-footer,.showtype-modal .fe-modal-footer-base{display:flex;align-items:center;justify-content:flex-end;flex-shrink:0;background:var(--f-neutral-00);padding:.875rem 1.5rem;box-shadow:none}.modal-footer>:not(:first-child),.showtype-modal .fe-modal-footer-base>:not(:first-child){margin-left:.3125rem}.modal-footer>:not(:last-child),.showtype-modal .fe-modal-footer-base>:not(:last-child){margin-right:.3125rem}.modal-open .modal{overflow-x:auto}.modal.farris-modal .actions{flex:1;margin:-.25rem 0}.modal.farris-modal .actions ul{list-style:none;margin:0;padding:0;display:flex;justify-content:flex-end}.modal.farris-modal .actions .f-btn-icon{cursor:pointer;color:var(--f-text-07);text-align:center}.modal.farris-modal .actions .f-btn-icon:hover{color:var(--f-theme-05)}.modal.farris-modal .actions .f-btn-icon:active{color:var(--f-theme-01)}.modal.farris-modal .actions .modal-tips-iconwrap .f-icon{font-size:2rem}.fe-cmp-page-modal .action-list .f-icon,.fe-cmp-page-modal .close-icon .f-icon{font-size:14px}.modal.farris-modal .actions .modal-tips-iconwrap .modal-tips-content{padding-top:.25rem}.modal.farris-modal .ng-draggable{cursor:move}.modal.farris-modal .modal-dialog{max-width:none;margin:0;top:50%;left:50%;position:absolute;pointer-events:all}.modal.farris-modal.fade .modal-dialog{transform:none;transition:none}.modal.farris-modal .modal-content{height:100%;overflow:hidden}.modal.farris-modal .modal-body{padding:0}.farris-messager{flex-direction:column;position:absolute;top:0;bottom:0;left:0;right:0}.farris-messager .modal-tips{margin-bottom:0;flex-shrink:1;flex-grow:1;flex-basis:auto;overflow-y:auto;display:flex;flex-direction:row}.farris-messager .modal-tips .modal-tips-iconwrap{margin:.5625rem 0;padding:0}.farris-messager .modal-tips .modal-tips-content{margin:0;padding:.5625rem .9375rem .5625rem 0}.farris-messager .fixdiv{overflow:auto}.f-modal-fitContent{display:flex!important;align-items:center;justify-content:center}.f-modal-fitContent-scroll{align-items:flex-start}.f-modal-fitContent .modal-dialog{position:relative!important;top:0!important;left:0!important;margin:1.875rem 0!important;min-height:7.5rem}.f-modal-fitContent .farris-messager{position:relative!important}.overlay-container{position:fixed;z-index:9999;pointer-events:none;top:0;left:0;height:100%;width:100%}.fe-cmp-page-modal .action-wrapper{position:absolute;right:-12px;top:-12px;z-index:400}.fe-cmp-page-modal .action-wrapper .close-icon{background:rgba(0,0,0,.4);width:22px;height:22px;border-radius:12px;color:#fff;text-align:center;line-height:22px;display:block;cursor:pointer}.fe-cmp-page-modal .action-wrapper .close-icon:hover{background:rgba(0,0,0,.6)}.fe-cmp-page-modal .action-list{position:absolute;right:-32px;top:20px;color:rgba(255,255,255,.85)}.fe-cmp-page-modal .action-list .action-list--item{display:block;width:32px;height:32px;text-align:center}.fe-cmp-page-modal .action-list .action-list--icon{display:block;cursor:pointer;margin:0 auto;line-height:32px;border-radius:0 3px 3px 0}.fe-cmp-page-modal .action-list .action-list--icon:hover{color:#fff}.fe-cmp-page-modal .action-list .max-icon{background:linear-gradient(-63deg,#517BFF 0,#74A1FF 95%)}.fe-cmp-page-modal .action-list .close-icon{background:linear-gradient(-51deg,#FE6568 0,#FA6568 0,#F67574 100%)}.fe-cmp-page-modal .modal-body{border-radius:16px}.fe-cmp-page-modal.modal .modal-content{overflow:visible}.farris-modal{background-color:rgba(0,0,0,.45)}.farris-nav{display:flex;flex-direction:row;align-items:center;border-bottom:1px solid #e9e9e9;overflow:hidden;border-color:var(--f-neutral-06)!important}.farris-nav-item{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.farris-nav-item-link{padding:.75rem 1rem;cursor:pointer;border-bottom:2px solid transparent}.farris-nav-item-link-text{position:relative;font-size:1rem;font-weight:400}.farris-nav-item-tag{position:absolute;right:-.75rem;top:calc(10px - 100%);padding:0 .375rem;color:#fff;font-size:.75rem;line-height:1.125rem;border-radius:1.125rem;background-color:var(--f-semantic-danger-01)}.nav,.pagination{padding-left:0;list-style:none}.farris-nav.farris-nav-vertical{flex-direction:column;align-items:flex-start}.farris-nav.farris-nav-vertical .farris-nav-item{width:100%}.farris-nav-item-link-text{color:var(--f-text-03)}.farris-nav-item.active .farris-nav-item-link{border-color:var(--f-theme-03)}.farris-nav-item.active .farris-nav-item-link-text{color:var(--f-theme-03)}.farris-nav-item.disabled .farris-nav-item-link-text{color:var(--f-text-07)}.farris-nav-item:hover:not(.disabled):not(.active) .farris-nav-item-link-text{color:var(--f-theme-05)}.nav{display:flex;flex-wrap:wrap;margin-bottom:0}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:6px;border-top-right-radius:6px}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:6px}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--f-text-00);background:var(--f-theme-04)}.nav-fill .nav-item{flex-grow:1;flex-shrink:1;flex-basis:auto;text-align:center}.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.farris-notify{position:fixed;z-index:999999}.farris-notify.toasty-position-top-left{top:.75rem;left:.75rem}.farris-notify.toasty-position-top-right{top:.75rem;right:.75rem}.farris-notify.toasty-position-bottom-right{bottom:.75rem;right:.75rem}.farris-notify.toasty-position-bottom-left{bottom:.75rem;left:.75rem}.farris-notify.toasty-position-top-center{top:.75rem;left:50%;transform:translate(-50%,0)}.farris-notify.toasty-position-bottom-center{bottom:.75rem;left:50%;transform:translate(-50%,0)}.farris-notify.toasty-position-center-center{top:50%;left:50%;transform:translate(-50%,0)}.f-message-strip .toast,.farris-notify .toast{margin:0 0 .625rem;padding:0;width:24rem;border:1px solid var(--f-neutral-08);background:#fff;display:table;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);border-radius:8px;position:relative}.f-message-strip .toast .toast-close,.farris-notify .toast .toast-close{position:absolute;border:0;top:.625rem;right:.625rem;color:rgba(0,0,0,.25)}.f-message-strip .toast.toasty-type-danger,.f-message-strip .toast.toasty-type-info,.f-message-strip .toast.toasty-type-success,.f-message-strip .toast.toasty-type-warning,.farris-notify .toast.toasty-type-danger,.farris-notify .toast.toasty-type-info,.farris-notify .toast.toasty-type-success,.farris-notify .toast.toasty-type-warning{border-color:var(--f-neutral-08)}.f-message-strip .toast .toast-close .modal_close,.farris-notify .toast .toast-close .modal_close{font-size:1rem}.f-message-strip .toast .toast-close.f-btn-icon.f-bare,.farris-notify .toast .toast-close.f-btn-icon.f-bare{outline:unset}.f-message-strip .toast .modal-tips,.farris-notify .toast .modal-tips{padding:.625rem .75rem .625rem 1.25rem}.f-message-strip .toast .modal-tips-content,.farris-notify .toast .modal-tips-content{margin:0 1.75rem}.f-message-strip .toast .modal-tips-iconwrap .f-icon,.farris-notify .toast .modal-tips-iconwrap .f-icon{font-size:1rem;border-radius:100%;vertical-align:middle}.f-message-strip .toast.toasty-type-info .modal-tips-iconwrap .f-icon,.farris-notify .toast.toasty-type-info .modal-tips-iconwrap .f-icon{box-shadow:0 3px 8px 0 rgba(var(--f-semantic-info-01),.3)}.f-message-strip .toast.toasty-type-success .modal-tips-iconwrap .f-icon,.farris-notify .toast.toasty-type-success .modal-tips-iconwrap .f-icon{box-shadow:0 3px 8px 0 rgba(var(--f-semantic-success-01),.3)}.f-message-strip .toast.toasty-type-danger .modal-tips-iconwrap .f-icon,.farris-notify .toast.toasty-type-danger .modal-tips-iconwrap .f-icon{box-shadow:0 3px 8px 0 rgba(var(--f-semantic-danger-01),.3)}.f-message-strip .toast.toasty-type-warning .modal-tips-iconwrap .f-icon,.farris-notify .toast.toasty-type-warning .modal-tips-iconwrap .f-icon{box-shadow:0 3px 8px 0 rgba(var(--f-semantic-warning-01),.3)}.farris-notify .toast.toasty-type-danger,.farris-notify .toast.toasty-type-info,.farris-notify .toast.toasty-type-success,.farris-notify .toast.toasty-type-warning{background:#fff}.f-message-strip .toast{width:100%;box-shadow:none}.f-message-strip .toast.toasty-type-info{background:var(--f-semantic-info-03)}.f-message-strip .toast.toasty-type-success{background:var(--f-semantic-success-03)}.f-message-strip .toast.toasty-type-danger{background:var(--f-semantic-danger-03)}.f-message-strip .toast.toasty-type-warning{background:var(--f-semantic-warning-03)}.f-message-strip .toast .modal-tips{display:flex;padding:.5rem 1rem}.f-message-strip .toast .modal-tips-content{margin:0}.f-catch-attention-debounce{position:relative;z-index:1;outline:var(--f-theme-03) solid 1px;animation:debounceAttention .2s ease 0s infinite normal}@keyframes debounceAttention{0%{outline:solid var(--f-theme-03)}100%{outline:solid 18px}}.farris-notify .toast-title-beforeshow{opacity:0}@keyframes farrisMoveUpIn{0%{transform:translateY(-100%);transform-origin:0 0;opacity:0}100%{transform:translateY(0);transform-origin:0 0;opacity:1}}@keyframes farrisMoveUpOut{0%{transform:translateY(0);transform-origin:0 0;opacity:1}100%{transform:translateY(-100%);transform-origin:0 0;opacity:0}}.f-cmp-footer-accordion.f-state-collapse .f-toolbar .toolbar--collapse-icon,.f-cmp-number-spinner .btn-number-flag-up .number-arrow-chevron,.pagination .pg-pagelist.show .pg-pagelist-info .f-icon{transform:rotate(180deg)}.toast.fadeIn{animation:farrisMoveUpIn .2s linear}.toast.fadeOut{animation:farrisMoveUpOut .2s linear}.f-cmp-number-spinner .sub-btn-group{border-right:1px solid var(--f-neutral-04)}.f-cmp-number-spinner .number-arrow-chevron{font-size:12px;min-width:12px}.f-cmp-number-spinner .input-group .btn-group-number,.input-group .btn-group-number{background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-cmp-number-spinner .input-group .btn-group-number.btn-number-flag .number-arrow-chevron,.input-group .btn-group-number.btn-number-flag .number-arrow-chevron{color:var(--f-text-07);border-left:1px solid var(--f-neutral-04)}.f-cmp-number-spinner .input-group .btn-group-number.btn-number-flag .number-arrow-chevron:nth-child(2),.input-group .btn-group-number.btn-number-flag .number-arrow-chevron:nth-child(2){border-top:1px solid var(--f-neutral-04)}.f-cmp-number-spinner .input-group .btn-group-number.btn-number-flag .number-arrow-chevron:active,.f-cmp-number-spinner .input-group .btn-group-number.btn-number-flag .number-arrow-chevron:hover,.input-group .btn-group-number.btn-number-flag .number-arrow-chevron:active,.input-group .btn-group-number.btn-number-flag .number-arrow-chevron:hover{color:var(--f-theme-05);background:var(--f-neutral-12)}.f-cmp-number-spinner .input-group .btn-group-number.btn-number-flag .number-arrow-chevron.not-allowed,.input-group .btn-group-number.btn-number-flag .number-arrow-chevron.not-allowed{background:var(--f-neutral-12)}.input-group .btn-group-number{height:1.5rem;flex-direction:column;background-color:var(--f-neutral-12);border-left:1px solid var(--f-neutral-04);width:1.5rem;overflow:hidden;margin:0;flex-shrink:0}.input-group .btn-group-number .btn-number-flag{height:50%;display:flex;box-shadow:none;padding:0 5px;margin-left:1px;overflow:hidden;transition:all .1s linear}.input-group .btn-group-number .btn-number-flag .number-arrow-chevron{flex:1;line-height:1}.input-group .btn-group-number .btn-number-flag:hover{height:60%!important}.input-group .btn-group-number .btn-number-flag:nth-child(2){border-top:1px solid var(--f-neutral-04);border-top-right-radius:0}input::-webkit-inner-spin-button,input::-webkit-outer-spin-button{-webkit-appearance:none!important;margin:0}.input-group.number-range{position:relative}.input-group.number-range .input-container{display:flex;padding:0}.input-group.number-range .input-container .sub-input-group{flex:1;position:relative;display:flex;transition:all .3s ease-out}.input-group.number-range .input-container .sub-input-group .sub-input{width:100%;border:none;outline:0;background-color:rgba(0,0,0,0);min-width:2px;padding:.125rem 4px .125rem .5rem}.input-group.number-range .input-container .sub-input-group .btn-group-number .btn-number-flag,.input-group.number-range .input-container .sub-input-group:first-child .sub-btn-group{border-radius:0}.input-group.number-range .input-container .spliter{width:15px;text-align:center}.number-range .input-container .sub-input-group .sub-input{background-color:transparent}.number-range .input-container .sub-input-group .sub-input::-moz-placeholder{color:var(--f-text-09)}.number-range .input-container .sub-input-group .sub-input::placeholder{color:var(--f-text-09)}.number-range .input-container .sub-input-group .sub-input:disabled::-moz-placeholder,.number-range .input-container .sub-input-group .sub-input[readonly]::-moz-placeholder{color:var(--f-text-09)}.number-range .input-container .sub-input-group .sub-input:disabled::placeholder,.number-range .input-container .sub-input-group .sub-input[readonly]::placeholder{color:var(--f-text-09)}.number-range .sub-input-group:last-of-type .sub-btn-group{border-right:none}.f-order .f-list-view-emptydata .f-empty-title{padding:10px 0;margin-bottom:0}.f-order .f-order-item{border:none;background-color:initial}.f-order .f-order-item.f-listview-hover{cursor:pointer;color:#424347;background:#edf5ff!important}.f-order .f-order-item.f-listview-hover .f-list-remove-icon{display:initial}.f-order .f-order-item.f-listview-active{border-color:none}.f-order .f-order-item.moving{opacity:0}.f-order .f-order-add-button{display:flex!important;align-items:center!important}.f-order .f-order-add-icon{width:1.2rem;height:1.2rem;background-color:#f0f8ff;border-radius:1.2rem;display:inline-block;margin-right:4px}.f-order .f-order-add-icon .f-icon{line-height:1.2!important}.f-order .f-order-header{display:flex;margin:4px 60px 0 0}.f-order .f-order-header .f-order-header-order-field,.f-order .f-order-header .f-order-header-order-type{flex:1}.f-order .f-order-header .f-order-header-order-field{margin:0 4px 0 10px}.f-order .f-order-header .f-order-header-order-type{margin:0 10px 0 4px}.f-order-item-content{display:flex;margin:4px 0}.f-order-item-content .f-order-item-content-order-field,.f-order-item-content .f-order-item-content-order-type{flex:1}.f-order-item-content .f-order-item-content-order-field{margin:0 4px 0 10px}.f-order-item-content .f-order-item-content-order-type{margin:0 10px 0 4px}.f-cmp-footer{display:flex;flex-direction:column;padding:.875rem;margin:0;background:var(--f-neutral-19);border-radius:4px;box-shadow:0 4px 10px 0 rgba(31,35,41,.1)}.f-cmp-footer .f-cmp-footer-header{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:space-between;margin:0 0 .5rem;border-bottom:1px dashed rgba(0,0,0,.1);padding:0 0 .75rem}.f-cmp-footer .f-cmp-footer-header .f-content{display:inline-flex;align-items:center;white-space:nowrap;flex-shrink:1;flex-grow:1;flex-basis:0}.f-cmp-footer .f-cmp-footer-header .f-toolbar{min-width:10rem;flex-shrink:0;display:inline-flex;align-items:center;justify-content:flex-end;color:var(--f-text-04);margin-left:auto}.f-cmp-footer .f-cmp-footer-header .f-toolbar .toolbar--collapse{cursor:pointer}.f-cmp-footer .f-cmp-footer-header .f-toolbar .toolbar--collapse-icon{font-family:FarrisIcons;margin:0 .375rem;font-size:.875rem;transition:transform .1s linear}.f-cmp-footer .f-cmp-footer-header .f-toolbar .toolbar--collapse-icon:hover{color:var(--f-theme-01)}.f-cmp-footer-accordion.f-state-collapse .f-cmp-footer-header{border-bottom:none;margin-bottom:0;padding-bottom:0}.f-cmp-footer-accordion.f-state-collapse .f-cmp-footer-content{display:none}.f-tmpl-footer-same-gutter{margin:0 10rem 0 0}.f-page-header-el-mt,.f-page-header-el-my{margin-top:.8125rem}.f-page-header-el-mb,.f-page-header-el-my{margin-bottom:.8125rem}.f-cmp-footer-hasgap{position:relative}.f-cmp-footer-nogap::before{display:none!important}#page-header,.f-page-header,.f-pt-header{z-index:unset}.f-page-card #page-header,.f-page-card .f-page-header,.f-page-card .f-pt-header{z-index:105!important}.f-page-header{flex-shrink:0;background:var(--f-neutral-00);box-shadow:none}.f-page-header-el-mx{margin-left:.875rem;margin-right:.875rem}.f-page-header-base{padding:.75rem .875rem;min-height:2.875rem;display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:space-between}.f-page-header-base .f-title{display:inline-flex;align-items:center}.f-page-header-base .f-title .f-title-text{font-size:1.0625rem;line-height:1.625rem;color:var(--f-text-01);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0 .875rem 0 0}.f-page-header-base .f-title .f-title-icon{display:inline-flex;width:1.625rem;height:1.625rem;line-height:1.625rem;text-align:center;background:var(--f-ornament-02);border-radius:.25rem;color:var(--f-text-00);justify-content:center;align-items:center;flex-shrink:0;overflow:hidden;margin:0 .625rem 0 0}.f-page-header-base .f-title .f-title-icon img{display:block;width:1.625rem;height:1.625rem}.f-page-header-base .f-title .f-title-icon .f-icon::before{vertical-align:bottom}.f-page-header-base .f-title .f-title-subtitle{padding:0 0 0 .875rem;font-size:.8125rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-left:1px solid var(--f-neutral-08);margin:0 .875rem 0 0}.fv-grid-hierarchy-cell,.fv-tree{border-width:1px;border-style:solid}.f-page-header-base .f-title .f-title-pagination,.f-page-header-base .f-title .f-title-status{margin:0 .875rem 0 0}.f-page-header-base .f-title .f-title-pagination span{width:1.25rem;height:1.25rem;margin:0 .375rem 0 0;color:var(--f-text-02);line-height:1.125rem;border-width:1px;border-style:solid;border-color:var(--f-neutral-08);border-radius:6px;background:var(--f-neutral-12);cursor:pointer}.f-page-header-base .f-title .f-title-pagination span.f-state-disabled{cursor:default;color:var(--f-text-07);border-color:var(--f-neutral-05);background:var(--f-neutral-09)}.f-page-header-base .f-title .f-title-pagination span:not(.f-state-disabled):hover{color:var(--f-theme-05);border-color:var(--f-theme-05);background:var(--f-neutral-12)}.f-page-header-base .f-title .f-title-pagination span:last-child{margin:0}.f-page-header-base .f-content{display:inline-flex;align-items:center;white-space:nowrap;flex-shrink:1;flex-grow:1;flex-basis:0}.f-page-header-base .f-toolbar{flex-shrink:0;display:inline-flex;align-items:center;justify-content:flex-end;color:var(--f-text-04);margin-left:auto}.f-text-orna-bill,.f-text-orna-dict,.f-text-orna-manage,.f-text-orna-param,.f-text-orna-query{color:var(--f-text-00)!important}.f-page-header-base .f-toolbar-viewchange{margin-left:.375rem}.page-item:first-child .page-link,.page-link{margin-left:0}.f-text-orna-manage{background:linear-gradient(135deg,#4190FF 0,#657CFF 100%)!important;box-shadow:0 3px 10px 0 rgba(var(--f-ornament-03-start),.3)}.f-text-orna-dict{background:linear-gradient(135deg,#4EC87A 0,#52D389 100%)!important;box-shadow:0 3px 10px 0 rgba(var(--f-ornament-05-start),.3)}.f-text-orna-bill{background:linear-gradient(135deg,#1FC8DC 0,#41D2BD 100%)!important;box-shadow:0 3px 10px 0 rgba(var(--f-ornament-02-start),.3)}.f-text-orna-query{background:linear-gradient(135deg,#FC8249 0,#FE9539 100%)!important;box-shadow:0 3px 10px 0 rgba(var(--f-ornament-01-start),.3)}.f-text-orna-param{background:linear-gradient(135deg,#8B82FF 0,#A082FF 100%)!important;box-shadow:0 3px 10px 0 rgba(var(--f-ornament-04-start),.3)}.page-link,.page-link:hover{background-color:var(--f-neutral-12)}.f-color-orna-manage{color:var(--f-ornament-03-start)!important}.f-color-orna-dict{color:var(--f-ornament-05-start)!important}.f-color-orna-bill{color:var(--f-ornament-02-start)!important}.f-color-orna-query{color:var(--f-ornament-01-start)!important}.f-color-orna-param{color:var(--f-ornament-04-start)!important}.pagination{display:flex;border-radius:6px}.page-link{position:relative;display:block;padding:.1875rem;line-height:1rem;color:var(--f-text-02);border:1px solid var(--f-neutral-08)}.page-item:first-child .page-link,.pagination-lg .page-item:first-child .page-link,.pagination-sm .page-item:first-child .page-link{border-top-left-radius:6px;border-bottom-left-radius:6px}.page-item:last-child .page-link,.pagination-lg .page-item:last-child .page-link,.pagination-sm .page-item:last-child .page-link{border-top-right-radius:6px;border-bottom-right-radius:6px}.page-link:hover{z-index:2;text-decoration:none}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 4px 2px rgba(99,136,255,.12)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item.active .page-link{z-index:1;color:var(--f-text-00);background:var(--f-theme-06)!important;border-color:var(--f-theme-05)}.page-item.disabled .page-link{color:var(--f-text-07);pointer-events:none;cursor:auto;background:var(--f-neutral-09);border-color:var(--f-neutral-05);box-shadow:none}.page-link,.query-solution .solution-action .icon-group .f-icon-remove,.switch small,.switch.checked small{box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.06)}.pagination-lg .page-link{padding:.75rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-link{padding:.1875rem;font-size:.75rem;line-height:1.5}.ngx-pagination::after,.ngx-pagination::before{content:" ";display:table}.ngx-pagination::after{clear:both}.ngx-pagination li{-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:.0625rem;border-radius:0;display:inline-block}.ngx-pagination a,.ngx-pagination button{color:var(--f-text-02);display:block;cursor:pointer}.ngx-pagination .current{cursor:default}.ngx-pagination .disabled{color:var(--f-neutral-09);cursor:default}.ngx-pagination .disabled:hover{background:0 0}.ngx-pagination .pagination-next a::after,.ngx-pagination .pagination-next.disabled::after,.ngx-pagination .pagination-previous a::before,.ngx-pagination .pagination-previous.disabled::before{display:inline-block;margin-right:.5rem}.ngx-pagination .small-screen,.pagination-container .page-item.ellipsis:hover>.page-link>.page-link-label,.pagination-container .page-item.ellipsis>.page-link>.f-icon{display:none}.ngx-pagination .show-for-sr{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}.pagination{font-size:.75rem;padding:.625rem}.page-link{border-radius:6px;min-width:calc(1rem + .375rem + 2px);height:calc(1rem + .375rem + 2px);text-align:center;overflow:hidden}.page-link .f-icon{vertical-align:top}.page-link:focus{color:var(--f-theme-01);border-color:var(--f-theme-03)}.page-link.disabled{color:var(--f-text-07);background:var(--f-neutral-09);border-color:var(--f-neutral-05);box-shadow:none}.page-link:hover{color:var(--f-theme-05);background:var(--f-neutral-12);border-color:var(--f-theme-05)}.page-link:active{color:var(--f-theme-01);background:var(--f-neutral-12);border-color:var(--f-theme-01)}.page-item{margin:auto 3px}.pagination-lg .page-link{height:auto;width:auto}.page-item.current .page-link,.page-item.current:active .page-link,.page-item.current:hover .page-link{z-index:1;color:var(--f-text-00);background:var(--f-theme-06)!important;border-color:var(--f-theme-05);box-shadow:0 2px 6px 0 rgba(var(--f-neutral-15),.15)}.pagination .pg-pagelist{margin:0 12px;height:100%}.pagination .pg-pagelist .pg-pagelist-info{font-size:13px;color:var(--f-text-02);cursor:pointer;height:100%;display:inline-flex;align-items:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pagination .pg-pagelist .pg-pagelist-info:hover,.pagination .pg-pagelist.show .pg-pagelist-info{color:var(--f-theme-03)}.pagination .pg-pagelist .pg-pagelist-info .cur-pagesize{padding:0 4px;font-size:15px;font-weight:600}.pagination .pg-pagelist .pg-pagelist-info .f-icon{font-size:12px;margin:0 0 0 8px;transition:transform .2s linear}.pagination .pg-pagelist .dropdown-menu{min-width:120px;margin-bottom:.25rem}.pagination .pg-pagelist .dropdown-menu .dropdown-item{padding-left:14px}.pagination .pagination-message{color:var(--f-text-02);font-size:13px;display:inline-flex;align-items:center;height:100%}.pagination .pagination-message .badge{font-size:13px}.pagination .pagination-message .pg-message-total{font-size:15px;font-weight:600;padding:0 4px;line-height:20px}.badge,.popover,.table thead th,.tooltip{font-weight:400}.farris-gotopagenumber{text-align:center;-moz-appearance:textfield;width:40px}.farris-gotopagenumber::-webkit-inner-spin-button,.farris-gotopagenumber::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.pagination-container .page-item.ellipsis>.page-link{background:0 0;border:none;box-shadow:none;line-height:8px;font-size:16px}.popover,.popover-header{background-color:rgba(var(--f-neutral-00-rgb),.9)}.pagination-container .page-item.ellipsis:hover>.page-link{line-height:20px}.badge-round-success,.pagination-container .page-item.ellipsis:hover>.page-link>.f-icon{display:inline-block!important}@media screen and (max-width:601px){.ngx-pagination.responsive .small-screen{display:inline-block}.ngx-pagination.responsive li:not(.small-screen):not(.pagination-previous):not(.pagination-next){display:none}}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;font-style:normal;line-height:1.4286;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.75rem;word-wrap:break-word;background-clip:padding-box;border:1px solid var(--f-neutral-00);border-radius:4px;box-shadow:0 2px 8px 0 rgba(0,32,74,.15)}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 6px}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top] .arrow,.bs-popover-top .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom:0;border-top-color:rgba(var(--f-neutral-00-rgb),.4)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-top .arrow::after{bottom:1px;border-top-color:rgba(var(--f-neutral-00-rgb),.9)}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right] .arrow,.bs-popover-right .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:6px 0}.bs-popover-auto[x-placement^=left],.bs-popover-left,.bs3.bs-popover-auto[x-placement^=left],.bs3.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left:0;border-right-color:rgba(var(--f-neutral-00-rgb),.4)}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-right .arrow::after{left:1px;border-right-color:rgba(var(--f-neutral-00-rgb),.9)}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom] .arrow,.bs-popover-bottom .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(var(--f-neutral-00-rgb),.4)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;border-bottom-color:rgba(var(--f-neutral-00-rgb),.9)}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid rgba(var(--f-neutral-00-rgb),.9)}.bs-popover-auto[x-placement^=left] .arrow,.bs-popover-left .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:6px 0}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(var(--f-neutral-00-rgb),.4)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:rgba(var(--f-neutral-00-rgb),.9)}.popover-header{line-height:1;padding:.5rem .75rem;margin-bottom:0;font-size:.8125rem;color:var(--f-text-01);border-bottom:1px solid rgba(var(--f-neutral-00-rgb),.9);border-top-left-radius:calc(6px - 1px);border-top-right-radius:calc(6px - 1px)}.bs3.popover-top,.bs3.popover.top{margin-bottom:10px}.popover-header:empty{display:none}.popover-body{max-width:17.25rem;padding:.5rem .75rem;color:var(--f-text-02)}.bs3.popover.top>.arrow{margin-left:-2px}.popover.bottom>.arrow{margin-left:-4px}.bs3.bs-popover-auto[x-placement^=left] .arrow,.bs3.bs-popover-auto[x-placement^=right] .arrow,.bs3.bs-popover-left .arrow,.bs3.bs-popover-right .arrow{margin:.3rem 0}.bs-popover-bottom-left .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-bottom-left .arrow::before{top:0;border-bottom-color:rgba(255,255,255,.4)!important}.bs-popover-bottom-left .arrow::after,.bs-popover-bottom-left .arrow::before{border-width:0 .5rem .5rem}.bs-popover-bottom-left .arrow::after{top:1px;border-bottom-color:#fff!important}.popover.popover-fitcontent .popover-body{max-width:initial;padding:initial}.popover .arrow-left .arrow{left:calc(50% - 10px)}.f-progress-step .f-progress-step-list{display:flex;flex-direction:row;align-items:center}.f-progress-step .step{display:inline-block}.f-progress-step .step .f-progressstep-row{display:flex;position:relative;padding-right:.4375rem;padding-bottom:.9375rem}.f-progress-step .step .f-progressstep-row .f-progress-step-content{display:inline-block}.f-progress-step .step .f-progressstep-row .f-progress-step-content .step-icon{display:inline-block;width:1.875rem;height:1.875rem;margin-right:.5rem;margin-left:.5rem;line-height:1.875rem;border-radius:100%;font-size:.75rem;text-align:center;vertical-align:middle}.f-progress-step .step .f-progressstep-row .f-progress-step-content .f-progress-step-title{display:inline-block;vertical-align:middle}.f-progress-step .step .f-progressstep-row .f-progress-step-content .f-progress-step-title .step-message,.f-progress-step .step .f-progressstep-row .f-progress-step-content .f-progress-step-title .step-name{margin-bottom:0}.f-progress-step .step .f-progressstep-row .f-progress-step-content .f-progress-step-title .step-name{font-size:.875rem;line-height:1.25rem;padding-right:.625rem}.f-progress-step .step .f-progressstep-row .f-progress-step-content .f-progress-step-title .step-name.step-name-success{opacity:.85}.f-progress-step .step .f-progressstep-row .f-progress-step-line{flex:1 1 auto;position:relative;display:inline-flex;min-width:3.75rem;vertical-align:middle}.f-progress-step .step .f-progressstep-row .f-progress-step-line::after{content:"";left:0;height:.125rem;overflow:hidden;position:absolute;right:.625rem;top:50%;margin-top:-.0625rem}.f-progress-step .step .f-progressstep-row .f-progress-step-line .triangle{position:absolute;right:0;top:50%;display:inline-block;width:.4375rem;height:.4375rem;margin-top:-.21875rem;transform:rotate(45deg)}.f-progress-step .f-progress-step-list-block .step{display:block}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row{padding:0;flex-direction:column}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line{flex:1 1 auto;width:.625rem;min-width:.625rem;min-height:2.5rem;margin:.5rem 0 1.25rem 1.375rem}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line::after{content:"";border-top:0}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line .triangle{top:auto;left:-.3125rem;bottom:-.5rem;border-top:0}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line .f-progress-step-title .step-name{padding-right:.875rem}.f-progress-step .f-progress-step-horizontal-fill{display:flex;justify-content:space-between;flex-wrap:wrap}.f-progress-step .f-progress-step-horizontal-fill .step{flex:1 1 auto}.f-progress-step .f-progress-step-vertical-fill{display:flex;flex-direction:column;align-content:space-between}.f-progress-step .f-progress-step-vertical-fill .step{display:flex;flex:1 1 auto}.f-progress-step .f-progress-step-vertical-fill .step .f-progressstep-row{flex:1 1 auto;display:flex}.f-progress-step li.clickable{cursor:pointer}.f-progress-step li.click-disable{cursor:not-allowed}.f-progress-step .f-progress-step-empty{color:#000;opacity:.65;font-size:.875rem}.f-progress-step .f-progressstep-row-multi{display:flex;flex-direction:column;align-items:left}.f-progress-step .f-progressstep-row-multi .f-progressstep-multi-item-content{display:flex;flex-direction:row;align-items:center;cursor:pointer}.f-progress-step .f-progressstep-row-multi .f-step-multi-item{position:relative;padding-right:.4375rem;padding-bottom:.9375rem}.f-progress-step .f-progressstep-row-multi .f-step-multi-item:last-child{padding-bottom:0}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row.f-progressstep-row-multi{flex-direction:row}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row.f-progressstep-row-multi .f-step-multi-item{padding:0;flex-direction:column}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row.f-progressstep-row-multi .f-step-multi-item .f-progress-step-line{display:block}.f-progress-step .step .f-progressstep-row .f-progress-step-content .step-icon{color:#fff;background:var(--f-neutral-02)}.f-progress-step .step .f-progressstep-row .f-progress-step-content .f-progress-step-title .step-name{color:#8C8C8C}.f-progress-step .step .f-progressstep-row .f-progress-step-content .f-progress-step-title .step-name.step-name-success{color:var(--f-text-03)}.f-progress-step .step .f-progressstep-row .f-progress-step-line::after{border-top:2px dotted rgba(0,0,0,.2)}.f-progress-step .step .f-progressstep-row .f-progress-step-line .triangle{border-top:1px solid rgba(0,0,0,.2);border-right:1px solid rgba(0,0,0,.2)}.f-progress-step .step .f-progressstep-row .f-progress-step-line.f-progress-step-line-success .triangle,.f-progress-step .step .f-progressstep-row .f-progress-step-line.f-progress-step-line-success::after{border-color:var(--f-theme-03)}.f-progress-step .step .f-progressstep-row.step-finish .f-progress-step-content .step-icon{color:#fff;background:linear-gradient(135deg,#529DFF 0,#559FFF 100%)}.f-progress-step .step .f-progressstep-row.step-finish:hover .f-progress-step-content .step-icon{background:var(--f-theme-04)}.f-progress-step .step .f-progressstep-row.step-finish:active .f-progress-step-content .step-icon{background:var(--f-theme-02)}.f-progress-step .step .f-progressstep-row.step-active .f-progress-step-content .step-icon{color:#fff;background:var(--f-theme-04)}.f-progress-step .step .f-progressstep-row.step-active:hover .f-progress-step-content .step-icon{background:linear-gradient(135deg,#529DFF 0,#559FFF 100%)}.f-progress-step .step .f-progressstep-row.step-active:active .f-progress-step-content .step-icon{background:var(--f-theme-02)}.f-progress-step .step .f-progressstep-row.step-error .f-progress-step-content .step-icon{background:#F46160}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line{border-left:2px dotted rgba(0,0,0,.2)}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line .triangle{border-bottom:1px solid rgba(0,0,0,.2)}.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line.f-progress-step-line-success,.f-progress-step .f-progress-step-list-block .step .f-progressstep-row .f-progress-step-line.f-progress-step-line-success .triangle{border-color:var(--f-theme-05)}.f-progress-step .f-progress-step-empty{color:var(--f-text-05)}.f-progress-step .f-progressstep-row-multi .f-step-multi-item.f-step-multi-item-active .f-progress-step-title .step-name,.f-progress-step .f-progressstep-row-multi .f-step-multi-item.f-step-multi-item-finish .f-progress-step-title .step-name{color:var(--f-text-03)!important}.f-progress-step .f-progressstep-row-multi .f-step-multi-item.f-step-multi-item-active .step-icon{background:var(--f-theme-04)}.f-progress-step .f-progressstep-row-multi .f-step-multi-item.f-step-multi-item-finish .step-icon,.f-progress-step .f-progressstep-row-multi .f-step-multi-item:hover.f-step-multi-item-active .step-icon{background:linear-gradient(135deg,#529DFF 0,#559FFF 100%)}.f-progress-step .f-progressstep-row-multi .f-step-multi-item:hover.f-step-multi-item-finish .step-icon{background:var(--f-theme-04)}.f-progress{display:inline-block;font-size:.875rem;color:rgba(0,0,0,.65)}.f-progress.f-progress-line{position:relative;width:100%}.f-progress.f-progress-line .f-progress-text .f-progress-text-icon{font-size:1.25rem}.f-progress .f-progress-outer{display:inline-block;width:100%}.f-progress .f-progress-inner{position:relative;display:inline-block;width:100%;overflow:hidden;vertical-align:middle;background-color:#efefef;border-radius:100px}.f-progress .f-progress-bg,.f-progress .f-progress-success-bg{position:relative;border-radius:100px;transition:all .4s cubic-bezier(.08,.82,.17,1) 0s}.f-progress .f-progress-success-bg{position:absolute;top:0;left:0}.f-progress .f-progress-text{display:inline-block;width:1.75rem;margin-left:.5rem;color:rgba(0,0,0,.65);font-size:1em;line-height:1;white-space:nowrap;text-align:left;vertical-align:middle;word-break:normal}.f-progress-status-active .f-progress-bg::before{position:absolute;top:0;right:0;bottom:0;left:0;background:#fff;border-radius:.625rem;opacity:0;animation:f-progress-active 2.4s ease-in-out infinite;content:""}.condition-with-line.farris-form-controls-inline .input-group,.query-solution .farris-panel{border:none}.f-progress-show-info .f-progress-outer{padding-right:48px;margin-right:-48px}.f-progress.f-progress-circle .f-progress-inner{position:relative;line-height:1;background-color:transparent}.f-progress.f-progress-circle .f-progress-text{position:absolute;top:50%;left:50%;width:100%;margin:0;padding:0;color:rgba(0,0,0,.65);line-height:1;white-space:normal;text-align:center;transform:translate(-50%,-50%)}.f-progress.f-progress-circle .f-progress-text .f-progress-text-icon{font-size:1.3em}@keyframes f-progress-active{0%{width:0;opacity:.1}20%{width:0;opacity:.5}100%{width:100%;opacity:0}}.f-progress .f-progress-bg{background:var(--f-theme-04)}.f-progress .f-progress-success-bg,.f-progress-status-success .f-progress-bg{background:var(--f-semantic-success-01)}.f-progress-status-error .f-progress-bg{background:var(--f-semantic-danger-01)}.f-progress.f-progress-circle .f-progress-text .f-progress-text-icon.f-icon-checkmark{color:var(--f-semantic-success-01)}.f-progress.f-progress-circle .f-progress-text .f-progress-text-icon.f-icon-x{color:var(--f-semantic-danger-01)}.f-progress .f-progress-inner:not(.f-progress-circle-gradient) .f-progress-circle-path{stroke:var(--f-semantic-info-01)}.f-progress-status-success .f-progress-inner:not(.f-progress-circle-gradient) .f-progress-circle-path{stroke:var(--f-semantic-success-01)}.f-progress-status-error .f-progress-inner:not(.f-progress-circle-gradient) .f-progress-circle-path{stroke:var(--f-semantic-danger-01)}.farris-star-rating{cursor:pointer;display:flex;position:relative}.farris-star-rating .default-light-color{color:#FBDB10}.farris-star-rating .default-dark-color{color:#E8E8E8}.star-dark-area span,.star-light-area span{box-sizing:content-box;padding-right:4px}.farris-star-rating .f-star-sm{font-size:14px}.farris-star-rating .f-star-md{font-size:16px}.farris-star-rating .f-star-lg{font-size:18px}.farris-star-rating .f-star-exlarge{font-size:24px}.farris-star-rating .star-dark-area{overflow:hidden;display:flex;flex-wrap:nowrap}.farris-star-rating .f-utils-fill{padding-left:2px;font-size:14px}.farris-star-rating .font-small{line-height:14px}.farris-star-rating .font-middle{line-height:16px}.farris-star-rating .font-large{line-height:18px}.farris-star-rating .font-exlarge{line-height:24px}.farris-star-rating .star-light-area{position:absolute;left:0;top:0;z-index:2;width:0%;overflow:hidden;display:flex;flex-wrap:nowrap}.farris-star-rating .star-dark-area span,.farris-star-rating .star-light-area span{flex-shrink:0}.f-toolbar{flex-shrink:0;display:inline-flex;align-items:center;justify-content:flex-end}.f-toolbar .f-btn-separator{display:inline-block;width:1px;background-color:#c2cbd1;height:1em;margin:0 .5rem}.f-response-toolbar{display:block}.f-response-toolbar-lg .btn{line-height:1.4286;padding:.25rem 1.125rem}.f-response-toolbar-sm .btn{line-height:1.4286;padding:.125rem .5rem}.query-solution .solution-header{height:auto!important;margin-bottom:10px!important;display:flex;align-items:center;justify-content:space-between}.query-solution .solution-header-title{padding:.25rem 6px .25rem 12px;border-radius:6px;display:flex;flex-direction:row;align-items:center;color:var(--f-theme-03);font-size:.8125rem;vertical-align:middle;cursor:pointer}.query-solution .solution-header-title .header-title--change{margin:0 4px}.query-solution .solution-header-title .solution-header-title-text{margin-right:6px;overflow:hidden;height:22px}.query-solution .solution-header-title .f-accordion-expand{color:var(--f-theme-03)}.query-solution .solution-header-title .f-icon{font-size:16px;margin:0;width:auto;height:auto}.query-solution .solution-action{display:flex;align-items:center;flex-shrink:0}.query-solution .solution-action .dropdown .btn{border:0}.query-solution .solution-action .icon-group{display:flex!important;align-items:center}.query-solution .solution-action .icon-group .f-icon-remove{color:var(--f-text-02);background:var(--f-neutral-12);border:1px solid var(--f-neutral-08);border-radius:6px;width:calc(1.5rem + .125rem);height:calc(1.5rem + .125rem);text-align:center;line-height:20px;display:block}.query-solution .solution-action .icon-group .f-icon-remove:hover{border-color:var(--f-theme-05);color:var(--f-theme-05);background:var(--f-neutral-12)}.query-solution .solution-action .icon-group .f-icon-home-setup,.query-solution .solution-action .icon-group .f-icon-packup{font-size:.875rem}.query-solution .solution-action .icon-group .icon-group-packup{margin-right:0;margin-left:4px}.query-solution .solution-action span{vertical-align:inherit}.query-solution .solution-action .divide{color:var(--f-neutral-13);position:relative;margin:0 .3125rem}.query-solution .solution-action .divide::after{position:absolute;content:"";height:12px;width:1px;background-color:var(--f-neutral-13);left:0;top:50%;margin-top:-6px}.query-solution .solution-header-title-menu{margin-top:8px}.query-solution .solution-header-title-menu-inner{position:relative;width:18.9375rem}.query-solution .solution-header-title-menu-inner .menu-item--change{margin:0 4px 0 0}.query-solution .solution-header-title-menu-inner .solution-header-title-menu-arrow{position:absolute;content:"";display:block;left:1.5rem;top:-.5rem;width:8.49px;height:8.49px;background:0 0;border-style:solid;border-width:4.24px;box-shadow:-2px -2px 5px rgba(0,0,0,.08);transform:translateX(-50%) rotate(45deg);border-color:#fff transparent transparent #fff}.query-solution .solution-header-title-menu-inner .solution-header-dropdown-item{cursor:pointer;display:flex;flex-direction:row;align-items:center}.query-solution .solution-header-title-menu-inner .solution-header-dropdown-item.solution-header-dropdown-item-active{background:var(--f-neutral-10)}.query-solution .solution-header-title-menu-inner .solution-header-dropdown-item .solution-header-dropdown-item-title{flex-shrink:1;flex-grow:1;flex-basis:0;padding-right:.25rem;color:var(--f-text-02);font-size:.875rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.query-solution .solution-header-title-menu-inner .solution-header-dropdown-item .solution-header-dropdown-item-tip{flex-shrink:0;height:1.125rem;min-width:2.5rem;padding:0 4px;line-height:1.125rem;font-size:.75rem;background:var(--f-semantic-success-01);color:#fff;border-radius:2px;text-align:center}.query-solution .solution-header-title-menu-inner .solution-header-dropdown-item .solution-header-dropdown-item-public{flex-shrink:0;height:1.125rem;min-width:2.5rem;padding:0 4px;line-height:1.125rem;font-size:.75rem;background:#2a87ff;color:#fff;border-radius:2px;text-align:center}.query-solution .solution-header-title-menu-inner .solution-header-dropdown-item-btns{display:flex;flex-direction:row;align-items:center;justify-content:flex-end;height:2.25rem;padding:0 .875rem;line-height:2.25rem;border-top:1px solid rgba(0,0,0,.07)}.query-solution .solution-header-title-menu-inner .solution-header-dropdown-item-btns .dropdown-item-btn{margin-left:.5rem;color:var(--f-theme-03);cursor:pointer}.query-solution .summary-condition{flex-shrink:0;flex-grow:1;flex-basis:0;overflow:hidden;margin:0 12px 0 0;display:flex}.query-solution .summary-condition--item .summary-condition--label,.summary-list--tips .summary-condition--label{margin:0 2px 0 0}.query-solution .summary-list{overflow:hidden}.query-solution .summary-condition-wrapper{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;background:var(--f-aid-02);border:1px solid var(--f-aid-01);border-radius:3px;font-size:13px;color:#2D2F33;line-height:24px;height:26px;box-shadow:0 1px 4px 0 rgba(0,28,65,.08)}.query-solution .summary-condition--item{padding:0 12px;vertical-align:top}.query-solution .summary-condition--item .summary-condition--text{margin:0 0 0 8px}.query-solution .summary-condition--spliter{width:1px;height:14px;background:#DDE1EB;display:inline-block;margin:5px 0 0}.query-solution{padding:16px;background:#fff}.query-solution .solution-header .dropdown-item{width:100%}.query-solution .solution-header-title{max-width:288px;background:unset}.query-solution .solution-header .dropdown-menu{max-height:unset}.query-solution .solution-header-title-btns{border-top:1px solid rgba(0,0,0,.07);text-align:right;width:100%;color:#2A87FF;padding:8px 0}.solutionmanager-inner{padding:0 14px;flex:1;height:100%}.solutionmanager-inner .solutionmanager-grid-delete{font-size:.875rem;color:var(--f-theme-03)}.summary-list--tips .summary-condition--text{margin:0 0 0 8px}.summary-list--tips .summary-condition--gutter{margin:0 10px 0 4px}.summary-list--tips .tooltip{margin-top:-6px}.summary-list--tips .tooltip-inner{text-align:left;background:rgba(var(--f-neutral-00-rgb),.95);color:var(--f-text-02);font-size:13px;line-height:24px}.summary-list--tips .arrow{left:35px!important}.summary-list--tips .arrow::before{border-width:0 .3rem .3rem;border-bottom-color:rgba(var(--f-neutral-00-rgb),.4)}.farris-form.condition-div{margin-right:-5px;margin-left:-5px}.farris-form.condition-div .qlabel-gutter{display:none}.farris-form.condition-div>[class*=col-]{padding-left:5px!important;padding-right:5px!important}.condition-with-line.farris-form-controls-inline .qlabel-gutter{display:inline;margin-left:2px}.condition-with-line.farris-form-controls-inline .qradio-group .qlabel-gutter{margin-right:8px}.condition-with-line.farris-form-controls-inline .farris-input-wrap{flex-basis:0}.condition-with-line.farris-form-controls-inline .common-group{border:1px solid #D8DCE6;border-radius:3px;padding-left:8px;padding-right:1px}.condition-with-line.farris-form-controls-inline .common-group .col-form-label{font-size:13px;color:#6A6F79;width:auto;margin-right:0;flex-grow:0;flex-shrink:1;flex-basis:auto;max-width:220px}.f-cmp-inputgroup .f-transfer-date .search-tag-item.search-field:hover,.f-search-box .search-tag-item.search-field:hover,.querycondition-advanced .add-condition-btn{color:var(--f-theme-03)}.condition-with-line.farris-form-controls-inline .common-group .f-solution-radio-group{flex-shrink:1;flex-grow:1;flex-basis:0}.condition-with-line.farris-form-controls-inline .common-group .input-group,.condition-with-line.farris-form-controls-inline .common-group .input-group.f-state-focus{outline:0;box-shadow:none;border:none}.condition-with-line.farris-form-controls-inline .common-group:not(.q-state-readonly):hover{border-color:var(--f-theme-08);box-shadow:0 0 0,0 0 4px 2px rgba(99,136,255,.12)}.condition-with-line.farris-form-controls-inline .farris-group-multi-label .farris-group-wrap .col-form-label .farris-label-text{text-align:left}.condition-with-fixed.farris-form-controls-inline .datepicker-range-group .farris-input-wrap,.condition-with-fixed.farris-form-controls-inline .number-range-group .farris-input-wrap{min-width:120px}.condition-with-line.f-form-label-xl .farris-group-wrap .col-form-label{max-width:153px}.query-solution .condition-div{max-height:204px;overflow-y:auto}.querycondition-advanced .add-condition-btn .f-icon{background-color:var(--f-aid-03)}.query-solution .farris-input-wrap.farris-checkradio-hor{overflow-x:auto;flex-wrap:nowrap;white-space:nowrap;width:100%}.query-solution .solution-header .solution-header-item-active{background:#F7F7F7}.f-search-box-panel{height:100%;z-index:9998;position:absolute;overflow:auto;background:var(--f-neutral-20);box-shadow:0 2px 20px 0 rgba(3,18,51,.12);border-radius:3px}.f-search-field-container .switch.switch-small{min-width:1.88rem;height:.85rem}.f-search-field-container .switch.switch-small small{top:0}.multi-date-display:empty:before{color:var(--f-text-09)}.f-cmp-inputgroup .f-transfer-date .search-tag-item,.f-search-box .search-tag-item{cursor:default;padding:0 20px 0 5px!important;background:var(--f-aid-04)!important;border:1px solid var(--f-aid-05);position:relative;margin-right:3px!important;margin-top:1px!important;margin-bottom:0!important;line-height:19px;height:22px;float:left;max-width:200px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;display:inline!important;border-radius:6px}.f-cmp-inputgroup .f-transfer-date .search-tag-item .f-icon,.f-search-box .search-tag-item .f-icon{cursor:pointer;position:absolute;right:2px;font-size:12px;top:7px}.f-cmp-inputgroup .f-transfer-date .search-tag-item.search-field,.f-search-box .search-tag-item.search-field{background:0 0;border:0;cursor:pointer;height:26px;line-height:24px}.f-cmp-inputgroup .f-transfer-date .search-tag-item.search-field.selected,.f-search-box .search-tag-item.search-field.selected{background:rgba(207,237,255,.35);border-color:var(--f-aid-05)}.f-cmp-inputgroup .f-transfer-date .search-tag-item.search-field.has-filter,.f-search-box .search-tag-item.search-field.has-filter{background-color:#f2f8ff;border:1px solid #e4f0ff}.f-cmp-inputgroup .f-transfer-date .inputbox,.f-search-box .inputbox{flex:1;position:relative;min-width:50px;height:24px;margin:0;padding:0;float:left;overflow:hidden}.f-cmp-inputgroup .f-transfer-date.f-search-fields .multi--item.search-tag-item,.f-cmp-inputgroup .f-transfer-date.f-search-shadow-fields .multi--item.search-tag-item,.f-search-box.f-search-fields .multi--item.search-tag-item,.f-search-box.f-search-shadow-fields .multi--item.search-tag-item{margin-bottom:4px!important}.f-cmp-inputgroup .f-transfer-date .search-input,.f-search-box .search-input{position:absolute;top:0;align-items:center;display:flex;left:-2px;width:100%}.f-cmp-inputgroup .f-transfer-date.f-search-shadow-fields.active,.f-search-box.f-search-shadow-fields.active{border-color:var(--f-theme-05)}.f-cmp-inputgroup .f-transfer-date.f-search-fields .more,.f-search-box.f-search-fields .more{padding-right:20px}.f-cmp-inputgroup .f-transfer-date.f-search-fields .more::after,.f-search-box.f-search-fields .more::after{content:"...";position:absolute;right:10px;top:0;cursor:pointer}.f-cmp-inputgroup .f-transfer-date.f-state-disabled .search-tag-item{background:var(--f-neutral-09);border-color:var(--f-neutral-09);color:var(--f-text-02)}.f-cmp-inputgroup .f-transfer-date.f-state-disabled .multi--more-text{color:var(--f-text-09)}.search-tip-info{height:32px;line-height:32px;border-bottom:1px solid var(--f-neutral-04);font-size:12px;color:#848C9A;margin-bottom:5px;padding:0 7px;align-items:center;justify-content:space-between}.search-tip-info .f-icon-close,.search-tip-info .f-icon-group-delete::before{cursor:pointer;top:2px;position:relative;right:-5px;font-size:12px}.search-tip-info .f-icon-close:hover,.search-tip-info .f-icon-group-delete:hover::before{color:red}.lookup-filter-bar .clear-search-fields{width:28px;height:28px;display:flex;align-items:center;justify-content:center;border:1px solid var(--f-neutral-04);margin-left:3px;border-radius:3px;cursor:pointer}.lookup-filter-bar .clear-search-fields:hover{color:var(--f-aid-10);border-color:var(--f-theme-05)}.search-box-container{background-color:#fff;background-clip:padding-box}.search-box-container-title{color:#878d99;text-align:left;margin-bottom:10px}.f-section{display:flex;flex-direction:column;position:relative;padding:.625rem .875rem .75rem;margin:0;border-radius:8px;background:#fff}.f-section.f-section-fill{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.f-section.f-section-fill>.f-section-content{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column;min-height:0}.f-section.f-section-content-fill{display:flex;flex-direction:column}.f-section.f-section-content-fill .f-section-content{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column}.f-section-header{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:space-between;padding:0 .625rem 0 0;margin:0 0 .5rem}.f-section-header .f-title::before .f-content{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.f-section-header .f-toolbar{flex-shrink:0;display:inline-flex;align-items:center;justify-content:flex-end;color:var(--f-text-04);margin-left:auto}.f-section-header .f-btn-collapse-expand span,.f-section.f-state-collapse>.f-section-extend{display:none}.f-section-header .f-btn-collapse-expand{color:var(--f-theme-03)}.f-section-header .f-btn-collapse-expand::after{width:1rem;height:1rem;font-size:.875rem;line-height:1rem;margin-left:0;color:var(--f-text-07);background:var(--f-neutral-07);border-radius:10px}.f-section-header .f-btn-collapse-expand:hover::after{background:var(--f-neutral-05)}.f-section-header .f-max-accordion .f-icon-maximize,.f-section-header .f-max-accordion .f-icon-minimize{color:var(--f-text-03);font-size:14px;cursor:pointer;margin-left:.5rem;vertical-align:middle}.f-section-header .f-max-accordion .f-icon-maximize:hover,.f-section-header .f-max-accordion .f-icon-minimize:hover{color:var(--f-theme-05)}.f-section-header .f-max-accordion .f-icon-maximize:active,.f-section-header .f-max-accordion .f-icon-minimize:active{color:var(--f-theme-01)}.f-section-extend{margin:0 0 .75rem}.f-section-accordion.f-state-collapse>.f-section-header{margin-bottom:0}.f-section-accordion.f-state-collapse>.f-section-content{height:0;overflow:hidden;flex:0 1 0!important}.f-section-maximize{position:fixed;top:0;bottom:0;left:0;right:0;z-index:1031;background:var(--f-neutral-19)}.f-section-maximize>.f-section-content{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column;overflow-y:auto;overflow-x:hidden}.f-section-maximize>.f-section-content>.f-struct-is-subgrid{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column}.f-section-maximize>.f-section-content>.f-struct-is-subgrid .f-grid-is-sub{flex-shrink:1;flex-grow:1;flex-basis:0;height:auto}.f-section-maximize .f-tabs-content-fill .f-struct-is-subgrid{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column}.f-section-maximize .f-tabs-content-fill .f-grid-is-sub{flex-shrink:1;flex-grow:1;flex-basis:0;height:auto}.f-section-form.f-section-custom-accordion.f-state-collapse .f-form-layout>:not(.f-state-visible),.f-section-form.f-section-custom-accordion.f-state-collapse .f-section-formgroup-inputs>:not(.f-state-visible),.f-section-form.f-section-custom-accordion.f-state-collapse .f-section-formgroup.f-state-visible>:not(.f-state-visible){display:none}.f-section-form.f-section-custom-accordion.f-state-collapse .f-section-formgroup-inputs.f-state-visible-all>*{display:initial}.f-section-nogap::before,.f-section-nogutter::before{display:none!important}.f-section-tabs{padding:0 .875rem 1rem}.f-section-treegrid.f-section-in-nav{flex-shrink:1;flex-grow:1;flex-basis:0}.f-section-treegrid.f-section-in-nav>.f-section-content{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column}.f-section-treegrid.f-section-in-nav>.f-section-content .f-componet-treetable{flex-shrink:1;flex-grow:1;flex-basis:0}.f-section--header-manage .f-section-header .f-title::before{background:linear-gradient(135deg,#4190FF 0,#657CFF 100%)!important}.f-section--header-dict .f-section-header .f-title::before{background:linear-gradient(135deg,#4EC87A 0,#52D389 100%)!important}.f-section--header-bill .f-section-header .f-title::before{background:linear-gradient(135deg,#1FC8DC 0,#41D2BD 100%)!important}.f-section--header-query .f-section-header .f-title::before{background:linear-gradient(135deg,#FC8249 0,#FE9539 100%)!important}.f-section--header-param .f-section-header .f-title::before{background:linear-gradient(135deg,#8B82FF 0,#A082FF 100%)!important}.f-page-main .f-section-like-query.f-section,.f-page-main .f-section-query.f-section{margin:0}.f-title-noline{padding-left:0}.f-title-noline::before{display:none}.f-section .f-section-content--toolbar{padding:0 0 0 .75rem;margin-top:.40625rem;margin-bottom:.40625rem}.f-splitter-pane,.switch{padding:0;position:relative}.f-section .f-section-header--toolbar{overflow:hidden;flex:1;margin-left:.875rem!important}.f-splitter{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:row;flex-wrap:nowrap;overflow:hidden;position:relative}.f-splitter-pane.f-splitter-pane-main{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:auto;display:flex}.f-splitter-pane>.f-splitter-resize-bar{position:absolute;font-size:.1px;display:block;touch-action:none}.f-splitter-pane>.f-splitter-resize-bar:hover{background:rgba(42,135,255,.07)}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-e{cursor:e-resize;width:.4375rem;right:-.3125rem;height:100%;top:0}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-w{cursor:w-resize;width:.4375rem;left:-.3125rem;height:100%;top:0}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s{cursor:s-resize;height:.4375rem;bottom:-.3125rem;width:100%;left:0}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n{cursor:n-resize;height:.4375rem;top:-.3125rem;width:100%;left:0}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-e::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-w::before{content:"";position:absolute;background:#E9ECF3}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-e::after,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n::after,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s::after,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-w::after{content:"";position:absolute;top:50%;left:50%;width:6px;height:60px;margin:-30px 0 0 -3px;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjdweCIgaGVpZ2h0PSI2MHB4IiB2aWV3Qm94PSIwIDAgNyA2MCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDY0ICg5MzUzNykgLSBodHRwczovL3NrZXRjaC5jb20gLS0+DQogICAgPHRpdGxlPue8lue7hCAyMjwvdGl0bGU+DQogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+DQogICAgPGcgaWQ9IuaWsOeJiCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+DQogICAgICAgIDxnIGlkPSI2LuW3puagkeWPs+S4u+S7jiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQ1NS4wMDAwMDAsIC00MTguMDAwMDAwKSI+DQogICAgICAgICAgICA8ZyBpZD0i57yW57uELTIyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0NTUuNTAwMDAwLCA0MTguMDAwMDAwKSI+DQogICAgICAgICAgICAgICAgPHBhdGggZD0iTTMsMCBDNSwxLjc3NTIwMjYgNiwzLjE3ODcxMTM4IDYsNC4yMTA1MjYzMiBDNiwxMi4xMDQzMjc2IDYsNTMuNzk4NDE1MyA2LDU1Ljc4OTQ3MzcgQzYsNTYuNzEzMzQ4NiA1LDU4LjExNjg1NzQgMyw2MCBDMSw1OC4xMTAyOTA0IDAsNTYuNzA2NzgxNiAwLDU1Ljc4OTQ3MzcgQzAsMzMuMDcyNzA3MSAwLDE1Ljg5NDM0MTIgMCw0LjIxMDUyNjMyIEMwLDMuMzUxODIxNjQgMSwxLjk0ODMxMjg3IDMsMCBaIiBpZD0i55+p5b2iIiBmaWxsPSIjRTlFQ0YzIj48L3BhdGg+DQogICAgICAgICAgICAgICAgPHBhdGggZD0iTTMsNDUgQzMuNTUyMjg0NzUsNDUgNCw0NS40NDc3MTUzIDQsNDYgQzQsNDYuNTUyMjg0NyAzLjU1MjI4NDc1LDQ3IDMsNDcgQzIuNDQ3NzE1MjUsNDcgMiw0Ni41NTIyODQ3IDIsNDYgQzIsNDUuNDQ3NzE1MyAyLjQ0NzcxNTI1LDQ1IDMsNDUgWiBNMyw0MSBDMy41NTIyODQ3NSw0MSA0LDQxLjQ0NzcxNTMgNCw0MiBDNCw0Mi41NTIyODQ3IDMuNTUyMjg0NzUsNDMgMyw0MyBDMi40NDc3MTUyNSw0MyAyLDQyLjU1MjI4NDcgMiw0MiBDMiw0MS40NDc3MTUzIDIuNDQ3NzE1MjUsNDEgMyw0MSBaIE0zLDM3IEMzLjU1MjI4NDc1LDM3IDQsMzcuNDQ3NzE1MyA0LDM4IEM0LDM4LjU1MjI4NDcgMy41NTIyODQ3NSwzOSAzLDM5IEMyLjQ0NzcxNTI1LDM5IDIsMzguNTUyMjg0NyAyLDM4IEMyLDM3LjQ0NzcxNTMgMi40NDc3MTUyNSwzNyAzLDM3IFogTTMsMzMgQzMuNTUyMjg0NzUsMzMgNCwzMy40NDc3MTUzIDQsMzQgQzQsMzQuNTUyMjg0NyAzLjU1MjI4NDc1LDM1IDMsMzUgQzIuNDQ3NzE1MjUsMzUgMiwzNC41NTIyODQ3IDIsMzQgQzIsMzMuNDQ3NzE1MyAyLjQ0NzcxNTI1LDMzIDMsMzMgWiBNMywyOSBDMy41NTIyODQ3NSwyOSA0LDI5LjQ0NzcxNTMgNCwzMCBDNCwzMC41NTIyODQ3IDMuNTUyMjg0NzUsMzEgMywzMSBDMi40NDc3MTUyNSwzMSAyLDMwLjU1MjI4NDcgMiwzMCBDMiwyOS40NDc3MTUzIDIuNDQ3NzE1MjUsMjkgMywyOSBaIE0zLDI1IEMzLjU1MjI4NDc1LDI1IDQsMjUuNDQ3NzE1MyA0LDI2IEM0LDI2LjU1MjI4NDcgMy41NTIyODQ3NSwyNyAzLDI3IEMyLjQ0NzcxNTI1LDI3IDIsMjYuNTUyMjg0NyAyLDI2IEMyLDI1LjQ0NzcxNTMgMi40NDc3MTUyNSwyNSAzLDI1IFogTTMsMjEgQzMuNTUyMjg0NzUsMjEgNCwyMS40NDc3MTUzIDQsMjIgQzQsMjIuNTUyMjg0NyAzLjU1MjI4NDc1LDIzIDMsMjMgQzIuNDQ3NzE1MjUsMjMgMiwyMi41NTIyODQ3IDIsMjIgQzIsMjEuNDQ3NzE1MyAyLjQ0NzcxNTI1LDIxIDMsMjEgWiBNMywxNyBDMy41NTIyODQ3NSwxNyA0LDE3LjQ0NzcxNTMgNCwxOCBDNCwxOC41NTIyODQ3IDMuNTUyMjg0NzUsMTkgMywxOSBDMi40NDc3MTUyNSwxOSAyLDE4LjU1MjI4NDcgMiwxOCBDMiwxNy40NDc3MTUzIDIuNDQ3NzE1MjUsMTcgMywxNyBaIE0zLDEzIEMzLjU1MjI4NDc1LDEzIDQsMTMuNDQ3NzE1MyA0LDE0IEM0LDE0LjU1MjI4NDcgMy41NTIyODQ3NSwxNSAzLDE1IEMyLjQ0NzcxNTI1LDE1IDIsMTQuNTUyMjg0NyAyLDE0IEMyLDEzLjQ0NzcxNTMgMi40NDc3MTUyNSwxMyAzLDEzIFoiIGlkPSLlvaLnirbnu5PlkIgiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4NCiAgICAgICAgICAgIDwvZz4NCiAgICAgICAgPC9nPg0KICAgIDwvZz4NCjwvc3ZnPg==);background-repeat:no-repeat;background-size:cover;background-position:center center}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-e:hover,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n:hover,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s:hover,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-w:hover{background:0 0}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-e:hover::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n:hover::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s:hover::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-w:hover::before{background-image:linear-gradient(214deg,#3F65FF 0,#4D9AFF 100%);box-shadow:0 2px 5px 0 rgba(42,135,255,.2)}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-e:hover::after,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n:hover::after,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s:hover::after,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-w:hover::after{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjdweCIgaGVpZ2h0PSI2MHB4IiB2aWV3Qm94PSIwIDAgNyA2MCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDY0ICg5MzUzNykgLSBodHRwczovL3NrZXRjaC5jb20gLS0+DQogICAgPHRpdGxlPue8lue7hCAyMjwvdGl0bGU+DQogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+DQogICAgPGRlZnM+DQogICAgICAgIDxsaW5lYXJHcmFkaWVudCB4MT0iNTAuMzcxODk3MSUiIHkxPSIwJSIgeDI9IjQ5LjY4MjQwNDUlIiB5Mj0iMTAwJSIgaWQ9ImxpbmVhckdyYWRpZW50LTEiPg0KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzNGNjVGRiIgb2Zmc2V0PSIwJSI+PC9zdG9wPg0KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzREOUFGRiIgb2Zmc2V0PSIxMDAlIj48L3N0b3A+DQogICAgICAgIDwvbGluZWFyR3JhZGllbnQ+DQogICAgPC9kZWZzPg0KICAgIDxnIGlkPSLmlrDniYgiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPg0KICAgICAgICA8ZyBpZD0iNi7lt6bmoJHlj7PkuLvku47lpIfku70tMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQ1NS4wMDAwMDAsIC00MTguMDAwMDAwKSI+DQogICAgICAgICAgICA8ZyBpZD0i57yW57uELTIyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0NTUuNTAwMDAwLCA0MTguMDAwMDAwKSI+DQogICAgICAgICAgICAgICAgPHBhdGggZD0iTTMsMCBDNSwxLjc3NTIwMjYgNiwzLjE3ODcxMTM4IDYsNC4yMTA1MjYzMiBDNiwxMi4xMDQzMjc2IDYsNTMuNzk4NDE1MyA2LDU1Ljc4OTQ3MzcgQzYsNTYuNzEzMzQ4NiA1LDU4LjExNjg1NzQgMyw2MCBDMSw1OC4xMTAyOTA0IDAsNTYuNzA2NzgxNiAwLDU1Ljc4OTQ3MzcgQzAsMzMuMDcyNzA3MSAwLDE1Ljg5NDM0MTIgMCw0LjIxMDUyNjMyIEMwLDMuMzUxODIxNjQgMSwxLjk0ODMxMjg3IDMsMCBaIiBpZD0i55+p5b2iIiBmaWxsPSJ1cmwoI2xpbmVhckdyYWRpZW50LTEpIj48L3BhdGg+DQogICAgICAgICAgICAgICAgPHBhdGggZD0iTTMsNDUgQzMuNTUyMjg0NzUsNDUgNCw0NS40NDc3MTUzIDQsNDYgQzQsNDYuNTUyMjg0NyAzLjU1MjI4NDc1LDQ3IDMsNDcgQzIuNDQ3NzE1MjUsNDcgMiw0Ni41NTIyODQ3IDIsNDYgQzIsNDUuNDQ3NzE1MyAyLjQ0NzcxNTI1LDQ1IDMsNDUgWiBNMyw0MSBDMy41NTIyODQ3NSw0MSA0LDQxLjQ0NzcxNTMgNCw0MiBDNCw0Mi41NTIyODQ3IDMuNTUyMjg0NzUsNDMgMyw0MyBDMi40NDc3MTUyNSw0MyAyLDQyLjU1MjI4NDcgMiw0MiBDMiw0MS40NDc3MTUzIDIuNDQ3NzE1MjUsNDEgMyw0MSBaIE0zLDM3IEMzLjU1MjI4NDc1LDM3IDQsMzcuNDQ3NzE1MyA0LDM4IEM0LDM4LjU1MjI4NDcgMy41NTIyODQ3NSwzOSAzLDM5IEMyLjQ0NzcxNTI1LDM5IDIsMzguNTUyMjg0NyAyLDM4IEMyLDM3LjQ0NzcxNTMgMi40NDc3MTUyNSwzNyAzLDM3IFogTTMsMzMgQzMuNTUyMjg0NzUsMzMgNCwzMy40NDc3MTUzIDQsMzQgQzQsMzQuNTUyMjg0NyAzLjU1MjI4NDc1LDM1IDMsMzUgQzIuNDQ3NzE1MjUsMzUgMiwzNC41NTIyODQ3IDIsMzQgQzIsMzMuNDQ3NzE1MyAyLjQ0NzcxNTI1LDMzIDMsMzMgWiBNMywyOSBDMy41NTIyODQ3NSwyOSA0LDI5LjQ0NzcxNTMgNCwzMCBDNCwzMC41NTIyODQ3IDMuNTUyMjg0NzUsMzEgMywzMSBDMi40NDc3MTUyNSwzMSAyLDMwLjU1MjI4NDcgMiwzMCBDMiwyOS40NDc3MTUzIDIuNDQ3NzE1MjUsMjkgMywyOSBaIE0zLDI1IEMzLjU1MjI4NDc1LDI1IDQsMjUuNDQ3NzE1MyA0LDI2IEM0LDI2LjU1MjI4NDcgMy41NTIyODQ3NSwyNyAzLDI3IEMyLjQ0NzcxNTI1LDI3IDIsMjYuNTUyMjg0NyAyLDI2IEMyLDI1LjQ0NzcxNTMgMi40NDc3MTUyNSwyNSAzLDI1IFogTTMsMjEgQzMuNTUyMjg0NzUsMjEgNCwyMS40NDc3MTUzIDQsMjIgQzQsMjIuNTUyMjg0NyAzLjU1MjI4NDc1LDIzIDMsMjMgQzIuNDQ3NzE1MjUsMjMgMiwyMi41NTIyODQ3IDIsMjIgQzIsMjEuNDQ3NzE1MyAyLjQ0NzcxNTI1LDIxIDMsMjEgWiBNMywxNyBDMy41NTIyODQ3NSwxNyA0LDE3LjQ0NzcxNTMgNCwxOCBDNCwxOC41NTIyODQ3IDMuNTUyMjg0NzUsMTkgMywxOSBDMi40NDc3MTUyNSwxOSAyLDE4LjU1MjI4NDcgMiwxOCBDMiwxNy40NDc3MTUzIDIuNDQ3NzE1MjUsMTcgMywxNyBaIE0zLDEzIEMzLjU1MjI4NDc1LDEzIDQsMTMuNDQ3NzE1MyA0LDE0IEM0LDE0LjU1MjI4NDcgMy41NTIyODQ3NSwxNSAzLDE1IEMyLjQ0NzcxNTI1LDE1IDIsMTQuNTUyMjg0NyAyLDE0IEMyLDEzLjQ0NzcxNTMgMi40NDc3MTUyNSwxMyAzLDEzIFoiIGlkPSLlvaLnirbnu5PlkIgiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4NCiAgICAgICAgICAgIDwvZz4NCiAgICAgICAgPC9nPg0KICAgIDwvZz4NCjwvc3ZnPg==);box-shadow:0 2px 5px 0 rgba(42,135,255,.2)}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s::before{height:1px;top:50%;left:0;right:0}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-n::after,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-s::after{transform:rotate(90deg)}.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-e::before,.f-splitter-pane>.f-splitter-resize-bar.f-splitter-resize-bar-w::before{width:1px;top:0;left:50%;bottom:0}.f-splitter-resize-overlay{z-index:98;width:100%;height:100%;cursor:e-resize;background:0 0;position:absolute}.f-splitter-horizontal-resize-proxy,.f-splitter-vertical-resize-proxy{background:rgba(42,135,255,.04);display:none;position:absolute;z-index:100}.f-splitter-horizontal-resize-proxy{width:.4375rem;left:0;height:100%}.f-splitter-vertical-resize-proxy{height:.4375rem;top:0;width:100%}.f-component-text{display:block;width:100%;overflow:hidden}.f-form-control-text{height:calc(1.5rem + .125rem);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.f-form-control-textarea{height:calc(calc(1.5rem + .125rem) + 2.321475rem);word-break:break-all;overflow-y:auto;white-space:pre-wrap}.f-form-control-textarea,textarea.form-control{min-height:60px}.f-form-control-text,.f-form-control-textarea{display:block;padding:.1875rem .5rem;font-size:.8125rem;line-height:1.4286;color:var(--f-text-02);background:0 0;background-clip:padding-box;border:1px solid transparent;border-bottom-color:var(--f-neutral-06);border-radius:0}.f-state-view .form-group .farris-label-text{color:var(--f-text-02)}.f-form-control-textarea.f-component-text-auto-size{min-height:calc(calc(1.5357375rem + 2px) + 1.1607375rem);height:auto}.f-form-control-text.f-component-text-auto-size{overflow-y:auto;word-break:break-all;white-space:pre-wrap;min-height:calc(1.5357375rem + 2px);height:auto}.switch{color:var(--f-text-02);background:var(--f-neutral-04);display:inline-block;box-sizing:content-box;margin:0;cursor:pointer;transition:.3s ease-out all;white-space:nowrap}.switch.checked{background:var(--f-theme-04)}.switch.disabled{background:rgba(var(--f-neutral-04),.5)}.switch.disabled .switch-pane{opacity:.5}.switch.checked.disabled{background:rgba(var(--f-theme-03),.5)}.switch.readonly{background:rgba(var(--f-neutral-04),.5)}.switch.readonly .switch-pane{opacity:.5}.switch.checked.readonly{background:rgba(var(--f-theme-03),.5)}.switch small{right:calc(100% - 1.875rem);border-radius:100%;position:absolute;transition:.3s ease-out all;background:var(--f-neutral-00)}.switch.switch-small{min-width:1.625rem;height:.75rem;border-radius:.75rem}.switch.switch-small small{width:.875rem;height:.875rem;left:0;top:-2px}.switch.switch-small.checked small{right:-1px;left:auto}.switch.switch-small>.switch-pane>span{font-size:12px}.switch.switch-small>.switch-pane .switch-label-checked{padding-right:1rem;padding-left:.25rem}.switch.switch-small>.switch-pane .switch-label-unchecked{padding-left:1rem;padding-right:.25rem}.switch.switch-medium{min-width:2.5rem;height:1.375rem;border-radius:1.375rem}.switch.switch-medium small{width:1.125rem;height:1.125rem;left:2px;top:2px}.switch.switch-medium.checked small{right:2px;left:auto}.switch.switch-medium>.switch-pane>span{font-size:12px;line-height:1.375rem}.switch.switch-medium>.switch-pane .switch-label-checked{padding-right:1.625rem;padding-left:.4583333333rem}.switch.switch-medium>.switch-pane .switch-label-unchecked{padding-left:1.625rem;padding-right:.4583333333rem}.switch.switch-large{min-width:2.75rem;height:1.5rem;border-radius:1.5rem}.switch.switch-large small{width:1.25rem;height:1.25rem;left:2px;top:2px}.switch.switch-large.checked small{right:2px;left:auto}.switch.switch-large>.switch-pane>span{font-size:14px;line-height:1.5rem}.switch.switch-large>.switch-pane .switch-label-checked{padding-right:1.75rem;padding-left:.5rem}.switch.switch-large>.switch-pane .switch-label-unchecked{padding-left:1.75rem;padding-right:.5rem}.switch.switch-small>.switch-pane>span{line-height:unset}.switch.checked .switch-pane{top:0}.switch.checked .switch-pane .switch-label-checked{opacity:1;display:inline-block}.switch.checked .switch-pane .switch-label-unchecked{opacity:0;display:none}.switch.disabled,.switch.readonly{cursor:not-allowed}.switch.square,.switch.square small{border-radius:4px}.switch .switch-pane{display:flex;flex-direction:column;height:100%;min-height:100%;justify-content:flex-start;align-items:center;top:0;position:relative;pointer-events:none}.switch .switch-pane>span{display:block;min-height:100%}.switch .switch-pane .switch-label-checked{color:var(--f-text-00);opacity:0;display:none}.switch .switch-pane .switch-label-unchecked{opacity:1;display:inline-block}.f-datagrid-cell-content .switch.switch-medium{min-width:1.625rem;height:.75rem;border-radius:.75rem}.f-datagrid-cell-content .switch.switch-medium small{width:.875rem;height:.875rem;left:0;top:-1px;box-shadow:0 2px 3px 0 rgba(0,0,0,.16)}.f-datagrid-cell-content .switch.switch-medium.checked small{right:0;left:auto}.f-datagrid-cell-content .switch.switch-medium>.switch-pane>span{font-size:12px;line-height:.75rem}.f-datagrid-cell-content .switch.switch-medium>.switch-pane .switch-label-checked{padding-right:1rem;padding-left:.25rem}.f-datagrid-cell-content .switch.switch-medium>.switch-pane .switch-label-unchecked{padding-left:1rem;padding-right:.25rem}.f-cmp-switch{max-width:100%}.f-cmp-switch .switch-pane .switch-label-checked,.f-cmp-switch .switch-pane .switch-label-unchecked{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.table{width:100%;background-color:var(--f-neutral-00);table-layout:fixed}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid var(--f-neutral-07)}.table thead th{vertical-align:middle;border-bottom:2px solid var(--f-neutral-07)}.table tbody+tbody{border-top:2px solid var(--f-neutral-07)}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered,.table-bordered td,.table-bordered th{border:1px solid var(--f-neutral-07)}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(even){background-color:var(--f-neutral-11)}.table-active,.table-active>td,.table-active>th,.table-hover .table-active:hover,.table-hover .table-active:hover>td,.table-hover .table-active:hover>th,.table-hover tbody tr:hover{background-color:var(--f-aid-03)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:var(--f-neutral-07)}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width:887.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}@media (max-width:1689.98px){.table-responsive-el{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-el>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.table thead{background:var(--f-neutral-09);color:var(--f-text-04)}.table thead th{padding:.4375rem .75rem;line-height:1.25rem;border-width:0 0 1px;border-color:var(--f-neutral-13);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;position:relative}.table thead th::after{content:"";position:absolute;right:0;top:50%;margin-top:-.5625rem;display:block;height:1.125rem;width:1px;background-color:var(--f-neutral-06)}.table thead th:last-child::after{display:none}.table td{border-top-width:0;border-bottom:1px solid var(--f-neutral-07);border-color:var(--f-neutral-07);padding:.25rem .75rem;height:calc(.5rem + 1px + 1.1607375rem);line-height:1.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.table td.selected,.table th.selected,.table tr.selected{border-color:var(--f-neutral-07);color:var(--f-text-03);background-color:var(--f-aid-02)}.table-striped tbody tr.selected:nth-of-type(even){background-color:var(--f-aid-02)}.f-datagrid-norecords{width:100%;position:relative;flex:1 1 0;height:100%;justify-content:center}.f-datagrid-norecords-content,.f-table-norecords-content,.f-transfer-norecords .f-transfer-norecords-content{height:7.5rem;padding:5rem 0 0;width:100%;text-align:center;font-size:1rem;color:var(--f-text-07);background:url(data:image/png;base64,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) top center no-repeat;position:absolute;top:50%;margin:-3.75rem 0 0 -.625rem;line-height:2.5rem}.f-transfer-norecords{height:100%;position:relative}.table-hover tbody .f-table-norecords-row:hover{background:initial}.f-table-norecords,.f-table-norecords .f-table-norecords-row td{border:none}.farris-tabs{position:relative;display:flex;flex:1 1 auto}.farris-tabs .margin-right-14{margin-right:14px}.farris-tabs .farris-tabs-header-extend{height:auto;display:flex;align-items:center}.farris-tabs .farris-tabs-header{display:flex;flex-shrink:0;flex-grow:0;align-items:center;margin:0 0 .625rem;padding:.75rem 0 0}.farris-tabs .farris-tabs-header .farris-tabs-title{position:relative;display:flex;width:100%}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer{margin:0}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer.spacer-sides{margin:0 1.5625rem}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer.spacer-sides-dropdown{margin:0 3.75rem 0 1.75rem}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs{overflow:hidden}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item{color:var(--f-text-04);border-width:0;border-style:solid;border-color:transparent;font-size:1rem;margin:0 2rem 0 0;position:relative}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item::after{content:"";position:absolute;bottom:0;left:0;right:0;height:3px;display:none;border-radius:10px;box-shadow:0 2px 6px 0 rgba(78,148,255,.4)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item:hover{color:var(--f-theme-05);border-color:transparent}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item:last-child{margin-right:0}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link{border:none;padding:0 0 .375rem;color:inherit;cursor:pointer;text-decoration:none}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link.tabs-text-truncate{overflow:hidden;white-space:nowrap;display:flex;align-items:center}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link.disabled{color:var(--f-text-07);background-color:transparent;border-color:transparent;pointer-events:none}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link .st-tab-text{max-width:310px;overflow:hidden}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link .farris-title-text-custom{position:relative}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link .farris-title-text-custom::after{content:"";height:100%;position:absolute;right:0;width:30px;background-image:linear-gradient(to left,rgba(255,255,255,.8) 0,rgba(255,255,255,.3) 100%)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item.f-state-active{border-color:var(--f-theme-03);color:var(--f-theme-03)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item.f-state-active::after{display:block;background:var(--f-theme-04)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-fill .nav-item.f-state-active::after,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills .nav-item .nav-link .farris-title-text-custom::after,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills .nav-item.f-state-active::after,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills.nav-fill .nav-item.f-state-active::after{display:none}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item.f-state-active:hover{border-color:var(--f-theme-05)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item.f-state-active .nav-link{color:var(--f-theme-03)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item:active{color:var(--f-theme-02);border-color:transparent}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-fill .nav-item{flex-shrink:1;flex-grow:1;flex-basis:0;background:var(--f-neutral-10);border:none;margin-right:0;margin-left:0}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-fill .nav-item.f-state-active{background-color:var(--f-neutral-00)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-fill .nav-item .nav-link{padding-top:.4375rem;padding-bottom:.4375rem;justify-content:center}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-fill .nav-item .nav-link .st-tab-text{max-width:none}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills .nav-item{border:none;font-size:.875rem;margin:0 .875rem 0 0}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills .nav-item .nav-link{padding:.3125rem .75rem;color:var(--f-text-02);background:var(--f-neutral-09)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills .nav-item .nav-link:hover{color:var(--f-theme-03);background:var(--f-aid-02)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills .nav-item .nav-link.disabled{opacity:.6}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills .nav-item.f-state-active .nav-link{color:var(--f-text-00);background:var(--f-theme-04)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs.nav-pills.nav-fill .nav-item{margin-left:0;margin-right:0}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn{position:absolute;z-index:120}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn:has(>.show){z-index:140}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .dropdown-toggle-split,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .sc-nav-rg,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn.sc-nav-lr{height:1.25rem;width:1.25rem;border-radius:6px;border:1px solid var(--f-neutral-06);background:var(--f-neutral-12)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .dropdown-toggle-split:hover,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .sc-nav-rg:hover,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn.sc-nav-lr:hover{border-color:var(--f-theme-05)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn.sc-nav-lr{left:0;top:50%;margin-top:-.625rem}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn.sc-nav-lr::after{content:" ";width:.5rem;height:.5rem;border-top:1px solid var(--f-text-04);border-right:1px solid var(--f-text-04);transform:rotate(225deg);position:absolute;top:.25rem;left:.4375rem}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .sc-nav-rg{padding:0}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .sc-nav-rg::after{content:" ";width:.5rem;height:.5rem;border-top:1px solid var(--f-text-04);border-right:1px solid var(--f-text-04);transform:rotate(45deg);position:absolute;top:.25rem;right:.4375rem}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .dropdown-toggle-split{color:var(--f-text-04);margin-left:.3125rem;padding:0}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn.dropdown{position:absolute;top:50%;margin-top:-.625rem;right:.375rem}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .dropdown-toggle:active,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .dropdown-toggle:hover{color:var(--f-theme-05)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-btn .dropdown-toggle::after{width:1em;height:1em;content:"\eb82";font-family:FarrisIcons;border:none;font-size:12px;line-height:1;vertical-align:1px}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-lr:hover:after,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-rg:hover:after{border-top:1px solid var(--f-theme-05);border-right:1px solid var(--f-theme-05)}.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-lr:active:after,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .sc-nav-rg:active:after{border-top:1px solid var(--f-theme-01);border-right:1px solid var(--f-theme-01)}.farris-tabs .farris-tabs-header.farris-tabs-inHead{border-bottom:none}.farris-tabs .farris-tabs-header.farris-tabs-inHead .farris-tabs-title{width:41.6666667%}.farris-tabs .farris-tabs-header.farris-tabs-inHead .farris-tabs-toolbar{flex:1 1 0;align-items:center;display:flex;justify-content:flex-end;margin-left:.875rem;overflow:hidden}.farris-tabs .farris-tabs-header.farris-tabs-inContent{display:block}.farris-tabs .farris-tabs-header.farris-tabs-inContent .farris-tabs-title{border-bottom:none}.farris-tabs .farris-tabs-header.farris-tabs-inContent .farris-tabs-toolbar{margin:.625rem 0}.farris-tabs .farris-tabs-header.farris-tabs-nav-fill,.farris-tabs .farris-tabs-header.farris-tabs-nav-fill .farris-tabs-title,.farris-tabs .farris-tabs-header.farris-tabs-nav-pills,.farris-tabs .farris-tabs-header.farris-tabs-nav-pills .farris-tabs-title{border:none}.farris-tabs .farris-tabs-header .farris-tabs-toolbar .btn-link{margin-right:.75rem}.farris-tabs .farris-tabs-header .farris-tabs-toolbar .btn-link:last-child{margin-right:0}.farris-tabs .farris-tabs-header .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0;right:0;left:auto;min-height:80px}.farris-tabs .farris-tabs-header .st-drop-close{width:1rem;height:1rem;text-align:center;cursor:pointer;position:relative;opacity:.4}.farris-tabs .farris-tabs-header .st-drop-close .material-icons{font-size:1rem;margin:-.625rem 0 0 .3125rem}.farris-tabs .farris-tabs-header .st-drop-close:hover{opacity:1}.farris-tabs .farris-tabs-header .active{color:var(--f-theme-03)}.farris-tabs .farris-tabs-header .f-tabs-toolbar-btn{padding:.125rem .8125rem;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;position:relative;color:var(--f-theme-03);border:none;background:0 0;white-space:nowrap}.farris-tabs .farris-tabs-header .f-tabs-toolbar-btn:hover{color:var(--f-theme-05)}.farris-tabs .farris-tabs-header .f-tabs-toolbar-btn:active{color:var(--f-theme-02)}.farris-tabs .farris-tabs-header .farris-tabs-inline-flex{display:inline-flex}.farris-tabs .scroll-tab-tooltips{padding:0;margin:0;width:7.5rem;text-align:left}.farris-tabs .scroll-tab-tooltips li{list-style:none;padding:0;margin:0}.farris-tabs.f-tabs-content-fill .f-tab-active,.farris-tabs.f-tabstrip-fill .f-tab-active{display:flex;flex:1 1 auto;flex-direction:column;overflow:auto}.farris-tabs.f-tabs-content-fill .f-tab-active{position:relative}.farris-tabs .f-tab-d-none{display:none}.farris-tabs.f-tabs-header-sm .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item .nav-link{padding-top:.25rem;padding-bottom:.25rem}.f-cmp-tabs-with-pill .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item{border-radius:4px 4px 0 0;padding:0 .625rem;margin:0 1rem 0 0}.f-cmp-tabs-with-pill .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item.f-state-active{border-color:var(--f-theme-03);color:#fff;background:var(--f-theme-03)}.f-cmp-tabs-with-pill .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item.f-state-active:hover{border-color:var(--f-theme-03)}.f-cmp-tabs-with-pill .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item.f-state-active .nav-link{color:#fff}.nav-pills .nav-link{padding:.3125rem .75rem}.farris-tabs-toolbar .sc-nav-btn .morebtn{padding-right:12px;padding-left:12px;margin-right:0!important}.lookup-tabs-nav .nav-item-selected{color:var(--f-theme-03)!important}.lookup-tabs-nav .lookup-selected-total{color:var(--f-text-00)!important;background:var(--f-theme-04)!important}.lookup-tabs-nav .tabs-ink-bar{background:linear-gradient(214deg,#3F65FF 0,#4D9AFF 100%)!important}.farris-tabs-inContent .farris-tabs-toolbar:has(.f-component-tabs-view){display:flex}.farris-tabs-inContent .farris-tabs-toolbar .f-component-tabs-view{height:auto}.farris-tabs.one-page{overflow:hidden}.farris-tabs.one-page .farris-tabs-content{overflow:auto;position:relative}.farris-tabs .st-drop-close{line-height:1}.farris-tabs .tabs-li-absolute{padding:4px;margin:0;position:relative}.farris-tabs .farris-tabs-header{flex-wrap:nowrap!important}.farris-tabs .tabs-li-absolute input{line-height:26px;height:26px;padding-right:24px}.farris-tabs .tabs-icon-search{position:absolute;right:4px;top:50%;font-size:14px;padding:0 4px;width:auto;height:24px;color:rgba(0,0,0,.25);margin-top:-12px;line-height:20px}.farris-tabs .dropdown-no-data{height:26px;line-height:26px;text-align:center;padding-top:5px}.farris-tabs .farris-tabs-header .farris-tabs-header-post,.farris-tabs .farris-tabs-header .farris-tabs-header-pre,.farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .spacer .farris-nav-tabs .nav-item{flex-shrink:0}.farris-tabs .farris-tabs-header .farris-tabs-title{flex:1 0}.farris-tags .farris-tags-item-container li.farris-tag-item{border-color:#E6E6E6}.farris-tags .farris-tags-item-container.farris-tag-item-capsule .farris-tag-item{border-radius:24px}.farris-tags .farris-tags-item-container.farris-tag-item-capsule .farris-tag-item.farris-tag-item-checkable:not(.farris-tag-item-checked){background:#fff;border:1px solid #e6e6e6;cursor:pointer}.farris-tags.farris-tags-nowrap{overflow:hidden}.farris-tags.farris-tags-nowrap .farris-tags-item-container{display:flex;flex-wrap:nowrap;overflow:hidden}.farris-tags .farris-tags-item-container .farris-tag-item{background:rgba(var(--f-theme-03),.06);border:1px solid;color:var(--f-text-02);display:inline-block;padding:0 8px;margin:0 10px 0 0;line-height:24px;font-size:13px;white-space:nowrap;border-radius:3px;cursor:default;opacity:1;transition:all .3s cubic-bezier(.78,.14,.15,.86)}.farris-tags .farris-tags-item-container .farris-tag-item a,.farris-tags .farris-tags-item-container .farris-tag-item a:hover{color:var(--f-text-02)}.farris-tags .farris-tags-item-container .farris-tag-item>a:first-child:last-child{display:inline-block;margin:0 -8px;padding:0 8px}.farris-tags .farris-tags-item-container .farris-tag-item .tag-delete{color:var(--f-text-06);display:inline-block;font-size:10px;width:16px;text-align:right;margin:0;cursor:pointer;transition:all .3s cubic-bezier(.78,.14,.15,.86);position:relative;z-index:10}.farris-tags .farris-tags-item-container .farris-tag-item .tag-delete .f-icon{font-size:12px}.farris-tags .farris-tags-item-container .farris-tag-item .tag-delete:hover{color:var(--f-text-02)}.farris-tags .farris-tags-item-container .farris-tag-item>.f-icon+span,.farris-tags .farris-tags-item-container .farris-tag-item>span+.f-icon{margin-left:7px}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-success{color:var(--f-semantic-success-01);border-color:var(--f-semantic-success-02);background:var(--f-semantic-success-03)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-success.farris-tag-item-actived{color:var(--f-semantic-success-03);border-color:var(--f-semantic-success-01);background:var(--f-semantic-success-01)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-info{color:var(--f-semantic-info-01);border-color:var(--f-semantic-info-02);background:var(--f-semantic-info-03)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-info.farris-tag-item-actived{color:var(--f-semantic-info-03);border-color:var(--f-semantic-info-01);background:var(--f-semantic-info-01)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-error{color:var(--f-semantic-danger-01);border-color:var(--f-semantic-danger-02);background:var(--f-semantic-danger-03)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-error.farris-tag-item-actived{color:var(--f-semantic-danger-03);border-color:var(--f-semantic-danger-01);background:var(--f-semantic-danger-01)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-warning{color:var(--f-semantic-warning-01);border-color:var(--f-semantic-warning-02);background:var(--f-semantic-warning-03)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-warning.farris-tag-item-actived{color:var(--f-semantic-warning-03);border-color:var(--f-semantic-warning-01);background:var(--f-semantic-warning-01)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-checkdisabled{cursor:not-allowed;color:rgba(0,0,0,.45)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-checked{background-color:#fff}.farris-tags .farris-tags-item-container .farris-tag-item:last-child{margin-right:0}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-checkable:not(.farris-tag-item-checked){color:var(--f-text-02);background-color:transparent;border-color:transparent}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-checkable:not(.farris-tag-item-checked):active{color:var(--f-text-02)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-checkable:not(.farris-tag-item-checked):hover{color:var(--f-theme-03)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-checkdisabled{background-color:transparent;border-color:transparent;color:var(--f-text-07)}.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-actived,.farris-tags .farris-tags-item-container .farris-tag-item.farris-tag-item-checked{background:var(--f-theme-03);border-color:var(--f-theme-03);color:var(--f-text-00)}.farris-tags .farris-tags-item-container .farris-tag-add-button{cursor:pointer;background:#fff;border-radius:6px;border:1px dashed var(--f-neutral-04)}.farris-tags .farris-tags-item-container .farris-tag-add-button .farris-tag-add-text{color:var(--f-text-06)}.farris-tags .farris-tags-item-container .farris-tag-add-button .f-icon{color:var(--f-text-04)}.farris-tags .farris-tags-item-container .farris-tag-add-button:hover{border-color:var(--f-theme-05)}.farris-tags .farris-tags-item-container .farris-tag-add-button:hover .f-icon,.farris-tags .farris-tags-item-container .farris-tag-add-button:hover .farris-tag-add-text{color:var(--f-theme-05)}.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled{opacity:.6;border-style:solid;cursor:not-allowed}.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled .farris-tag-add-text{color:rgba(0,0,0,.25)}.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled,.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled:hover{background:var(--f-neutral-08);border-color:var(--f-neutral-05)}.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled .f-icon,.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled .farris-tag-add-text,.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled:hover .f-icon,.farris-tags .farris-tags-item-container .farris-tag-add-button.farris-tag-add-button-disabled:hover .farris-tag-add-text{color:var(--f-text-07)}.farris-tags .farris-tags-item-container .farris-tag-input-box{display:inline-block}.farris-tags .farris-tags-item-container .farris-tag-input-box .form-control{height:24px;width:100px}.farris-tags .farris-tags-item-container .farris-tag-input-box .form-control:focus{box-shadow:none}.farris-tags.farris-tags-checkable .farris-tag-item{line-height:22px}.time-picker-panel{box-sizing:border-box;margin:0;padding:0;color:var(--f-text-04);font-size:14px;font-variant:tabular-nums;line-height:1.5;list-style:none;font-feature-settings:"tnum";position:absolute;z-index:9999;min-width:200px;background:var(--f-neutral-20)}.time-picker-panel .time-picker-panel-inner{position:relative;left:0;font-size:14px;text-align:left;list-style:none;background-clip:padding-box;border-radius:10px;outline:0;box-shadow:0 2px 20px 0 rgba(3,18,51,.12);padding:3px 0}.time-picker-panel .time-picker-panel-inner .time-picker-panel-input-wrap{position:relative;padding:7px 2px 7px 12px;border-bottom:1px solid var(--f-neutral-08)}.time-picker-panel .time-picker-panel-inner .time-picker-panel-input-wrap .time-picker-panel-input:-moz-placeholder-shown{text-overflow:ellipsis}.time-picker-panel .time-picker-panel-inner .time-picker-panel-input-wrap .time-picker-panel-input:placeholder-shown{text-overflow:ellipsis}.time-picker-panel .time-picker-panel-inner .time-picker-panel-input-wrap .time-picker-panel-input{width:100%;max-width:154px;margin:0;padding:0;line-height:normal;border:0;outline:0;cursor:auto}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox{zoom:1}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select{position:relative;float:left;width:4.125rem;max-height:192px;overflow:hidden;font-size:14px;border-left:1px solid var(--f-neutral-08)}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select ul{width:4.125rem;margin:0;padding:0 0 160px;list-style:none}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select ul li{height:2rem;margin:0 6px;padding:0;border-radius:6px;line-height:2rem;text-align:center;list-style:none;cursor:pointer;transition:all .3s;-webkit-user-select:none;-moz-user-select:none;user-select:none;color:var(--f-text-02)}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select:first-child,.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select:first-child{margin-left:0;border-left:0}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select ul li:hover{color:var(--f-theme-03)}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select ul li.time-picker-panel-select-option-selected{background:var(--f-aid-02);color:var(--f-theme-03)}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select ul li.time-picker-panel-select-option-disabled,.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select ul li.time-picker-panel-select-option-disabled:hover{color:var(--f-text-07)}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select ul li:last-child::after{height:162px;display:block;content:""}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select:last-child{border-right:0}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox .time-picker-panel-select:hover{overflow-y:auto}.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox::after,.time-picker-panel .time-picker-panel-inner .time-picker-panel-combobox::before{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0}.calendar-time-picker{display:block;height:228px;width:100%;background:var(--f-neutral-20)}.calendar-time-picker .calendar-time-picker-panel{z-index:9999;width:100%;color:var(--f-text-04)}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner{position:relative;display:inline-block;width:100%;overflow:hidden;font-size:14px;line-height:1.5;text-align:left;list-style:none;background:var(--f-neutral-20);background-clip:padding-box;outline:0}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox{width:100%;display:flex}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-column-3 .calendar-time-picker-select{width:33.33%}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select{position:relative;flex:1;height:226px;overflow:hidden;font-size:14px;border-right:1px solid var(--f-neutral-08)}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select ul{width:100%;max-height:206px;margin:0;padding:0;list-style:none}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select li{color:var(--f-text-02);height:2rem;margin:0 6px;line-height:2rem;border-radius:6px;text-align:center;list-style:none;cursor:pointer;transition:all .3s;-webkit-user-select:none;-moz-user-select:none;user-select:none}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select li:hover{color:var(--f-theme-03)}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select li:last-child::after{display:block;height:202px;content:""}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select li.calendar-time-picker-select-option-selected{color:var(--f-theme-03);background:var(--f-aid-02)}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select li.calendar-time-picker-select-option-disabled,.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select li.calendar-time-picker-select-option-disabled:hover{color:var(--f-text-09);background:#f8f9fa;cursor:not-allowed}.calendar-time-picker .calendar-time-picker-panel .calendar-time-picker-inner .calendar-time-picker-combobox .calendar-time-picker-select:hover{overflow-y:auto}.time-picker-overlay{top:0;bottom:0;left:0;right:0;position:fixed;z-index:8888;display:none}.tooltip,.tooltip .arrow{display:block;position:absolute}.time-picker-overlay .time-picker-panel-box{top:0;left:0;height:100%;width:100%;position:absolute;z-index:8888;flex-direction:column;min-width:1px;min-height:1px;transform:translate(0,0)}.input-group .input-group-append.f-cmp-iconbtn-wrapper{align-items:center;background:var(--f-neutral-12)}.input-group .input-group-append.f-cmp-iconbtn-wrapper .f-cmp-iconbtn{background:var(--f-neutral-12);cursor:pointer;padding:0 .5rem;color:var(--f-text-08)}.input-group .input-group-append.f-cmp-iconbtn-wrapper .f-cmp-iconbtn:hover{color:var(--f-theme-05)}.input-group .input-group-append.f-cmp-iconbtn-wrapper .f-cmp-iconbtn:active{color:var(--f-theme-03)}.input-group .input-group-append.f-cmp-iconbtn-wrapper .f-cmp-iconbtn .f-icon{font-size:.75rem}.f-component-timepicker .timepicker-btn{padding:0 .5rem;color:var(--f-text-07)}.f-component-timepicker .timepicker-btn:hover{color:var(--f-theme-05)}.tooltip{z-index:1070;margin:0;font-style:normal;line-height:1.4286;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.75rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:1}.tooltip .arrow{width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:rgba(var(--f-neutral-00-rgb),.4)}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:rgba(var(--f-neutral-00-rgb),.4)}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:rgba(var(--f-neutral-00-rgb),.4)}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:rgba(var(--f-neutral-00-rgb),.4)}.tooltip-inner{max-width:18.75rem;max-height:6.25rem;overflow:hidden;padding:.5rem .625rem;color:var(--f-text-02);text-align:left;background-color:rgba(var(--f-neutral-00-rgb),.95);box-shadow:0 2px 8px 0 rgba(0,0,0,.15);border-radius:6px}.tooltip-inner-lg{max-width:37.5rem;max-height:initial;overflow:initial}.f-tooltip{position:absolute;display:none;padding:.25em .5em;max-width:12.5em;line-height:1.2rem;border-radius:5px}.f-tooltip-left,.f-tooltip-right{padding:0 .6em}.f-tooltip-bottom,.f-tooltip-top{padding:.6em 0}.f-tooltip-bottom-left,.f-tooltip-top-left,.f-tooltip-top-right{padding:0}.f-tooltip-default{background-color:rgba(var(--f-neutral-00-rgb),.9);color:var(--f-text-02);border:1px solid var(--f-neutral-00)}.f-tooltip-text{padding:.5em .3em;white-space:pre-line;border-radius:3px;box-shadow:0 2px 8px 0 rgba(0,32,74,.15)}.f-tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid;border-width:1em}.f-tooltip-right .f-tooltip-arrow{top:50%;left:0;margin-top:-.5em;border-width:1em 1em 1em 0;border-right-color:var(--f-neutral-00)}.f-tooltip-left .f-tooltip-arrow{top:50%;right:0;margin-top:-.5em;border-width:1em 0 1em 1em;border-left-color:var(--f-neutral-00)}.f-tooltip-bottom .f-tooltip-arrow,.f-tooltip-top .f-tooltip-arrow{left:50%;margin-left:-.5em;border-width:1em;border-top-color:var(--f-neutral-00)}.f-tooltip-top .f-tooltip-arrow{bottom:0;border-bottom-width:0}.f-tooltip-bottom-left .f-tooltip-arrow,.f-tooltip-top-left .f-tooltip-arrow{left:10px;margin-left:-.5em;border-bottom-width:0}.f-tooltip-top-left .f-tooltip-arrow,.f-tooltip-top-right .f-tooltip-arrow{bottom:0;margin-bottom:-.5em}.f-tooltip-bottom-right .f-tooltip-arrow,.f-tooltip-top-right .f-tooltip-arrow{right:10px;margin-right:-.5em;border-bottom-width:0}.f-tooltip-bottom .f-tooltip-arrow{top:0;border-top-width:0}.f-tooltip-bottom-left .f-tooltip-arrow{top:0}.f-tooltip-info.f-tooltip-top-left .f-tooltip-arrow,.f-tooltip-info.f-tooltip-top-right .f-tooltip-arrow{border-top-color:rgba(var(--f-neutral-00-rgb),.9)}.f-tooltip-info.f-tooltip-bottom .f-tooltip-arrow{border-bottom-color:rgba(var(--f-neutral-00-rgb),.9)}.f-tooltip-info.f-tooltip-right .f-tooltip-arrow{border-right-color:rgba(var(--f-neutral-00-rgb),.9)}.f-tooltip-info.f-tooltip-left .f-tooltip-arrow{border-left-color:rgba(var(--f-neutral-00-rgb),.9)}.f-tooltip-info .f-tooltip-text{background-color:rgba(var(--f-neutral-00-rgb),.9);box-shadow:0 2px 8px 0 rgba(0,32,74,.15)}.f-tooltip-danger .f-tooltip-text{color:var(--f-semantic-danger-01);background-color:var(--f-semantic-danger-03);border-color:var(--f-semantic-danger-02)}.f-tooltip-danger.f-tooltip-top .f-tooltip-arrow,.f-tooltip-danger.f-tooltip-top-left .f-tooltip-arrow{border-top-color:var(--f-semantic-danger-02)}.f-transfer{padding:.125rem;border:1px solid var(--f-neutral-06);border-radius:6px}.f-transfer .option-pane,.f-transfer .option-pane-content .columns-box{padding:0}.transfer-search-box{margin:.75rem .875rem}.f-transfer .transfer-search-box .f-cmp-inputgroup .input-group,.f-transfer .transfer-search-box .f-cmp-inputgroup .input-group>.form-control:not(:last-child){border-radius:6px}.f-transfer .transfer-search-box .f-cmp-inputgroup .input-group>.input-group-append{border-radius:0 6px 6px 0}.f-transfer .transfer-search-box .f-cmp-inputgroup .input-group>.input-group-append>.input-group-clear{border-radius:6px!important}.f-transfer .option-pane-content .columns-box .fv-tree-view .fv-grid-hierarchy-cell div span{overflow:hidden;text-overflow:ellipsis}.f-transfer .option-pane .option-pane-group{padding:.375rem 0}.f-transfer .option-pane .f-transfer-list-item{padding:.375rem .875rem;cursor:default;margin:0;border-radius:0;color:var(--f-text-03)}.f-transfer .option-pane .f-transfer-list-item .f-list-select{padding:0}.f-transfer .option-pane .f-transfer-list-item.f-un-select{color:var(--f-text-08)}.f-transfer .option-pane .f-transfer-list-item:not(.f-un-select):hover{background:var(--f-neutral-11)}.f-transfer .option-pane .f-transfer-list-item.f-listview-active{background:var(--f-neutral-10)}.f-transfer .option-pane .f-transfer-list-item .custom-checkbox{padding:0;margin:0;width:100%;overflow:hidden}.f-transfer .option-pane .f-transfer-list-item .custom-control-label{padding-left:1.375rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.f-transfer .selection-pane{border-left:1px solid var(--f-neutral-06);padding:0}.f-transfer .selection-pane .selection-pane-title{padding:.875rem .875rem .375rem;background:var(--f-neutral-10);color:var(--f-text-01);display:flex;align-items:center}.fv-grid-hierarchy-cell,.fv-tree-node-cell{padding:0 .75rem;display:flex;line-height:28px;top:0;white-space:nowrap}.f-transfer .selection-pane .selection-pane-title>.selection-count{font-size:18px;margin:0 .25rem}.f-transfer .selection-pane .selection-pane-title>.selection-title-action{font-size:13px;color:#2a87ff;flex:1;text-align:right}.f-transfer .selection-pane .selection-pane-title>.selection-title-action>i{margin:0 .5rem}.fv-grid-hierarchy-cell{position:absolute;text-overflow:ellipsis;flex-direction:column;align-items:center;z-index:1;border-color:transparent;background-color:transparent;overflow:hidden}.fv-tree,.fv-tree-content,.fv-tree-content-primary{overflow:scroll;position:relative}.fv-grid-bordered .fv-grid-hierarchy-cell{border-right-color:#eaecf3}.fv-grid-horizontal-bordered .fv-grid-hierarchy-cell{border-bottom-color:#eaecf3}.fv-tree{display:flex;flex-direction:column;border-color:transparent;flex:1;color:#424347;width:100%}.fv-tree-content{flex:1;display:flex;width:100%;z-index:0;background:#fff}.fv-tree-content-hover{cursor:pointer}.fv-tree-content-primary{flex:1}.fv-tree-data{height:100%;width:100%;position:relative;overflow:hidden}.fv-tree-data .fv-grid-hierarchy-cell{border:none}.fv-tree-node{left:0;width:100%;position:absolute}.fv-tree-node.selected,.fv-tree-node:active,.fv-tree-node:hover{left:0;position:absolute;background:#e7f1ff}.fv-tree-strip .fv-tree-node-odd{background-color:#fff}.fv-tree-strip .fv-tree-node-even{background-color:#f7f8fb}.fv-tree-node-hover{cursor:pointer;color:#424347;background:#edf5ff!important}.fv-tree-node-selected{color:#424347!important;background-color:#dae9ff!important}.fv-tree-node-cell{position:absolute;text-overflow:ellipsis;flex-direction:column;align-items:center;z-index:1;border-style:solid;border-width:1px;border-color:transparent transparent #eaecf3;background-color:transparent}.fv-tree-data :first-child .fv-tree-node-cell{background:0 0;border-left:none}.fv-tree-node-cell-input{font-size:12px;height:12px;width:12px;border:1px solid #aeb5c6}.fv-tree-node-cell .f-icon.f-icon-checkbox-checked{color:#2a87ff!important}.fv-tree-node-cell .custom-control-input:checked~.custom-control-label::before{color:#2a87ff}.fv-tree-node-cell input[type=checkbox]{display:none}.fv-tree-node-cell input[type=checkbox]+label{position:relative;padding-left:18px;cursor:pointer;display:flex}.fv-tree-node-cell input[type=checkbox]+label::before{content:"\e304";font-family:FarrisIcons;position:absolute;left:0;top:0;color:#d8dce6}.fv-tree-node-cell input[type=checkbox]:indeterminate+label::before{content:"\e306";font-family:FarrisIcons;position:absolute;left:0;top:0;color:#2a87ff}.fv-upload-and-preview .ffileUploadAndPreview{font-size:13px}.fv-upload-and-preview .ffileUploadAndPreview-content-fill{flex-grow:1;flex-shrink:1;flex-basis:0;display:flex;flex-direction:column;overflow:hidden}.fv-upload-and-preview .ffileUploadAndPreview-content-fill .uploadAndpreview--header{flex-shrink:0}.fv-upload-and-preview .ffileUploadAndPreview-content-fill .uploadAndpreview--content{flex-grow:1;flex-shrink:1;flex-basis:0;overflow:auto}.fv-upload-and-preview .uploadAndpreview--header{display:flex;align-items:center;margin:0 0 9px;position:relative}.fv-upload-and-preview .uploadAndpreview--header .ffileupload--browser{position:absolute;margin:0;padding:0;left:1em;top:-9000px;width:calc(100% - 2em);opacity:0;font-size:0}.fv-upload-and-preview .uploadAndpreview--header .header--left-container{display:flex;align-items:center}.fv-upload-and-preview .uploadAndpreview--header .upload-container{height:44px;background:#FAFCFD;border:1px dashed #D8DFED;border-radius:6px;padding:0 22px;cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:130px;display:inline-block;line-height:44px;align-items:center;max-width:160px}.fv-upload-and-preview .uploadAndpreview--header .upload-container.f-state-disabled{opacity:.6;cursor:default}.fv-upload-and-preview .uploadAndpreview--header .upload-container .upload-icon{color:#2F8AFF;font-size:18px;margin:0 10px 0 0}.fv-upload-and-preview .uploadAndpreview--header .header--right-container{margin-left:auto;min-height:44px;display:flex;align-items:center}.fv-upload-and-preview .uploadAndpreview--header .header--countInfo{min-height:44px;display:flex;align-items:center;font-size:14px}.fv-upload-and-preview .uploadAndpreview--header .header--countInfo .count{font-size:16px;font-weight:600;margin:0 6px}.fv-upload-and-preview .uploadAndpreview--content{margin-bottom:10px}.fv-upload-and-preview .uploadAndpreview--table td{border-left:none;border-right:none;vertical-align:middle!important;padding-top:12px;padding-bottom:12px}.fv-upload-and-preview .uploadAndpreview--table .td--hascheckbox{position:relative;padding-left:44px}.fv-upload-and-preview .smooth-dnd-ghost .td--hascheckbox .preview-checkbox,.fv-upload-and-preview .uploadAndpreview--table .td--hascheckbox .preview-checkbox{position:absolute;top:50%;margin-top:-8px;left:14px}.fv-upload-and-preview .uploadAndpreview--title-container{display:flex;overflow:hidden}.fv-upload-and-preview .uploadAndpreview--title-container .uploadAndpreview--right{align-self:center;flex:1 1 0;overflow:hidden}.fv-upload-and-preview .uploadAndpreview--right .item-content--title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;cursor:pointer}.fv-upload-and-preview .uploadAndpreview--right .item-content--title.no-preview{cursor:default}.fv-upload-and-preview .uploadAndpreview--title-container .ffilepreview--filetype-icon{width:28px;height:28px}.fv-upload-and-preview .uploadAndpreview--state-container p{margin:0;padding:0}.fv-upload-and-preview .uploadAndpreview--state-container .f-icon{font-size:18px}.fv-upload-and-preview .ffileupload--support-info .support-info--wrapper{padding:0 8px;margin:0 0 8px}.fv-upload-and-preview .ffileupload--support-info .support-info--wrapper li{color:#B4BCCC;margin:0;padding:0;display:inline-block}.fv-upload-and-preview .uploadAndpreview--date-container,.fv-upload-and-preview .uploadAndpreview--filesize-container{color:rgba(45,47,51,.45);font-size:12px}.fv-upload-and-preview .uploadAndpreview--state-container .f-icon{margin:0 8px 0 0}.fv-upload-and-preview .uploadAndpreview--nodata{padding:0 8px;margin:0 0 8px;color:#B4BCCC}.fv-upload-and-preview .uploadAndpreview--action-container{display:flex;flex-direction:row;align-items:center;min-width:90px;height:100%}.fv-upload-and-preview .uploadAndpreview--action-container .preview-btn{height:22px;width:22px;border-radius:16px;display:inline-block;padding:0;color:#2b87ff;text-align:center;border:none;margin:0 14px 0 0}.fv-upload-and-preview .uploadAndpreview--action-container .preview-btn[disabled]{color:gray;opacity:.5;cursor:not-allowed;background:#e6e6e6;border:1px solid #bdbdbd}.fv-upload-and-preview .uploadAndpreview--action-container .preview-btn:not([disabled]):hover{color:#fff}.fv-upload-and-preview .uploadAndpreview--action-container .preview-btn .f-icon{margin:0 auto;display:block;font-size:16px;position:relative}.fv-upload-and-preview .ffilepreview--filetype-zip{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--filetype-xls{background-image:url(data:image/png;base64,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dGUAMjAxOS0xMi0yOFQwOTozMTo1NiswMDowMLhrE7kAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTktMDEtMDhUMTk6NDM6NTkrMDA6MDCdstIMAAAAIHRFWHRzb2Z0d2FyZQBodHRwczovL2ltYWdlbWFnaWNrLm9yZ7zPHZ0AAAAYdEVYdFRodW1iOjpEb2N1bWVudDo6UGFnZXMAMaf/uy8AAAAYdEVYdFRodW1iOjpJbWFnZTo6SGVpZ2h0ADUxMo+NU4EAAAAXdEVYdFRodW1iOjpJbWFnZTo6V2lkdGgANTEyHHwD3AAAABl0RVh0VGh1bWI6Ok1pbWV0eXBlAGltYWdlL3BuZz+yVk4AAAAXdEVYdFRodW1iOjpNVGltZQAxNTQ2OTc2NjM5OiA9twAAABN0RVh0VGh1bWI6OlNpemUAMjc5NTUxQgHjNFMAAABadEVYdFRodW1iOjpVUkkAZmlsZTovLy9kYXRhL3d3d3Jvb3Qvd3d3LmVhc3lpY29uLm5ldC9jZG4taW1nLmVhc3lpY29uLmNuL2ZpbGVzLzExOC8xMTg0MjYwLnBuZ1tLqmgAAAAASUVORK5CYII=)}.fv-upload-and-preview .ffilepreview--filetype-txt{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--filetype-ppt{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--filetype-pdf{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--filetype-img{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5AIKAx4vKar87wAAByBJREFUeNrtnEtv29gZhp/vHFIXy5f4OoknbdPAQQsPZtBNgGZQYNCi6GWZxSz7P1r0R/Q3tOtidtOuBy6aFJ0OUBTpLXGSqR3PxJIpWqJEkRR5upCixLEtShZtyYnejSTykDrfo+9yziFFmGqqUSSvfnAch7m5OSqVCr7vY4wZd/8uBoIIhUKB1dVV6vU6S0tLxwE5jsP8/DxbW1tsbm5eD4LgjoisjLvzFyFjTCWfz997+PDh7u3bt2k0Gj1IPUBRFLG1tcXGxsaParXab4IgeA/Q4+78BSnO5/MP5ufnf3X//v0/3L17F9u2jwLa29tDa329XC5/6nneB+Pu8ThUKpUerK2t/SyO49319XUA1IudrVaLIAjudD3nrVQYht8NguBOq9XqbesBMsbQzTlvS1idJC0iK68WJ2uQo+RosXtjZEiv0qmABOFvz7/gUXUbEZV6wsshw4w9ww+/8RElu9QX1EAe9Ki6zWe7Wyh5M6LPmITl4hIfrn+fUq5EP0caLMREoUSj3xAPMsjAP3bmFhsYILIvjzIBZIAEIS8xSypkVtrQ3XbZNVCI9ZMBrqiQH+T2ec+qsqwCmsbicXuOP4Xv8CSeHbeN4wOUIHxLe/yiuM0tq4Z0gQlwU3t8zz7g960b3AvXxm3nmXXmEDPAnER8XHzKd6xaN8zovcbAsgr5uPCUW1bt0obbCICE9+0qm5ZLfEqbpAvpo9zXWCTjtvViAQmGm7qOnVKzDHBdNyhKfCmr20hVbBCvMEBRYnISp59wGF0Q7REACcEA81oBPGMRmOxG4Umc4Ow4tOotzju1jZSk/9W+gm9Uah+32/M0jZWZLfX9OodfHeLuVonDjD0zK0AKw7/bC/w1WjnVcAU8i4t8Fl7NpooJ+K6Pu+cC4NdaVHer57p2PlIOCozik9YN/hyu0kahuyfUHVv4Mi7xO3+D3XgGNWrSEIj8CGfHIYle5j6v4lHfr58boJEGigI4SY7f+ht8Hq2wablc1T6esfhve4G/R0tUknwmoZW0E9xdl7ARHsk7JjG4z1xyxRyFhULmyXvkqYYALaP5PFrhi2gZm4QYoY1CMJnlndrzGp7jnZiU4zDG2XFYy69hFaxMIWUyWRXohVCEIkFQGcJpuk0OvzrEJKdYLtCqt6juVEna2Q5IJ36BJ4kTfNfHLtjkZ3InttGWojCbJwqiTunPUCOH2HlLacXSNxcxBpz/OYR+dLyNrVm5uYqVz96cifcgANEK3/XxKt6J+yM/ol6uI0pQOluTJh9Qt7y7z1xMfHr2re/XaVabmY+sJx6QiTtlPGyGfY1/0S46IQRH0WQDEmg4DRpOI90zBMJGiLvnnl7t3ihAXYOru9XBDRZoHDTwDrzB2g+gY4CMMSfMbS7+WkVn5Fyl3WoPddyRkBzogH52v1LmlVKIyMvbPuSlT2tLo7Q6su285T33aB76oIf/znbYxt1zWd1YPbWqKS1Yto1t2xg6cGzbRkRQ6uUxPUBzc3OICNeuXTtCUolisbpIwS+gL+LKanfG7tUbqJI+U1EyQBCFhFHI4juLx/YnJqE0U+Ldd9dZnVklMZ3Rt4igtaZQKBwH9IKaZR0dbIkIytKIlvP3IIE4iKk8PaAdtjuJ+QzfKaYTMs5OlcJCkZnF4pEMoVCIVli2hW3bPUCv2nwM0KQoCiLyszlypc60onHQIGoNXrpFCbPLs1h5jUkgDtvH06d59W3/3DpZgAwU5goU5gqICN6BR7083FqPSQxWXrN2aw1RMnJtmcwyL9DyWjx/uE8cDL+k6u4d4j5zMym8EwkojmLKjyuEXnimqYNJDJUnBzSqzZHz5sQBMqZjnFf2RppXxWFM+dE+LS8Y6TwTB6j2da0THqNKOov6lcflI2vYw2pyAAk0q03K25W+s/ahTilCvexx8OXBma98TEwVi5oR+4/2OyX9xW0iJ1t9fFuK8c5OldxMjoVrC5cUkAHPaaC0orRU6t/hWoxqmpcQNUTLGqP7lXRD0/UpLZWGXnWcDEACV64tcCXlFzbAwl98Sk+CTnIwEM8qDj6cpV3qf4XXGNMZFw2pyQAEA3VeBBSCNtKJKgPGSHeptf+g8Kz3ek9Okh5CF7nwMpAHGZMQJzGcwUUzlYEkiUmSuEcpSQxJkhAPsWRlTEJikoGapwMysD67zger76PGfZ+0wOxGQMGOeoO/pKi4erVIXBx83mUwLOavkFN26jGpgAyGn3/7p/zkxo/HC+cFo9scM+ostx6JCJayspnNa6XRk/InoAvuxqVM0hepKaAUTQGlaAooRVNAKZoCStEUUIqmgFI0BZSiKaAUTQGl6HVAFeB8//ww2Yq7DHp6HdA94MG4ezlG/afLoKfXAe0Cv6QD6W3ypBj4J/DrLoOeTlru+CPwD+AO8FY8YIlOWN3jNThwwiO6puLII7qmmmo0/R/bJffeYyphcAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOS0xMi0yOFQwOTozMTo1NiswMDowMLhrE7kAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTktMDEtMDhUMTk6NDM6MjIrMDA6MDCVcI/vAAAAIHRFWHRzb2Z0d2FyZQBodHRwczovL2ltYWdlbWFnaWNrLm9yZ7zPHZ0AAAAYdEVYdFRodW1iOjpEb2N1bWVudDo6UGFnZXMAMaf/uy8AAAAYdEVYdFRodW1iOjpJbWFnZTo6SGVpZ2h0ADUxMo+NU4EAAAAXdEVYdFRodW1iOjpJbWFnZTo6V2lkdGgANTEyHHwD3AAAABl0RVh0VGh1bWI6Ok1pbWV0eXBlAGltYWdlL3BuZz+yVk4AAAAXdEVYdFRodW1iOjpNVGltZQAxNTQ2OTc2NjAyht+3/AAAABJ0RVh0VGh1bWI6OlNpemUAMjU4MjFCXXziJwAAAFp0RVh0VGh1bWI6OlVSSQBmaWxlOi8vL2RhdGEvd3d3cm9vdC93d3cuZWFzeWljb24ubmV0L2Nkbi1pbWcuZWFzeWljb24uY24vZmlsZXMvMTE4LzExODM3MDcucG5nZ8+z2wAAAABJRU5ErkJggg==)}.fv-upload-and-preview .ffilepreview--filetype-doc{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--filetype-any{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--filetype-wps{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--filetype-wpt{background-image:url(data:image/png;base64,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)}.fv-upload-and-preview .ffilepreview--item-icon{margin:0 .625rem 0 0}.fv-upload-and-preview .ffilepreview--filetype-icon{display:inline-block;width:38px;height:38px;background-repeat:no-repeat;background-position:0 0;background-size:cover}.fv-upload-and-preview .smooth-dnd-ghost.uploadAndpreview--preview-item.smooth-dnd-draggable-wrapper{background-color:#dae9ff}.fv-upload-and-preview .upfile-drag-handle{position:relative;top:-2px;margin-right:5px;cursor:grab}.fv-upload-and-preview .upfile-drag-handle:active{cursor:grabbing}.fv-upload-and-preview .upload-progress{display:inline-block;font-size:.875rem;color:rgba(0,0,0,.65)}.fv-upload-and-preview .upload-progress.upload-progress-line{position:relative;width:100%}.fv-upload-and-preview .upload-progress.upload-progress-line .upload-progress-text .upload-progress-text-icon{font-size:1.25rem}.fv-upload-and-preview .upload-progress .upload-progress-outer{display:inline-block;width:100%}.fv-upload-and-preview .upload-progress .upload-progress-inner{position:relative;display:inline-block;width:100%;overflow:hidden;vertical-align:middle;background-color:#efefef;border-radius:100px}.fv-upload-and-preview .upload-progress .upload-progress-bg,.fv-upload-and-preview .upload-progress .upload-progress-success-bg{position:relative;border-radius:100px;height:6px;transition:all .4s cubic-bezier(.08,.82,.17,1) 0s}.fv-upload-and-preview .upload-progress .upload-progress-success-bg{position:absolute;top:0;left:0}.fv-upload-and-preview .upload-progress .upload-progress-text{display:inline-block;width:1.75rem;margin-left:.5rem;color:rgba(0,0,0,.65);font-size:1em;line-height:1;white-space:nowrap;text-align:left;vertical-align:middle;word-break:normal}.fv-upload-and-preview .upload-progress.upload-progress-status-active .upload-progress-bg::before{position:absolute;top:0;right:0;bottom:0;left:0;background:#fff;border-radius:.625rem;opacity:0;animation:upload-progress-active 2.4s ease-in-out infinite;content:""}.fv-upload-and-preview .upload-progress-show-info .upload-progress-outer{padding-right:48px;margin-right:-48px}@keyframes upload-progress-active{0%{width:0;opacity:.1}20%{width:0;opacity:.5}100%{width:100%;opacity:0}}.fv-upload-and-preview .uploadAndpreview--action-container .preview-btn{color:var(--f-theme-03)!important;background:var(--f-aid-02)!important}.fv-upload-and-preview .uploadAndpreview--action-container .preview-btn:not([disabled]):hover{background:var(--f-theme-05)!important}.fv-upload-and-preview .uploadAndpreview--action-container .preview-btn:not([disabled]) .f-icon:hover{color:#fff;width:22px}.fv-upload-and-preview .uploadAndpreview--table .uploadAndpreview--currentfile{background-color:var(--f-aid-02)}.fv-upload-and-preview .uploadAndpreview--table .uploadAndpreview--currentfile .preview-btn{background-color:var(--f-aid-03)}.f-verify-list .list-icon,.f-verify-nums .nums-count,.f-verify-nums .nums-icon{color:var(--f-semantic-danger-01)}.f-verify-list .list-warning{color:var(--f-semantic-warning-01)}.f-verify-detail{position:absolute;left:14px;bottom:16px;z-index:900}.f-verify-detail .f-verify-detail-content{position:relative}.f-verify-detail .f-verify-detail-content .f-verify-form-main{position:absolute;padding-bottom:.5rem;left:0;bottom:1.75rem;width:28.125rem}.f-page-has-query .f-page-header .f-page-header-base,.f-page-has-scheme .f-page-header .f-page-header-base,.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-title{padding:.75rem .875rem}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content{border-radius:4px;width:100%;overflow:hidden}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-arrow{display:block;position:absolute;left:1.125rem;bottom:.25rem;width:.625rem;height:.625rem;background:0 0;border-style:solid;border-width:.3125rem;transform:translateX(-50%) rotate(45deg)}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list{position:relative}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-close{position:absolute;right:.75rem;top:.625rem;font-size:.75rem;cursor:pointer;width:1.25rem;height:1.25rem;line-height:1.25rem;text-align:center}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list{overflow-y:auto}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list .f-verify-list-content{display:none}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list .f-verify-list-content.active{display:block}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list .f-verify-list{cursor:pointer;position:relative;padding:.5rem .875rem .5rem 2.5rem;list-style-type:none}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list .f-verify-list .list-icon{position:absolute;left:.875rem;top:.75rem;font-size:.875rem}.f-page,.f-page-root{bottom:0;right:0;left:0;overflow:hidden;position:absolute}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list .f-verify-list .list-con p{margin-bottom:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list .f-verify-list .list-con .list-title{font-size:.875rem;line-height:1.375rem}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-list .f-verify-forms-list .f-verify-list .list-con .list-msg{font-size:.75rem;color:rgba(0,0,0,.45);line-height:1.25rem}.f-verify-detail .f-verify-nums{padding:.125rem .5rem;cursor:pointer}.f-verify-detail .f-verify-nums .nums-icon{margin-right:.25rem;vertical-align:middle}.f-verify-detail .f-verify-nums .nums-count{font-size:.875rem;line-height:1.25rem}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content{background:var(--f-neutral-20);box-shadow:0 2px 8px 0 rgba(var(--f-neutral-15-rgb),.15)}.f-verify-detail .f-verify-detail-content .f-verify-form-main .f-verify-form-content .f-verify-form-content-arrow{box-shadow:2px 2px 5px rgba(var(--f-neutral-15-rgb),.08);border-color:transparent var(--f-neutral-20) var(--f-neutral-20) transparent}.f-verify-detail .f-verify-forms-title .btn-group{border-radius:14px;padding:3px;background:var(--f-aid-04)}.f-verify-detail .f-verify-forms-title .btn-group .verify-title-btn{color:var(--f-text-02);border:1px solid var(--f-neutral-08);background:var(--f-neutral-12);box-shadow:0 4px 10px 0 rgba(var(--f-neutral-15),.06);margin:0;border-radius:0}.f-verify-detail .f-verify-forms-title .btn-group .verify-title-btn:first-child{border-radius:14px 0 0 14px}.f-verify-detail .f-verify-forms-title .btn-group .verify-title-btn:last-child{border-radius:0 14px 14px 0}.f-verify-detail .f-verify-forms-title .btn-group .verify-title-btn.disabled{color:var(--f-text-07);border-color:var(--f-neutral-05);background:var(--f-neutral-08);box-shadow:none}.f-verify-detail .f-verify-forms-title .btn-group .verify-title-btn+.verify-title-btn{margin-left:-1px}.f-verify-detail .f-verify-forms-title .btn-group .verify-title-btn.f-state-selected{color:var(--f-text-00);border-color:var(--f-theme-03);background:var(--f-theme-04);box-shadow:0 4px 10px 0 rgba(var(--f-theme-03),.2)}.f-verify-detail .f-verify-forms-title .f-verify-close{color:var(--f-text-07)}.f-verify-detail .f-verify-forms-list .f-verify-list-content{padding:0}.f-verify-detail .f-verify-forms-list .f-verify-list-content .f-verify-list{border-top:1px dotted var(--f-neutral-05)!important;padding:.5rem .875rem .5rem 2.5rem}.f-verify-detail .f-verify-forms-list .f-verify-list-content .f-verify-list:last-child{border:none}.f-verify-detail .f-verify-forms-list .f-verify-list-content .f-verify-list .list-icon{color:var(--f-semantic-danger-01)}.f-verify-detail .f-verify-forms-list .f-verify-list-content .f-verify-list .list-icon.list-warning{color:var(--f-semantic-warning-01)}.f-verify-detail .f-verify-forms-list .f-verify-list-content .f-verify-list .list-con .list-title{font-size:.875rem;color:var(--f-text-02);line-height:1.375rem}.f-verify-detail .f-verify-forms-list .f-verify-list-content .f-verify-list .list-con .list-msg{font-size:.75rem;color:rgba(var(--f-text-06),.9);line-height:1.25rem}.f-verify-detail .f-verify-nums{border-radius:6px!important;background:var(--f-semantic-danger-03);box-shadow:0 2px 8px 0 rgba(var(--f-neutral-15-rgb),.15)}@font-face{font-family:FarrisIcons;font-style:normal;font-weight:400;src:url(data:font/ttf;base64,AAEAAAALAIAAAwAwR1NVQiCLJXoAAAE4AAAAVE9TLzI2JE+JAAABjAAAAGBjbWFwTohH7gAAC/AAACWUZ2x5ZqfrFDEAADaIAAH0DGhlYWQnvvaKAAAA4AAAADZoaGVhCNUHTgAAALwAAAAkaG10eApz/50AAAHsAAAKBGxvY2GWVxNEAAAxhAAABQRtYXhwA6wBEAAAARgAAAAgbmFtZchH0mwAAiqUAAACi3Bvc3QSpDltAAItIAAAK3cAAQAAA4D/gABcBVX/9v/3BQAAAQAAAAAAAAAAAAAAAAAAAoEAAQAAAAEAAGP+/t1fDzz1AAsEAAAAAADh1NlIAAAAAOHU2Uj/9v9xBQADjAAAAAgAAgAAAAAAAAABAAACgQEEACEAAAAAAAIAAAAKAAoAAAD/AAAAAAAAAAEAAAAKADAAPgACREZMVAAObGF0bgAaAAQAAAAAAAAAAQAAAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAQEAgGQAAUAAAKJAswAAACPAokCzAAAAesAMgEIAAACAAUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBmRWQAwOAA7LcDgP+AAAAD3ACPAAAAAQAAAAAAAAAAAAAAAAACBAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAD//wQA//8EAP//BAD//wQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAQAABAD/+QQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP/5BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP/2BAD/9gQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//kEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAP//BAD//wQA//8EAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEVQAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAD//wQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABEQAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEkgAABJIAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAASSAAAEAAAABJIAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAD//wQAAAAEAAAABAAAAAQAAAAEAP/9BAAAAAQAAAAEAAAABAD//wQA//8EAP/9BAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAREAAAEAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAP//BAAAAAQAAAAEAAAABAAAAAQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQB//8EAP//BAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQ8AAAENf/+BAAAAAQA//8EAAAABAD//wQAAAAEAP//BAD//wQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQB//4ETgAABAAAAAVVAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAE/wAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAD//wQA//8EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAAAAAFAAAAAwAAACwAAAAEAAAHMAABAAAAAAYqAAMAAQAAACwAAwAKAAAHMAAEBf4AAAA4ACAABAAY4DLhSeIO4wrlKuYr5kPmmua85tfnBegs6SLrGOs/60/rb+t/64nrqeu568nr2evp6/nsqey3//8AAOAA4QDiAOMA5QDmAOYt5kXmvObX5wDoAOkA6wTrGutB61HrceuB65rrsOvA69Dr4evw7KDssP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAOACcAS4BSgFeAbICCAI0At4C3gLeAugDQAOEA6wD9gQSBE4EagR6BJgEqgS8BM4E3gTwBQIAAAGPAGsAZgBhAoACfgJ/An0AZwBlAGIAZAJzAnECcgJwAngAYwBsAnwCegJ7AnkAbQBoAGkAagBeAA8AEQAVABMAEgBYAFMCdgJ3AnUBrwBSAFYAUQBZAF0AXwBgAFoCbwBOAFUCXgAEAE8AWwA5ABQAOgA9AAMBrwA/AFwASwJ0AEYAQgBKADwANwA7ADgAPgAKAAgABwBAACECawJsAEgCagHpAm0AKgHoAm4AIwAkACkAJgAWAA0AJQBBAEUATABJAEQARwAoACcAIAAiADYALgAvADIBsAA1Ak4ATQBDAAkCaQBXADQAFwAMADEALQAsADMAMAArAB0AGgAZAAsAHwAbABwAGAAeAAYABQAQAFAAVAGOAYUBiQGMAmgCZwHnAkkCQAGHAYsCSAJHAY0BiAGGAYoBfAGDAX8BgQGCAYABewGEAX4BfQF1AXMBcQFyAXkBdwF6AXQBeAF2AWoBbQFvAWcBaQFsAW4BcAFoAWsBZgFiAV0BZAFfAWEBYwFeAWUBYAFDAUgBSQFAAUIBRgFHAUUBQQFPAVABTQFLAU4BTAFEAVwBWgFbAVYBVAFXAVgBVQFZAVIBUwFKAVEBAAECAQEA/wD6ASYBPQEsATsBOQEvAPsBKgE0APwBBwEJAREBCgEIAQ0BBgEFAQ4BAwEQATMBIQEgAPUAkAE3ARkBMgD4AI4AigEkAI8AiwEXAP0BOgE+AT8BMQD+ARUBEwESAR8A+QEbARQBGAEaATUBIgDzASMBKwELARwBHgEoAScBJQEtATgBNgEEAQwBFgD3APIBKQD0AS4BMAE8AR0BDwCMAI0AngCXAJ8AkQCTAJ0AqACmAKAApwClAKsAnACWAJIAlACbAJoAlQCYAH4AfACjAKQAqgCtAK4AoQB9AIEAiQCHAIQAiACAAIYAhQB7AKkB5wD2AIIAfwCDAG4AegB5AHgAdwB2AHMAdAB1AHIAcQBvAHAArACiAJkA5gDsAOsA7gDpAOoA7wDnAOMA5ADwAO0A5QDoAPEA2QDbANoA4gDcAN4A3QDfAOAA4QDXANAA0wDRANYA1QDUANIAzwDYAMYAzADIAMkAxQDOAMoAxwDNAMsAwQDAAMMAvADCALsAxAC/AL0AvgCwALkArwC1ALQAtgCyALgAsQC6ALcAswJfAlwCYAJmAmUCZAJjAmICYQJdAlsCWgJZAlMCVgJRAlICVAJVAlcCWAJQAk8CTgJNAkwBsAJLAkoCRQJGAkECQgJDAkQCMQIwAj8CPgI9AjwCOwI4AjkCOgIzAjQCNQI2AjcCMgIvAi4CLQIsAisCKgIpAigCJwImAiUCJAIjAiICIAIhAh8CHgIdAhwCGwIaAhkCGAIXAhYCFQIUAhMCEgIRAhACDwIOAg0CDAILAgoCCQIIAgcCBgIFAgQCAwICAgECAAH/Af4B/QH8AfsB+gH5AfgB9wH2AfUB9AHzAfIB8QHwAe8B7gHtAewBrwHrAeoB5gHlAeQB4wHiAeEB4AHfAd4B3QHcAdsB2gHZAdgB1wHWAdUB1AHTAdIB0QHQ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AAAAhAAA5pUAAOaVAAAAiAAA5pYAAOaWAAAAgAAA5pcAAOaXAAAAhgAA5pgAAOaYAAAAhQAA5pkAAOaZAAAAewAA5poAAOaaAAAAqQAA5rwAAOa8AAAB5wAA5tcAAObXAAAA9gAA5wAAAOcAAAAAggAA5wEAAOcBAAAAfwAA5wIAAOcCAAAAgwAA5wMAAOcDAAAAbgAA5wQAAOcEAAAAegAA5wUAAOcFAAAAeQAA6AAAAOgAAAAAeAAA6AEAAOgBAAAAdwAA6AIAAOgCAAAAdgAA6AMAAOgDAAAAcwAA6AQAAOgEAAAAdAAA6AUAAOgFAAAAdQAA6AYAAOgGAAAAcgAA6AcAAOgHAAAAcQAA6AgAAOgIAAAAbwAA6AkAAOgJAAAAcAAA6AoAAOgKAAAArAAA6AsAAOgLAAAAogAA6AwAAOgMAAAAmQAA6A0AAOgNAAAA5gAA6A4AAOgOAAAA7AAA6A8AAOgPAAAA6wAA6BAAAOgQAAAA7gAA6BEAAOgRAAAA6QAA6BIAAOgSAAAA6gAA6BMAAOgTAAAA7wAA6BQAAOgUAAAA5wAA6BUAAOgVAAAA4wAA6BYAAOgWAAAA5AAA6BcAAOgXAAAA8AAA6BgAAOgYAAAA7QAA6BkAAOgZAAAA5QAA6BoAAOgaAAAA6AAA6BsAAOgbAAAA8QAA6BwAAOgcAAAA2QAA6B0AAOgdAAAA2wAA6B4AAOgeAAAA2gAA6B8AAOgfAAAA4gAA6CAAAOggAAAA3AAA6CEAAOghAAAA3gAA6CIAAOgiAAAA3QAA6CMAAOgjAAAA3wAA6CQAAOgkAAAA4AAA6CUAAOglAAAA4QAA6CYAAOgmAAAA1wAA6CcAAOgnAAAA0AAA6CgAAOgoAAAA0wAA6CkAAOgpAAAA0QAA6CoAAOgqAAAA1gAA6CsAAOgrAAAA1QAA6CwAAOgsAAAA1AAA6QAAAOkAAAAA0gAA6QEAAOkBAAAAzwAA6QIAAOkCAAAA2AAA6QMAAOkDAAAAxgAA6QQAAOkEAAAAzAAA6QUAAOkFAAAAyAAA6QYAAOkGAAAAyQAA6QcAAOkHAAAAxQAA6QgAAOkIAAAAzgAA6QkAAOkJAAAAygAA6QoAAOkKAAAAxwAA6QsAAOkLAAAAzQAA6QwAAOkMAAAAywAA6Q0AAOkNAAAAwQAA6Q4AAOkOAAAAwAAA6Q8AAOkPAAAAwwAA6RAAAOkQAAAAvAAA6REAAOkRAAAAwgAA6RIAAOkSAAAAuwAA6RMAAOkTAAAAxAAA6RQAAOkUAAAAvwAA6RUAAOkVAAAAvQAA6RYAAOkWAAAAvgAA6RcAAOkXAAAAsAAA6RgAAOkYAAAAuQAA6RkAAOkZAAAArwAA6RoAAOkaAAAAtQAA6RsAAOkbAAAAtAAA6RwAAOkcAAAAtgAA6R0AAOkdAAAAsgAA6R4AAOkeAAAAuAAA6R8AAOkfAAAAsQAA6SAAAOkgAAAAugAA6SEAAOkhAAAAtwAA6SIAAOkiAAAAswAA6wQAAOsEAAACXwAA6wUAAOsFAAACXAAA6wYAAOsGAAACYAAA6wcAAOsHAAACZgAA6wgAAOsIAAACZQAA6wkAAOsJAAACZAAA6woAAOsKAAACYwAA6wsAAOsLAAACYgAA6wwAAOsMAAACYQAA6w0AAOsNAAACXQAA6w4AAOsOAAACWwAA6w8AAOsPAAACWgAA6xAAAOsQAAACWQAA6xEAAOsRAAACUwAA6xIAAOsSAAACVgAA6xMAAOsTAAACUQAA6xQAAOsUAAACUgAA6xUAAOsVAAACVAAA6xYAAOsWAAACVQAA6xcAAOsXAAACVwAA6xgAAOsYAAACWAAA6xoAAOsaAAACUAAA6xsAAOsbAAACTwAA6xwAAOscAAACTgAA6x0AAOsdAAACTQAA6x4AAOseAAACTAAA6x8AAOsfAAABsAAA6yAAAOsgAAACSwAA6yEAAOshAAACSgAA6yIAAOsiAAACRQAA6yMAAOsjAAACRgAA6yQAAOskAAACQQAA6yUAAOslAAACQgAA6yYAAOsmAAACQwAA6ycAAOsnAAACRAAA6ygAAOsoAAACMQAA6ykAAOspAAACMAAA6yoAAOsqAAACPwAA6ysAAOsrAAACPgAA6ywAAOssAAACPQAA6y0AAOstAAACPAAA6y4AAOsuAAACOwAA6y8AAOsvAAACOAAA6zAAAOswAAACOQAA6zEAAOsxAAACOgAA6zIAAOsyAAACMwAA6zMAAOszAAACNAAA6zQAAOs0AAACNQAA6zUAAOs1AAACNgAA6zYAAOs2AAACNwAA6zcAAOs3AAACMgAA6zgAAOs4AAACLwAA6zkAAOs5AAACLgAA6zoAAOs6AAACLQAA6zsAAOs7AAACLAAA6zwAAOs8AAACKwAA6z0AAOs9AAACKgAA6z4AAOs+AAACKQAA6z8AAOs/AAACKAAA60EAAOtBAAACJwAA60IAAOtCAAACJgAA60MAAOtDAAACJQAA60QAAOtEAAACJAAA60UAAOtFAAACIwAA60YAAOtGAAACIgAA60cAAOtHAAACIAAA60gAAOtIAAACIQAA60kAAOtJAAACHwAA60oAAOtKAAACHgAA60sAAOtLAAACHQAA60wAAOtMAAACHAAA600AAOtNAAACGwAA604AAOtOAAACGgAA608AAOtPAAACGQAA61EAAOtRAAACGAAA61IAAOtSAAACFwAA61MAAOtTAAACFgAA61QAAOtUAAACFQAA61UAAOtVAAACFAAA61YAAOtWAAACEwAA61cAAOtXAAACEgAA61gAAOtYAAACEQAA61kAAOtZAAACEAAA61oAAOtaAAACDwAA61sAAOtbAAACDgAA61wAAOtcAAACDQAA610AAOtdAAACDAAA614AAOteAAACCwAA618AAOtfAAACCgAA62AAAOtgAAACCQAA62EAAOthAAACCAAA62IAAOtiAAACBwAA62MAAOtjAAACBgAA62QAAOtkAAACBQAA62UAAOtlAAACBAAA62YAAOtmAAACAwAA62cAAOtnAAACAgAA62gAAOtoAAACAQAA62kAAOtpAAACAAAA62oAAOtqAAAB/wAA62sAAOtrAAAB/gAA62wAAOtsAAAB/QAA620AAOttAAAB/AAA624AAOtuAAAB+wAA628AAOtvAAAB+gAA63EAAOtxAAAB+QAA63IAAOtyAAAB+AAA63MAAOtzAAAB9wAA63QAAOt0AAAB9gAA63UAAOt1AAAB9QAA63YAAOt2AAAB9AAA63cAAOt3AAAB8wAA63gAAOt4AAAB8gAA63kAAOt5AAAB8QAA63oAAOt6AAAB8AAA63sAAOt7AAAB7wAA63wAAOt8AAAB7gAA630AAOt9AAAB7QAA634AAOt+AAAB7AAA638AAOt/AAABrwAA64EAAOuBAAAB6wAA64IAAOuCAAAB6gAA64MAAOuDAAAB5gAA64QAAOuEAAAB5QAA64UAAOuFAAAB5AAA64YAAOuGAAAB4wAA64cAAOuHAAAB4gAA64gAAOuIAAAB4QAA64kAAOuJAAAB4AAA65oAAOuaAAAB3wAA65sAAOubAAAB3gAA65wAAOucAAAB3QAA650AAOudAAAB3AAA654AAOueAAAB2wAA658AAOufAAAB2gAA66AAAOugAAAB2QAA66EAAOuhAAAB2AAA66IAAOuiAAAB1wAA66MAAOujAAAB1gAA66QAAOukAAAB1QAA66UAAOulAAAB1AAA66YAAOumAAAB0wAA66cAAOunAAAB0gAA66gAAOuoAAAB0QAA66kAAOupAAAB0AAA67AAAOuwAAABzwAA67EAAOuxAAABzgAA67IAAOuyAAABzQAA67MAAOuzAAABzAAA67QAAOu0AAABywAA67UAAOu1AAABygAA67YAAOu2AAAByQAA67cAAOu3AAAByAAA67gAAOu4AAABxwAA67kAAOu5AAABxgAA68AAAOvAAAABxQAA68EAAOvBAAABxAAA68IAAOvCAAABwwAA68MAAOvDAAABwgAA68QAAOvEAAABwQAA68UAAOvFAAABwAAA68YAAOvGAAABvwAA68cAAOvHAAABvgAA68gAAOvIAAABvQAA68kAAOvJAAABvAAA69AAAOvQAAABuwAA69EAAOvRAAABugAA69IAAOvSAAABuQAA69MAAOvTAAABuAAA69QAAOvUAAABtwAA69UAAOvVAAABtgAA69YAAOvWAAABtQAA69cAAOvXAAABtAAA69gAAOvYAAABswAA69kAAOvZAAABsgAA6+EAAOvhAAABsQAA6+IAAOviAAABsAAA6+MAAOvjAAABrwAA6+QAAOvkAAABrgAA6+UAAOvlAAABrQAA6+YAAOvmAAABrAAA6+cAAOvnAAABqwAA6+gAAOvoAAABqgAA6+kAAOvpAAABqQAA6/AAAOvwAAABqAAA6/EAAOvxAAABpwAA6/IAAOvyAAABpgAA6/MAAOvzAAABpQAA6/QAAOv0AAABpAAA6/UAAOv1AAABowAA6/YAAOv2AAABogAA6/cAAOv3AAABoQAA6/gAAOv4AAABoAAA6/kAAOv5AAABnwAA7KAAAOygAAABngAA7KEAAOyhAAABnQAA7KIAAOyiAAABnAAA7KMAAOyjAAABmwAA7KQAAOykAAABlgAA7KUAAOylAAABlQAA7KYAAOymAAABlAAA7KcAAOynAAABkwAA7KgAAOyoAAABkgAA7KkAAOypAAABkQAA7LAAAOywAAABkAAA7LEAAOyx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Ad8B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AgACAQICAgMCBAIFAgYCBwIIAgkCCgILAgwCDQIOAg8CEAIRAhICEwIUAhUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIgIjAiQCJQImAicCKAIpAioCKwIsAi0CLgIvAjACMQIyAjMCNAI1AjYCNwI4AjkCOgI7AjwCPQI+Aj8CQAJBAkICQwJEAkUCRgJHAkgCSQJKAksCTAJNAk4CTwJQAlECUgJTAlQCVQJWAlcCWAJZAloCWwJcAl0CXgJfAmACYQJiAmMCZAJlAmYCZwJoAmkCagJrAmwCbQJuAm8CcAJxAnICcwJ0AnUCdgJ3AngCeQJ6AnsCfAJ9An4CfwKAAoECggKDAoQChQKGAocCiAKJAooCiwKMAo0CjgKPApACkQKSApMClAKVApYClwKYApkCmgKbApwCnQKeAp8CoAKhAqICowKkAqUCpgKnAqgCqQKqAqsCrAKtAq4CrwKwArECsgKzArQCtQK2ArcCuAK5AroCuwK8Ar0CvgK/AsACwQLCAsMCxALFAsYCxwLIAskCygLLAswCzQLOAs8C0ALRAtIC0wLUAtUC1gLXAtgC2QLaAtsC3ALdAt4C3wLgAuEC4gLjAuQC5QLmAucC6ALpAuoC6wLsAu0C7gLvAvAC8QLyAvMC9AL1AvYC9wL4AvkC+gL7AvwC/QL+Av8DAAMBAwIDAwMEAwUDBgMHAwgDCQMKAwsDDAMNAw4DDwMQAxEDEgMTAxQDFQMWAxcDGAMZAxoDGwMcAx0DHgMfAyADIQMiAyMDJAMlAyYDJwMoAykDKgMrAywDLQMuAy8DMAMxAzIDMwM0AzUDNgM3AzgDOQM6AzsDPAM9Az4DPwNAA0EDQgNDA0QDRQNGA0cDSANJA0oDSwNMA00DTgNPA1ADUQNSA1MDVANVA1YDVwNYA1kDWgNbA1wDXQNeA18DYANhA2IDYwNkA2UDZgNnA2gDaQNqA2sDbANtA24DbwNwA3EDcgNzA3QDdQN2A3cDeAN5A3oDewN8A30DfgN/A4ADgQOCAAphLWNodWxpcmVuCmNsb2NrLWVjYjUKY2xvY2stZTEwNwllMTAwLXVuZG8OZTIwOS1zdWJ0aXRsZXMHZTIwOC1oZBJlMTE3LWNhbmNlbC1jaXJjbGUTZTExNi1jYW5jZWwtb3V0bGluZQxlMTNkLXByZXZpZXcLZTExNS1jYW5jZWwEc3RvcApjYWxjdWxhdG9yDHNvcnQtZGVzYy1zbQ5lbmNsb3N1cmVfZWRpdBJlMDFjLWFycm93LXBhcmVudDENZTIwYS1wbGF5bGlzdBBlMDFkLWFycm93LXJvb3QxEWUwMjAtYXJyb3dzLXN3YXAxF2UwMWYtYXJyb3dzLWRpbWVuc2lvbnMxE2UxMDQtbm9uLXJlY3VycmVuY2UVZTAxZS1hcnJvd3MtcmVzaXppbmcxEGUxMjctc29ydC1hc2Mtc20IZTE0MS1wYW4OZTIwNi12b2x1bWUtdXAKZTIwMS1wYXVzZQllMjAwLXBsYXkMZTIwNC1mb3J3YXJkEGUyMDUtdm9sdW1lLWRvd24UZTE0OS1rcGktc3RhdHVzLW9wZW4PZTIwNy12b2x1bWUtb2ZmC2UyMDMtcmV3aW5kDWUxMzItZG93bmxvYWQSZTExOS1jaGVjay1vdXRsaW5lC2UxMzMtdXBsb2FkEmUxMjMtbWludXMtY2lyY2xlMQ1lMTI0LXNvcnQtYXNjC2UxMjktZmlsdGVyC2UxMjYtdW5zb3J0C2UxMzEtbG9nb3V0CmUxMzAtbG9naW4OZTEyNS1zb3J0LWRlc2MQZTEyMC1wbHVzLWNpcmNsZRRlMTQ4LWtwaS1zdGF0dXMtaG9sZAxlMTQ1LXBsdXMtc20OZTE0NC1jb25uZWN0b3IWZTEzNS1oeXBlcmxpbmstb3Blbi1zbQtlMTM2LWxhdW5jaBRlMTQ3LWtwaS1zdGF0dXMtZGVueQllMTQzLWNhcnQLZTEzNy13aW5kb3cNZTE0Ni1taW51cy1zbQ1lMTQwLXpvb20tb3V0FGUxMzktd2luZG93LW1pbmltaXplE2UxMzQtaHlwZXJsaW5rLW9wZW4SZTExMS1saW5rLXZlcnRpY2FsCWUxMTMtbG9jawtlMTAzLXJlbG9hZA1lMTA1LXJlc2V0LXNtFGUxMTItdW5saW5rLXZlcnRpY2FsFmUxMTAtdW5saW5rLWhvcml6b250YWwOZTEwNi1yZWxvYWQtc20LZTExNC11bmxvY2sLZTEwOS1mbG9wcHkKZTExOC1jaGVjaxFlMTJhLWZpbHRlci1jbGVhchJlMTBlLWF0dGFjaG1lbnQtNDULZTEzYy13cmVuY2gaZTEyZS1maWx0ZXItYWRkLWV4cHJlc3Npb24OZTEyYi1maWx0ZXItc20PZTEwZC1hdHRhY2htZW50FWUxMmYtZmlsdGVyLWFkZC1ncm91cBJlMTFjLWNsb3NlLW91dGxpbmUYZTEyZC1maWx0ZXItc29ydC1kZXNjLXNtFGUxMGYtbGluay1ob3Jpem9udGFsCGUxMGItZGl0F2UxMmMtZmlsdGVyLXNvcnQtYXNjLXNtCmUxM2ItZ2VhcnMJZTAzMC1tZW51CWUxMDEtcmVkbwplMjBiLWF1ZGlvEmUwMjktbGF5b3V0LTEtYnktNBFlMDI3LWhhbmRsZXItZHJhZw9lMDIyLWNhdGVnb3JpemUMZTIwYy1wbGF5LXNtEmUwMzEtbW9yZS12ZXJ0aWNhbAtlMDI4LWxheW91dAxlMTNmLXpvb20taW4SZTAyMS1kcmFnLWFuZC1kcm9wEmUwMmEtbGF5b3V0LTItYnktMgllMDJlLXJvd3MKZTEwMi1yZXNldAplMTBhLXByaW50GGUwMmItbGF5b3V0LXNpZGUtYnktc2lkZRBlMDFiLWFycm93LWRyaWxsE2UwMmMtbGF5b3V0LXN0YWNrZWQMZTAyZC1jb2x1bW5zFWUwMDMtYXJyb3ctNDUtdXAtbGVmdBNlMDBhLWFycm93LWVuZC1kb3duFWUwMTEtYXJyb3dzLW5vLWNoYW5nZQtlMDBiLXNlZWstdxRlMDA5LWFycm93LWVuZC1yaWdodBdlMDAyLWFycm93LTQ1LWRvd24tbGVmdBFlMDA4LWFycm93LWVuZC11cBBlMDE4LWFycm93LXJpZ2h0D2UwMTktYXJyb3ctZG93bg9lMDFhLWFycm93LWxlZnQYZTAwMS1hcnJvdy00NS1kb3duLXJpZ2h0GGUwMTItYXJyb3ctb3ZlcmZsb3ctZG93bg1lMDE3LWFycm93LXVwFmU3MDMtbWFya2VyLXBpbi10YXJnZXQNZTgwOC1kaWdnLWJveAplODA5LWVtYWlsCWU4MDctZGlnZxJlODA2LWRlbGljaW91cy1ib3gMZTgwMy1ibG9nZ2VyEGU4MDQtYmxvZ2dlci1ib3gOZTgwNS1kZWxpY2lvdXMKZTgwMi1pbmJveAllODAxLXVzZXIKZTgwMC1zaGFyZQplNzA1LXVucGluCGU3MDQtcGluDmU2OTktZm9udC1zaXplEGU2ODktcGFuZS1mcmVlemUcZTY5MC10b2dnbGUtZnVsbC1zY3JlZW4tbW9kZRJlNjg4LXRhYmxlLXVubWVyZ2UKZTcwMS1nbG9iZRJlNjk2LWN1c3RvbS1mb3JtYXQPZTY5MS1mb3JtdWxhLWZ4EmU3MDAtZ2xvYmUtb3V0bGluZQ9lNzAyLW1hcmtlci1waW4LZTY5NC1kb2xsYXIVZTY5OC1kZWNpbWFsLWRlY3JlYXNlFWU2OTctZGVjaW1hbC1pbmNyZWFzZQtlNjkzLXN5bWJvbAxlNjk1LXBlcmNlbnQIZTY5Mi1zdW0TZTY0My10ZXh0Ym94LWhpZGRlbhVlNjQ3LXRlbXBsYXRlLW1hbmFnZXIUZTY3Mi1oeXBlcmxpbmstZ2xvYmUbZTY3My1oeXBlcmxpbmstZ2xvYmUtcmVtb3ZlDGU2NDItdGV4dGJveA9lNjQ2LWVkaXQtdG9vbHMLZTYzZC1idXR0b24KZTY3Ny10YWJsZRFlNjgyLXRhYmxlLWRlbGV0ZRVlNjc4LXRhYmxlLXByb3BlcnRpZXMQZTY4My1jZWxscy1tZXJnZRxlNjg2LWNlbGwtc3BsaXQtaG9yaXpvbnRhbGx5FmU2ODEtdGFibGUtY2VsbC1kZWxldGULZTY3NS1hbmNob3IbZTY4Ny1jY2VsbC1zcGxpdC12ZXJ0aWNhbGx5EWU4MGMtZmFjZWJvb2stYm94G2U2ODUtY2VsbHMtbWVyZ2UtdmVydGljYWxseR1lNjg0LWNlbGxzLW1lcmdlLWhvcml6b250YWxseRVlNjgwLXRhYmxlLXJvdy1kZWxldGUPZTY3OS10YWJsZS1jZWxsFGU2NzQtaHlwZXJsaW5rLWVtYWlsF2U2NzYtdGFibGUtbGlnaHQtZGlhbG9nHmU2N2MtdGFibGUtY29sdW1uLWluc2VydC1yaWdodBRlNjhmLXZhbGlkYXRpb24tZGF0YQ1lODBiLWZjYWVib29rD2U2OGEtcm93LWZyZWV6ZRJlNjhiLWNvbHVtbi1mcmVlemUbZTY3ZS10YWJsZS1yb3ctaW5zZXJ0LWJlbG93HWU2N2ItdGFibGUtY29sdW1uLWluc2VydC1sZWZ0G2U2N2QtdGFibGUtcm93LWluc2VydC1hYm92ZRplNjdhLXRhYmxlLWNlbGwtcHJvcGVydGllcxxlNjlhLWltYWdlLWFic29sdXRlLXBvc2l0aW9uEmU2OGMtdG9vbGJhci1mbG9hdBhlNjdmLXRhYmxlLWNvbHVtbi1kZWxldGUOZTgwYS1lbWFpbC1ib3gSZTY4ZC1zcGVsbC1jaGVja2VyFWU2OGUtdmFsaWRhdGlvbi14aHRtbAhlOTE5LWNzcwplOTE3LWh0bWw1B2U5MWYtdmILZTkxZC12YnByb2oUZTkyMi1maWxlLWhvcml6b250YWwIZTkxYi1leGUHZTkxYS1qcwtlOTFjLWNzcHJvagplOTIxLWNsb3VkB2U5MWUtY3MJZTkxOC1odG1sCGU5MjAtc2xuDmU5MTItZmlsZS1hc2N4D2U5MTAtZmlsZS1mbGFzaAllOTE1LWZpbG0JZTkxNi1jc3MzDWU5MTQtZmlsZS16aXANZTkwZS1maWxlLXBkZg1lOTBkLWZpbGUtcHB0EGU5MTEtZmlsZS1jb25maWcNZTkwZi1maWxlLXBzZA1lOTEzLWZpbGUtYmFjDWU5MDctZmlsZS1hZGQOZTkwMy1mb2xkZXItdXAPZTkwYS1maWxlLWV4Y2VsFWU5MDUtYWdncmVnYXRlLWZpZWxkcwllOTA2LWZpbGUIZTkwOS1jc3YIZTkwYy1tZGIQZTkwNC1mb2xkZXItbW9yZQ5lOTBiLWZpbGUtd29yZA1lOTA4LWZpbGUtdHh0EGU5MDEtZm9sZGVyLW9wZW4IZTgyNy1yc3MKZTgyOS12aW1lbwtlOTAwLWZvbGRlcgxlODI4LXJzcy1ib3gQZTgyYy15b3V0dWJlLWJveAxlODJiLXlvdXR1YmUOZTgyYS12aW1lby1ib3gRZTgyNi1kcmliYmJsZS1ib3gPZTkwMi1mb2xkZXItYWRkFmU4MWMtdGVsbC1hLWZyaWVuZC1ib3gPZTgxZS10dW1ibHItYm94C2U4MWQtdHVtYmxyEGU4MjAtdHdpdHRlci1ib3gPZTgyMi15YW1tZXItYm94C2U4MjEteWFtbWVyDGU4MjMtYmVoYW5jZRBlODI0LWJlaGFuY2UtYm94DWU4MjUtZHJpYmJibGUMZTgxZi10d2l0dGVyDmU4MTUtcGludGVyZXN0EmU4MTYtcGludGVyZXN0LWJveBFlODE5LXN0dW1ibGUtdXBvbgtlODBkLWdvb2dsZRBlODE0LW15c3BhY2UtYm94FWU4MWEtc3R1bWJsZS11cG9uLWJveA1lODExLWxpbmtlZGluEWU4MTItbGlua2VkaW4tYm94EGU4MGYtZ29vZ2xlLXBsdXMPZTgwZS1nb29nbGUtYm94D2U4MTgtcmVkZGl0LWJveBRlODEwLWdvb2dsZS1wbHVzLWJveAxlODEzLW15c3BhY2ULZTgxNy1yZWRkaXQSZTgxYi10ZWxsLWEtZnJpZW5kEHN0cmlwLWNzcy1mb3JtYXQOdmlkZW8tZXh0ZXJuYWwTc3RyaXAtc3Bhbi1lbGVtZW50cwpzZWxlY3QtYWxsGHRhYmxlLWFsaWduLWJvdHRvbS1yaWdodBNzdHJpcC1hbGwtZm9ybWF0aW5nCHRleHRhcmVhCmltYWdlLWVkaXQJdGV4dC13cmFwGHRhYmxlLWFsaWduLW1pZGRsZS1yaWdodBJ0YWJsZS1hbGlnbi1yZW1vdmUNdHJhY2stY2hhbmdlcxh0cmFjay1jaGFuZ2VzLXJlamVjdC1hbGwMYWxpZ24tcmVtb3ZlDGFsaWduLWNlbnRlcg1hbGlnbi1qdXN0aWZ5C2FsaWduLXJpZ2h0CWJvcmRlci1ubwxhcHBseS1mb3JtYXQLYm9yZGVyLWxlZnQNYm9yZGVyLWJvdHRvbQtib3JkZXJzLWFsbBdib3JkZXJzLWluc2lkZS12ZXJ0aWNhbA9ib3JkZXJzLW91dHNpZGUZYm9yZGVycy1pbnNpZGUtaG9yaXpvbnRhbARjb3B5CWNsZWFyLWNzcwpib3JkZXItdG9wDGJvcmRlci1yaWdodBtlNjcxLWh5cGVybGluay1saWdodC1kaWFsb2cRYm9yZGVycy1zaG93LWhpZGUOYm9yZGVycy1pbnNpZGUOZGljdGlvbmFyeS1hZGQLY3VzdG9tLWljb24HY29tbWVudBBkb2N1bWVudC1tYW5hZ2VyC2NvcHktZm9ybWF0D2NoYW5nZS1tYW51YWxseQ5jb21tZW50LXJlbW92ZQ1jYWxlbmRhci1kYXRlE2NvbW1lbnRzLXJlbW92ZS1hbGwQaW1hZ2UtbWFwLWVkaXRvcgNjdXQObW9kdWxlLW1hbmFnZXIFcGFzdGUSaW1hZ2UtbGlnaHQtZGlhbG9nDGNvZGUtc25pcHBldAxmb3JtLWVsZW1lbnQNbWVkaWEtbWFuYWdlcg1mbGFzaC1tYW5hZ2VyDXBhcmFncmFwaC1hZGQacGFzdGUtZnJvbS13b3JkLXN0cmlwLWZpbGUPcnVsZS1ob3Jpem9udGFsD3Bhc3RlLWZyb20td29yZA1wYXN0ZS1hcy1odG1sE3N0cmlwLWZvbnQtZWxlbWVudHMXdGFibGUtYWxpZ24tYm90dG9tLWxlZnQQZmluZC1hbmQtcmVwbGFjZRZ0YWJsZS1hbGlnbi10b3AtY2VudGVyCnBhc3RlLWh0bWwVc3RyaXAtd29yZC1mb3JtYXR0aW5nGXRhYmxlLWFsaWduLW1pZGRsZS1jZW50ZXIRZm9ybWF0LWNvZGUtYmxvY2sUdHJhY2stY2hhbmdlcy1yZWplY3QJZ3JvdXAtYm94BGZvcm0ZdGFibGUtYWxpZ24tYm90dG9tLWNlbnRlcgtzaWx2ZXJsaWdodBBwYXN0ZS1wbGFpbi10ZXh0CnNlbGVjdC1ib3gOcGFzdGUtbWFya2Rvd24XdGFibGUtYWxpZ24tbWlkZGxlLWxlZnQUdHJhY2stY2hhbmdlcy1lbmFibGUVdGFibGUtYWxpZ24tdG9wLXJpZ2h0DXN0eWxlLWJ1aWxkZXIUdGFibGUtYWxpZ24tdG9wLWxlZnQUdHJhY2stY2hhbmdlcy1hY2NlcHQYdHJhY2stY2hhbmdlcy1hY2NlcHQtYWxsEWEtZTYwNGZvbnQtZmFtaWx5EGEtZTYwOXN1Yi1zY3JpcHQWYS1lNjA1Zm9yZWdyb3VuZC1jb2xvcgphLWU2MDFib2xkCGEtZTYxMGg0E2EtZTYwOHN0cmlrZXRocm91Z2gXYS1lNjA2Y29udmVydC1sb3dlcmNhc2UXYS1lNjA3Y29udmVydC11cHBlcmNhc2UMYS1lNjAyaXRhbGljD2EtZTYwM3VuZGVybGluZRJhLWU2MWNhbGlnbi1ib3R0b20IYS1lNjBkaDEIYS1lNjBmaDMJYS1lNjBjYWxsCGEtZTYwZWgyEGEtZTYwYXN1cC1zY3JpcHQJYS1lNjBiZGl2EGEtZTYxZGFsaWduLWxlZnQPYS1lNjFhYWxpZ24tdG9wEmEtZTYxYmFsaWduLW1pZGRsZRVhLWU2MTVpbmRlbnQtaW5jcmVhc2UTYS1lNjE4aW5zZXJ0LW1pZGRsZRRhLWU2MTRsaXN0LXVub3JkZXJlZBVhLWU2MTZpbmRlbnQtZGVjcmVhc2UPYS1lNjE3aW5zZXJ0LXVwEWEtZTYxOWluc2VydC1kb3duCGEtZTYxMmg2EmEtZTYxM2xpc3Qtb3JkZXJlZAhhLWU2MTFoNRNhLWU1MjR0aHVtYm5haWxzLXVwFmEtZTUyOWZ1bGwtc2NyZWVuLWV4aXQVYS1lNTI2dGh1bWJuYWlscy1kb3duFWEtZTYwMHBhZ2UtcHJvcGVydGllcxVhLWU1Mjd0aHVtYm5haWxzLWxlZnQaYS1lNTIzYWxpZ24tYm90dG9tLWVsZW1lbnQRYS1lNTI4ZnVsbC1zY3JlZW4WYS1lNTI1dGh1bWJuYWlscy1yaWdodBFhLWU1MmFyZXNldC1jb2xvchphLWU1MjJhbGlnbi1taWRkbGUtZWxlbWVudBJhLWU1MWJiYWNrLWVsZW1lbnQZYS1lNTIwYWxpZ24tcmlnaHQtZWxlbWVudBVhLWU1MWNmb3J3YXJkLWVsZW1lbnQLYS1lNTE4c2hhcGUXYS1lNTIxYWxpZ24tdG9wLWVsZW1lbnQWYS1lNTFkYmFja3dhcmQtZWxlbWVudBNhLWU1MTlyb3VuZC1jb3JuZXJzGGEtZTUxZWFsaWduLWxlZnQtZWxlbWVudBNhLWU1MWFmcm9udC1lbGVtZW50GmEtZTUxZmFsaWduLWNlbnRlci1lbGVtZW50CmEtZTUxMGxpbmUZYS1lNTExYnJpZ2h0bmVzcy1jb250cmFzdAthLWU1MGZwYWludA9hLWU1MTVncmV5c2NhbGUNYS1lNTBlcGFsZXR0ZQ1hLWU1MTdzaGFycGVuE2EtZTUxM2ludmVydC1jb2xvcnMKYS1lNTE2Ymx1chBhLWU1MTJzYXR1cmF0aW9uEmEtZTUxNHRyYW5zcGVyYW5jeQxhLWU1MGFyb3RhdGUTYS1lNTA0em9vbS1iZXN0LWZpdAthLWU1MGRicnVzaBFhLWU1MGNyb3RhdGUtbGVmdAphLWU1MDZjcm9wE2EtZTUwOWZsaXAtdmVydGljYWwMYS1lNTA3bWlycm9yFWEtZTUwOGZsaXAtaG9yaXpvbnRhbBJhLWU1MDVpbWFnZS1yZXNpemUSYS1lNTBicm90YXRlLXJpZ2h0DWEtZTIwZXN0b3Atc20SYS1lNTAyaW1hZ2UtZXhwb3J0FGEtZTMwN3RyaS1zdGF0ZS1udWxsC2EtZTUwMWltYWdlE2EtZTMwMGhlYXJ0LW91dGxpbmUWYS1lNTAzem9vbS1hY3R1YWwtc2l6ZQxhLWUzMDhjaXJjbGULYS1lMzAxaGVhcnQSYS1lNTAwcGhvdG8tY2FtZXJhDmEtZTIwZHBhdXNlLXNtC2NvbGxhcHNlLW5lCXRodW1idGFjawtzLXRodW1idGFjawZtb3ZldG8NZmlsdGVyX2RlbGV0ZQ9maWx0ZXJfZ3JvdXBpbmcKZmlsdGVyX2FkZBNmaWx0ZXJfY2FuY2VsbGF0aW9uBnZlcm5hdgpjdy1hcnJvd2RlCGN3LWhvdGVsB2N3LXRyaXAFemhhZ2UHZGVuZ2hhbw10aXNoaXNodW9taW5nBERyYWcGYmlhbmppBmNoYWthbgJiZwRsaGp0CGR1bGltaW1hEXFpYW5taW5ncWlhbnpoYW5nBmZhbmt1aRRhLUNGX0Rlc2NlbmRpbmdPcmRlchNhLUNGX0FzY2VuZGluZ09yZGVyBWFib3V0CXl1bnhpYW94aRBlbmNsb3N1cmVfZGVsZXRlEmVuY2xvc3VyZV9kb3dubG9hZBBlbmNsb3N1cmVfdXBsb2FkEGVuY2xvc3VyZV9icm93c2UKdXBsb2FkX2JpZw9jYWxlbmRhcnNfbGluZTEJbW9yZV9saW5lDmRyb3AtZG93bl9saW5lEHBlcnNwZWN0aXZlX3ZpZXcKY2hhcnRfdmlldwlmb3JtX3ZpZXcJbGlzdF92aWV3CWNhcmRfdmlldwtyZW1vdmVfZmFjZQtkdWl6aGFuZ2Rhbg1kaXpoaXNoZW5xaW5nDWppbmd4aWFvcmVud3UHYmFpZmFuZwprZWh1Z3VhbnhpCGZheXVuZGFuCWxpYW54aXJlbg1mdWt1YW50b25nemhpD2thaXBpYW9zaGVucWluZw94aWFvc2hvdWRhY2hlbmcOeGlhb3Nob3VxaWFubGkOeGlhb3Nob3VtdWJpYW8Nc2h1anVzaGFuZ2Jhbwx4dWtlc2hhbmdwaW4Jemhlbmd6aGFvDHhpYW9zaG91eXVjZQ94aWFvc2hvdXR1YW5kdWkFaGVscDELaW5mby1jaXJjbGUKZGVwYXJ0bWVudARjb2RlBHBhdGgPZmxvd2xpbmUtbWFudWFsDWZsb3dsaW5lLW1vcmUSZmxvd2xpbmUtc2NoZWR1bGVkEWZsb3dsaW5lLWNhbmNlbGVkEGZsb3dsaW5lLXBlbmRpbmcMZmxvd2xpbmUtcnVuEGZsb3dsaW5lLWNyZWF0ZWQQZmxvd2xpbmUtcnVubmluZxBmbG93bGluZS13YWl0aW5nEGZsb3dsaW5lLXNraXBwZWQNZmxvd2xpbmUtdmlldxBmbG93bGluZS13YXJuaW5nC29yaWVudGF0aW9uBGxhc3QFZmlyc3QOeXVuaGFuZ3NoaWljb24aQ29sdW1uLWZpbHRlcmFuZGRlc2NlbmRpbmcZQ29sdW1uLWZpbHRlcmFuZGFzY2VuZGluZxxDb2x1bW5zLURlZmF1bHRmaWx0ZXJhbmRzb3J0DUNvbHVtbi1maWx0ZXISQ29sdW1ucy1kZXNjZW5kaW5nEUNvbHVtbnMtYXNjZW5kaW5nE0NvbHVtbnMtRGVmYXVsdHNvcnQPbGF1bmNocGFkLWZhY2UyCmxhdW5jaHBhZDIPZi1pY29uLWNoZWNrYm94DGYtaWNvbi1taW51cwpmLWljb24tYWRkCGRyb3Bkb3duCm5hdmlnYXRpb24Ray1pLW1lc3NhZ2VfZXJyb3ITay1pLW1lc3NhZ2Vfc3VjY2VzcwpzdWRva3UtbmV3CGxpc3QtbmV3CXRpbGVkLW5ldwxxaWVodWFuenV6aGkHcmFkaW8tMgZ0ZW5hbnQGc3Vkb2t1BXRpbGVkBWxpc3QxC3Nob3VjYW5namlhCmNvbGxlY3Rpb24DaWRlDG9jY2x1ZGUtZmFjZQdvY2NsdWRlDmxhdW5jaHBhZC1mYWNlCWxhdW5jaHBhZAtpbmZvcm1hdGlvbgdiYWNrbG9nB21lc3NhZ2UJbWF4aW1pemUxBnNlYXJjaAppbmRleC1mYWNlBWluZGV4CHl4c190ZXh0DXl4c19jb250YWluZXILeXhzX2NvbHVtbnMIeXhzX21vdmUIeXhzX2NvcHkKeXhzX2RlbGV0ZQl5eHNfbGV2ZWwJeXhzX2VhcnRoDXl4c19jdXN0b21pemUIc2lnbl9vdXQLdXNlcl9jZW50ZXIGcmVtb3ZlBnBhY2t1cAZjYW1lcmEGbmFycm93DWFtcGxpZmljYXRpb24JY2xvY2t3aXNlEGNvdW50ZXJjbG9ja3dpc2UGZWRpdG9yBHNraW4EYXJlYQhwYXNzd29yZAhsYW5ndWFnZQViYXNpYwhtaW5pbWl6ZQxtYXhpbWl6YXRpb24NbmV3LWRpbWVuc2lvbhFmaWxlLWZvbGRlci1jbG9zZRBmaWxlLWZvbGRlci1vcGVuCG5ldy1lZGl0CG5ldy1mb3JtBXdvbWFuA21hbgZyZWNvcmQEbW9yZQRsaXN0CXRlbGVwaG9uZQhmdW5jdGlvbgtwcm9kdWN0bGlzdA5hdHRhY2htZW50bGlzdBNkb2N1bWVudGluZm9ybWF0aW9uDG5ldy1maWx0cmF0ZQ5uZXctZnVsbHNjcmVlbgdyb29maW5nDUJvdHRvbXNldHRpbmcPcGFnZS10aXRsZS10YXNrEXBhZ2UtdGl0bGUtcmV2aWV3EHBhZ2UtdGl0bGUtc3RhcnQPcGFnZS10aXRsZS10eXBlEXBhZ2UtdGl0bGUtcmVjb3JkEnBhZ2UtdGl0bGUtdm91Y2hlchBwYWdlLXRpdGxlLXF1ZXJ5EXBhZ2UtdGl0bGUtbnVtYmVyEXBhZ2UtdGl0bGUtbWFuYWdlFnBhZ2UtdGl0bGUtbWFpbnRlbmFuY2UVcGFnZS10aXRsZS1kaWN0aW9uYXJ5GHBhZ2UtdGl0bGUtY29uZmlndXJhdGlvbhVwYWdlLXRpdGxlLWFkbWluaXN0ZXIRcGFnZS10aXRsZS1kZWZpbmUXdHJpLXN0YXRlLWluZGV0ZXJtaW5hdGUQcGFuZWwtcmV0cmFjdGlvbgtlZGl0LWJ1dHRvbg5pbnB1dC1sYW5ndWFnZRdhdHRyaWJ1dGUtY29uZmlndXJhdGlvbgtFbmdpbmVlcmluZwNnaXQTcmFkaW9idXR0b24tY2hlY2tlZAxzaGFwZS1jaXJjbGUQY2hlY2tib3gtY2hlY2tlZBVrLWktaG9tZS13ZWF0aGVyLWxlYWYNay1pLWhvbWUtbW9yZQ1rLWktaG9tZS1yaW5nDGstaS1ob21lLWFkZA5rLWktaG9tZS1zZXR1cA5rLWktaG9tZS13b21hbgxrLWktaG9tZS1tYW4Oay1pLXRvcF9hZ2VuY3kMay1pLXRvcF9uZXdzDGstaS10b3BfaG9tZRJrLWktdG9wX2ltX2RlZmF1bHQXay1pLXRvcF9kZXZlbG9wbWVudHRvb2wMay1pLXRvcF9tZW51DmstaS10b3Bfc2VhcmNoCmstaS10b3BfbXkPay1pLWZsYWdfdXJnZW50DGstaS1uZXh0cGFnZRBrLWktcHJldmlvdXNwYWdlE2staS1tZXNzYWdlX3JvdXRpbmUTay1pLUV4aGFsZS1EaXNjb3VudBNrLWktbW9yZS1ob3Jpem9udGFsEGstaS1tZXNzYWdlX2hlbHATay1pLW1lc3NhZ2Vfd2FybmluZxZrLWktc3RlcHMtZGVsaXZlcmdvb2RzFWstaS1zdGVwcy1yZWNlaXZhYmxlcxFrLWktc3RlcHMtaW52b2ljZRRrLWktc3RlcHMtb3V0b2ZzdG9jaxRrLWktc3RlcHMtc2V0dGxlbWVudBNrLWktc3RlcHMtdHJhbnNwb3J0DGstaS1ib29rbWFyaxBrLWktc3Rhci1vdXRsaW5lCGstaS16b29tEGstaS1jbG9zZS1jaXJjbGUQay1pLWNoZWNrLWNpcmNsZQlrLWktY2xvc2UQay1pLXBsdXMtb3V0bGluZRFrLWktbWludXMtb3V0bGluZQtrLWktcmVvcmRlcg1rLWktcmV3aW5kLXNtDmstaS1mb3J3YXJkLXNtE2staS1hcnJvdy1zZWVrLWRvd24Ray1pLWFycm93LXNlZWstdXAKay1pLWRlbGV0ZQlrLWktZ3JvdXAIay1pLWdyaWQPay1pLWdyaWQtbGF5b3V0DmstaS1hcnJvd3Mta3BpFmstaS1hcnJvdy1jaGV2cm9uLWxlZnQXay1pLWFycm93LWNoZXZyb24tcmlnaHQWay1pLWFycm93LWNoZXZyb24tZG93bhRrLWktYXJyb3ctY2hldnJvbi11cBFrLWktYXJyb3ctNjAtbGVmdAtrLWktYXJyb3ctZRFrLWktYXJyb3ctNjAtZG93bg9rLWktYXJyb3ctNjAtdXAAAAA=) format("truetype")}.f-page-root{top:0}.f-page{top:0;display:flex;flex-direction:column;background:#EFF2F4}.f-page-main{flex-shrink:1;flex-grow:1;flex-basis:0;background:var(--f-neutral-19);box-shadow:0 2px 20px 0 rgba(3,18,51,.05);margin:.5rem}.f-page-has-query .f-page-main,.f-page-has-scheme .f-page-main{box-shadow:1px 3px 4px 0 rgba(0,28,64,.04)}.f-page-main>.f-section:last-child{margin-bottom:0}.f-page-main>.f-section:last-child::after{display:none}.f-page-is-managelist .f-page-main,.f-page-is-managelistwithsidebar .f-page-main{display:flex;flex-direction:column;overflow:hidden}.f-page-has-scheme .f-page-header{border-radius:.5rem .5rem 0 0}.f-page-has-query .f-page-main{margin-top:-.75rem}.f-page-has-query .f-page-header{margin:.5rem .5rem 0;border-radius:.5rem .5rem 0 0}.f-page-navigate .f-page-main{display:flex;flex-direction:column;overflow:hidden}.f-page-navigate .f-page-content{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:row;flex-wrap:nowrap;overflow:hidden}.f-page-navigate .f-page-content>.col,.f-page-navigate .f-page-content>[class*=col-]{padding-left:0;padding-right:0}.f-page-navigate .f-page-content-nav{display:flex;flex-direction:column;box-shadow:none;padding:0;position:relative;z-index:100}.f-page-navigate .f-page-content-main>.f-section:last-child::after,.f-scrollspy-container .f-struct-subsub-wrapper::after{display:none}.f-page-navigate .f-page-content-nav-extend{padding:.875rem .875rem 0}.f-page-navigate .f-page-content-main{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:auto}.f-page-navigate .f-page-content-nav.f-component-splitter-pane{padding:0}.f-page-is-listnav .f-page-content-main{position:relative;margin:0 0 0 -.25rem}.f-page-is-listnav .f-page-content-main .f-section-query.f-section,.f-page-is-listnav .f-page-content-main .f-section-scheme.f-section{margin:.5rem .5rem 0;padding:.625rem .875rem .125rem}.f-page-is-listnav .f-page-content-main .f-page-header{margin:.5rem .5rem 0}.f-page-is-listnav .f-page-content-main .f-page-header-base{padding-left:.75rem;padding-right:.75rem}.f-page-is-listnav .f-page-content-main .f-page-footer{padding-left:.75rem;padding-right:.75rem;margin-bottom:.5rem}.f-page-is-grid-grid .f-page-content-main,.f-page-is-tree-grid .f-page-content-main{display:flex;flex-direction:column}.f-page-card .f-page-main{overflow:auto}.f-page-is-wizard .f-page-main{display:flex;flex-direction:column;overflow:hidden}.f-page-is-managelist .f-section+.f-section,.f-page-is-managelist .f-struct-wrapper+.f-struct-wrapper>.f-section{margin:.5rem 0 0}.f-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.f-content{flex-shrink:1;flex-grow:1;flex-basis:0}.f-struct-like-card{background:#fff;border-radius:4px;margin:0 0 .5rem}.f-page-is-mainsubcard .f-page-main,.f-page-is-mainsubcard.f-page-is-sidescrollspy .f-page-main .f-scrollspy-content{margin:0}.f-page-is-mainsubcard .f-page-main::-webkit-scrollbar-track,.f-page-is-mainsubcard.f-page-is-sidescrollspy .f-page-main .f-scrollspy-content::-webkit-scrollbar-track{background-color:#EFF2F4}.f-page-is-mainsubcard .f-page-main>.f-struct-like-card:last-child,.f-page-is-mainsubcard.f-page-is-sidescrollspy .f-page-main .f-scrollspy-content>.f-struct-like-card:last-child{margin-bottom:0}.f-struct-subsub-wrapper{position:relative}.f-struct-subsub-wrapper::before{content:"";height:4px;background:#fff;display:block;margin:0 0 4px;box-shadow:2px 3px 3px 0 rgba(31,35,41,.08)}.f-struct-subsub-wrapper::after{content:"";position:absolute;width:16px;height:16px;background:#fff;top:-4px;left:50%;box-shadow:2px 2px 3px 0 rgba(31,35,41,.08);transform:rotate(45deg);z-index:100}.f-scrollspy-container .f-struct-subsub-wrapper{position:initial}.f-cmp-lib-portlet,.f-viewchange-content-item lib-portlet{height:100%}.f-area-hide{opacity:0;visibility:hidden;z-index:100;position:absolute;transform:scaleY(0);transform-origin:100% top;backface-visibility:hidden;transition:opacity .12s linear .12s,visibility .12s linear .12s,transform .12s linear .12s}.f-area-show{opacity:1;visibility:visible;transform:scaleY(1)}.f-page-is-listnav-with-header .f-page-content-main{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column}.f-page-content-main-extend{padding:20px 22px 0}.f-page-content-main-header{text-align:center}.f-page-content-main-header .f-title{margin:0 auto;font-size:20px}.f-page-content-main-header .f-description{margin:0 auto;color:var(--f-text-04)}.f-page-content-main-overflow{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:auto;padding:20px 22px}.f-page-content-main-overflow .f-struct-like-card{margin:0 auto;width:100%;max-width:1092px;box-shadow:none}.f-subgrid-by-table-footer{padding:0 .875rem}.f-subgrid-by-table-footer .btn{color:var(--f-semantic-info-01);background:var(--f-semantic-info-03);width:100%;justify-content:center;height:36px}.f-subgrid-by-table-footer .btn:disabled{color:var(--f-text-07);background:var(--f-neutral-08)}.f-section-oa-table .f-section-header .f-title{padding-left:0}.f-section-oa-table .f-section-header .f-title::before{display:none}.f-section-form.f-section{padding:.625rem 0 .25rem}.f-section-form .f-section-header{padding:0 .875rem;margin-bottom:.875rem}.f-form-layout{display:flex;flex-wrap:wrap}.f-form-layout .f-section-formgroup{flex:0 0 100%;max-width:100%}.f-section-formgroup .f-section-formgroup-legend{width:100%}.f-section-formgroup-legend{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:space-between}.f-section-formgroup-legend .f-header{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:space-between;justify-content:flex-start;color:var(--f-text-04);flex-shrink:1;flex-grow:1;flex-basis:auto;padding:0 .875rem;cursor:pointer;font-size:.875rem}.f-section-formgroup-legend .f-toolbar{justify-content:flex-start}.f-section-formgroup-legend .f-toolbar .btn{border:none;display:flex;align-items:center;font-size:13px;padding-left:.375rem;padding-right:.375rem}.f-section-formgroup-legend .f-btn-collapse-expand{color:var(--f-text-04)}.f-section-formgroup-legend .f-btn-collapse-expand::after{margin:0;font-size:14px}.f-section-formgroup-legend:hover .f-title,.f-section-formgroup-legend:hover .f-toolbar .f-btn-collapse-expand{color:var(--f-theme-05)}.f-section-formgroup-legend:active .f-title,.f-section-formgroup-legend:active .f-toolbar .f-btn-collapse-expand{color:var(--f-theme-01)}.f-section-formgroup-legend.legend-with-toolbar{height:2rem}.f-section-formgroup-legend.legend-with-toolbar .f-header{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:space-between;flex-shrink:1;flex-grow:1;flex-basis:auto;border:1px solid var(--f-aid-08);padding:0 .875rem;height:1.875rem;background:var(--f-aid-09)}.f-section-formgroup-legend.legend-with-toolbar .f-title{font-size:.875rem;color:var(--f-text-02);flex-shrink:1;flex-grow:1;flex-basis:0;cursor:pointer}.f-section-formgroup-inputs{display:flex;flex-wrap:wrap}.f-section-formgroup.f-state-collapse .f-section-formgroup-inputs{display:none}.f-section-formgroup+.f-section-formgroup{margin:.375rem 0 0}.f-cmp-grid-is-sub{min-height:19.375rem}.farris-subgrid{min-height:25.625rem}.f-section-grid.f-section-in-main,.f-section-grid.f-section-in-managelist,.f-section-grid.f-section-in-nav{flex-shrink:1;flex-grow:1;flex-basis:0}.f-section-grid.f-section-in-main .f-section-content,.f-section-grid.f-section-in-managelist .f-section-content,.f-section-grid.f-section-in-nav .f-section-content{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:column}.f-section-grid.f-section-in-main .f-component-grid,.f-section-grid.f-section-in-managelist .f-component-grid,.f-section-grid.f-section-in-nav .f-component-grid{flex-shrink:1;flex-grow:1;flex-basis:0}.f-section-extend-gridfilter,.f-tmpl-staticinfo-wrapper .staticinfo--header,.f-tmpl-staticinfo-wrapper .staticinfo--header .f-title{display:flex;align-items:center}.f-section-grid .f-component-grid{overflow:hidden}.f-grid-is-sub,.f-grid-is-subsub{height:21.875rem}.f-section-extend-gridfilter{background:var(--f-aid-02);border:1px solid;border-radius:2px;height:2.375rem;padding:.25rem .875rem}.f-page .f-page::before,.f-page-has-scheme .f-page-main .f-page-header::before,.f-page-is-listnav::before,.f-page-is-midcard::before{display:none}.f-section-extend-gridfilter>*{margin:0 .625rem 0 0}.f-grid-is-sub .f-component-grid{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.f-page .f-page{background:0 0}.f-page .f-page .f-page-layout{box-shadow:none}.f-page .f-page .f-page-header{margin:0}.f-page .f-page .f-page-main{margin-right:0;margin-left:0;margin-bottom:0}.f-page .f-page-has-scheme .f-section-scheme.f-section{margin-top:0;margin-right:0;margin-left:0}.f-page .f-page-has-scheme .f-page-header{margin-top:.5rem}.f-page-header,.farris-header{box-shadow:none}.f-page-header+.f-page-main,.f-page-header+.farris-split-section,.farris-header+.f-page-main,.farris-header+.farris-split-section{margin-top:0}.f-page-main{border-radius:8px 8px 12px 12px}.f-struct-like-card{box-shadow:none}.f-page.f-page-card,.f-page.f-page-is-managelist,.f-page.f-page-is-managelistwithsidebar,.f-page.f-page-is-onepage,.f-page.f-page-navigate{z-index:10}.f-page.f-page-card::before,.f-page.f-page-is-managelist::before,.f-page.f-page-is-managelistwithsidebar::before,.f-page.f-page-is-onepage::before,.f-page.f-page-navigate::before{z-index:-1;position:absolute;content:"";top:.5rem;bottom:.5rem;left:.5rem;right:.5rem;background:var(--f-neutral-18);box-shadow:0 2px 8px 0 rgba(var(--f-neutral-16),.1);border-radius:12px}.f-page-card .f-page-header,.f-page-card .farris-header,.f-page-is-managelist .f-page-header,.f-page-is-managelist .farris-header,.f-page-is-managelistwithsidebar .f-page-header,.f-page-is-managelistwithsidebar .farris-header,.f-page-is-onepage .f-page-header,.f-page-is-onepage .farris-header,.f-page-navigate .f-page-header,.f-page-navigate .farris-header{margin:.5rem .5rem 0;background:0 0}.f-page-footer{margin-left:.5rem;margin-right:.5rem;margin-bottom:.5rem;background:0 0}.f-page-main+.f-page-footer{margin-top:-.5rem}.f-page-navigate .f-page-main{background:rgba(255,255,255,.7);margin:0 .5rem .5rem}.f-page-navigate .f-page-content-nav{border-right:1px solid var(--f-neutral-07)}.f-page-navigate .f-page-content-nav.has-resize-bar{border-right:none}.f-page-navigate .f-page-content-nav .f-page,.f-page-navigate .f-page-content-nav .farris-main-area{background:0 0}.f-page-navigate .f-page-content-main .f-page-main{background:#fff}.f-page-headerextend{margin:.5rem .5rem 0}.f-page-is-sidescrollspy .f-page-main .f-scrollspy-content{padding:0}.f-scrollspy-tabs{position:relative;box-shadow:0 -2px 20px 0 rgba(3,18,51,.05)!important;z-index:100}.f-scrollspy-tabs .f-scrollspy-monitor-btn.active::after{background-image:var(--f-theme-11);left:14px!important;right:14px!important;width:auto!important;margin:0!important}.f-page-is-midcard .f-page-header{margin:0;background:0 0;box-shadow:none}.f-page-has-scheme .f-page-header{margin:0 .5rem;background:var(--f-neutral-19);position:relative}.f-page-has-scheme .f-page-header::before{content:"";position:absolute;top:-1px;left:0;right:0;box-shadow:0 2px 20px 0 rgba(3,18,51,.05);bottom:5px;z-index:-1;border-radius:.5rem .5rem 0 0}.f-page-has-scheme .f-page-main{margin-top:-.5rem}.f-page-is-mainsubcard .f-page-main{margin:.5rem}.f-page-is-mainsubcard .f-page-header+.f-page-main,.f-page-is-mainsubcard .farris-header+.f-page-main{margin-top:0}.f-page-is-mainsubcard .f-page-main,.f-page-is-mainsubcard.f-page-is-sidescrollspy .f-page-main .f-scrollspy-content{padding:0}.f-page-is-listnav-with-header .f-page-main{background:0 0}.f-page-is-listnav-with-header .f-page-content-main{background:var(--f-neutral-18)}.f-page-is-listnav .f-page-content,.f-page-is-listnav .f-page-content .f-page-content-main .f-page-card,.f-page-is-listnav .f-page-content .f-page-content-main .f-page-is-managelist,.f-page-is-listnav .f-page-content .f-page-content-nav .f-page{background:0 0}.f-page-is-listnav>.f-page-main{margin:.5rem}.f-page-is-listnav .f-page-content .f-page-content-nav{padding:0;box-shadow:0 0 8px 0 rgba(0,28,64,.08);border-right:none}.f-page-is-listnav .f-page-content .f-page-content-nav .f-page::before{top:0;left:0;right:0;bottom:0;border-radius:0;display:block}.f-page-is-listnav .f-page-content .f-page-content-main{margin:0}.f-page-is-listnav .f-page-content .f-page-content-main .f-page-card::before,.f-page-is-listnav .f-page-content .f-page-content-main .f-page-is-managelist::before{top:0;left:0;right:0;bottom:0;border-radius:0;display:block}.f-page .f-list-nav .f-list-nav-in{background:0 0!important;box-shadow:none!important}.f-page.f-page-is-midcard{overflow-y:auto;display:block}.f-page.f-page-is-midcard::-webkit-scrollbar-track{background-color:#EFF2F4}.f-page-layout{background:var(--f-neutral-19);box-shadow:0 2px 8px 0 rgba(var(--f-neutral-16),.1);border-radius:12px;margin:1rem}.f-page-layout .f-page-header{box-shadow:none}.f-page-layout .f-page-header .f-page-header-base{padding-top:1rem;padding-bottom:1rem}.f-page-container{margin:0 auto}@media (min-width:888px){.f-page-container{width:80%}.farris-form .farris-group-wrap{max-width:26.625rem}.farris-form .farris-group-auto .farris-group-wrap,.farris-form-auto .farris-group-wrap{max-width:none}}@media (min-width:1200px){.f-page-container{width:80%}}@media (min-width:1690px){.f-page-container{width:60%}}.f-btn-wrapper{padding-top:18px;padding-bottom:16px;text-align:center}.f-btn-wrapper .btn-lg{margin:0 6px}.f-tmpl-staticinfo-top{font-size:12px;color:rgba(0,0,0,.45);padding:0 0 40px}.f-tmpl-staticinfo-wrapper{background:rgba(42,135,255,.05);border:1px solid rgba(42,135,255,.2);border-radius:3px;padding:14px 20px 6px;margin:0 0 6px}.f-tmpl-staticinfo-wrapper .staticinfo--header .f-title .f-title-icon{margin:0 0 0 12px;border:1px solid #80B8FF;background:#D8E9FF;color:#4796FF;text-align:center;border-radius:2px}.f-tmpl-staticinfo-wrapper .staticinfo--header .f-title .f-title-icon:before{font-size:12px;line-height:14px;display:block}.f-tmpl-staticinfo-wrapper .staticinfo--header .f-title .f-title-icon.f-icon-woman{color:#FF7E7E;border-color:#FCABAB;background:#FFE9E9}.f-tmpl-staticinfo-wrapper .staticinfo--header .f-title .f-title-text{font-size:17px;color:#2D2F33;line-height:30px;margin:0}.f-tmpl-staticinfo-wrapper .staticinfo--content{padding:12px 0 0}.f-tmpl-staticinfo-wrapper .staticinfo--list{display:flex;margin:0 -14px 0 0;flex-wrap:wrap}.f-tmpl-staticinfo-wrapper .staticinfo--list .staticinfo--list-item{position:relative;padding:0 14px 0 0;margin:0 14px 8px 0;color:#36434D;font-size:14px;display:flex;align-items:center}.f-tmpl-staticinfo-wrapper .staticinfo--list .staticinfo--list-item:last-child::after,.f-tmpl-subgrid-by-card-list .f-list-view-multiple .f-list-select .custom-control{display:none}.f-tmpl-staticinfo-wrapper .staticinfo--list .staticinfo--list-item .f-icon{color:#878D99;font-size:13px;margin:0 4px 0 0}.f-tmpl-staticinfo-wrapper .staticinfo--list .staticinfo--list-item .f-title{margin:0 4px 0 0}.f-tmpl-staticinfo-wrapper .staticinfo--list .staticinfo--list-item::after{content:"";height:10px;width:1px;background:#E4E7EF;top:50%;margin-top:-5px;right:0;position:absolute}.f-section-scheme.f-section{background:0 0;margin:.5rem .5rem 0;padding:.625rem .875rem .25rem;box-shadow:none;border-radius:6px 6px 0 0}.f-section-like-query.f-section,.f-section-query.f-section{background:var(--f-neutral-19);margin:.5rem .5rem 0;padding:.625rem .875rem .25rem}.f-section-like-query .f-list-filter.list-filter-autolabel,.f-section-query .f-list-filter.list-filter-autolabel{padding-bottom:0!important}.f-section-like-query.f-section-form{margin:0!important;padding:.625rem 0 .25rem!important}.f-section-scheme{padding:0!important}.f-page-child-fill{flex-direction:column;flex:1 1 0;display:flex!important}.f-page-child-fill .f-struct-like-card-child-fill{display:flex;flex-direction:column;flex:1 1 0;overflow-y:auto}.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child{flex:1 1 0;flex-direction:column;display:flex;min-height:26.875rem}.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child:has(>.f-section-accordion.f-state-collapse){min-height:unset;display:block;flex:initial}.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child .f-section .f-component-tabs{flex:1 1 0;display:flex!important;flex-direction:column!important;overflow:hidden}.f-page-child-fill .f-struct-wrapper-child .f-struct-is-subgrid{flex:1 1 0;flex-direction:column;display:flex}.f-page-child-fill .f-struct-wrapper-child .f-grid-is-sub{height:auto;flex:1 1 0;flex-direction:column;display:flex}.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child .f-section .f-multiview-fill,.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child .f-section .f-multiview-fill .f-viewchange-content-item{display:flex;flex-direction:column;flex:1 1 0}.f-page-child-fill .f-struct-wrapper-child .f-section.f-section-fill .f-section-content{overflow:auto}.f-tmpl-subgrid-by-card{position:relative}.f-tmpl-subgrid-by-card .subgrid-by-card-item{padding:12px 12px 10px 40px;border-bottom:1px solid #E9E9E9;position:relative}.f-tmpl-subgrid-by-card .subgrid-by-card-item .card-item--order{position:absolute;top:16px;left:14px;border-radius:2px;background:#51BD78;line-height:1rem;color:#fff;font-size:12px;text-align:center;padding:0 2px;min-width:16px}.f-tmpl-subgrid-by-card .subgrid-by-card-item .card-item--header{padding:0;position:relative;margin:0 0 8px}.f-tmpl-subgrid-by-card .subgrid-by-card-item .card-item--header .card-item--toolbar{position:absolute;right:0;top:0}.f-tmpl-subgrid-by-card .subgrid-by-card-item .card-item--detail,.f-tmpl-subgrid-by-card .subgrid-by-card-item .card-item--title{font-size:1rem}.f-tmpl-subgrid-by-card .subgrid-by-card-item .card-item--detail{font-size:14px;padding:0;color:rgba(0,0,0,.75)}.f-tmpl-subgrid-by-card .subgrid-by-card-item .card-item--detail .card-item--item{margin-bottom:4px}.f-tmpl-subgrid-by-card-list .f-list-view-multiple .f-list-select{position:absolute;width:20px;height:20px;right:0;bottom:0}.f-tmpl-subgrid-by-card-list .f-list-view-multiple .f-list-select::before{position:absolute;font-size:12px;content:"\e118";color:#fff;font-family:FarrisIcons;z-index:100;right:0;bottom:-3px}.f-tmpl-subgrid-by-card-list .f-list-view-multiple .f-list-select::after{content:"";width:20px;height:20px;border:10px solid #fff;border-color:#fff #E6E6E6 #e6e6e6 #fff;position:absolute;bottom:0;right:0}.f-tmpl-subgrid-by-card-list .f-list-view-multiple .f-listview-active .subgrid-by-card-item{background:linear-gradient(270deg,rgba(235,244,255,.6) 0,#EBF4FF 100%)}.f-tmpl-subgrid-by-card-list .f-list-view-multiple .f-listview-active .f-list-select::after{border-color:#fff #63B7FF #63B7FF #fff}.f-tmpl-subgrid-by-card-list .f-list-view-multiple .f-tmpl-subgrid-by-card:hover .f-list-select::after{border-color:#fff #2A87FF #2A87FF #fff}.f-tmpl-subgrid-by-card-list .subgrid-by-card-footer{margin:8px 0 0;border:1px dashed #D9D9D9;height:28px}.f-tmpl-subgrid-by-card-list .subgrid-by-card-footer .btn{display:block;text-align:center;width:100%;height:100%}.farris-split-section{background:var(--f-neutral-19);box-shadow:0 2px 20px 0 rgba(3,18,51,.05);border-radius:8px;margin:.5rem;overflow:hidden;flex-wrap:nowrap}.farris-split-section .farris-lsection{padding:.875rem;box-shadow:1px 1px 4px 0 rgba(0,28,64,.1)}.farris-header,.farris-header+.farris-header{box-shadow:none}.farris-split-section .farris-rsection{padding:.875rem}.f-form-next-tab{margin-bottom:.3125rem!important}.farris-header{min-height:2.875rem;padding:.75rem .875rem;flex-shrink:0;background:var(--f-neutral-00)}.farris-form-title{margin:0;color:var(--f-text-01);font-size:1.0625rem;line-height:1.625rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.farris-card-content-bg .farris-panel .card-body{padding:.9375rem 0 0;background:var(--f-neutral-00)}.farris-card-section{padding:.875rem 0 .5rem}.farris-main-area{top:0;bottom:0;position:absolute;right:0;left:0;margin:0 auto;display:flex;background:#EFF2F4;overflow:hidden}.farris-cardpart-title{font-size:1rem;line-height:1.375rem;color:var(--f-text-01);margin:0 0 .75rem}.farris-grid-toolbar{display:flex;margin:0 0 .5rem;flex-shrink:0}.farris-grid-toolbar .farris-grid-title{padding:0;margin:0;font-size:1rem;line-height:1.375rem;color:var(--f-text-01)}.f-header-navbar{padding:0}.form-control{display:block;width:100%;height:calc(1.5357375rem + 2px);padding:.1875rem .5rem;font-size:.8125rem;line-height:1.4286;color:var(--f-text-02);background-color:var(--f-neutral-12);background-clip:padding-box;border:1px solid var(--f-neutral-04);border-radius:6px;box-shadow:0 0 0;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:var(--f-text-02);background-color:var(--f-neutral-12);border-color:var(--f-theme-08);outline:0;box-shadow:0 0 0,0 0 4px 2px rgba(99,136,255,.12)}.form-control::-moz-placeholder{color:var(--f-text-09);opacity:1}.form-control::placeholder{color:var(--f-text-09);opacity:1}.form-control:disabled,.form-control[readonly]{background-color:var(--f-neutral-12);opacity:1}select.form-control:focus::-ms-value{color:var(--f-text-02);background-color:var(--f-neutral-12)}.form-control-file,.form-control-range{display:block;width:100%}.form-control-plaintext{display:block;width:100%;padding-top:.1875rem;padding-bottom:.1875rem;margin-bottom:0;line-height:1.4286;color:var(--f-text-01);background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.32145rem + 2px);padding:.125rem .4375rem;font-size:.75rem;line-height:1.4286;border-radius:6px}.form-control-lg{height:calc(1.750025rem + 2px);padding:.25rem .3125rem;font-size:.875rem;line-height:1.4286;border-radius:6px}select.form-control[multiple],select.form-control[size],textarea.form-control{height:auto}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:var(--f-text-08)}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.col-form-label{font-size:inherit;line-height:1.4286}.col-form-label-lg{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.4286}.col-form-label-sm{padding-top:calc(.125rem + 1px);padding-bottom:calc(.125rem + 1px);font-size:.75rem;line-height:1.4286}.form-group{margin-bottom:.375rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex-grow:0;flex-shrink:0;flex-basis:auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.farris-form{flex-shrink:0}.farris-input-wrap{display:block;position:relative}.farris-input-wrap .form-control{width:100%;display:block}.farris-input-wrap .form-control.form-control-invalid{border-color:var(--f-semantic-danger-01)}.farris-input-wrap .form-control.form-control-invalid:focus{box-shadow:0 0 2px 1px rgba(244,97,96,.3)}.farris-input-wrap .input-group .form-control{width:1%}.farris-input-wrap .farris-feedback{position:absolute;top:100%;left:0;padding:.1875rem .5rem;z-index:122;display:none;border-radius:6px;transition:all .2s linear;cursor:pointer}.farris-input-wrap .farris-feedback .f-feedback-message{font-size:.8125rem;line-height:1.4286}.farris-input-wrap .farris-feedback .f-feedback-icon{font-size:14px}.farris-input-wrap .farris-feedback.f-state-invalid,.farris-input-wrap .farris-feedback.f-state-valid{display:block}.farris-input-wrap .farris-feedback.f-state-invalid{background:var(--f-semantic-danger-03);color:var(--f-semantic-danger-01)}.farris-input-wrap .farris-feedback.f-state-valid{background:var(--f-semantic-success-03);color:var(--f-semantic-success-01)}.farris-form-group{flex-wrap:nowrap!important}.farris-form-group .col-form-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%}.farris-form-group .farris-input-wrap .custom-control-label{display:inline}.farris-form-group .farris-input-wrap .custom-checkbox,.farris-form-group .farris-input-wrap .custom-radio{margin-bottom:0;margin-top:.125rem}.farris-label-info{padding:0 .25rem 0 0;flex-shrink:0}.farris-form-controls-inline .farris-group-wrap .farris-input-wrap,.form-inline .farris-input-wrap{flex-shrink:1;flex-grow:1;flex-basis:auto;min-width:1px}.farris-form-controls-inline .farris-group-wrap .col-form-label,.form-inline .col-form-label{display:flex;align-items:center;justify-content:flex-end!important;flex-direction:row!important}.farris-form-controls-inline .farris-group-wrap,.farris-form-inline{display:block}.farris-form-controls-inline .farris-group-wrap .col-form-label,.farris-form-inline .col-form-label{width:6rem;flex-shrink:0;margin-right:.625rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;justify-content:flex-end!important;flex-direction:row!important;align-self:start}.farris-form-controls-inline .farris-group-wrap .col-form-label>*,.farris-form-inline .col-form-label>*{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.farris-form-controls-inline .farris-group-wrap .col-form-label.col-form-label-multi,.farris-form-inline .col-form-label.col-form-label-multi{word-break:break-all;white-space:initial}.farris-form-controls-inline .farris-group-wrap .col-form-label.col-form-label-multi .farris-label-info,.farris-form-inline .col-form-label.col-form-label-multi .farris-label-info{align-self:flex-start;line-height:1.4286}.farris-form-controls-inline .farris-group-wrap .col-form-label.col-form-label-multi .farris-label-text,.farris-form-inline .col-form-label.col-form-label-multi .farris-label-text{white-space:initial;text-align:right;max-height:2.321475rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.farris-form-controls-inline .farris-group-wrap .form-group,.farris-form-inline .form-group{margin-bottom:.5rem;flex-wrap:nowrap!important}.farris-form-controls-inline .farris-group-multi-label .farris-group-wrap,.form-inline .farris-group-multi-label .farris-group-wrap{margin-bottom:0}.farris-form-controls-inline .farris-group-multi-label .farris-group-wrap .col-form-label,.form-inline .farris-group-multi-label .farris-group-wrap .col-form-label{padding-top:0;padding-bottom:0;word-break:break-all;white-space:initial}.farris-form-controls-inline .farris-group-multi-label .farris-group-wrap .col-form-label .farris-label-info,.form-inline .farris-group-multi-label .farris-group-wrap .col-form-label .farris-label-info{align-self:flex-start;line-height:1.4286}.farris-form-controls-inline .farris-group-multi-label .farris-group-wrap .col-form-label .farris-label-text,.form-inline .farris-group-multi-label .farris-group-wrap .col-form-label .farris-label-text{white-space:pre-wrap;text-align:right;max-height:2.321475rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.farris-form-controls-inline .farris-group-multi-label .farris-group-wrap .farris-input-wrap,.form-inline .farris-group-multi-label .farris-group-wrap .farris-input-wrap{align-self:flex-start}.farris-form-controls-inline.f-form-label-sm .farris-group-wrap .col-form-label,.farris-form-inline.f-form-label-sm .col-form-label{width:4.25rem}.farris-form-controls-inline.f-form-label-lg .farris-group-wrap .col-form-label,.farris-form-inline.f-form-label-lg .col-form-label{width:7.75rem}.farris-form-controls-inline.f-form-label-xl .farris-group-wrap .col-form-label,.farris-form-inline.f-form-label-xl .col-form-label{width:9.5rem}.farris-form-controls-inline.f-form-label-el .farris-group-wrap .col-form-label,.farris-form-inline.f-form-label-el .col-form-label{width:13rem}.farris-form-controls-inline .f-empty-input-placeholder,.farris-form-inline .f-empty-input-placeholder{padding-top:0;margin-top:0;margin-bottom:.5rem}.farris-form-controls-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.farris-form-controls-inline .farris-group-ver .col-form-label,.farris-form-controls-inline .farris-group-ver .form-group{display:block}.f-checkradio-no-label .farris-form-controls-inline .col-form-label,.f-checkradio-no-label .farris-form-inline .col-form-label{width:1px;overflow:hidden;height:calc(1.5357375rem + 1px * 2)}.f-checkradio-no-label .farris-form-controls-inline .custom-checkbox,.f-checkradio-no-label .farris-form-controls-inline .custom-radio,.f-checkradio-no-label .farris-form-inline .custom-checkbox,.f-checkradio-no-label .farris-form-inline .custom-radio{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.f-form-lable-auto .col-form-label{width:auto!important}.farris-form-controls-inline .f-checkradio-no-label .col-form-label,.farris-form-inline .f-checkradio-no-label .col-form-label{width:1px;overflow:hidden;height:calc(1.4286 * 1.4286 + .1875rem * 2 + 1px * 2)}.custom-control-label{margin-left:0}.f-input-underline .form-control{border-radius:0;background:0 0;border-width:0 0 1px;border-color:var(--f-neutral-02);border-style:solid}.f-input-underline .form-control:focus{background:0 0;border-color:var(--f-theme-08);color:var(--f-text-02);box-shadow:none}.f-input-underline .form-control:disabled,.f-input-underline .form-control:disabled:hover{background:0 0;border-color:var(--f-neutral-04);border-style:dashed;color:var(--f-text-02)}.f-input-underline .form-control:disabled::-moz-placeholder,.f-input-underline .form-control[readonly]::-moz-placeholder{color:var(--f-text-09)}.f-input-underline .form-control:disabled::placeholder,.f-input-underline .form-control[readonly]::placeholder{color:var(--f-text-09)}.f-input-underline .form-control[readonly],.f-input-underline .form-control[readonly]:hover{background:0 0;border-color:var(--f-neutral-04);border-style:dashed;color:var(--f-text-02)}.f-input-underline .f-cmp-inputgroup.actived .input-group{box-shadow:none}.f-input-underline .input-group{border-radius:0;border-width:0 0 1px;border-color:var(--f-neutral-02);border-style:solid}.f-input-underline .input-group .form-control{border:0}.f-input-underline .input-group.f-state-disabled,.f-input-underline .input-group.f-state-readonly{border-color:var(--f-neutral-04);border-style:dashed}.f-input-underline .input-group.f-state-focus{box-shadow:none}.f-state-form-view .farris-group-wrap .farris-label-text{color:var(--f-text-02)}.f-state-form-view .form-control:focus{background:var(--f-neutral-12);border-color:transparent;color:var(--f-text-02);box-shadow:none}.f-state-form-view .form-control:disabled,.f-state-form-view .form-control:disabled:hover,.f-state-form-view .form-control[readonly],.f-state-form-view .form-control[readonly]:hover{background:var(--f-neutral-12);border-color:transparent;color:var(--f-text-02)}.f-state-form-view .input-group,.f-state-form-view .input-group.f-state-disabled,.f-state-form-view .input-group.f-state-readonly{border-color:transparent}.farris-input-wrap .f-cmp-inputgroup.ng-invalid.ng-dirty .input-group,.farris-input-wrap .f-cmp-inputgroup.ng-invalid.ng-dirty .input-group:hover,.farris-input-wrap .f-cmp-inputgroup.ng-invalid.ng-touched .input-group,.farris-input-wrap .f-cmp-inputgroup.ng-invalid.ng-touched .input-group:hover,.farris-input-wrap .form-control.ng-invalid.ng-dirty,.farris-input-wrap .form-control.ng-invalid.ng-touched{border-color:#dc3545}.f-form-controls-fixed-with .farris-input-wrap{width:3.75rem}.f-checkradio-single{margin:0;padding:0;width:1rem;height:1rem;min-height:1rem;display:inline-flex}.f-checkradio-single .custom-control-label::after,.f-checkradio-single .custom-control-label::before{top:0;left:0}.f-form-table{width:100%;table-layout:fixed}.f-form-table td{padding-left:14px;padding-right:14px}.farris-input-wrap .form-control.ng-invalid.ng-dirty:focus,.farris-input-wrap .form-control.ng-invalid.ng-touched:focus{box-shadow:0 0 2px 1px rgba(220,53,69,.3)}.f-form-state-default .farris-input-wrap .form-control:disabled,.f-form-state-default .farris-input-wrap .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-default .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-default .farris-input-wrap .form-control[readonly]+.input-append-wrapper{background:var(--f-neutral-12)}.f-form-state-default .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-component-timepicker .input-group .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-component-timepicker .input-group.f-state-readonly{background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-default .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-default .f-component-timepicker .input-group.f-state-readonly .form-control{color:var(--f-text-02);background:var(--f-neutral-12)!important}.f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-component-timepicker .input-group.f-state-readonly .input-group-append{background:var(--f-neutral-12)}.f-form-state-default .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-default .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-default .f-component-timepicker .input-group.f-state-editable .form-control{color:var(--f-text-02);border-color:var(--f-neutral-04);background:var(--f-neutral-12)}.f-form-state-default .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-default .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-default .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-default .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-default .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-default .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-default .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-default .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-default .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-default .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-default .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-default .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-default .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-default .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-default .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-default .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-default .farris-editor.farris-editor-readonly .mce-container{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-default .farris-html-editor .ql-container.ql-disabled{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)!important}.f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly]{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly]+.input-append-wrapper{background:var(--f-neutral-10)}.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly{background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .form-control{color:var(--f-text-07);background:var(--f-neutral-10)!important}.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .input-group-append{background:var(--f-neutral-10)}.f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-editable .form-control{color:var(--f-text-02);border-color:var(--f-neutral-04);background:var(--f-neutral-12)}.f-form-state-default .f-form-pretend-lines .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-pretend-lines .farris-editor.farris-editor-readonly .mce-container{color:var(--f-text-07);background:var(--f-neutral-10)}.f-form-state-default .f-form-pretend-lines .farris-html-editor .ql-container.ql-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)!important}.f-form-state-create .farris-input-wrap .form-control:disabled,.f-form-state-create .farris-input-wrap .form-control[readonly],.f-form-state-edit .farris-input-wrap .form-control:disabled,.f-form-state-edit .farris-input-wrap .form-control[readonly],.f-input-text-light .farris-input-wrap .form-control:disabled,.f-input-text-light .farris-input-wrap .form-control[readonly]{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-create .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-form-state-edit .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-edit .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-input-text-light .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-input-text-light .farris-input-wrap .form-control[readonly]+.input-append-wrapper{background:var(--f-neutral-10)}.f-form-state-create .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-component-timepicker .input-group .form-control[readonly],.f-input-text-light .f-cmp-inputgroup .input-group .form-control:disabled,.f-input-text-light .f-cmp-inputgroup .input-group .form-control[readonly],.f-input-text-light .f-cmp-number-spinner .input-group .form-control:disabled,.f-input-text-light .f-cmp-number-spinner .input-group .form-control[readonly],.f-input-text-light .f-component-timepicker .input-group .form-control:disabled,.f-input-text-light .f-component-timepicker .input-group .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-create .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-component-timepicker .input-group.f-state-readonly,.f-input-text-light .f-cmp-inputgroup .input-group.f-state-disabled,.f-input-text-light .f-cmp-inputgroup .input-group.f-state-readonly,.f-input-text-light .f-cmp-number-spinner .input-group.f-state-disabled,.f-input-text-light .f-cmp-number-spinner .input-group.f-state-readonly,.f-input-text-light .f-component-timepicker .input-group.f-state-disabled,.f-input-text-light .f-component-timepicker .input-group.f-state-readonly{background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-create .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-create .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-create .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-create .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-create .f-component-timepicker .input-group.f-state-readonly .form-control,.f-form-state-edit .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-edit .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-edit .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-edit .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-edit .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-edit .f-component-timepicker .input-group.f-state-readonly .form-control,.f-input-text-light .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-input-text-light .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-input-text-light .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-input-text-light .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-input-text-light .f-component-timepicker .input-group.f-state-disabled .form-control,.f-input-text-light .f-component-timepicker .input-group.f-state-readonly .form-control{color:var(--f-text-07);background:var(--f-neutral-10)!important}.f-form-state-create .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-create .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-create .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-component-timepicker .input-group.f-state-readonly .input-group-append{background:var(--f-neutral-10)}.f-form-state-create .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-create .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-create .f-component-timepicker .input-group.f-state-editable .form-control,.f-form-state-edit .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-edit .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-edit .f-component-timepicker .input-group.f-state-editable .form-control,.f-input-text-light .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-input-text-light .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-input-text-light .f-component-timepicker .input-group.f-state-editable .form-control{color:var(--f-text-02);border-color:var(--f-neutral-04);background:var(--f-neutral-12)}.f-form-state-create .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-create .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-create .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-create .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-create .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-create .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-create .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-create .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-create .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-create .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-edit .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-edit .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .f-state-readonly.k-datepicker .k-picker-wrap,.f-input-text-light .farris-input-wrap .k-autocomplete.k-state-disabled,.f-input-text-light .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-input-text-light .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-input-text-light .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-input-text-light .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-input-text-light .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-input-text-light .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-create .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-create .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-create .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-create .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-create .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-create .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-create .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-create .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-create .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-edit .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-edit .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-autocomplete,.f-input-text-light .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-input-text-light .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-input-text-light .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .farris-editor.farris-editor-readonly .mce-container,.f-form-state-edit .farris-editor.farris-editor-readonly .mce-container,.f-input-text-light .farris-editor.farris-editor-readonly .mce-container{color:var(--f-text-07);background:var(--f-neutral-10)}.f-form-state-create .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .farris-html-editor .ql-container.ql-disabled,.f-input-text-light .farris-html-editor .ql-container.ql-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)!important}.f-form-state-create .f-form-state-default .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .form-control[readonly],.f-input-text-light .f-form-state-default .farris-input-wrap .form-control:disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-create .f-form-state-default .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-create .f-form-state-default .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-form-state-edit .f-form-state-default .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-edit .f-form-state-default .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-input-text-light .f-form-state-default .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-input-text-light .f-form-state-default .farris-input-wrap .form-control[readonly]+.input-append-wrapper{background:var(--f-neutral-12)}.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group .form-control[readonly],.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group .form-control:disabled,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group .form-control[readonly],.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group .form-control:disabled,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group .form-control[readonly],.f-input-text-light .f-form-state-default .f-component-timepicker .input-group .form-control:disabled,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group.f-state-readonly,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group.f-state-disabled,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group.f-state-readonly{background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group.f-state-readonly .form-control,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group.f-state-readonly .form-control,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group.f-state-disabled .form-control,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group.f-state-readonly .form-control{color:var(--f-text-02);background:var(--f-neutral-12)!important}.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group.f-state-readonly .input-group-append{background:var(--f-neutral-12)}.f-form-state-create .f-form-state-default .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-create .f-form-state-default .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-create .f-form-state-default .f-component-timepicker .input-group.f-state-editable .form-control,.f-form-state-edit .f-form-state-default .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-edit .f-form-state-default .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-edit .f-form-state-default .f-component-timepicker .input-group.f-state-editable .form-control,.f-input-text-light .f-form-state-default .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-input-text-light .f-form-state-default .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-input-text-light .f-form-state-default .f-component-timepicker .input-group.f-state-editable .form-control{color:var(--f-text-02);border-color:var(--f-neutral-04);background:var(--f-neutral-12)}.f-form-state-create .f-form-state-default .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-state-readonly.k-datepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .k-autocomplete.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-create .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-edit .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-autocomplete,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-input-text-light .f-form-state-default .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)}.f-form-state-create .f-form-state-default .farris-editor.farris-editor-readonly .mce-container,.f-form-state-edit .f-form-state-default .farris-editor.farris-editor-readonly .mce-container,.f-input-text-light .f-form-state-default .farris-editor.farris-editor-readonly .mce-container{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-create .f-form-state-default .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .farris-html-editor .ql-container.ql-disabled,.f-input-text-light .f-form-state-default .farris-html-editor .ql-container.ql-disabled{color:var(--f-text-02);background:var(--f-neutral-12);border-color:var(--f-neutral-04)!important}.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly]{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .form-control[readonly]+.input-append-wrapper{background:var(--f-neutral-10)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control[readonly],.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control:disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group .form-control[readonly],.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control:disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group .form-control[readonly],.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control:disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly{background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .form-control{color:var(--f-text-07);background:var(--f-neutral-10)!important}.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-readonly .input-group-append{background:var(--f-neutral-10)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-editable .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-editable .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-component-timepicker .input-group.f-state-editable .form-control{color:var(--f-text-02);border-color:var(--f-neutral-04);background:var(--f-neutral-12)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .f-state-readonly.k-datepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-autocomplete.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-autocomplete,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-editor.farris-editor-readonly .mce-container,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-editor.farris-editor-readonly .mce-container,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-editor.farris-editor-readonly .mce-container{color:var(--f-text-07);background:var(--f-neutral-10)}.f-form-state-create .f-form-state-default .f-form-pretend-lines .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .f-form-pretend-lines .farris-html-editor .ql-container.ql-disabled,.f-input-text-light .f-form-state-default .f-form-pretend-lines .farris-html-editor .ql-container.ql-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)!important}.f-form-state-default .f-form-state-create .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .form-control[readonly],.f-form-state-default .f-input-text-light .farris-input-wrap .form-control:disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .form-control[readonly]{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-state-create .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-default .f-form-state-create .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-form-state-default .f-form-state-edit .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-default .f-form-state-edit .farris-input-wrap .form-control[readonly]+.input-append-wrapper,.f-form-state-default .f-input-text-light .farris-input-wrap .form-control:disabled+.input-append-wrapper,.f-form-state-default .f-input-text-light .farris-input-wrap .form-control[readonly]+.input-append-wrapper{background:var(--f-neutral-10)}.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-input-text-light .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group .form-control[readonly]{color:var(--f-text-02);background:var(--f-neutral-12)}.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group.f-state-readonly{background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group.f-state-readonly .form-control,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group.f-state-readonly .form-control,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group.f-state-disabled .form-control,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group.f-state-readonly .form-control,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group.f-state-disabled .form-control,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group.f-state-readonly .form-control,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group.f-state-disabled .form-control,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group.f-state-readonly .form-control{color:var(--f-text-07);background:var(--f-neutral-10)!important}.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group.f-state-readonly .input-group-append,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group.f-state-disabled .input-group-append,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group.f-state-readonly .input-group-append{background:var(--f-neutral-10)}.f-form-state-default .f-form-state-create .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-default .f-form-state-create .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-default .f-form-state-create .f-component-timepicker .input-group.f-state-editable .form-control,.f-form-state-default .f-form-state-edit .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-default .f-form-state-edit .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-default .f-form-state-edit .f-component-timepicker .input-group.f-state-editable .form-control,.f-form-state-default .f-input-text-light .f-cmp-inputgroup .input-group.f-state-editable .form-control,.f-form-state-default .f-input-text-light .f-cmp-number-spinner .input-group.f-state-editable .form-control,.f-form-state-default .f-input-text-light .f-component-timepicker .input-group.f-state-editable .form-control{color:var(--f-text-02);border-color:var(--f-neutral-04);background:var(--f-neutral-12)}.f-form-state-default .f-form-state-create .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-default .f-form-state-create .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .k-autocomplete.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-combobox .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-dateinput .k-dateinput-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-datepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-datetimepicker .k-picker-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-dropdown .k-dropdown-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-multiselect-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-numerictextbox .k-numeric-wrap.k-state-disabled,.f-form-state-default .f-input-text-light .farris-input-wrap .k-timepicker .k-picker-wrap.k-state-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-form-state-create .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-form-state-edit .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-autocomplete,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-combobox .k-dropdown-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-datepicker .k-picker-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-datetimepicker .k-picker-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-dropdown .k-dropdown-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-multiselect-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .f-state-readonly.k-timepicker .k-picker-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap .k-state-disabled.k-dateinput .k-dateinput-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-autocomplete,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-combobox .k-dropdown-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-dateinput .k-dateinput-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-datepicker .k-picker-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-datetimepicker .k-picker-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-dropdown .k-dropdown-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-multiselect-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-numerictextbox .k-numeric-wrap,.f-form-state-default .f-input-text-light .farris-input-wrap [ng-reflect-readonly=true].k-timepicker .k-picker-wrap{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.f-form-state-default .f-form-state-create .farris-editor.farris-editor-readonly .mce-container,.f-form-state-default .f-form-state-edit .farris-editor.farris-editor-readonly .mce-container,.f-form-state-default .f-input-text-light .farris-editor.farris-editor-readonly .mce-container{color:var(--f-text-07);background:var(--f-neutral-10)}.f-form-state-default .f-form-state-create .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-edit .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-input-text-light .farris-html-editor .ql-container.ql-disabled{color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)!important}.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control:disabled,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control[readonly],.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .form-control:disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .form-control[readonly],.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-create .farris-card-content-bg .farris-input-wrap .form-control:disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .form-control[readonly],.f-form-state-create .farris-card-section .farris-input-wrap .form-control:disabled,.f-form-state-create .farris-card-section .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-edit .farris-card-content-bg .farris-input-wrap .form-control:disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .form-control[readonly],.f-form-state-edit .farris-card-section .farris-input-wrap .form-control:disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .form-control[readonly]{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .farris-card-content-bg .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .farris-card-section .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .farris-card-section .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .farris-card-section .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .farris-card-section .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .farris-card-section .farris-input-wrap .farris-html-editor .ql-container.ql-disabled{border-width:1px!important;border-color:var(--f-neutral-06)}.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly]{border:0}.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-editable{border-width:1px;border-color:var(--f-neutral-04)}.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-section-form .f-form-layout .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-focus{border-color:var(--f-theme-08);color:var(--f-text-02)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .form-control[readonly]{border-width:0 0 1px;border-radius:0;border-style:solid;border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .farris-html-editor .ql-container.ql-disabled{border-width:0 0 1px!important;border-radius:0;border-style:solid;border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly]{border:0}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus{border-width:0 0 1px;border-radius:0;border-style:solid;border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-editable{border-width:1px;border-color:var(--f-neutral-04)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-focus{border-color:var(--f-theme-08);color:var(--f-text-02)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .form-control[readonly]{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled{border-width:1px!important;border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly]{border:0}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable{border-width:1px;border-color:var(--f-neutral-04)}.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-create .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-edit .f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus{border-color:var(--f-theme-08);color:var(--f-text-02)}.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control[readonly],.f-form-state-default .f-section-form .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-default .farris-card-content-bg .farris-input-wrap .form-control:disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .form-control[readonly],.f-form-state-default .farris-card-section .farris-input-wrap .form-control:disabled,.f-form-state-default .farris-card-section .farris-input-wrap .form-control[readonly]{border-width:0 0 1px;border-radius:0;border-style:solid;border-color:var(--f-neutral-06)}.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .farris-card-content-bg .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .farris-card-section .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .farris-card-section .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .farris-card-section .farris-input-wrap .farris-html-editor .ql-container.ql-disabled{border-width:0 0 1px!important;border-radius:0;border-style:solid;border-color:var(--f-neutral-06)}.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly]{border:0}.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus{border-width:0 0 1px;border-radius:0;border-style:solid;border-color:var(--f-neutral-06)}.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-editable{border-width:1px;border-color:var(--f-neutral-04)}.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-focus{border-color:var(--f-theme-08);color:var(--f-text-02)}.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .form-control[readonly],.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .form-control:disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .form-control[readonly]{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .farris-html-editor .ql-container.ql-disabled{border-width:1px!important;border-color:var(--f-neutral-06)}.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly]{border:0}.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-editable{border-width:1px;border-color:var(--f-neutral-04)}.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-rregion-mtable-form-next-tab .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-section-form .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-sidebar-content .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .farris-card-content-bg .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .farris-card-section .f-form-pretend-lines .farris-input-wrap .f-component-timepicker .input-group.f-state-focus{border-color:var(--f-theme-08);color:var(--f-text-02)}.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .form-control[readonly]{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .farris-html-editor .ql-container.ql-disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .farris-editor.farris-editor-disabled .mce-tinymce,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .farris-editor.farris-editor-readonly .mce-tinymce,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .farris-html-editor .ql-container.ql-disabled{border-width:1px!important;border-color:var(--f-neutral-06)}.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group .form-control[readonly],.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control:disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group .form-control[readonly]{border:0}.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-readonly.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-disabled.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-readonly.f-state-focus{border-width:1px;border-color:var(--f-neutral-06)}.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-editable,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-editable{border-width:1px;border-color:var(--f-neutral-04)}.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-create .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-create .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-rregion-mtable-form-next-tab .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-section-form .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .f-sidebar-content .farris-form .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-content-bg .farris-input-wrap .f-component-timepicker .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-inputgroup .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-cmp-number-spinner .input-group.f-state-focus,.f-form-state-default .f-form-state-edit .farris-card-section .farris-input-wrap .f-component-timepicker .input-group.f-state-focus{border-color:var(--f-theme-08);color:var(--f-text-02)}.f-form-pretend-lines .f-form-control-text,.f-form-pretend-lines .f-form-control-textarea{border-width:1px!important;color:var(--f-text-07);background:var(--f-neutral-10);border-color:var(--f-neutral-06)}.form-group--has-tips{position:relative}.form-group--has-tips .farris-label-tips{position:absolute;right:0;bottom:calc(.75rem + 1px);margin-bottom:-7px}.farris-label-tips,.farris-label-tips--highlight{display:inline-block;width:14px;height:14px;border:1px solid var(--f-theme-03);background:var(--f-aid-04);color:var(--f-theme-03);border-radius:7px;line-height:1;text-align:center}.farris-label-tips .f-icon,.farris-label-tips--highlight .f-icon{font-size:13px;vertical-align:top;transform:scale(.7)}.badge,.farris-label-tips--highlight .f-icon{vertical-align:baseline}.farris-label-tips--highlight:has(.f-icon-question),.farris-label-tips:has(.f-icon-question){border-color:var(--f-semantic-warning-01)}.farris-label-tips--highlight{border:none;color:#fff;background-image:linear-gradient(225deg,#FFB362 0,#FF8538 100%)}.form-label-plaintext .farris-label-text{color:var(--f-text-08)}.form-row{margin-right:-.5rem;margin-left:-.5rem}.form-row>.col,.form-row>[class*=col-]{padding-right:.5rem;padding-left:.5rem}.col-form-label{padding-top:0;padding-bottom:0;margin-bottom:.375rem;margin-left:0}.farris-form-controls-inline .farris-group-wrap .col-form-label,.farris-form-inline .col-form-label{padding-top:calc(.1875rem + 1px);padding-bottom:calc(.1875rem + 1px);margin-bottom:0}.f-list-view-content .f-list-view-group .f-list-content .f-tmpl-card--header-multicontent01 .header-multicontent01--content .header-multicontent01--footer{min-height:31px}.f-component-wizard-page-detail-footer{border-top:1px solid var(--f-neutral-08);padding:.75rem .875rem .875rem}.f-tmpl-card--header-multicontent01{background:#FEFEFF;border:1px solid #E4E7EF;border-radius:4px;width:19.375rem;margin:0 1rem 1rem 0;box-shadow:0 2px 10px 0 rgba(0,25,58,.1)}.f-tmpl-card--header-multicontent01 .header-multicontent01--header{color:#fff;border-radius:4px;height:2.5rem;padding:0 1.375rem;position:relative;background:linear-gradient(225deg,var(--f-aid-01),var(--f-theme-03))}.f-tmpl-card--header-multicontent01 .header-multicontent01--header .f-title{font-size:1rem;line-height:2.5rem;margin:0}.f-tmpl-card--header-multicontent01 .header-multicontent01--header .f-state{text-align:center;position:absolute;top:-1px;right:-1px;width:3.75rem;height:1.5rem;line-height:1.5rem;color:#fff;font-size:.75rem}.f-tmpl-card--header-multicontent01 .header-multicontent01--header .f-state span{display:block;border-radius:0 0 0 6px}.f-tmpl-card--header-multicontent01 .header-multicontent01--content{padding:1rem 1.375rem;position:relative}.f-tmpl-card--header-multicontent01 .header-multicontent01--content .f-title{font-size:1rem;height:22px}.f-tmpl-card--header-multicontent01 .header-multicontent01--content p{margin:0 0 .5rem}.f-tmpl-card--header-multicontent01 .header-multicontent01--content .f-state{position:absolute;right:0;top:13px}.f-tmpl-card--header-multicontent01 .header-multicontent01--content .f-state span{border-radius:4px 0 0 4px;padding-top:4px;padding-bottom:4px}.f-tmpl-card--header-multicontent01 .header-multicontent01--footer .f-emphasize{font-size:1.375rem;color:#F7962A}.f-tmpl-card--header-multicontent01 .header-multicontent01--footer .f-toolbar{margin:0}.f-tmpl-card--header-multicontent01 .header-multicontent01--footer .f-toolbar span{cursor:pointer;margin:0 1rem 0 0}.f-tmpl-list--columns01{display:flex;flex-wrap:no-wrap;border:1px solid #ddd;position:relative;margin:-1px 8px 0;flex-direction:row;padding:20px 8px 12px;align-items:center}.f-tmpl-list--columns01 p{margin-bottom:4px}.f-tmpl-list--columns01 .f-state{position:absolute;top:-1px;left:0}.f-tmpl-list--columns01 .f-state span{border-radius:0 0 4px 4px;padding-left:12px;padding-right:11px}.f-tmpl-list--columns01 .f-emphasize{font-size:1.375rem;color:#F7962A}.f-template-common-row{padding:12px 16px;align-items:center}.f-template-common-row .item-action-primary{display:inline-block;margin-right:16px;width:60px;height:60px;border-radius:50%;overflow:hidden}.f-template-common-row .item-action-primary .ap-img{display:block;width:60px;height:60px;border-radius:50%}.f-template-common-row .listview-item-content{border-bottom:1px solid #d9d9d9;flex:1 1 auto}.f-template-common-row .listview-item-content .listview-item-main{flex-grow:1;flex-shrink:1;flex-basis:0}.f-template-common-row .listview-item-content .listview-item-title{font-size:16px;color:rgba(0,0,0,.85)}.f-template-common-row .listview-item-content .listview-item-subtitle{font-size:14px;color:rgba(0,0,0,.45)}.badge-pill-success,.badge-success{color:#fff}.f-template-common-row .listview-item-content .listview-item-btns .btn{margin-left:6px;margin-right:6px}.f-listview-active .f-tmpl-list--columns01{box-shadow:0 2px 10px 0 rgba(0,25,58,.1)}.badge-arrow-left-success,.badge-arrow-right-success,.badge-pill-success,.badge-round-success,.badge-success{background:var(--f-semantic-success-01)}.f-listview-active .f-template-common-row .listview-item-content{border-color:var(--f-theme-03)}.f-page-is-onepage .f-onepage-tabs{margin:0 .5rem}.f-onepage-content{overflow-y:auto}.badge{display:inline-block;padding:.1875rem .5rem;font-size:.75rem;line-height:1;text-align:center;white-space:nowrap;border-radius:6px}.badge-pill,.badge-pill-border-success,.badge-pill-success{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-border-arrow-left-success,.badge-border-success,.badge-pill-border-success{color:var(--f-semantic-success-01);background:var(--f-semantic-success-03)}.badge-pill-border-success{border:1px solid var(--f-semantic-success-01)}.badge-border-success{padding:.125rem .4375rem;border:1px solid var(--f-semantic-success-02);border-radius:2px}.badge-border-arrow-left-success{border:1px solid var(--f-semantic-success-02);position:relative;margin-left:12px}.badge-border-arrow-left-success::after,.badge-border-arrow-left-success::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-left-success::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-success-02);border-width:6px 12px 6px 0}.badge-border-arrow-left-success::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-success-03);border-width:5px 10px 5px 0}.badge-border-arrow-right-success{position:relative;margin-right:12px}.badge-border-arrow-right-success::after,.badge-border-arrow-right-success::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-right-success::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-success-02);border-width:6px 0 6px 12px}.badge-border-arrow-right-success::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-success-03);border-width:5px 0 5px 10px}.badge-arrow-left-success::before,.badge-arrow-right-success::before{margin-top:-8px;border-top:8px solid transparent;border-bottom:8px solid transparent;content:"";top:50%}.badge-arrow-left-success{position:relative;color:#fff;margin-left:8px}.badge-arrow-left-success::before{position:absolute;border-right:8px solid transparent;border-left:0 solid transparent;left:-8px;border-right-color:var(--f-semantic-success-01)}.badge-arrow-right-success{position:relative;color:#fff;margin-right:8px}.badge-arrow-right-success::before{position:absolute;border-left:8px solid transparent;border-right:0 solid transparent;right:-8px;border-left-color:var(--f-semantic-success-01)}.badge-round-success{width:6px;height:6px;border-radius:3px;line-height:1;overflow:hidden;padding:0}.badge-round-outer-success{position:relative;width:14px;height:14px;display:block;background:rgba(var(--f-semantic-success-01),.18);border-radius:7px}.badge-round-outer-success::after{content:"";width:8px;height:8px;position:absolute;top:50%;left:50%;margin:-4px 0 0 -4px;border-radius:4px;background:var(--f-semantic-success-01)}.badge-pill-border-info,.badge-pill-info{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-info,.badge-pill-info{color:#fff;background:var(--f-semantic-info-01)}.badge-border-arrow-left-info,.badge-border-info,.badge-pill-border-info{color:var(--f-semantic-info-01);background:var(--f-semantic-info-03)}.badge-pill-border-info{border:1px solid var(--f-semantic-info-01)}.badge-border-info{padding:.125rem .4375rem;border:1px solid var(--f-semantic-info-02);border-radius:2px}.badge-border-arrow-left-info{border:1px solid var(--f-semantic-info-02);position:relative;margin-left:12px}.badge-arrow-left-info,.badge-arrow-right-info,.badge-round-info{background:var(--f-semantic-info-01)}.badge-border-arrow-left-info::after,.badge-border-arrow-left-info::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-left-info::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-info-02);border-width:6px 12px 6px 0}.badge-border-arrow-left-info::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-info-03);border-width:5px 10px 5px 0}.badge-border-arrow-right-info{position:relative;margin-right:12px}.badge-border-arrow-right-info::after,.badge-border-arrow-right-info::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-round-info,.badge-round-warning{width:6px;border-radius:3px;padding:0;display:inline-block!important;line-height:1;overflow:hidden;height:6px}.badge-border-arrow-right-info::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-info-02);border-width:6px 0 6px 12px}.badge-border-arrow-right-info::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-info-03);border-width:5px 0 5px 10px}.badge-arrow-left-info::before,.badge-arrow-right-info::before{margin-top:-8px;border-top:8px solid transparent;border-bottom:8px solid transparent}.badge-arrow-left-info{position:relative;color:#fff;margin-left:8px}.badge-arrow-left-info::before{content:"";position:absolute;top:50%;border-right:8px solid transparent;border-left:0 solid transparent;left:-8px;border-right-color:var(--f-semantic-info-01)}.badge-arrow-right-info{position:relative;color:#fff;margin-right:8px}.badge-arrow-right-info::before,.badge-round-outer-info::after{position:absolute;content:"";top:50%}.badge-arrow-right-info::before{border-left:8px solid transparent;border-right:0 solid transparent;right:-8px;border-left-color:var(--f-semantic-info-01)}.badge-round-outer-info{position:relative;width:14px;height:14px;display:block;background:rgba(var(--f-semantic-info-01),.18);border-radius:7px}.badge-round-outer-info::after{width:8px;height:8px;left:50%;margin:-4px 0 0 -4px;border-radius:4px;background:var(--f-semantic-info-01)}.badge-pill-border-warning,.badge-pill-warning{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-arrow-left-warning,.badge-arrow-right-warning,.badge-pill-warning,.badge-round-outer-warning::after,.badge-round-warning,.badge-warning{background:var(--f-semantic-warning-01)}.badge-pill-warning,.badge-warning{color:#fff}.badge-border-arrow-left-warning,.badge-border-warning,.badge-pill-border-warning{color:var(--f-semantic-warning-01);background:var(--f-semantic-warning-03)}.badge-pill-border-warning{border:1px solid var(--f-semantic-warning-01)}.badge-border-warning{padding:.125rem .4375rem;border:1px solid var(--f-semantic-warning-02);border-radius:2px}.badge-border-arrow-left-warning{border:1px solid var(--f-semantic-warning-02);position:relative;margin-left:12px}.badge-border-arrow-left-warning::after,.badge-border-arrow-left-warning::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-left-warning::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-warning-02);border-width:6px 12px 6px 0}.badge-border-arrow-left-warning::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-warning-03);border-width:5px 10px 5px 0}.badge-border-arrow-right-warning{position:relative;margin-right:12px}.badge-border-arrow-right-warning::after,.badge-border-arrow-right-warning::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-right-warning::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-warning-02);border-width:6px 0 6px 12px}.badge-border-arrow-right-warning::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-warning-03);border-width:5px 0 5px 10px}.badge-arrow-left-warning::before,.badge-arrow-right-warning::before{margin-top:-8px;border-top:8px solid transparent;border-bottom:8px solid transparent;content:"";top:50%}.badge-arrow-left-warning{position:relative;color:#fff;margin-left:8px}.badge-arrow-left-warning::before{position:absolute;border-right:8px solid transparent;border-left:0 solid transparent;left:-8px;border-right-color:var(--f-semantic-warning-01)}.badge-arrow-right-warning{position:relative;color:#fff;margin-right:8px}.badge-arrow-right-warning::before{position:absolute;border-left:8px solid transparent;border-right:0 solid transparent;right:-8px;border-left-color:var(--f-semantic-warning-01)}.badge-round-outer-warning{position:relative;width:14px;height:14px;display:block;background:rgba(var(--f-semantic-warning-01),.18);border-radius:7px}.badge-round-outer-warning::after{content:"";width:8px;height:8px;position:absolute;top:50%;left:50%;margin:-4px 0 0 -4px;border-radius:4px}.badge-pill-border-danger,.badge-pill-danger{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-danger,.badge-pill-danger{color:#fff;background:#F46160}.badge-border-arrow-left-danger,.badge-border-danger,.badge-pill-border-danger{color:#F46160;background:var(--f-semantic-danger-03)}.badge-pill-border-danger{border:1px solid #F46160}.badge-border-danger{padding:.125rem .4375rem;border:1px solid var(--f-semantic-danger-02);border-radius:2px}.badge-border-arrow-left-danger{border:1px solid var(--f-semantic-danger-02);position:relative;margin-left:12px}.badge-border-arrow-left-danger::after,.badge-border-arrow-left-danger::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-left-danger::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-danger-02);border-width:6px 12px 6px 0}.badge-border-arrow-left-danger::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-danger-03);border-width:5px 10px 5px 0}.badge-border-arrow-right-danger{position:relative;margin-right:12px}.badge-border-arrow-right-danger::after,.badge-border-arrow-right-danger::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-right-danger::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-danger-02);border-width:6px 0 6px 12px}.badge-border-arrow-right-danger::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-danger-03);border-width:5px 0 5px 10px}.badge-arrow-left-danger::before,.badge-arrow-right-danger::before{margin-top:-8px;border-top:8px solid transparent;border-bottom:8px solid transparent}.badge-arrow-left-danger{background:#F46160;position:relative;color:#fff;margin-left:8px}.badge-arrow-left-danger::before{content:"";position:absolute;top:50%;border-right:8px solid transparent;border-left:0 solid transparent;left:-8px;border-right-color:#F46160}.badge-arrow-right-danger{background:#F46160;position:relative;color:#fff;margin-right:8px}.badge-arrow-right-danger::before,.badge-round-outer-danger::after{position:absolute;content:"";top:50%}.badge-arrow-right-danger::before{border-left:8px solid transparent;border-right:0 solid transparent;right:-8px;border-left-color:#F46160}.badge-round-danger{width:6px;height:6px;border-radius:3px;display:inline-block!important;line-height:1;overflow:hidden;padding:0;background:#F46160}.badge-round-outer-danger{position:relative;width:14px;height:14px;display:block;background:rgba(244,97,96,.18);border-radius:7px}.badge-round-outer-danger::after{width:8px;height:8px;left:50%;margin:-4px 0 0 -4px;border-radius:4px;background:#F46160}.badge-pill-border-primary,.badge-pill-primary{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-arrow-left-primary,.badge-arrow-right-primary,.badge-pill-primary,.badge-primary,.badge-round-primary{background:var(--f-theme-03)}.badge-pill-primary,.badge-primary{color:#fff}.badge-border-arrow-left-primary,.badge-border-primary,.badge-pill-border-primary{color:var(--f-theme-03);background:var(--f-semantic-info-03)}.badge-pill-border-primary{border:1px solid var(--f-theme-03)}.badge-border-primary{padding:.125rem .4375rem;border:1px solid var(--f-theme-05);border-radius:2px}.badge-border-arrow-left-primary{border:1px solid var(--f-theme-05);position:relative;margin-left:12px}.badge-border-arrow-left-primary::after,.badge-border-arrow-left-primary::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-left-primary::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-theme-05);border-width:6px 12px 6px 0}.badge-border-arrow-left-primary::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-info-03);border-width:5px 10px 5px 0}.badge-border-arrow-right-primary{position:relative;margin-right:12px}.badge-border-arrow-right-primary::after,.badge-border-arrow-right-primary::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-round-continue,.badge-round-primary{border-radius:3px;display:inline-block!important;line-height:1;overflow:hidden}.badge-border-arrow-right-primary::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-theme-05);border-width:6px 0 6px 12px}.badge-border-arrow-right-primary::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-info-03);border-width:5px 0 5px 10px}.badge-arrow-left-primary::before,.badge-arrow-right-primary::before{margin-top:-8px;border-top:8px solid transparent;border-bottom:8px solid transparent;content:"";top:50%}.badge-arrow-left-primary{position:relative;color:#fff;margin-left:8px}.badge-arrow-left-primary::before{position:absolute;border-right:8px solid transparent;border-left:0 solid transparent;left:-8px;border-right-color:var(--f-theme-03)}.badge-arrow-right-primary{position:relative;color:#fff;margin-right:8px}.badge-arrow-right-primary::before{position:absolute;border-left:8px solid transparent;border-right:0 solid transparent;right:-8px;border-left-color:var(--f-theme-03)}.badge-round-primary{width:6px;height:6px;padding:0}.badge-round-outer-primary{position:relative;width:14px;height:14px;display:block;background:rgba(var(--f-theme-03),.18);border-radius:7px}.badge-round-outer-primary::after{content:"";width:8px;height:8px;position:absolute;top:50%;left:50%;margin:-4px 0 0 -4px;border-radius:4px;background:var(--f-theme-03)}.badge-pill-border-continue,.badge-pill-continue{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-continue,.badge-pill-continue{color:#fff;background:var(--f-semantic-submit-01)}.badge-border-arrow-left-continue,.badge-border-continue,.badge-pill-border-continue{color:var(--f-semantic-submit-01);background:var(--f-semantic-submit-03)}.badge-pill-border-continue{border:1px solid var(--f-semantic-submit-01)}.badge-border-continue{padding:.125rem .4375rem;border:1px solid var(--f-semantic-submit-02);border-radius:2px}.badge-border-arrow-left-continue{border:1px solid var(--f-semantic-submit-02);position:relative;margin-left:12px}.badge-arrow-left-continue,.badge-arrow-right-continue,.badge-round-continue{background:var(--f-semantic-submit-01)}.badge-border-arrow-left-continue::after,.badge-border-arrow-left-continue::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-left-continue::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-submit-02);border-width:6px 12px 6px 0}.badge-border-arrow-left-continue::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-submit-03);border-width:5px 10px 5px 0}.badge-border-arrow-right-continue{position:relative;margin-right:12px}.badge-border-arrow-right-continue::after,.badge-border-arrow-right-continue::before{width:0;height:0;content:"";position:absolute;top:50%;border:solid transparent}.badge-border-arrow-right-continue::before{left:-12px;z-index:2;margin-top:-6px;border-right-color:var(--f-semantic-submit-02);border-width:6px 0 6px 12px}.badge-border-arrow-right-continue::after{z-index:3;left:-10px;margin-top:-5px;border-right-color:var(--f-semantic-submit-03);border-width:5px 0 5px 10px}.badge-arrow-left-continue::before,.badge-arrow-right-continue::before{margin-top:-8px;border-top:8px solid transparent;border-bottom:8px solid transparent;content:"";top:50%}.badge-arrow-left-continue{position:relative;color:#fff;margin-left:8px}.badge-arrow-left-continue::before{position:absolute;border-right:8px solid transparent;border-left:0 solid transparent;left:-8px;border-right-color:var(--f-semantic-submit-01)}.badge-arrow-right-continue{position:relative;color:#fff;margin-right:8px}.badge-arrow-right-continue::before{position:absolute;border-left:8px solid transparent;border-right:0 solid transparent;right:-8px;border-left-color:var(--f-semantic-submit-01)}.badge-round-continue{width:6px;height:6px;padding:0}.badge-round-outer-continue{position:relative;width:14px;height:14px;display:block;background:rgba(var(--f-semantic-submit-01),.18);border-radius:7px}.badge-round-outer-continue::after{content:"";width:8px;height:8px;position:absolute;top:50%;left:50%;margin:-4px 0 0 -4px;border-radius:4px;background:var(--f-semantic-submit-01)}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:6px}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:6px;border-top-right-radius:6px}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:6px;border-bottom-left-radius:6px}.card-body{flex-grow:1;flex-shrink:1;flex-basis:auto;padding:1.25rem}.card-footer,.card-header{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03)}.card-title{margin-bottom:.75rem}.card-header,.card-subtitle,.card-text:last-child{margin-bottom:0}.card-subtitle{margin-top:-.375rem}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header-pills,.card-header-tabs{margin-right:-.625rem;margin-left:-.625rem}.card-header{border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(6px - 1px) calc(6px - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(6px - 1px) calc(6px - 1px)}.card-header-tabs{margin-bottom:-.75rem;border-bottom:0}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(6px - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(6px - 1px);border-top-right-radius:calc(6px - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(6px - 1px);border-bottom-left-radius:calc(6px - 1px)}.card-deck{display:flex;flex-direction:column}.card-deck .card{margin-bottom:14px}@media (min-width:576px){.card-deck{flex-flow:row wrap;margin-right:-14px;margin-left:-14px}.card-deck .card{display:flex;flex-grow:1;flex-shrink:0;flex-basis:0%;flex-direction:column;margin-right:14px;margin-bottom:0;margin-left:14px}}.card-group{display:flex;flex-direction:column}.card-group>.card{margin-bottom:14px}@media (min-width:576px){.card-group{flex-flow:row wrap}.card-group>.card{flex-grow:1;flex-shrink:0;flex-basis:0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:6px}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:6px;border-top-right-radius:6px}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:6px;border-bottom-left-radius:6px}.card-group>.card:not(:first-child):not(:last-child):not(:only-child),.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}.card-columns{-moz-column-count:3;column-count:3;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.card-columns .card{margin-bottom:.75rem}.accordion .card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion .card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion .card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion .card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.f-form-is-table{box-shadow:0 2px 10px 0 rgba(0,0,0,.04)}.table.table-bordered.f-table-has-form td:first-child{border-left:unset}.table.table-bordered.f-table-has-form td:last-child{border-right:unset}.table.table-bordered.f-table-has-form>:first-child td{border-top:unset}.f-table-has-form{overflow:hidden;box-shadow:0 0 0 1px var(--f-neutral-07);border-radius:10px;margin:0}.f-table-has-form td{padding:0;height:43px;border:1px solid var(--f-neutral-07)}.f-table-has-form .farris-group-wrap--label{padding:.75rem 1rem;width:124px}.f-table-has-form .farris-group-wrap--label .farris-label-wrap{height:100%}.f-table-has-form .farris-group-wrap--label .form-group--has-tips{display:flex}.f-table-has-form .farris-group-wrap--label .form-group--has-tips .farris-label-tips{position:relative;bottom:auto;margin:1px 0 0 4px;flex-shrink:0}.f-table-has-form .farris-group-wrap--label .form-group--has-tips .col-form-label{flex:1 1 0}.f-table-has-form .farris-group-wrap--label .col-form-label{display:flex;margin:0;align-items:center;flex-shrink:0;justify-content:flex-end!important;flex-direction:row!important;align-self:start;word-break:break-all;min-width:82px;height:100%}.f-table-has-form .farris-group-wrap--label .farris-label-text{text-align:right;white-space:pre-wrap}.f-table-has-form .farris-group-wrap--label .farris-label-info{padding:0 .25rem 0 0;flex-shrink:0;line-height:1.4286;white-space:nowrap}.f-table-has-form .farris-group-wrap--input{position:relative;overflow:initial}.f-table-has-form .farris-group-wrap--input .farris-input-wrap{height:100%}.f-table-has-form .farris-group-wrap--input .farris-input-wrap.farris-textarea-wrap{min-height:60px}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .form-control{height:100%;border:none;border-radius:0;padding-left:1rem}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .form-control.form-control-invalid,.f-table-has-form .farris-group-wrap--input .farris-input-wrap .form-control.form-control-invalid:focus{box-shadow:inset 0 0 0 1pxvar --f-semantic-danger-01}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-cmp-inputgroup,.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-component-timepicker{height:100%}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-cmp-inputgroup .input-group,.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-cmp-number-spinner .input-group,.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-component-timepicker .input-group{height:100%;border:none}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-cmp-number-spinner .input-group .btn-group-number{height:100%}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-cmp-number-spinner .input-group .btn-group-number .btn-number-flag,.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-cmp-number-spinner .input-group .btn-group-number .btn-number-flag:nth-child(2){border:none}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .f-cmp-number-spinner .number-arrow-chevron,.f-table-has-form .farris-group-wrap--input .farris-input-wrap .input-group .input-group-append.f-cmp-iconbtn-wrapper .f-cmp-iconbtn .f-icon{font-size:1rem}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .lookupbox .input-group-append .f-icon-lookup{font-size:1.125rem}.f-table-has-form .farris-group-wrap--input .farris-input-wrap farris-checkboxgroup .farris-input-wrap,.f-table-has-form .farris-group-wrap--input .farris-input-wrap farris-radiogroup .farris-input-wrap{padding:.75rem 1rem}.f-table-has-form .farris-group-wrap--input .farris-input-wrap .farris-checkradio-hor{align-items:center}.f-table-has-form .farris-group-wrap--input .farris-html-editor{border:none}.f-table-has-form .farris-group-wrap--input .farris-html-editor-border .ql-container.ql-disabled{border:none!important;padding:.75rem 1rem}.f-table-has-form .farris-group-wrap--input .farris-switch-outlayer{height:100%;display:flex;align-items:center;margin-left:1rem}.f-table-has-form .farris-group-wrap--input>.farris-input-wrap>.custom-control{height:100%;display:flex;align-items:center;padding:.75rem 1rem}.f-table-has-form .farris-group-wrap--input .f-component-text{height:100%;display:flex;align-items:center}.f-table-has-form .farris-group-wrap--input .f-component-text .f-form-control-text,.f-table-has-form .farris-group-wrap--input .f-component-text .f-form-control-textarea{border-color:transparent;padding-left:1rem}.f-table-has-form .input-group .input-group-append{padding-right:.5rem}.f-table-has-form .input-group .input-append-wrapper{padding-right:0}.f-table-has-form .input-group .input-group-append.f-cmp-iconbtn-wrapper{padding-right:.5rem}.f-table-has-form .input-group .input-group-append.f-cmp-iconbtn-wrapper .datepicker-clear{right:.5rem!important}.f-table-has-form .input-append-wrapper .input-group-text{padding-left:1rem;padding-right:1rem}.f-table-has-form .input-append-button{border-left:1px solid var(--f-neutral-07);margin-left:1px}.f-table-has-form .f-cmp-static-text-input-append .input-append-button,.f-table-has-form .f-cmp-text-input-append .input-append-button,.f-table-has-form .f-cmp-textarea-input-append .input-append-button{margin-left:0}.f-table-has-form .farris-editor .farris-editor-placeholder,.f-table-has-form .farris-editor .mce-tinymce{border:none}.f-table-has-form .farris-input-wrap .f-cmp-text-is-textarea{flex-direction:row}.f-table-has-form .farris-input-wrap .f-cmp-text-is-textarea .f-form-control-textarea{flex:1 1 0;width:100%}.f-table-has-form .farris-input-wrap .f-personnel-selector,.f-table-has-form .farris-input-wrap .f-personnel-selector .s-select-help{height:100%}.f-table-has-form .farris-input-wrap .f-personnel-selector .s-input-group{border:none!important}.f-table-has-form .farris-input-wrap .farris-tags{white-space:pre-wrap;height:100%;display:flex;align-items:center;margin-left:1rem}.f-table-has-form .farris-input-wrap .farris-tags .farris-tags-item-container{word-break:break-all;padding-left:4px}.f-table-has-form .farris-input-wrap .farris-tags .farris-tags-item-container .farris-tag-item{margin-top:4px;margin-bottom:4px;white-space:pre-wrap}@-moz-document url-prefix(){.f-table-has-form tr{height:43px}.f-table-has-form td{height:100%}} \ No newline at end of file -- Gitee From ebd505149f9bfbd7cf2440268ee5f913270ec151 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Mon, 7 Apr 2025 19:56:09 +0800 Subject: [PATCH 194/287] =?UTF-8?q?fix:=20time-picker=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/farris-theme/theme/components/time-picker.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/farris-theme/theme/components/time-picker.scss b/packages/farris-theme/theme/components/time-picker.scss index 99dc3db4a22..27cd8ea1913 100644 --- a/packages/farris-theme/theme/components/time-picker.scss +++ b/packages/farris-theme/theme/components/time-picker.scss @@ -10,15 +10,15 @@ font-feature-settings: 'tnum'; position: absolute; z-index: 9999; - + min-width: 200px; + background:$f-cmp-timepicker-bg; + .time-picker-panel-inner { position: relative; left: 0; font-size: 14px; text-align: left; list-style: none; - background:$f-cmp-timepicker-bg; - margin:$f-cmp-timepicker-panel-spacer 0 0; background-clip: padding-box; border-radius: $f-cmp-timepicker-panel-border-radius; outline: 0; @@ -91,7 +91,7 @@ } } &:last-child::after { - height: 252px; + height: 162px; display: block; content: ''; } -- Gitee From 5d8ef855b0e23e286f5121d0bdbe02aeca20bccb Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Tue, 8 Apr 2025 15:38:50 +0800 Subject: [PATCH 195/287] =?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=E5=88=97=E8=A1=A8=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../date-picker/src/date-picker.props.ts | 2 + .../src/date-time-picker.props.ts | 3 +- .../src/components/field-list.component.tsx | 58 ++ .../filter/src/compositions/use-condition.ts | 19 +- .../compositions/use-render-field-item.tsx | 41 +- .../components/filter/src/filter-panel.scss | 21 + .../src/composition/use-picker-state.ts | 4 +- .../components/picker/src/picker.props.ts | 3 +- .../components/picker/src/types/index.ts | 2 +- .../time-picker/src/time-picker.props.ts | 2 + packages/mobile-ui-vue/demos/filter/base.vue | 51 +- .../mobile-ui-vue/demos/form/control-type.vue | 8 +- packages/mobile-ui-vue/package.json | 1 - pnpm-lock.yaml | 909 ++++++++++++------ 14 files changed, 773 insertions(+), 351 deletions(-) create mode 100644 packages/mobile-ui-vue/components/filter/src/components/field-list.component.tsx 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 480357edad5..dc461348b39 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 @@ -12,6 +12,8 @@ export const datePickerProps = { ...buttonEditProps, ...datePickerPanelProps, + placeholder: { type: String, default: '请选择日期' }, + round: { type: Boolean, default: false } }; 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 1447215526d..adc8cdfc08e 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 @@ -6,7 +6,8 @@ export const DATA_TIME_PICKER_NAME = 'FmDateTimePicker'; export const dateTimePickerProps = { ...buttonEditProps, - ...dateTimePickerPanelProps + ...dateTimePickerPanelProps, + placeholder: { type: String, default: '请选择日期时间' }, }; export type DateTimePickerProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/filter/src/components/field-list.component.tsx b/packages/mobile-ui-vue/components/filter/src/components/field-list.component.tsx new file mode 100644 index 00000000000..779e4e7c1e9 --- /dev/null +++ b/packages/mobile-ui-vue/components/filter/src/components/field-list.component.tsx @@ -0,0 +1,58 @@ +import { computed, defineComponent, PropType, ref, watch } from 'vue'; +import { useBem } from '@/components/common'; +import { FILTER_PANEL_NAME } from '../filter-panel.props'; + +export default defineComponent({ + props: { + modelValue: { type: Array as PropType, default: () => [] }, + data: { type: Array as PropType>, default: () => [] }, + valueField: { type: String, default: '' }, + textField: { type: String, default: '' }, + multiSelect: { type: Boolean, default: false }, + }, + setup(props, context) { + const { emit } = context; + + const { bem } = useBem(FILTER_PANEL_NAME); + + const modelValue = ref(props.modelValue); + watch(()=>props.modelValue, ()=>{ + modelValue.value = props.modelValue; + }); + + const isSelected = (item: Record)=>{ + return modelValue.value.includes(item[props.valueField]); + }; + + const getListItemClass = (item: Record)=>{ + const classList = [bem(['field', 'list', 'item'])]; + isSelected(item) && classList.push(bem(['field', 'list', 'item'], 'selected')); + return classList; + }; + + const handleClick = (item: Record) => { + const value = item[props.valueField]; + if(props.multiSelect) { + if(!isSelected(item)) { + modelValue.value.push(value); + } else { + modelValue.value = modelValue.value.filter(el=> el !== value); + } + } else { + modelValue.value = [value]; + } + + emit('change', modelValue.value); + }; + + return () => ( +
    + {props.data.map((item: Record) => ( +
    handleClick(item)}> + {item[props.textField]} +
    + ))} +
    + ); + } +}); 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 index f820544b866..93665496197 100644 --- a/packages/mobile-ui-vue/components/filter/src/compositions/use-condition.ts +++ b/packages/mobile-ui-vue/components/filter/src/compositions/use-condition.ts @@ -37,16 +37,16 @@ export const userCondition = () => { const { code, controlType } = config; const conditions: FilterCondition[] = []; switch (controlType) { + case ControlType.Number: 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.DatePickerRange: - case ControlType.NumberRange:{ + case ControlType.NumberRange: + case ControlType.DatePickerRange:{ const { start, end } = value; const startCondition = { ...ConditionTemplate, FilterField: code, Value: start, Compare: FilterCompareType.GreaterOrEqual }; @@ -68,6 +68,19 @@ export const userCondition = () => { break; } case ControlType.List:{ + const listConditions: FilterCondition[] = []; + value.forEach((itemValue: string, index: number) => { + const condition = { + ...ConditionTemplate, + FilterField: code, + Value: itemValue, + Compare: FilterCompareType.Equal, + Relation: index === value.length - 1 ? FilterRelation.And : FilterRelation.Or + }; + listConditions.push(condition); + }); + addBrackets(listConditions); + conditions.push(...listConditions); break; } default:{ 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 2f02a322b04..4a8b2f19e66 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 @@ -1,9 +1,10 @@ +import { SetupContext } from "vue"; 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"; import DatePicker from "@/components/date-picker"; +import { ControlType, FieldConfig, FilterPanelEmits } from "./type"; +import { FILTER_PANEL_NAME } from "../filter-panel.props"; +import FieldList from '../components/field-list.component'; export const useRenderFieldItem = (filterData: Record, context: SetupContext) => { const { emit } = context; @@ -15,19 +16,23 @@ export const useRenderFieldItem = (filterData: Record, context: Set emit('change', { code, value, data: filterData }); }; - const renderInputGroup = (config: FieldConfig) =>{ + const getFieldProps = (config: FieldConfig)=>{ const { code, editor = {} } = config; - const inputProps = { + return { ...editor, modelValue: getValue(code, filterData), - onChange: (value: any) => handleChange(code, value) + onChange: (value: any) => handleChange(code, value), + onConfirm: (value: any) => handleChange(code, value), }; + }; + + const renderInputGroup = (config: FieldConfig) =>{ + const inputProps = getFieldProps(config); return ( ); }; @@ -53,12 +58,7 @@ export const useRenderFieldItem = (filterData: Record, context: Set }; const renderDatePicker = (config: FieldConfig) => { - const { code, editor = {} } = config; - const inputProps = { - ...editor, - modelValue: getValue(code, filterData), - onChange: (value: any) => handleChange(code, value) - }; + const inputProps = getFieldProps(config); return ( , context: Set ); }; + const renderList = (config: FieldConfig) =>{ + const inputProps = getFieldProps(config); + + return ( + + ); + }; + const renderFieldItem = (config: FieldConfig) => { const { controlType } = config; switch (controlType) { case ControlType.DatePicker: return renderDatePicker(config); - break; case ControlType.DatePickerRange: return renderDatePickerRange(config); - break; case ControlType.Number: return renderNumber(config); - break; case ControlType.NumberRange: return renderNumberRange(config); - break; case ControlType.List: - - break; + return renderList(config); case ControlType.RadioGroup: break; 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 ab6a6c2add6..42f4f318147 100644 --- a/packages/mobile-ui-vue/components/filter/src/filter-panel.scss +++ b/packages/mobile-ui-vue/components/filter/src/filter-panel.scss @@ -32,6 +32,27 @@ border: 1px solid #999; } } + @include e(list, true) { + display: flex; + flex-wrap: wrap; + margin: 0 -5px; + @include e(item, true){ + height: 30px; + width: 89px; + font-size: 13px; + text-align: center; + overflow: hidden; + padding: 6px 8px; + margin: 0 5px 10px 5px; + background: var(--fm-background); + border-radius: var(--fm-radius-md); + color: var(--fm-primary-color); + @include m(selected) { + background: var(--fm-primary-color); + color: var(--fm-background-white); + } + } + } .fm-input-group .fm-input-group__body{ padding: 6px 8px; 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 a444eb15cb0..77ce6775416 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 @@ -17,7 +17,9 @@ export const usePickerInputState = ( }; onMounted(() => { - updateInputValue(); + if((props as any).modelValue) { + updateInputValue(); + } }); const handleConfirm = (value: any[]) => { 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 e334441619b..bdc2394985d 100644 --- a/packages/mobile-ui-vue/components/picker/src/picker.props.ts +++ b/packages/mobile-ui-vue/components/picker/src/picker.props.ts @@ -10,7 +10,8 @@ export const PICKER_NAME = 'FmPicker'; export const pickerProps = { ...buttonEditProps, - ...pickerPanelProps + ...pickerPanelProps, + placeholder: { type: String, default: '请选择' }, }; export type PickerProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/picker/src/types/index.ts b/packages/mobile-ui-vue/components/picker/src/types/index.ts index b42d6b7d200..a786d0d5bc8 100644 --- a/packages/mobile-ui-vue/components/picker/src/types/index.ts +++ b/packages/mobile-ui-vue/components/picker/src/types/index.ts @@ -22,7 +22,7 @@ export interface UsePickerState { export interface UseColumns { columns: ComputedRef; - getPickeds: () => ColumnItem[]; + getPickeds: () => (ValueType | ColumnItem)[]; getValue: () => ValueType[]; getTextValue: () => string; setDefaultValue: () => void; 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 3dd704548b2..8a0685e246d 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 @@ -7,6 +7,8 @@ export const TIME_PICKER_NAME = 'FmTimePicker'; export const timePickerProps = { ...buttonEditProps, ...timePickerPanelProps, + + placeholder: { type: String, default: '请选择时间' }, round: { type: Boolean, default: false } }; diff --git a/packages/mobile-ui-vue/demos/filter/base.vue b/packages/mobile-ui-vue/demos/filter/base.vue index 66a3c78232c..ea954bcae6b 100644 --- a/packages/mobile-ui-vue/demos/filter/base.vue +++ b/packages/mobile-ui-vue/demos/filter/base.vue @@ -1,9 +1,9 @@ diff --git a/packages/mobile-ui-vue/demos/date-picker/formatter.vue b/packages/mobile-ui-vue/demos/date-picker/formatter.vue index 7d37a997b2a..3a5b6ab8763 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/min-max.vue b/packages/mobile-ui-vue/demos/date-picker/min-max.vue index bccee245541..1786b1943e8 100644 --- a/packages/mobile-ui-vue/demos/date-picker/min-max.vue +++ b/packages/mobile-ui-vue/demos/date-picker/min-max.vue @@ -7,5 +7,5 @@ diff --git a/packages/mobile-ui-vue/demos/date-picker/type.vue b/packages/mobile-ui-vue/demos/date-picker/type.vue index 6a453c35487..f2a95012193 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 58ba9b637e7..915b2b0ebcb 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 f0fba9ab5b0..d95f9652094 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/date-time-picker/max&min.vue b/packages/mobile-ui-vue/demos/date-time-picker/max&min.vue index 9e55e861af6..2ed704b7d12 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 @@ -2,7 +2,7 @@ diff --git a/packages/mobile-ui-vue/demos/dialog/avatar.vue b/packages/mobile-ui-vue/demos/dialog/avatar.vue index f370355d899..85086ba515a 100644 --- a/packages/mobile-ui-vue/demos/dialog/avatar.vue +++ b/packages/mobile-ui-vue/demos/dialog/avatar.vue @@ -15,7 +15,7 @@ diff --git a/packages/mobile-ui-vue/demos/popup/position.vue b/packages/mobile-ui-vue/demos/popup/position.vue index 44966d393d2..850bbf2408d 100644 --- a/packages/mobile-ui-vue/demos/popup/position.vue +++ b/packages/mobile-ui-vue/demos/popup/position.vue @@ -12,7 +12,7 @@ diff --git a/packages/mobile-ui-vue/demos/time-picker/formatter.vue b/packages/mobile-ui-vue/demos/time-picker/formatter.vue index fb6ca76dff8..5094810c943 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/min-max.vue b/packages/mobile-ui-vue/demos/time-picker/min-max.vue index 6e246d61221..c9dc489bff9 100644 --- a/packages/mobile-ui-vue/demos/time-picker/min-max.vue +++ b/packages/mobile-ui-vue/demos/time-picker/min-max.vue @@ -6,5 +6,5 @@ > diff --git a/packages/mobile-ui-vue/demos/time-picker/type.vue b/packages/mobile-ui-vue/demos/time-picker/type.vue index d7de10908d6..8683ef1ade3 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 @@ diff --git a/packages/mobile-ui-vue/farris.config.mjs b/packages/mobile-ui-vue/farris.config.mjs index 7c008eaa28b..64fd25fb984 100644 --- a/packages/mobile-ui-vue/farris.config.mjs +++ b/packages/mobile-ui-vue/farris.config.mjs @@ -2,7 +2,7 @@ import { fileURLToPath, URL } from 'node:url'; const { BUILD_TYPE } = process.env; const outDir = BUILD_TYPE === 'app' ? "dist" : 'package'; -const externals = [BUILD_TYPE === 'components' ? "@components" : '']; +const externals = [BUILD_TYPE === 'components' ? "@farris/mobile-ui-vue" : '']; const externalDependencies = BUILD_TYPE !== 'app'; export default { @@ -35,7 +35,6 @@ export default { target: 'es2015', alias: [ { find: '@', replacement: fileURLToPath(new URL('./', import.meta.url)) }, - { find: '@components', replacement: fileURLToPath(new URL('./components', import.meta.url)) }, { find: '@farris/mobile-ui-vue', replacement: fileURLToPath(new URL('./components', import.meta.url)) } ] }; diff --git a/packages/mobile-ui-vue/src/components/demo-block/demo-block.component.tsx b/packages/mobile-ui-vue/src/components/demo-block/demo-block.component.tsx index 9c7c18aafb0..a2261b62bb1 100644 --- a/packages/mobile-ui-vue/src/components/demo-block/demo-block.component.tsx +++ b/packages/mobile-ui-vue/src/components/demo-block/demo-block.component.tsx @@ -1,5 +1,5 @@ import { defineComponent, SetupContext, computed, ref } from 'vue'; -import { useBem } from '@components/common'; +import { useBem } from '@farris/mobile-ui-vue/common'; export default defineComponent({ name: 'FmDemoBlock', diff --git a/packages/mobile-ui-vue/src/components/demo-tabs/demo-tab.component.tsx b/packages/mobile-ui-vue/src/components/demo-tabs/demo-tab.component.tsx index b6525078a14..e705a8e089a 100644 --- a/packages/mobile-ui-vue/src/components/demo-tabs/demo-tab.component.tsx +++ b/packages/mobile-ui-vue/src/components/demo-tabs/demo-tab.component.tsx @@ -1,5 +1,5 @@ import { computed, defineComponent, SetupContext } from 'vue'; -import { useBem } from '@components/common'; +import { useBem } from '@farris/mobile-ui-vue/common'; export default defineComponent({ name: 'FmDemoTab', diff --git a/packages/mobile-ui-vue/src/components/demo-tabs/demo-tabs.component.tsx b/packages/mobile-ui-vue/src/components/demo-tabs/demo-tabs.component.tsx index 0a81300170b..d87b3a73933 100644 --- a/packages/mobile-ui-vue/src/components/demo-tabs/demo-tabs.component.tsx +++ b/packages/mobile-ui-vue/src/components/demo-tabs/demo-tabs.component.tsx @@ -1,6 +1,6 @@ /* eslint-disable no-use-before-define */ import { defineComponent, SetupContext, VNode, ref, h, onActivated, onMounted, nextTick } from 'vue'; -import { inBrowser, useBem } from '@components/common'; +import { inBrowser, useBem } from '@farris/mobile-ui-vue/common'; import DemoTab from './demo-tab.component'; export default defineComponent({ diff --git a/packages/mobile-ui-vue/src/main.ts b/packages/mobile-ui-vue/src/main.ts index 8416fb56241..c8c1404abf9 100644 --- a/packages/mobile-ui-vue/src/main.ts +++ b/packages/mobile-ui-vue/src/main.ts @@ -5,7 +5,7 @@ import router from './router'; import FarrisMobile from '@farris/mobile-ui-vue'; import FarrisMobileDemo from './components'; -import '@components/index.scss'; +import '@farris/mobile-ui-vue/index.scss'; /* -------------------------------- 临时的外部依赖 - 开始 -------------------------------- */ // @todo 临时引入的外部依赖,待其独立后统一移除 diff --git a/packages/mobile-ui-vue/tsconfig.json b/packages/mobile-ui-vue/tsconfig.json index 89d2e46d2ba..8d6f077f48a 100644 --- a/packages/mobile-ui-vue/tsconfig.json +++ b/packages/mobile-ui-vue/tsconfig.json @@ -37,11 +37,11 @@ "@/*": [ "./*" ], - "@components/*": [ - "./components/*" - ], "@farris/mobile-ui-vue": [ "./components" + ], + "@farris/mobile-ui-vue/*": [ + "./components/*" ] } }, -- Gitee From f82ce23722a8e37ffd99a3084f84acb6ed7395a5 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Wed, 9 Apr 2025 17:13:11 +0800 Subject: [PATCH 202/287] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/compositions/use-click-away/index.ts | 5 ---- .../src/compositions/use-expose/index.ts | 2 +- .../src/compositions/use-lay-render/index.ts | 4 ++-- .../common/src/utils/src/dom/event.ts | 23 ------------------- 4 files changed, 3 insertions(+), 31 deletions(-) diff --git a/packages/mobile-ui-vue/components/common/src/compositions/use-click-away/index.ts b/packages/mobile-ui-vue/components/common/src/compositions/use-click-away/index.ts index 6f8688c47aa..cc58ca6230e 100644 --- a/packages/mobile-ui-vue/components/common/src/compositions/use-click-away/index.ts +++ b/packages/mobile-ui-vue/components/common/src/compositions/use-click-away/index.ts @@ -1,6 +1,5 @@ import { Ref, unref } from 'vue'; import { useEventListener } from '../use-event-listener'; -import { inBrowser, initNodePath } from '../../utils'; export type ClickAwayOptions = { eventName?: string @@ -12,10 +11,6 @@ export function useClickAway( listener: EventListener, options: ClickAwayOptions = {}, ) { - if (!inBrowser) { - return; - } - const { eventName = 'click', active = true } = options; const isOutsideElement = (event: Event)=>{ diff --git a/packages/mobile-ui-vue/components/common/src/compositions/use-expose/index.ts b/packages/mobile-ui-vue/components/common/src/compositions/use-expose/index.ts index 3a06d4ac461..c555f0c8550 100644 --- a/packages/mobile-ui-vue/components/common/src/compositions/use-expose/index.ts +++ b/packages/mobile-ui-vue/components/common/src/compositions/use-expose/index.ts @@ -3,7 +3,7 @@ import { getCurrentInstance } from 'vue'; // expose public api export function useExpose(apis: Record) { const instance = getCurrentInstance(); - if (instance) { + if (instance && instance.proxy) { Object.assign(instance.proxy, apis); } } diff --git a/packages/mobile-ui-vue/components/common/src/compositions/use-lay-render/index.ts b/packages/mobile-ui-vue/components/common/src/compositions/use-lay-render/index.ts index 992df2d45b2..0a8ce6baf78 100644 --- a/packages/mobile-ui-vue/components/common/src/compositions/use-lay-render/index.ts +++ b/packages/mobile-ui-vue/components/common/src/compositions/use-lay-render/index.ts @@ -1,4 +1,4 @@ -import { ref, watch, WatchSource } from 'vue'; +import { ref, VNode, watch, WatchSource } from 'vue'; export function useLazyRender(show: WatchSource) { const inited = ref(false); @@ -13,5 +13,5 @@ export function useLazyRender(show: WatchSource) { { immediate: true } ); - return (render: () => JSX.Element) => () => (inited.value ? render() : null); + return (render: () => VNode) => () => (inited.value ? render() : null); } diff --git a/packages/mobile-ui-vue/components/common/src/utils/src/dom/event.ts b/packages/mobile-ui-vue/components/common/src/utils/src/dom/event.ts index 4bd7afe82ec..07e07fc6add 100644 --- a/packages/mobile-ui-vue/components/common/src/utils/src/dom/event.ts +++ b/packages/mobile-ui-vue/components/common/src/utils/src/dom/event.ts @@ -12,26 +12,3 @@ export function preventDefault(event: Event, isStopPropagation?: boolean) { stopPropagation(event); } } - -export function trigger(target: Element, type: string) { - const inputEvent = document.createEvent('HTMLEvents'); - inputEvent.initEvent(type, true, true); - target.dispatchEvent(inputEvent); -} - -// ios event没有path属性 -export const initNodePath = (event: Event) => { - const path: any[] = []; - let currentElem: any = event.target; - while (currentElem) { - path.push(currentElem); - currentElem = currentElem.parentElement; - } - if (path.indexOf(window) === -1 && path.indexOf(document) === -1) { - path.push(document); - } - if (path.indexOf(window) === -1) { - path.push(window); - } - return path; -}; -- Gitee From 96d7e4b1fb8062d131be15703df953b9e01c4c53 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Wed, 9 Apr 2025 19:10:22 +0800 Subject: [PATCH 203/287] =?UTF-8?q?fix:=20=E8=B0=83=E9=80=9A=E5=9F=BA?= =?UTF-8?q?=E4=BA=8E=E6=96=B0=E7=89=88=E8=A1=A8=E5=8D=95=E5=90=91=E5=AF=BC?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E5=87=BA=E6=9D=A5=E7=9A=84=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=8D=A1=E7=89=87=E6=A8=A1=E6=9D=BF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/mobile-render/src/main.ts | 11 ++++- .../component-converters/input-converter.ts | 4 +- .../listview-converter.ts | 6 +-- .../component-normalizer-factory.ts | 6 +-- ...normalizer.ts => form-group-normalizer.ts} | 6 +-- .../metadata/form/normalizers/index.ts | 2 +- .../mobile-render/src/utils/format-utils.ts | 40 +++++++++++++++++++ packages/mobile-render/src/utils/index.ts | 1 + .../src/views/page/dynamic-view-context.ts | 6 +-- .../components/form-item/index.ts | 10 ++--- .../src/schema/form-item.schema.json | 27 +++++++++---- 11 files changed, 89 insertions(+), 30 deletions(-) rename packages/mobile-render/src/services/metadata/form/normalizers/{form-item-normalizer.ts => form-group-normalizer.ts} (86%) create mode 100644 packages/mobile-render/src/utils/format-utils.ts diff --git a/packages/mobile-render/src/main.ts b/packages/mobile-render/src/main.ts index 660dfba3808..1f03eb36d91 100644 --- a/packages/mobile-render/src/main.ts +++ b/packages/mobile-render/src/main.ts @@ -1,18 +1,20 @@ import '@components/index.scss'; import './assets/main.scss'; -import { createApp } from 'vue'; +import { createApp, App as AppInstance } 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 { formatUtils } from './utils'; import App from './app.vue'; import router from './router'; import { checkFormRoute, addFormRoute } from './router/use-form-routes'; + // devkit export const devkitProviders: StaticProvider[] = [ ...befRootProviders, @@ -23,10 +25,15 @@ const devkit = createDevkit({ providers: [...devkitProviders] }); +const devkitPlugin = (app: AppInstance) => { + devkit.install(app); + app.config.globalProperties.$formatUtils = formatUtils; +}; + // 创建App const app = createApp(App); app.use(router); -app.use(devkit); +app.use(devkitPlugin); app.use(MobileUI); // 注册组件 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 180bc5e7ac2..4a264d58c8c 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 @@ -22,8 +22,8 @@ class InputConverter extends ComponentConverter { delete input[propName]; }); - input.id = originInput.id + '-form-item'; - input.type = 'form-item'; + input.id = originInput.id + '-form-group'; + input.type = 'form-group'; input.label = originInput.title; input.binding = originInput.binding; input.editor = { 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 index 53714265810..0a5b3f787c4 100644 --- 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 @@ -35,13 +35,13 @@ class ListViewConverter extends ComponentConverter { * 转换行模板 */ public convertContentTemplate(listview: any) { - let { contentTemplate } = listview; + const { contentTemplate } = listview; delete listview.contentTemplate; const regex = /props\.item/g; - contentTemplate = contentTemplate.replace(regex, 'item'); + const itemTemplate = contentTemplate.replace(regex, 'item'); - listview.itemTemplate = contentTemplate; + listview.itemTemplate = itemTemplate; } /** 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 index 412077695a9..07da819805a 100644 --- 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 @@ -1,7 +1,7 @@ import { FormMetadataQuery } from '../form-metadata-query'; import { ComponentNormalizer } from './component-normalizer'; import { ListviewNormalizer } from './listview-normalizer'; -import { FormItemNormalizer } from './form-item-normalizer'; +import { FormGroupNormalizer } from './form-group-normalizer'; import { ButtonGroupNormalizer } from './button-group-normalizer'; @@ -39,8 +39,8 @@ class ComponentNormalizerFactory { let componentNormalizer; if (componentType === 'list-view') { componentNormalizer = new ListviewNormalizer(this.formMetadataQuery); - } else if (componentType === 'form-item') { - componentNormalizer = new FormItemNormalizer(this.formMetadataQuery); + } else if (componentType === 'form-group') { + componentNormalizer = new FormGroupNormalizer(this.formMetadataQuery); } else if (componentType === 'button-group') { componentNormalizer = new ButtonGroupNormalizer(this.formMetadataQuery); } else { 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-group-normalizer.ts similarity index 86% rename from packages/mobile-render/src/services/metadata/form/normalizers/form-item-normalizer.ts rename to packages/mobile-render/src/services/metadata/form/normalizers/form-group-normalizer.ts index e4db3a7a3ab..a4510594adf 100644 --- a/packages/mobile-render/src/services/metadata/form/normalizers/form-item-normalizer.ts +++ b/packages/mobile-render/src/services/metadata/form/normalizers/form-group-normalizer.ts @@ -2,9 +2,9 @@ import { schemaMap } from '@farris/mobile-ui-vue'; import { ComponentNormalizer } from './component-normalizer'; /** - * FormItem标准化器 + * FormGroup标准化器 */ -class FormItemNormalizer extends ComponentNormalizer { +class FormGroupNormalizer extends ComponentNormalizer { /** * 标准化组件 @@ -25,4 +25,4 @@ class FormItemNormalizer extends ComponentNormalizer { } } -export { FormItemNormalizer }; +export { FormGroupNormalizer }; diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/index.ts b/packages/mobile-render/src/services/metadata/form/normalizers/index.ts index e7eb5186602..ba6f3cd6989 100644 --- a/packages/mobile-render/src/services/metadata/form/normalizers/index.ts +++ b/packages/mobile-render/src/services/metadata/form/normalizers/index.ts @@ -1,4 +1,4 @@ export * from './component-normalizer'; export * from './listview-normalizer'; -export * from './form-item-normalizer'; +export * from './form-group-normalizer'; export * from './component-normalizer-factory'; diff --git a/packages/mobile-render/src/utils/format-utils.ts b/packages/mobile-render/src/utils/format-utils.ts new file mode 100644 index 00000000000..91e97fff54f --- /dev/null +++ b/packages/mobile-render/src/utils/format-utils.ts @@ -0,0 +1,40 @@ +const formatUtils = { + /** + * 枚举格式化 + */ + enum: function (value: boolean, options: any): any { + return value; + }, + + /** + * 日期格式化 + */ + date: function (value: boolean, options: any): any { + return value; + }, + + + /** + * 数字格式化 + */ + number: function (value: boolean, options: any): any { + return value; + }, + + /** + * 字符串格式化 + * + */ + string: function (value: boolean, options: any): any { + return value; + }, + + /** + * 布尔值格式化 + */ + bool: function (value: boolean, options: any): any { + return value; + }, +}; + +export { formatUtils }; diff --git a/packages/mobile-render/src/utils/index.ts b/packages/mobile-render/src/utils/index.ts index ffd6e57c4b8..1524c09c298 100644 --- a/packages/mobile-render/src/utils/index.ts +++ b/packages/mobile-render/src/utils/index.ts @@ -1,4 +1,5 @@ export * from './type-util'; export * from './json-util'; export * from './string-util'; +export * from './format-utils'; diff --git a/packages/mobile-render/src/views/page/dynamic-view-context.ts b/packages/mobile-render/src/views/page/dynamic-view-context.ts index 314c1124a16..dd5ad5ab92d 100644 --- a/packages/mobile-render/src/views/page/dynamic-view-context.ts +++ b/packages/mobile-render/src/views/page/dynamic-view-context.ts @@ -21,11 +21,11 @@ export class DynamicViewContextWithViewModel extends DefaultDynamicViewContext { */ public createVNodeByTemplate(template: string, templateContext: any) { const { entityState, uiState, stateMachine } = this.viewModel.state; - const extendTemplateContext = Object.assign({ viewModel: this.viewModel, - entityState, uiState, stateMachine - + entityState, + uiState, + stateMachine }, templateContext); return super.createVNodeByTemplate(template, extendTemplateContext); diff --git a/packages/mobile-ui-vue/components/form-item/index.ts b/packages/mobile-ui-vue/components/form-item/index.ts index c52eef2821f..9257fcac6a2 100644 --- a/packages/mobile-ui-vue/components/form-item/index.ts +++ b/packages/mobile-ui-vue/components/form-item/index.ts @@ -3,7 +3,7 @@ import { propsResolver } from './src/form-item.props'; import FormItemInstallless from './src/form-item.component'; import FormItemDesign from './src/designer/form-item.design.component'; -const FORM_REGISTERED_NAME = 'form-item'; +const FORM_ITEM_REGISTERED_NAME = 'form-group'; const FormItem = withInstall(FormItemInstallless); @@ -11,16 +11,16 @@ FormItem.register = ( componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record ) => { - componentMap[FORM_REGISTERED_NAME] = FormItem; - propsResolverMap[FORM_REGISTERED_NAME] = propsResolver; + componentMap[FORM_ITEM_REGISTERED_NAME] = FormItem; + propsResolverMap[FORM_ITEM_REGISTERED_NAME] = propsResolver; }; FormItem.registerDesigner = ( componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record ) => { - componentMap[FORM_REGISTERED_NAME] = FormItemDesign; - propsResolverMap[FORM_REGISTERED_NAME] = propsResolver; + componentMap[FORM_ITEM_REGISTERED_NAME] = FormItemDesign; + propsResolverMap[FORM_ITEM_REGISTERED_NAME] = propsResolver; }; export * from './src/form-item.props'; 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 6aa73adc773..57c71e28033 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 @@ -1,7 +1,7 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://farris-design.gitee.io/form-item.schema.json", - "title": "form-item", + "title": "form-group", "description": "", "type": "object", "properties": { @@ -12,7 +12,7 @@ "type": { "description": "类型", "type": "string", - "default": "form-item" + "default": "form-group" }, "appearance": { "description": "外观", @@ -27,11 +27,24 @@ }, "default": {} }, + "visible": { + "description": "是否可见", + "type": "boolean", + "default": true + }, "label": { "description": "标签", "type": "string", "default": "" }, + "labelWidth": { + "description": "标签宽度", + "type": "number" + }, + "labelAlign": { + "description": "标签排列方式", + "type": "string" + }, "editor": { "description": "编辑器", "type": "obejct", @@ -41,17 +54,15 @@ "description": "绑定", "type": "object", "default": {} - }, - "visible": { - "description": "是否可见", - "type": "boolean", - "default": true } }, - "required": [ "id", "type", "editor" + ], + "ignore": [ + "id", + "type" ] } \ No newline at end of file -- Gitee From c600ef3181cc4e9e50bd7774ddf9c784cae54bb8 Mon Sep 17 00:00:00 2001 From: LuPing Zou <“zouluping@inspur.com”> Date: Mon, 7 Apr 2025 17:19:44 +0800 Subject: [PATCH 204/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E7=AB=AFL?= =?UTF-8?q?istView=E7=BB=84=E4=BB=B6=E9=9B=86=E6=88=90=E6=BB=91=E5=8A=A8?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E6=A0=8F=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/button-group.component.tsx | 9 +- .../button-group/src/button-group.props.ts | 9 +- .../components/list-view-item.component.tsx | 51 +++++--- .../list-view/src/composition/use-data.ts | 28 ++--- .../src/composition/use-selection.ts | 36 +++--- .../list-view/src/list-view.component.tsx | 30 ++--- .../list-view/src/list-view.props.ts | 4 + .../src/schema/list-view.schema.json | 1 - .../swipe-cell/src/composition/type.ts | 25 +--- .../swipe-cell/src/swipe-cell.component.tsx | 97 ++++++++------- .../swipe-cell/src/swipe-cell.props.ts | 1 + .../mobile-ui-vue/demos/list-view/index.vue | 4 + .../demos/list-view/swipe-cell.vue | 112 ++++++++++++++++++ .../demos/swipe-cell/async-close.vue | 4 +- .../mobile-ui-vue/demos/swipe-cell/base.vue | 6 +- 15 files changed, 283 insertions(+), 134 deletions(-) create mode 100644 packages/mobile-ui-vue/demos/list-view/swipe-cell.vue 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 index e79694a3b03..6f692a10867 100644 --- 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 @@ -40,7 +40,7 @@ export default defineComponent({ function isButtonItemPlain(buttonItem: ButtonItem): boolean { if (isDefaultMode.value) { - return buttonItem.plain; + return !!buttonItem.plain; } const shouldDefaultToPlain = props.mode === 'outline' || props.mode === 'text'; return buttonItem.plain ?? shouldDefaultToPlain; @@ -55,7 +55,7 @@ export default defineComponent({ function isButtonItemNoBorder(buttonItem: ButtonItem): boolean { if (isDefaultMode.value) { - return buttonItem.noBorder; + return !!buttonItem.noBorder; } return props.mode === 'text'; } @@ -65,6 +65,7 @@ export default defineComponent({ [bem('item')]: true, [bem('item', 'bare-vertical')]: buttonItem.variant === 'bare-vertical', [bem('item', 'disabled')]: isButtonItemDisabled(buttonItem), + [buttonItem.customClass ?? '']: typeof buttonItem.customClass === 'string' && buttonItem.customClass, }; }; @@ -79,7 +80,9 @@ export default defineComponent({ function renderDefaultButton(buttonItem: ButtonItem) { return ( onButtonItemClick(buttonItem)} > {buttonItem.icon && } 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 index 1c053e9fc56..b81fbbb39b6 100644 --- 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 @@ -9,12 +9,15 @@ export const BUTTON_GROUP_NAME = 'fm-button-group'; export type ButtonGroupMode = 'default' | 'group' | 'outline' | 'text'; export type ButtonItemVariant = 'default' | 'bare-vertical'; -export type ButtonItem = ButtonProps & { +export type ButtonItem = Partial void; -}; + customClass: string; + customStyle: string; + onClick: (eventParam?: any) => void; +}>; export const buttonGroupProps = { diff --git a/packages/mobile-ui-vue/components/list-view/src/components/list-view-item.component.tsx b/packages/mobile-ui-vue/components/list-view/src/components/list-view-item.component.tsx index 25e7b6a3891..5befcc70bd7 100644 --- a/packages/mobile-ui-vue/components/list-view/src/components/list-view-item.component.tsx +++ b/packages/mobile-ui-vue/components/list-view/src/components/list-view-item.component.tsx @@ -1,4 +1,5 @@ -import { SetupContext, toRefs } from "vue"; +import { computed, SetupContext, toRefs } from "vue"; +import { SwipeCell } from '@components/swipe-cell'; import { LIST_VIEW_NAME, ListViewProps } from '../list-view.props'; import { UseData, UseSelection } from '../composition/types'; import { useBem } from '@components/common'; @@ -18,16 +19,20 @@ export default function ( const { isMultiSelectMode, isItemSelected, toggleSelectItem } = useSelectionComposition; const { checkboxProps } = toRefs(props); + const shouldRenderSwipeCell = computed(() => { + return Array.isArray(props.swipeToolbar) && props.swipeToolbar.length > 0; + }); + const shouldDisableSwipeCell = computed(() => isMultiSelectMode.value); - const onListItemClick = (item: any, index: number) => { + function onListItemClick(item: any, index: number): void { emit('clickItem', { data: item, index }); - }; + } - const onCheckboxClick = (evt: MouseEvent) => { - evt && evt.stopPropagation(); - }; + function onCheckboxClick(event: MouseEvent): void { + event && event.stopPropagation(); + } - const renderCheckbox = (item: any) => { + function renderCheckbox(item: any) { return ( ); - }; + } - const renderItemContent = (item: any, index: number, disabled: boolean) => { + function renderItemContent(item: any, index: number, disabled: boolean) { if (slots.item) { return slots.item({ item, index, disabled }); } return (
    {getItemText(item)}
    ); - }; + } - const renderSingleItem = (item: any, index: number, isChildItem?: boolean, parentItemIndex?: number) => { + function renderSwipeCell(item: any, index: number, disabled: boolean) { + if (!shouldRenderSwipeCell.value) { + return renderItemContent(item, index, disabled); + } + return ( + + {renderItemContent(item, index, disabled)} + + ); + } + + function renderSingleItem(item: any, index: number, isChildItem?: boolean, parentItemIndex?: number) { const itemClass = { [bem('item')]: true, [bem('item', 'child')]: isChildItem, @@ -59,20 +78,20 @@ export default function ( const rootItemIndex = isChildItem ? parentItemIndex : index; return ( -
    onListItemClick(item, rootItemIndex)}> +
    onListItemClick(item, rootItemIndex!)}> {isMultiSelectMode.value && (
    {shouldShowCheckbox && renderCheckbox(item)}
    )}
    - {renderItemContent(item, index, shouldDisableItem)} + {renderSwipeCell(item, index, shouldDisableItem)}
    ); - }; + } - const renderItem = (item: any, index: number) => { + function renderItem(item: any, index: number): void { const children = getItemChildren(item); const hasChildren = children.length > 0; @@ -90,7 +109,7 @@ export default function (
    ); - }; + } return { renderItem }; } diff --git a/packages/mobile-ui-vue/components/list-view/src/composition/use-data.ts b/packages/mobile-ui-vue/components/list-view/src/composition/use-data.ts index a2fbc44a41d..89d58e42e26 100644 --- a/packages/mobile-ui-vue/components/list-view/src/composition/use-data.ts +++ b/packages/mobile-ui-vue/components/list-view/src/composition/use-data.ts @@ -1,22 +1,22 @@ -import { SetupContext, computed } from 'vue'; +import { computed } from 'vue'; import { ListViewProps } from '../list-view.props'; import { UseData } from './types'; -export function useData(props: ListViewProps, _context: SetupContext): UseData { +export function useData(props: ListViewProps): UseData { - const getFieldPathArr = (fullPath: string): string[] => { + function getFieldPathArr(fullPath: string): string[] { if (!fullPath || typeof fullPath !== 'string') { return []; } return fullPath.split('.').filter(path => !!path); - }; + } const idFieldPathArr = computed(() => getFieldPathArr(props.idField)); const textFieldPathArr = computed(() => getFieldPathArr(props.textField)); const disableFieldPathArr = computed(() => getFieldPathArr(props.disableField)); const childFieldPathArr = computed(() => getFieldPathArr(props.childField)); - const getFieldByPathArr = (object: any, fieldPathArr: string[]): any => { + function getFieldByPathArr(object: any, fieldPathArr: string[]): any { if (!object || !fieldPathArr || !fieldPathArr.length) { return undefined; } @@ -24,9 +24,9 @@ export function useData(props: ListViewProps, _context: SetupContext): UseData { return currentObject ? currentObject[path] : currentObject; }, object); return fieldValue; - }; + } - const setFieldByPathArr = (object: any, fieldPathArr: string[], value: any): any => { + function setFieldByPathArr(object: any, fieldPathArr: string[], value: any): any { if (!object || !fieldPathArr || !fieldPathArr.length) { return object; } @@ -42,25 +42,25 @@ export function useData(props: ListViewProps, _context: SetupContext): UseData { } } return object; - }; + } - const getItemID = (item: any): any => { + function getItemID(item: any): any { return getFieldByPathArr(item, idFieldPathArr.value); - }; + } - const getItemText = (item: any): any => { + function getItemText(item: any): any { return getFieldByPathArr(item, textFieldPathArr.value) || ''; - }; + } const isItemDisabled = (item: any): boolean => { return !!getFieldByPathArr(item, disableFieldPathArr.value); }; - const getItemChildren = (item: any): any[] => { + function getItemChildren(item: any): any[] { const children = getFieldByPathArr(item, childFieldPathArr.value); const isChildrenValid = Array.isArray(children); return isChildrenValid ? children : []; - }; + } const listItems = computed(() => { const originalItems = props.data || []; diff --git a/packages/mobile-ui-vue/components/list-view/src/composition/use-selection.ts b/packages/mobile-ui-vue/components/list-view/src/composition/use-selection.ts index eb97d25f80f..79376bc17c7 100644 --- a/packages/mobile-ui-vue/components/list-view/src/composition/use-selection.ts +++ b/packages/mobile-ui-vue/components/list-view/src/composition/use-selection.ts @@ -15,13 +15,13 @@ export function useSelection( return props.enableMultiSelect && props.multiSelect; }); - const toggleMultiSelect = (value: boolean) => { + function toggleMultiSelect(value: boolean): void { emit('update:multiSelect', value); - }; + } const { listItems, getItemID, getItemChildren } = useDataCompostion; - const getId2ItemMap = () => { + function getId2ItemMap(): Map { const id2Item = new Map(); listItems.value.forEach((item) => { id2Item.set(getItemID(item), item); @@ -33,9 +33,9 @@ export function useSelection( }); }); return id2Item; - }; + } - const getItemsFromIDs = (ids: string[]): any[] => { + function getItemsFromIDs(ids: string[]): any[] { const items: any[] = []; const id2Item = getId2ItemMap(); ids.forEach((id) => { @@ -46,7 +46,7 @@ export function useSelection( targetItem && items.push(targetItem); }); return items; - }; + } const selectedItems: Ref = ref(getItemsFromIDs(props.selectedValues)); @@ -54,27 +54,27 @@ export function useSelection( selectedItems.value = ref(getItemsFromIDs(newValues)).value; }); - const getItemIndexFromSelectedItems = (item: any): number => { + function getItemIndexFromSelectedItems(item: any): number { const targetID = getItemID(item); if (!isDef(targetID)) { return -1; } return selectedItems.value.findIndex(i => getItemID(i) === targetID); - }; + } - const isItemSelected = (item: any) => { + function isItemSelected(item: any): boolean { return getItemIndexFromSelectedItems(item) >= 0; - }; + } - const getSelectedItems = () => { + function getSelectedItems(): any[] { return [...selectedItems.value]; - }; + } - const emitSelectionChange = () => { + function emitSelectionChange(): void { emit('selectionChange', getSelectedItems()); - }; + } - const toggleSelectItem = (item: any) => { + function toggleSelectItem(item: any): void { const targetID = getItemID(item); if (!isDef(targetID)) { return; @@ -86,12 +86,12 @@ export function useSelection( selectedItems.value.push(item); } emitSelectionChange(); - }; + } - const clearSelection = () => { + function clearSelection(): void { selectedItems.value = []; emitSelectionChange(); - }; + } return { isMultiSelectMode, diff --git a/packages/mobile-ui-vue/components/list-view/src/list-view.component.tsx b/packages/mobile-ui-vue/components/list-view/src/list-view.component.tsx index a3ec5488852..11e34782d78 100644 --- a/packages/mobile-ui-vue/components/list-view/src/list-view.component.tsx +++ b/packages/mobile-ui-vue/components/list-view/src/list-view.component.tsx @@ -44,7 +44,7 @@ export default defineComponent({ const { emit, slots, expose } = context; const listComponentRef = ref(); - const useDataComposition = useData(props, context); + const useDataComposition = useData(props); const { listItems, isEmpty } = useDataComposition; const useSelectionComposition = useSelection(props, context, useDataComposition); @@ -90,20 +90,20 @@ export default defineComponent({ return props.emptyMessage || '暂无数据'; }); - const renderEmptyTemplate = () => { + function renderEmptyTemplate() { if (slots.empty) { return slots.empty(); } return ( {emptyMessage.value} ); - }; + } - const handleListContentLongPress = () => { + function handleListContentLongPress(): void { toggleMultiSelect(true); - }; + } - const renderListContent = () => { + function renderListContent() { const listContentClass = { [bem('content')]: true, [bem('content', 'split')]: shouldShowSplitLine.value, @@ -120,9 +120,9 @@ export default defineComponent({ ]])} ); - }; + } - const renderList = () => { + function renderList() { const listSlots = { finished: slots.finished, loading: slots.loading, @@ -149,9 +149,9 @@ export default defineComponent({ {slots.default?.()} ); - }; + } - const renderListWithPullRefresh = () => { + function renderListWithPullRefresh() { if (!enablePullRefresh.value) { return renderList(); } @@ -175,9 +175,9 @@ export default defineComponent({ {renderList()} ); - }; + } - const renderToolbar = () => { + function renderToolbar() { return (
    @@ -199,11 +199,11 @@ export default defineComponent({
    ); - }; + } - const checkListNeedLoadMore = () => { + function checkListNeedLoadMore(): void { listComponentRef.value?.check(); - }; + } expose({ check: checkListNeedLoadMore, 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 229a5883e35..57f5046c75c 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 @@ -18,6 +18,7 @@ import { ExtractPropTypes, PropType } from 'vue'; import { ListProps } from '@components/list'; import { PullRefreshProps } from '@components/pull-refresh'; import { CheckboxProps } from '@components/checkbox/src/checkbox.props'; +import { SwipeCellButton } from '@components/swipe-cell'; import { createPropsResolver } from '../../dynamic-resolver'; import { schemaMapper } from './schema/schema-mapper'; import listViewSchema from './schema/list-view.schema.json'; @@ -87,6 +88,9 @@ export const listViewProps = { /** 多选状态下,勾选框的属性 */ checkboxProps: { type: Object as PropType, default: { shape: 'round' } }, + + /** 列表行的滑动工具栏按钮 */ + swipeToolbar: { type: Array, 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 0816ea49c4d..b1fdd677d49 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 @@ -47,7 +47,6 @@ "type": "string", "default": "" }, - "itemTemplate": { "description": "列表行模板", "type": "string", diff --git a/packages/mobile-ui-vue/components/swipe-cell/src/composition/type.ts b/packages/mobile-ui-vue/components/swipe-cell/src/composition/type.ts index e41b9f6c3a9..f94d637b5f6 100644 --- a/packages/mobile-ui-vue/components/swipe-cell/src/composition/type.ts +++ b/packages/mobile-ui-vue/components/swipe-cell/src/composition/type.ts @@ -1,24 +1,9 @@ -import type { VNode } from 'vue'; +import { ButtonItem } from '@components/button-group'; -export interface SwipeCellButton { - - /** 按钮文本 */ - text?: string; - - /** 图标 */ - icon?: string | VNode; - - /** 自定义类名 */ - className?: string; - - /** 自定义样式 */ - style?: string; - - /** 点击事件回调方法 */ - onClick?: (close: (() => void)) => void; - - [key: string]: any; -} +export type SwipeCellButton = Pick< + ButtonItem, + 'id' | 'text' | 'icon' | 'visible' | 'disabled' | 'customClass' | 'customStyle' | 'onClick' +>; export type SwipeCellSide = 'left' | 'right'; diff --git a/packages/mobile-ui-vue/components/swipe-cell/src/swipe-cell.component.tsx b/packages/mobile-ui-vue/components/swipe-cell/src/swipe-cell.component.tsx index 146911c40b6..ac161881568 100644 --- a/packages/mobile-ui-vue/components/swipe-cell/src/swipe-cell.component.tsx +++ b/packages/mobile-ui-vue/components/swipe-cell/src/swipe-cell.component.tsx @@ -15,7 +15,6 @@ */ import { defineComponent, - SetupContext, ref, Ref, reactive, @@ -23,6 +22,7 @@ import { h, onMounted, computed, + watch, } from 'vue'; import { SWIPE_CELL_NAME, swipeCellProps, SwipeCellProps } from './swipe-cell.props'; import { @@ -43,7 +43,7 @@ export default defineComponent({ emits: ['click', 'open', 'close'], - setup(props: SwipeCellProps, context: SetupContext) { + setup(props: SwipeCellProps, context) { const { bem } = useBem(SWIPE_CELL_NAME); const { emit, slots, expose } = context; @@ -71,33 +71,33 @@ export default defineComponent({ /** 滑动时禁用点击 */ const forbidClick = ref(false); - const getElementWidth = (elementRef: Ref) => { + function getElementWidth(elementRef: Ref): number { return elementRef.value ? useRect(elementRef).width : 0; - }; + } - const setSideContentWidth = () => { + function setSideContentWidth(): void { state.leftSideWidth = getElementWidth(leftSideRef); state.rightSideWidth = getElementWidth(rightSideRef); - }; + } onMounted(() => { setSideContentWidth(); }); - const keepInRange = (num: number, min: number, max: number) => { + function keepInRange(num: number, min: number, max: number): number { return Math.min(Math.max(num, min), max); - }; + } - const open = (side: SwipeCellSide) => { + function open(side: SwipeCellSide): void { state.offset = side === 'left' ? state.leftSideWidth : -state.rightSideWidth; if (!state.opened) { state.opened = true; emit('open', side); } - }; + } - const close = (clickPosition?: SwipeCellClickPosition) => { + function close(clickPosition?: SwipeCellClickPosition): void { const side: SwipeCellSide = state.offset > 0 ? 'left' : 'right'; state.offset = 0; @@ -105,9 +105,9 @@ export default defineComponent({ state.opened = false; emit('close', { side, clickPosition }); } - }; + } - const handleSwipeEnd = () => { + function handleSwipeEnd(): void { const side: SwipeCellSide = state.offset > 0 ? 'left' : 'right'; const sideWidth = side === 'left' ? state.leftSideWidth : state.rightSideWidth; const offset = Math.abs(state.offset); @@ -119,18 +119,18 @@ export default defineComponent({ } else { close(); } - }; + } - const onTouchStart = (event: TouchEvent) => { + function onTouchStart(event: TouchEvent): void { if (props.disabled) { return; } setSideContentWidth(); state.startOffset = state.offset; touch.start(event); - }; + } - const onTouchMove = (event: TouchEvent) => { + function onTouchMove(event: TouchEvent): void { if (props.disabled) { return; } @@ -149,9 +149,9 @@ export default defineComponent({ } const newOffset = state.startOffset + deltaX.value; state.offset = keepInRange(newOffset, -state.rightSideWidth, state.leftSideWidth); - }; + } - const onTouchEnd = () => { + function onTouchEnd(): void { if (!state.moving) { return; } @@ -161,15 +161,20 @@ export default defineComponent({ setTimeout(() => { forbidClick.value = false; }); - }; + } - const onClick = (position: SwipeCellClickPosition, button?: SwipeCellButton) => { - if (forbidClick.value) { + function onClick(position: SwipeCellClickPosition, button?: SwipeCellButton, event?: MouseEvent): void { + if (forbidClick.value || button?.disabled) { return; } if (button && button.onClick) { - const closeFunc = () => close(position); - button.onClick(closeFunc); + const clickEventParam = { + close: () => close(position), + position, + button, + event, + }; + button.onClick(clickEventParam); } emit('click', { position, button }); const fromSideButton = position === 'left' || position === 'right'; @@ -182,9 +187,9 @@ export default defineComponent({ ) { close(position); } - }; + } - const getClickHandler = (position: SwipeCellClickPosition, button?: SwipeCellButton) => { + function getClickHandler(position: SwipeCellClickPosition, button?: SwipeCellButton) { return (event: MouseEvent) => { if ( position === 'left' @@ -193,11 +198,11 @@ export default defineComponent({ ) { event.stopPropagation(); } - onClick(position, button); + onClick(position, button, event); }; - }; + } - const renderButtonIcon = (button: SwipeCellButton) => { + function renderButtonIcon(button: SwipeCellButton) { const { icon } = button; if (typeof icon === 'string') { return ( @@ -207,13 +212,16 @@ export default defineComponent({ if (isVNode(icon)) { return h(icon, { class: bem('icon') }); } - }; + } - const renderSideButtons = (side: SwipeCellSide, buttons: SwipeCellButton[]) => { - return buttons.map((button, index) => ( + function renderSideButtons(side: SwipeCellSide, buttons: SwipeCellButton[]) { + return buttons.filter((button) => { + return !!button.visible || button.visible === undefined; + }).map((button, index) => (
    @@ -221,9 +229,9 @@ export default defineComponent({ {button.text}
    )); - }; + } - const renderSideContent = (side: SwipeCellSide, elementRef: Ref) => { + function renderSideContent(side: SwipeCellSide, elementRef: Ref) { const sideContentSlot = slots[side]; const slotParam = { close: () => close(side) }; const sideButtons = side === 'left' ? props.leftButtons : props.rightButtons; @@ -241,19 +249,28 @@ export default defineComponent({ {!sideContentSlot && renderSideButtons(side, sideButtons)} ); - }; + } + + watch( + () => props.disabled, + () => { + if (props.disabled && state.opened) { + close(); + } + }, + ); expose({ open, close: () => close(), }); - useEventListener('touchstart', onTouchStart, { target: rootRef, passive: true }); - useEventListener('touchmove', onTouchMove, { target: rootRef }); + useEventListener('touchstart', onTouchStart as EventListener, { target: rootRef, passive: true }); + useEventListener('touchmove', onTouchMove as EventListener, { target: rootRef }); useEventListener('touchend', onTouchEnd, { target: rootRef }); useEventListener('touchcancel', onTouchEnd, { target: rootRef }); - useEventListener('click', getClickHandler('cell'), { target: rootRef }); + useEventListener('click', getClickHandler('cell') as EventListener, { target: rootRef }); useClickAway(rootRef, () => onClick('outside'), { eventName: 'touchstart' }); diff --git a/packages/mobile-ui-vue/components/swipe-cell/src/swipe-cell.props.ts b/packages/mobile-ui-vue/components/swipe-cell/src/swipe-cell.props.ts index 71d000b8ac0..b0cfafdbef3 100644 --- a/packages/mobile-ui-vue/components/swipe-cell/src/swipe-cell.props.ts +++ b/packages/mobile-ui-vue/components/swipe-cell/src/swipe-cell.props.ts @@ -49,3 +49,4 @@ export const swipeCellProps = { }; export type SwipeCellProps = ExtractPropTypes; +export type { SwipeCellButton }; diff --git a/packages/mobile-ui-vue/demos/list-view/index.vue b/packages/mobile-ui-vue/demos/list-view/index.vue index 57b2fb963c5..ae9847676d6 100644 --- a/packages/mobile-ui-vue/demos/list-view/index.vue +++ b/packages/mobile-ui-vue/demos/list-view/index.vue @@ -6,12 +6,16 @@ + + + diff --git a/packages/mobile-ui-vue/demos/list-view/swipe-cell.vue b/packages/mobile-ui-vue/demos/list-view/swipe-cell.vue new file mode 100644 index 00000000000..8bfac2dba6f --- /dev/null +++ b/packages/mobile-ui-vue/demos/list-view/swipe-cell.vue @@ -0,0 +1,112 @@ + + + + + diff --git a/packages/mobile-ui-vue/demos/swipe-cell/async-close.vue b/packages/mobile-ui-vue/demos/swipe-cell/async-close.vue index 9fef557c866..642899ee5ca 100644 --- a/packages/mobile-ui-vue/demos/swipe-cell/async-close.vue +++ b/packages/mobile-ui-vue/demos/swipe-cell/async-close.vue @@ -28,8 +28,8 @@ const handleDelete = () => { const rightSideButtons = [ { text: '删除', - style: 'background-color: #F24645', - onClick: (close: () => void) => { + customStyle: 'background-color: #F24645', + onClick: ({ close }) => { Toast({ message: '正在删除...', overlay: true, duration: 1500 }); setTimeout(() => { close(); diff --git a/packages/mobile-ui-vue/demos/swipe-cell/base.vue b/packages/mobile-ui-vue/demos/swipe-cell/base.vue index 40a1ab89688..54c40fa17bf 100644 --- a/packages/mobile-ui-vue/demos/swipe-cell/base.vue +++ b/packages/mobile-ui-vue/demos/swipe-cell/base.vue @@ -12,7 +12,7 @@ import { Toast } from '../../components/toast'; const leftSideButtons = [ { text: '选择', - style: 'background-color: #3A90FF', + customStyle: 'background-color: #3A90FF', onClick: () => { Toast({ message: '选择' }); } @@ -23,7 +23,7 @@ const rightSideButtons = [ { text: '收藏', icon: 's-star-o', - style: 'background-color: #ED7B2F', + customStyle: 'background-color: #ED7B2F', onClick: () => { Toast({ message: '收藏' }); } @@ -31,7 +31,7 @@ const rightSideButtons = [ { text: '删除', icon: h(TrashIcon), - style: 'background-color: #F24645', + customStyle: 'background-color: #F24645', onClick: () => { Toast({ message: '删除' }); } -- Gitee From c20159b7c3f77ea6c25c9c55fae0ebf8d41cc7ae Mon Sep 17 00:00:00 2001 From: LuPing Zou <“zouluping@inspur.com”> Date: Thu, 10 Apr 2025 10:30:18 +0800 Subject: [PATCH 205/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E7=AB=AFN?= =?UTF-8?q?avbar=E7=BB=84=E4=BB=B6=E6=94=AF=E6=8C=81=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/icon/src/icon.component.tsx | 23 +-- .../mobile-ui-vue/components/navbar/README.md | 28 ---- .../mobile-ui-vue/components/navbar/index.ts | 23 ++- .../src/designer/nav.design.component.tsx | 47 +++--- .../navbar/src/designer/use-designer-rules.ts | 7 +- .../navbar/src/navbar.component.tsx | 132 +++++++++++---- .../components/navbar/src/navbar.props.ts | 53 +++--- .../components/navbar/src/navbar.scss | 152 +++++++++++------- .../property-config/navbar.property-config.ts | 48 +++--- .../navbar/src/schema/navbar.schema.json | 80 ++++----- .../navbar/src/schema/schema-mapper.ts | 2 +- .../navbar/src/schema/schema-resolver.ts | 2 +- packages/mobile-ui-vue/demos/navbar/index.vue | 10 +- .../mobile-ui-vue/demos/navbar/toolbar.vue | 28 ++++ 14 files changed, 375 insertions(+), 260 deletions(-) delete mode 100644 packages/mobile-ui-vue/components/navbar/README.md create mode 100644 packages/mobile-ui-vue/demos/navbar/toolbar.vue diff --git a/packages/mobile-ui-vue/components/icon/src/icon.component.tsx b/packages/mobile-ui-vue/components/icon/src/icon.component.tsx index 98f0c4797fa..d74cb826eed 100644 --- a/packages/mobile-ui-vue/components/icon/src/icon.component.tsx +++ b/packages/mobile-ui-vue/components/icon/src/icon.component.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { defineComponent, computed, CSSProperties, ComputedRef, SetupContext } from 'vue'; +import { defineComponent, computed, CSSProperties } from 'vue'; import { addUnit } from '@components/common'; import { IconProps, iconProps } from './icon.props'; @@ -22,22 +22,25 @@ export default defineComponent({ name: 'FmIcon', props: iconProps, emits: ['click'], - setup(props: IconProps, context: SetupContext) { + setup(props: IconProps, context) { const { emit } = context; - const iconClass: ComputedRef = computed(() => { + + const iconClass = computed(() => { const { classPrefix, name } = props; return [classPrefix, name ? `${classPrefix}-${name}` : '']; }); - const iconStyle: ComputedRef = computed(() => { - return { color: props.color, 'font-size': props.size ? addUnit(props.size) : '' }; - }); + const iconStyle = computed(() => ({ + color: props.color, + 'font-size': props.size ? addUnit(props.size) : '', + })); + + function onClick(event: MouseEvent): void { + emit('click', event); + } return () => ( - emit('click', event)}> + ); } }); diff --git a/packages/mobile-ui-vue/components/navbar/README.md b/packages/mobile-ui-vue/components/navbar/README.md deleted file mode 100644 index c8d3bce2fdf..00000000000 --- a/packages/mobile-ui-vue/components/navbar/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# fm-navbar -## API - -### Props - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| title | 标题 | string | `''` | -| left-text | 左侧文案 | string | `''` | -| right-text | 右侧文案 | string | `''` | -| left-arrow | 是否显示左侧箭头 | boolean | `false` | -| border | 是否显示下边框 | boolean | `true` | -| fixed | 是否固定在顶部 | boolean | `false` | - -### Slots - -| 名称 | 说明 | -| ----- | ------------------ | -| title | 自定义标题 | -| left | 自定义左侧区域内容 | -| right | 自定义右侧区域内容 | - -### Events - -| 事件名 | 说明 | 回调参数 | -| ----------- | ------------------ | -------- | -| clickLeft | 点击左侧按钮时触发 | - | -| clickRight | 点击右侧按钮时触发 | - | \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/navbar/index.ts b/packages/mobile-ui-vue/components/navbar/index.ts index 9860ea71a68..3984a04985f 100644 --- a/packages/mobile-ui-vue/components/navbar/index.ts +++ b/packages/mobile-ui-vue/components/navbar/index.ts @@ -7,14 +7,25 @@ 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; +Navbar.register = ( + componentMap: Record, + propsResolverMap: Record, + configResolverMap: Record, + resolverMap: Record, +) => { + componentMap[NAVBAR_REGISTERED_NAME] = Navbar; + propsResolverMap[NAVBAR_REGISTERED_NAME] = propsResolver; }; -Navbar.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { - componentMap[NAVBAR_REGISTERED_NAME] = NavbarDesign; - propsResolverMap[NAVBAR_REGISTERED_NAME] = propsResolver; +Navbar.registerDesigner = ( + componentMap: Record, + propsResolverMap: Record, + configResolverMap: Record, + resolverMap: Record, +) => { + componentMap[NAVBAR_REGISTERED_NAME] = NavbarDesign; + propsResolverMap[NAVBAR_REGISTERED_NAME] = propsResolver; }; + export { Navbar }; export default Navbar; diff --git a/packages/mobile-ui-vue/components/navbar/src/designer/nav.design.component.tsx b/packages/mobile-ui-vue/components/navbar/src/designer/nav.design.component.tsx index e2a066b8b42..08f46e49e04 100644 --- a/packages/mobile-ui-vue/components/navbar/src/designer/nav.design.component.tsx +++ b/packages/mobile-ui-vue/components/navbar/src/designer/nav.design.component.tsx @@ -1,4 +1,3 @@ - /** * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. * @@ -22,30 +21,30 @@ import { useDesignerRules } from './use-designer-rules'; import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; export default defineComponent({ - name: 'FNavDesign', - props: navbarProps, - emits: ['nav'] as (string[] & ThisType) | undefined, - setup(props: NavbarProps, context: SetupContext) { - const elementRef = ref(); - const designItemContext = inject('design-item-context') as DesignerItemContext; - const designerHostService = inject('designer-host-service'); - const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); - const componentInstance = useDesignerComponent(elementRef, designItemContext,designerRulesComposition); - - onMounted(() => { - elementRef.value.componentInstance = componentInstance; - }); + name: 'FNavDesign', + props: navbarProps, + emits: ['nav'] as (string[] & ThisType) | undefined, + setup(props: NavbarProps, context: SetupContext) { + const elementRef = ref(); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerHostService = inject('designer-host-service'); + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); - context.expose(componentInstance.value); + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); - const navbarProps = computed(() => ({ - ...props, - })); + context.expose(componentInstance.value); - return () => { - return ( - - ); - }; - } + const navbarProps = computed(() => ({ + ...props, + })); + + return () => { + return ( + + ); + }; + } }); diff --git a/packages/mobile-ui-vue/components/navbar/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/navbar/src/designer/use-designer-rules.ts index 00566e382cc..240365ea981 100644 --- a/packages/mobile-ui-vue/components/navbar/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/navbar/src/designer/use-designer-rules.ts @@ -1,6 +1,6 @@ import { DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; import { DraggingResolveContext } from "@/components/designer-canvas/src/composition/types"; -import { nextTick, ref } from "vue"; +import { ref } from "vue"; import { NavBarProperty } from "../property-config/navbar.property-config"; export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { @@ -14,14 +14,13 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe const isInFixedContextRules = true; function canAccepts(draggingContext: DraggingResolveContext): boolean { - return false; } - function checkCanMoveComponent() { return true; } + function checkCanDeleteComponent() { return true; } @@ -31,7 +30,6 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe } function getStyles(): string { - // return 'border-radius: 12px'; return ' '; } @@ -47,7 +45,6 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe const { schema } = designItemContext; return componentProp.getPropertyConfig(schema); } - return { canAccepts, 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 3b0436073a5..04c1d32cfcb 100644 --- a/packages/mobile-ui-vue/components/navbar/src/navbar.component.tsx +++ b/packages/mobile-ui-vue/components/navbar/src/navbar.component.tsx @@ -13,54 +13,122 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -import { SetupContext, defineComponent } from 'vue'; +import { defineComponent, computed, ref } from 'vue'; +import { useBem } from '@components/common'; +import { Icon } from '@components/icon'; +import { Popover } from '@components/popover'; +import { ButtonItem } from '@components/button-group'; import { NAVBAR_NAME, NavbarProps, navbarProps } from './navbar.props'; export default defineComponent({ name: NAVBAR_NAME, props: navbarProps, emits: ['click-left', 'click-right'], - setup(props: NavbarProps, context: SetupContext) { + setup(props: NavbarProps, context) { + const { bem } = useBem(NAVBAR_NAME); const { emit, slots } = context; + const showToolbarPopover = ref(false); - const handlerClickLeft = (event) => { + function onLeftClick(event: MouseEvent): void { emit('click-left', event); - }; + } - const handlerClickRight = (event) => { + function onRightClick(event: MouseEvent): void { emit('click-right', event); - }; + } - const navbarClass = { - 'fm-navbar': true, - 'fm-navbar-fixed': props.fixed, - 'fm-navbar-border-bottom': props.border - }; + const navbarClass = computed(() => ({ + [bem()]: true, + [bem('', 'fixed')]: props.fixed, + [bem('', 'bottom-border')]: props.showBottomBorder, + })); - return () => ( - <> -
    - {(props.leftArrow || props.leftText) && ( -
    - {slots.left ? ( - slots.left() - ) : ( - <> - {props.leftArrow && ( - - )} - {props.leftText && {props.leftText}} - - )} + const hasToolbarItems = computed(() => { + return Array.isArray(props.toolbarItems) && props.toolbarItems.length > 0; + }); + const shouldRenderLeft = computed(() => { + return props.leftArrow || !!props.leftText || !!slots.left; + }); + const shouldRenderRight = computed(() => { + return !!props.rightText || hasToolbarItems.value || !!slots.right; + }); + + function toolbarItemClass(item: ButtonItem) { + return { + [bem('toolbar-item')]: true, + [bem('toolbar-item', 'disabled')]: item.disabled, + }; + } + + function onToolbarItemClick(item: ButtonItem): void { + if (item.disabled) { + return; + } + showToolbarPopover.value = false; + item.onClick?.(); + } + + function renderLeftContent() { + return ( +
    + {slots.left ? ( + slots.left() + ) : ( + <> + {props.leftArrow && } + {props.leftText && {props.leftText}} + + )} +
    + ); + } + + function renderToolbar() { + return ( + {{ + triggerElement: () => ( + + ), + content: () => props.toolbarItems.filter((item) => { + return item.visible || item.visible === undefined; + }).map((item) => ( +
    onToolbarItemClick(item)}> + {item.text}
    + )), + }}
    + ); + } + + function renderRightContent() { + return ( +
    + {slots.right ? ( + slots.right() + ) : ( + <> + {hasToolbarItems.value && renderToolbar()} + {!hasToolbarItems.value && {props.rightText}} + )} -
    {slots.title ? slots.title() : props.title}
    -
    - {slots.right ? slots.right() : {props.rightText}} -
    - + ); + } + + return () => ( +
    + {shouldRenderLeft.value && renderLeftContent()} +
    {slots.title ? slots.title() : props.title}
    + {shouldRenderRight.value && renderRightContent()} +
    ); } }); 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 bd3add9711b..4ac0d4fe22f 100644 --- a/packages/mobile-ui-vue/components/navbar/src/navbar.props.ts +++ b/packages/mobile-ui-vue/components/navbar/src/navbar.props.ts @@ -15,40 +15,41 @@ */ import { ExtractPropTypes } from 'vue'; import { createPropsResolver } from '../../dynamic-resolver'; +import { ButtonItem } from '@components/button-group'; 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 NAVBAR_NAME = 'fm-navbar'; export const navbarProps = { - title: { - type: String - }, - fixed: { - type: Boolean, - default: false - }, - leftText: { - type: String - }, - rightText: { - type: String - }, - leftArrow: { - type: Boolean, - default: true - }, - border: { - type: Boolean, - default: false - } + + /** 标题 */ + title: { type: String, default: '' }, + + /** 是否固定在页面顶部 */ + fixed: { type: Boolean, default: false }, + + /** 左侧的文本 */ + leftText: { type: String, default: '' }, + + /** 右侧的文本 */ + rightText: { type: String, default: '' }, + + /** 是否显示左侧的箭头图标 */ + leftArrow: { type: Boolean, default: true }, + + /** 是否在下方显示分隔线 */ + showBottomBorder: { type: Boolean, default: true }, + + /** 右侧的下拉按钮工具栏 */ + toolbarItems: { type: Array, default: [] }, }; export const propsResolver = createPropsResolver( - navbarProps, - navbarSchema, - schemaMapper, - schemaResolver + navbarProps, + navbarSchema, + schemaMapper, + schemaResolver ); export type NavbarProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/navbar/src/navbar.scss b/packages/mobile-ui-vue/components/navbar/src/navbar.scss index e0e44693bca..2d8988936d2 100644 --- a/packages/mobile-ui-vue/components/navbar/src/navbar.scss +++ b/packages/mobile-ui-vue/components/navbar/src/navbar.scss @@ -1,72 +1,104 @@ @use '../../common/src/style/mixins/index.scss' as *; :root { - --fm-navbar-background: var(--fm-background-white); - --fm-navbar-color: var(--fm-text-color); - --fm-navbar-height: 44px; - --fm-navbar-title-size: 17px; - --fm-navbar-side-size: 16px; - --fm-navbar-arrow-size: 18px; + --fm-navbar-background: var(--fm-background-white); + --fm-navbar-color: var(--fm-text-color); + --fm-navbar-height: 44px; + --fm-navbar-title-size: 17px; + --fm-navbar-side-size: 16px; + --fm-navbar-arrow-size: 16px; + --fm-navbar-toolbar-item-height: 46px; } -.fm-navbar{ - position: relative; - z-index: 9; + +.fm-navbar { + position: relative; + z-index: 9; + display: flex; + align-items: center; + line-height: 1.5; + text-align: center; + user-select: none; + height: var(--fm-navbar-height); + color: var(--fm-navbar-color); + background-color: var(--fm-navbar-background); + + &--fixed { + position: fixed; + top: 0; + left: 0; + width: 100%; + } + + &--bottom-border { + @include hairline('bottom', #e6e6e6); + } + + &__title { + max-width: 60%; + margin: 0 auto; + font-weight: 500; + font-size: var(--fm-navbar-title-size); + @include ellipsis(); + } + + &__left, + &__right { + position: absolute; + top: 0; + bottom: 0; display: flex; align-items: center; - line-height: 1.5; - text-align: center; - user-select: none; - height: var(--fm-navbar-height); - color: var(--fm-navbar-color); - background-color: var(--fm-navbar-background); - &.fm-navbar-fixed { - position: fixed; - top: 0; - left: 0; - width: 100%; - } - &.fm-navbar-border-bottom{ - @include hairline('bottom', #eee); - } - &-title { - max-width: 60%; - margin: 0 auto; - font-weight: 500; - font-size: var(--fm-navbar-title-size); - @include ellipsis(); - } + max-width: 30%; + padding: 0 16px; + font-size: var(--fm-navbar-side-size); + @include ellipsis(); + cursor: pointer; + } + + &__left { + left: 0; - &-left, - &-right { - position: absolute; - top: 0; - bottom: 0; - display: flex; - align-items: center; - max-width: 30%; - padding: 0 16px; - font-size: var(--fm-navbar-side-size); - @include ellipsis(); - cursor: pointer; + &:active { + opacity: var(--fm-active-opacity); } - &-left { - left: 0; - &:active{ - opacity: var(--fm-active-opacity); - } - &.fm-navbar-left-padding{ - padding-left: 14px; - } + + &.fm-navbar-left-padding { + padding-left: 14px; } - &-right { - right: 0; - .fm-navbar-text:active { - opacity: var(--fm-active-opacity); - } + } + + &__right { + right: 0; + + .fm-navbar-text:active { + opacity: var(--fm-active-opacity); } - .fm-navbar-left-arrow{ - min-width: 1em; - margin-right: 4px; - font-size: var(--fm-navbar-arrow-size); + } + + &__left-arrow { + min-width: 1em; + margin-right: 4px; + font-size: var(--fm-navbar-arrow-size); + } + + &__toolbar { + padding: 0 !important; + + &-item { + padding: 0 var(--fm-padding-sm); + height: var(--fm-navbar-toolbar-item-height); + line-height: var(--fm-navbar-toolbar-item-height); + user-select: none; + cursor: pointer; + + &:not(:last-child) { + @include hairline('bottom'); + } + + &--disabled { + opacity: var(--fm-disabled-opacity); + cursor: not-allowed; + } } + } } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts b/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts index e6a0c287c42..9dd0f7ef285 100644 --- a/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts +++ b/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts @@ -1,31 +1,31 @@ import { BaseControlProperty } from "@/components/property-panel"; export class NavBarProperty extends BaseControlProperty { - constructor(componentId: string, designerHostService: any) { - super(componentId, designerHostService); - } - public getPropertyConfig(propertyData: any) { - // 基本信息 - this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); - // 外观 - this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); - // 行为 - this.propertyConfig.categories['behavior'] = this.getBehaviorConfig(propertyData); + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: any) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + // 行为 + this.propertyConfig.categories['behavior'] = this.getBehaviorConfig(propertyData); - return this.propertyConfig; - } + return this.propertyConfig; + } - private getBehaviorConfig(propertyData) { - return { - description: "基本信息", - title: "行为", - properties: { - title: { - title: "标题", - type: "string", - } - } - }; - } + private getBehaviorConfig(propertyData) { + return { + description: "基本信息", + title: "行为", + properties: { + title: { + title: "标题", + type: "string", + } + } + }; + } } 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 index 4a06ab6f5e7..70b1eae89e1 100644 --- a/packages/mobile-ui-vue/components/navbar/src/schema/navbar.schema.json +++ b/packages/mobile-ui-vue/components/navbar/src/schema/navbar.schema.json @@ -1,45 +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": "" + "$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" }, - "leftArrow": { - "description": "是否显示左侧返回按钮", - "type": "boolean", - "default": "true" + "style": { + "type": "string" } + }, + "default": {} + }, + "title": { + "description": "标题", + "type": "string", + "default": "" }, - "required": [ - "id", - "type" - ] + "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 index bc768d5bab9..90dc1493e55 100644 --- a/packages/mobile-ui-vue/components/navbar/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/navbar/src/schema/schema-mapper.ts @@ -1,5 +1,5 @@ import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; export const schemaMapper = new Map([ - ['appearance', resolveAppearance] + ['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 index b02bdf93eec..c1bf8da88a0 100644 --- a/packages/mobile-ui-vue/components/navbar/src/schema/schema-resolver.ts +++ b/packages/mobile-ui-vue/components/navbar/src/schema/schema-resolver.ts @@ -1,5 +1,5 @@ import { DynamicResolver } from "../../../dynamic-resolver"; export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { - return schema; + return schema; } diff --git a/packages/mobile-ui-vue/demos/navbar/index.vue b/packages/mobile-ui-vue/demos/navbar/index.vue index e7afdf085e9..d7634ae55c0 100644 --- a/packages/mobile-ui-vue/demos/navbar/index.vue +++ b/packages/mobile-ui-vue/demos/navbar/index.vue @@ -1,19 +1,23 @@ diff --git a/packages/mobile-ui-vue/demos/navbar/toolbar.vue b/packages/mobile-ui-vue/demos/navbar/toolbar.vue new file mode 100644 index 00000000000..41c86e044cd --- /dev/null +++ b/packages/mobile-ui-vue/demos/navbar/toolbar.vue @@ -0,0 +1,28 @@ + + + + + -- Gitee From 066b41ae761c202a76ea3d52f913207b8c5a9723 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Thu, 10 Apr 2025 17:40:53 +0800 Subject: [PATCH 206/287] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DMobileRenderer?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E6=89=93=E5=8C=85=E6=97=B6=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=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 --- .gitignore | 5 +- .ls-lint.yml | 2 + .../lib/data-services/validator.service.ts | 102 ++++++++++-------- packages/mobile-render/index-publish.html | 15 +++ packages/mobile-render/index.html | 5 +- .../public/assets/farris-mobile-page-vue.css | 1 + .../public/assets/farris-mobile-ui-vue.css | 1 + packages/mobile-render/scripts/build.sh | 3 - packages/mobile-render/scripts/publish.sh | 25 +++++ packages/mobile-render/src/main.ts | 3 - packages/mobile-render/vite.config.ts | 2 +- 11 files changed, 108 insertions(+), 56 deletions(-) create mode 100644 packages/mobile-render/index-publish.html create mode 100644 packages/mobile-render/public/assets/farris-mobile-page-vue.css create mode 100644 packages/mobile-render/public/assets/farris-mobile-ui-vue.css create mode 100644 packages/mobile-render/scripts/publish.sh diff --git a/.gitignore b/.gitignore index 3d706bf102b..0c76a4b3711 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,10 @@ dist-ssr /packages/ui-vue/theme-default /packages/mobile-ui-vue/package /packages/mobile-command-services/package +/packages/mobile-command-services/dist +/packages/mobile-command-services/dist-rollup +/packages/mobile-render/publish /packages/expression-engine/package /packages/expression-engine/dist-rollup /publish.sh -/packages/mobile-command-services/dist + diff --git a/.ls-lint.yml b/.ls-lint.yml index 01db09cca21..625af457582 100644 --- a/.ls-lint.yml +++ b/.ls-lint.yml @@ -101,6 +101,7 @@ ignore: - packages/mobile-command-services/.vscode - packages/mobile-command-services/node_modules - packages/mobile-command-services/dist + - packages/mobile-command-services/dist-rollup - packages/mobile-command-services/public - packages/mobile-command-services/src - packages/mobile-command-services/lib @@ -144,4 +145,5 @@ ignore: - packages/mobile-render/dist - packages/mobile-render/node_modules - packages/mobile-render/public + - packages/mobile-render/publish - packages/mobile-render/scripts 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 3402db5179e..9a841138f5e 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, FormError, FormArrayError } from '@farris/devkit-vue'; +import { ViewModel, ViewModelState, FlattenedControlError, FormErrorFormatter } from "@farris/devkit-vue"; import { BaseDataService } from './base-data.service'; /** @@ -6,29 +6,27 @@ import { BaseDataService } from './base-data.service'; */ class ValidatorService extends BaseDataService { + /** + * 表单错误格式化器 + */ + private formErrorFormatter: FormErrorFormatter; + /** * 构造函数 */ constructor(viewModel: ViewModel) { super(viewModel); + this.formErrorFormatter = new FormErrorFormatter(); } /** * 验证所有表单 */ - public validateAll(): Promise { - 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.toastService.error('存在校验不通过的项'); - return Promise.reject(allViewModelErrors) + public validateAll(): Promise { + const errors = this.validateViewModels(); + if (errors && errors.length > 0) { + this.toastService.error('存在校验不通过的项,请检查'); + return Promise.reject(errors) } return Promise.resolve(null); @@ -37,62 +35,74 @@ class ValidatorService extends BaseDataService { /** * 验证当前视图模型表单 */ - public validate(): Promise { - const allErrors = this.validateByViewModel(this.viewModel); - if (allErrors && allErrors.length > 0) { - this.toastService.error('存在校验不通过的项'); - return Promise.reject(allErrors) - } + public validate(): Promise { + const errors = this.validateByViewModel(this.viewModel); + if (errors && errors.length > 0) { + this.toastService.error('存在校验不通过的项,请检查'); + return Promise.reject(errors) + } - return Promise.resolve(null); + return Promise.resolve(null); } /** * 处理字段验证 */ - public handleValidateFields(): Promise { - // return this.validate(); + public handleValidateFields(): Promise { return this.validateAll(); } /** - * 验证指定视图模型的表单 + * 重置验证状态 */ - private validateByViewModel(viewModel: ViewModel): FormArrayError | null { - const { formStore, formArrayStore } = viewModel; - let allErrors: FormArrayError = []; + public resetFieldsValidate(): void { + return; + } + + /** + * 清空子表验证状态 + */ + public clearValidationChildResult(): void { + return; + } + /** + * 验证所有视图模型的表单 + */ + private validateViewModels(): FlattenedControlError[] | null { + const viewModels = this.module.getViewModels().filter(viewModel => viewModel.enableValidation); + let errors: FlattenedControlError[] = []; + viewModels.forEach((viewModel) => { + const viewModelError = this.validateByViewModel(viewModel) as FlattenedControlError[]; + if (viewModelError && Array.isArray(viewModelError)) { + errors = errors.concat(viewModelError); + } + }); + return errors; + } + + /** + * 验证单个视图模型的表单 + */ + private validateByViewModel(viewModel: ViewModel): FlattenedControlError[] | null { + const { formStore, formArrayStore } = viewModel; + 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 resetFieldsValidate(): void { - return; - } - - /** - * 清空子表验证状态 - */ - public clearValidationChildResult(): void { - return; - } } export { ValidatorService }; diff --git a/packages/mobile-render/index-publish.html b/packages/mobile-render/index-publish.html new file mode 100644 index 00000000000..3f5ff874fea --- /dev/null +++ b/packages/mobile-render/index-publish.html @@ -0,0 +1,15 @@ + + + + + + Mobile Render + + + + + + +
    + + diff --git a/packages/mobile-render/index.html b/packages/mobile-render/index.html index 1542cc42d03..1be0b4e8b69 100644 --- a/packages/mobile-render/index.html +++ b/packages/mobile-render/index.html @@ -4,8 +4,9 @@ Mobile Render - + + +
    diff --git a/packages/mobile-render/public/assets/farris-mobile-page-vue.css b/packages/mobile-render/public/assets/farris-mobile-page-vue.css new file mode 100644 index 00000000000..b8115616c75 --- /dev/null +++ b/packages/mobile-render/public/assets/farris-mobile-page-vue.css @@ -0,0 +1 @@ +@charset "UTF-8";a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0}html{line-height:1;-webkit-tap-highlight-color:transparent}ol,ul{list-style:none}table{border-collapse:collapse;border-spacing:0}caption,td,th{font-weight:400;vertical-align:middle}blockquote,q{quotes:none}blockquote::after,blockquote::before,q::after,q::before{content:'';content:none}a img{border:none}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary{display:block}*,::after,::before{box-sizing:border-box}body{min-height:100vh;color:#333;background-color:#fff}@supports ((height:constant(safe-area-inset-top)) or (height:env(safe-area-inset-top))) and (-webkit-overflow-scrolling:touch){body{padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom)}}a{text-decoration:none;background:0 0}button,input[type=number],input[type=text],input[type=password],input[type=email],input[type=search],select,textarea{margin:0;font-family:inherit;-webkit-appearance:none}.fm-text-light{color:#888}.fm-text-lighter{color:#777}.fm-text-lightest{color:#666}.fm-text-emph{color:#333}.fm-text-primary{color:#3A90FF}.fm-utils-clearfix::after{content:'';clear:both;overflow:hidden}.fm-page{position:absolute;top:0;left:0;bottom:0;right:0;display:flex;flex-direction:column;background:#f9fafb;overflow:hidden}.fm-page-header{flex-shrink:0}.fm-page-main{flex-basis:0;flex-shrink:1;flex-grow:1;padding-bottom:12px;overflow:auto;display:flex;flex-direction:column}.fm-page-navbar{flex-shrink:0}.fm-page-footer{background-color:#fff}.fm-page-footer-btns{display:flex;flex-direction:row;align-items:center;height:100%}.fm-page-footer-btns-item{flex:1;display:flex;flex-direction:column;text-align:center;justify-content:center}.fm-page-footer-btns-item-icon{margin-bottom:4px;font-size:18px}.fm-page-footer-btns-item-text{font-size:12px;color:#999}.fm-page-footer-btns-item:hover .fm-page-footer-btns-item-icon{font-size:22px;color:#3a90ff}.fm-page-footer-btns-item:hover .fm-page-footer-btns-item-text{color:#3a90ff}.fm-form-control,.fm-textarea{width:100%;font-size:14px;color:#333}.fm-form-control{display:block;min-width:0;height:22px;margin:0;padding:0 4px;line-height:inherit;text-align:left;background-color:transparent;border:1px solid #ddd;border-radius:3px;resize:none}.fm-form-control:focus{border-color:#3499f6}.fm-textarea{border-radius:4px;padding:6px 16px;border:1px solid #ddd;outline:0;line-height:24px;display:inline-flex;vertical-align:middle}.fm-textarea:focus{border-color:#3499f6}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-info{background-color:#4D9AFF!important}.bg-submit{background-color:#5AC1C3!important}.bg-success{background-color:#5CC171!important}.bg-warning{background-color:#FF9800!important}.bg-danger{background-color:#F24645!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #DDD;border-radius:0}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border{position:relative;border:none}html:not([data-scale]) .border::before{content:'';position:absolute;left:0;top:0;width:200%;height:200%;border:1px solid #DDD;border-radius:0;transform-origin:0 0;transform:scale(.5);box-sizing:border-box;pointer-events:none}}.border-top{border-top:1px solid #DDD;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border-top{border-top:none}html:not([data-scale]) .border-top::before{content:'';position:absolute;background-color:#DDD;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:100%;height:1PX;transform-origin:50% 50%;transform:scaleY(.5)}}.border-right{border-right:1px solid #DDD;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border-right{border-right:none}html:not([data-scale]) .border-right::after{content:'';position:absolute;display:block;z-index:1;top:0;right:0;bottom:auto;left:auto;width:1PX;height:100%;background:#DDD;transform-origin:100% 50%;transform:scaleX(.5)}}.border-bottom{border-bottom:1px solid #DDD;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border-bottom{border-bottom:none}html:not([data-scale]) .border-bottom::after{content:'';position:absolute;background-color:#DDD;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.border-left{border-left:1px solid #DDD;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border-left{border-left:none}html:not([data-scale]) .border-left::before{content:'';position:absolute;background-color:#DDD;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:1PX;height:100%;transform-origin:100% 50%;transform:scaleX(.5)}}.border-0::before,.border-bottom-0::after,.border-left-0::before,.border-right-0::after,.border-top-0::before{display:none!important}.border-0{border:0}.border-top-0{border-top:0}.border-right-0{border-right:0}.border-bottom-0{border-bottom:0}.border-left-0{border-left:0}.clearfix::after{display:block;clear:both;content:""}.display-none{display:none!important}.display-inline{display:inline!important}.display-inline-block{display:inline-block!important}.display-block{display:block!important}.display-table{display:table!important}.display-table-row{display:table-row!important}.display-table-cell{display:table-cell!important}.display-flex,.fm-utils-flex-column{display:flex!important}.display-inline-flex{display:inline-flex!important}.flex-direction-row{flex-direction:row!important}.flex-direction-column{flex-direction:column!important}.flex-direction-row-reverse{flex-direction:row-reverse!important}.flex-direction-column-reverse{flex-direction:column-reverse!important}.flex-row,.fm-utils-flex-row{flex-direction:row!important}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-bottom,.fixed-top{position:fixed;z-index:1030;right:0;left:0}.fixed-top{top:0}.fixed-bottom{bottom:0}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.m-base{margin:4px!important}.mt-base,.my-base{margin-top:4px!important}.mr-base,.mx-base{margin-right:4px!important}.mb-base,.my-base{margin-bottom:4px!important}.ml-base,.mx-base{margin-left:4px!important}.p-base{padding:4px!important}.pt-base,.py-base{padding-top:4px!important}.pr-base,.px-base{padding-right:4px!important}.pb-base,.py-base{padding-bottom:4px!important}.pl-base,.px-base{padding-left:4px!important}.m-xs{margin:8px!important}.mt-xs,.my-xs{margin-top:8px!important}.mr-xs,.mx-xs{margin-right:8px!important}.mb-xs,.my-xs{margin-bottom:8px!important}.ml-xs,.mx-xs{margin-left:8px!important}.p-xs{padding:8px!important}.pt-xs,.py-xs{padding-top:8px!important}.pr-xs,.px-xs{padding-right:8px!important}.pb-xs,.py-xs{padding-bottom:8px!important}.pl-xs,.px-xs{padding-left:8px!important}.m-sm{margin:12px!important}.mt-sm,.my-sm{margin-top:12px!important}.mr-sm,.mx-sm{margin-right:12px!important}.mb-sm,.my-sm{margin-bottom:12px!important}.ml-sm,.mx-sm{margin-left:12px!important}.p-sm{padding:12px!important}.pt-sm,.py-sm{padding-top:12px!important}.pr-sm,.px-sm{padding-right:12px!important}.pb-sm,.py-sm{padding-bottom:12px!important}.pl-sm,.px-sm{padding-left:12px!important}.m-md{margin:16px!important}.mt-md,.my-md{margin-top:16px!important}.mr-md,.mx-md{margin-right:16px!important}.mb-md,.my-md{margin-bottom:16px!important}.ml-md,.mx-md{margin-left:16px!important}.p-md{padding:16px!important}.pt-md,.py-md{padding-top:16px!important}.pr-md,.px-md{padding-right:16px!important}.pb-md,.py-md{padding-bottom:16px!important}.pl-md,.px-md{padding-left:16px!important}.m-lg{margin:24px!important}.mt-lg,.my-lg{margin-top:24px!important}.mr-lg,.mx-lg{margin-right:24px!important}.mb-lg,.my-lg{margin-bottom:24px!important}.ml-lg,.mx-lg{margin-left:24px!important}.p-lg{padding:24px!important}.pt-lg,.py-lg{padding-top:24px!important}.pr-lg,.px-lg{padding-right:24px!important}.pb-lg,.py-lg{padding-bottom:24px!important}.pl-lg,.px-lg{padding-left:24px!important}.m-xl{margin:32px!important}.mt-xl,.my-xl{margin-top:32px!important}.mr-xl,.mx-xl{margin-right:32px!important}.mb-xl,.my-xl{margin-bottom:32px!important}.ml-xl,.mx-xl{margin-left:32px!important}.p-xl{padding:32px!important}.pt-xl,.py-xl{padding-top:32px!important}.pr-xl,.px-xl{padding-right:32px!important}.pb-xl,.py-xl{padding-bottom:32px!important}.pl-xl,.px-xl{padding-left:32px!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-align-left{text-align:left!important}.text-align-right{text-align:right!important}.text-align-center{text-align:center!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.visible{visibility:visible}.invisible{visibility:hidden}.d-flex{display:flex}.d-inline-flex{display:inline-flex}.d-block{display:block}.d-inline-block{display:inline-block}.d-inline{display:inline}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.fm-utils-absolute-all{top:0;bottom:0;position:absolute;right:0;left:0}.fm-utils-flex-column{flex-direction:column!important;overflow:hidden}.fm-utils-fill-flex-column,.fm-utils-fill-flex-row{flex-shrink:1;display:flex!important;overflow:hidden}.fm-utils-fill-flex-column{flex-grow:1;flex-basis:0;flex-direction:column!important}.fm-utils-flex-row{display:flex!important;overflow:hidden;flex-wrap:nowrap}.fm-utils-flex-row-wrap{display:flex!important;flex-direction:row!important;overflow:hidden;flex-wrap:wrap!important}.fm-utils-fill-flex-row{flex-grow:1;flex-basis:0;flex-direction:row!important;flex-wrap:nowrap!important}.fm-utils-fill-flex-row-wrap{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex!important;flex-direction:row!important;overflow:hidden;flex-wrap:wrap!important}.fm-utils-fill{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-utils-fill-auto{flex-shrink:1;flex-grow:1;flex-basis:0;overflow-x:hidden;overflow-y:auto}.fm-utils-overflow-xhya{overflow-x:hidden!important;overflow-y:auto!important}.fm-utils-overflow-xayh{overflow-y:hidden!important;overflow-x:auto!important}.fm-utils-overflow-xaya{overflow:auto!important}.fm-utils-overflow-hidden{overflow:hidden!important}.fm-utils-overflow-auto{overflow:auto!important}.fm-overflow-x-auto{overflow-x:auto!important}.fm-overflow-x-hidden,.fm-overflow-y-auto,.fm-overflow-y-hidden{overflow-x:hidden!important}.fm-overflow-y-auto{overflow-y:auto!important}.fm-overflow-y-hidden{overflow-y:hidden!important}.fm-overflow-hidden{overflow:hidden!important}.fm-utils-text-break{white-space:normal!important;word-break:break-all!important}.fm-utils-display-none{display:none!important}.fm-multi-ellipsis-l2,.fm-multi-ellipsis-l3{display:-webkit-box;-webkit-box-orient:vertical;text-overflow:ellipsis;overflow:hidden}.fm-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-multi-ellipsis-l2{-webkit-line-clamp:2}.fm-multi-ellipsis-l3{-webkit-line-clamp:3}.fm-float-button-wrapper{position:absolute;right:16px;bottom:50px}.fm-listview-error{background:#fff;box-shadow:0 2px 6px 0 rgba(0,0,0,.12)}.fm-error-cell{position:relative;display:flex;justify-content:space-between;align-items:center;padding:0 16px;height:32px}.fm-error-cell:not(:last-child)::after{content:'';height:1px;position:absolute;background-color:#f1f1f1;display:block;z-index:1;bottom:0;left:16px;right:0;transform:translateY(.5)}.fm-error-text{font-size:13px;color:#f24645;line-height:22px}.fm-error-icon{background:#F24645;color:#fff;border-radius:100%;margin-right:4px}.fm-tmpl-single-header{height:32px;display:flex;align-items:center;padding:0 0 0 16px;background:#F8F9FB}.fm-tmpl-single-header h6{color:#999;font-size:15px;font-weight:400;margin:0}.fm-tmpl-singlelist-with-iconarea{background:#fff;overflow:hidden}.fm-tmpl-singlelist-with-iconarea .singlelist--item{align-items:center;padding:0 0 0 16px;display:flex}.fm-tmpl-singlelist-with-iconarea .singlelist--item:last-child .singlelist--item-title-wrapper{border-bottom:none}.fm-tmpl-singlelist-with-iconarea .singlelist--item .item-img-round--wrapper .item-img-round--img{width:26px;height:26px;border-radius:13px}.fm-tmpl-singlelist-with-iconarea .singlelist--item .item-img-round--wrapper .item-img-round--img .fm-icon{line-height:26px}.fm-tmpl-singlelist-with-iconarea .singlelist--item-title-wrapper{flex-shrink:1;flex-grow:1;flex-basis:0;color:#333;font-size:16px;line-height:22px;padding:11px 0 10px;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-singlelist-with-iconarea .singlelist--item-title-wrapper{border-bottom:none}html:not([data-scale]) .fm-tmpl-singlelist-with-iconarea .singlelist--item-title-wrapper::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.item-img-round--wrapper{margin:0 10px 0 0}.item-img-round--wrapper .item-img-round--img{width:30px;height:30px;border-radius:15px;text-align:center;color:#fff}.item-img-round--wrapper .item-img-round--img .fm-icon{font-size:18px;line-height:30px}.item-img-round--wrapper .fm-bg-yellow{background:#FBB902}.item-img-round--wrapper .fm-bg-orange{background:#FF9800}.item-img-round--wrapper .fm-bg-blue{background:#4D9AFF}.item-img-round--wrapper .fm-bg-lightblue{background:#5ACBCD}.item-img-round--wrapper .fm-bg-purple{background:#817EFF}.item-img-round--wrapper .fm-bg-darkgreen{background:#51BD78}.fm-tmpl-header-with-img{display:flex;align-items:center}.fm-tmpl-header-with-img h5{font-size:16px;color:#333;margin:0;font-weight:400}.fm-tmpl-header-with-img .header-with-img--img-wrapper{margin:0 8px 0 0}.fm-tmpl-header-with-img .header-with-img--img-wrapper .header-with-img--img{width:20px;height:20px;border-radius:10px;line-height:20px;text-align:center;color:#fff;background-image:linear-gradient(180deg,#64CDFB 1%,#3A90FF 100%)}.fm-tmpl-header-with-img .header-with-img--img-wrapper .header-with-img--img .fm-icon{font-size:12px}.fm-tmpl-header-with-img .header-with-img--img-wrapper .fm-bg-blue{color:#fff;background-image:linear-gradient(180deg,#64CDFB 1%,#3A90FF 100%)}.fm-tmpl-header-with-img .header-with-img--img-wrapper .fm-bg-orange{color:#fff;background-image:linear-gradient(180deg,#FFB951 15%,#FF9800 100%)}.fm-tmpl-header-with-img .header-with-img--img-wrapper .fm-bg-green{color:#fff;background-image:linear-gradient(180deg,#7ACC8D 15%,#51BD78 100%)}.fm-cmp-collapse-style::after{display:none}.fm-cmp-collapse-style .van-collapse-item__title{align-items:center}.fm-cmp-collapse-style .van-collapse-item__content{padding:0}.fm-cmp-collapse-style.van-collapse{margin:0 0 12px}.fm-cmp-collapse-style.van-collapse:last-child{margin-bottom:0}.fm-tmpl-collapse-sub::after{border-bottom:0}.fm-tmpl-collapse-sub-header{display:flex;flex-direction:column-reverse}.fm-tmpl-collapse-sub-header .van-collapse-item__title .expand,.fm-tmpl-collapse-sub-header .van-collapse-item__title--expanded .collapse{display:none}.fm-tmpl-collapse-sub-header .van-collapse-item__title{color:#888;flex-direction:row-reverse;justify-content:center}.fm-tmpl-collapse-sub-header .van-collapse-item__title h6{color:#888;font-size:13px;font-weight:400}.fm-tmpl-collapse-sub-header .van-collapse-item__title .collapse-icon{margin:0 8px;transition:transform .3s}.fm-tmpl-collapse-sub-header .van-collapse-item__title--expanded .expand{display:inline-block}.fm-tmpl-collapse-sub-header .van-collapse-item__title--expanded .collapse-icon{transform:rotate(180deg)}.fm-btn-block-wrapper{height:42px;background:#fff;display:flex;align-items:center}.fm-btn-block-wrapper .fm-button{font-size:14px!important;height:100%}.fm-btn-with-icon .fm-btn-text{margin:0 8px}.fm-btn-with-icon .fm-btn-icon{font-size:14px}.fm-tmpl-list-with-img-detail.fm-tmpl-list-with-border{margin-bottom:12px}.fm-tmpl-list-with-img-detail.fm-tmpl-list-with-border .img-detail--item{margin-bottom:0;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-list-with-img-detail.fm-tmpl-list-with-border .img-detail--item{border-bottom:none}html:not([data-scale]) .fm-tmpl-list-with-img-detail.fm-tmpl-list-with-border .img-detail--item::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-round-bg{margin:4px auto 0;width:36px;height:36px;background:#3A90FF;border-radius:20px;line-height:36px;font-size:13px;text-align:center;overflow:hidden;white-space:nowrap}.fm-round-bg-text{color:#FFF}.fm-tmpl-list-with-img-detail .img-detail--item{padding:12px 16px;background:#fff;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-list-with-img-detail .img-detail--item{border-bottom:none}html:not([data-scale]) .fm-tmpl-list-with-img-detail .img-detail--item::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--item-content{display:flex;position:relative}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--status{position:absolute;right:0;top:23px}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--content{position:relative;flex-shrink:1;flex-grow:1;flex-basis:0}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--header{display:flex;align-items:center;justify-content:space-between;margin:0 0 6px}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--header .title{line-height:22px;font-weight:400;font-size:16px;color:#333}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--header .time{line-height:18px;color:#999;font-size:13px}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--info{line-height:18px;color:#999;font-size:13px;margin:0 0 4px}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--info>.gutter{margin:0 14px 0 0}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--actions{padding:18px 0 0;text-align:right}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--actions .fm-button{margin-left:13px}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--actions .fm-button:first-child{margin-left:0}.fm-tmpl-result{display:flex;flex-direction:column;padding-top:40px;align-items:center}.fm-tmpl-result-header .fm-result-title{display:flex;flex-direction:row;font-size:20px;color:#333}.fm-tmpl-result-header .fm-result-title .fm-result-title-number{color:#FF9800}.fm-tmpl-result-content{max-width:84%;padding-top:30px;padding-bottom:30px;text-align:center}.fm-tmpl-result-content .fm-result-img{width:140px;height:140px;margin:0 auto}.fm-tmpl-result-content .fm-result-img img{display:block;width:140px;height:140px}.fm-tmpl-result-content .fm-result-text{padding-top:30px;padding-bottom:10px;font-size:16px;color:#333;text-align:center}.fm-tmpl-result-content .fm-result-tip{line-height:22px;font-size:16px;color:#888;text-align:center}.fm-tmpl-result-footer{width:140px;margin:0 auto}.fm-tmpl-result-footer .fm-result-btn{margin-bottom:16px}.fm-tmpl-result-footer .fm-result-btn:last-child{margin-bottom:0}.fm-tabbar-style{border-top:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tabbar-style{border-top:none}html:not([data-scale]) .fm-tabbar-style::before{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:100%;height:1PX;transform-origin:50% 50%;transform:scaleY(.5)}}.fm-tabbar-style .show-fixed-width{padding:0 17px;flex-shrink:0;flex-grow:0;flex-basis:auto}.fm-tabbar-style .show-fixed-width+.show-left-width{padding:7px 16px 7px 0}.fm-tabbar-style .show-fixed-width .van-tabbar-item__icon .fm-icon{font-size:19px}.fm-tabbar-style .show-fixed-width .van-tabbar-item__text{font-size:12px;transform:scale(.8333)}.fm-tabbar-style .show-left-width{padding:7px 16px}.fm-tabbar-style .show-left-width .fm-button{height:100%}.fm-tmpl-detail-header{padding-left:16px;background-color:#fff}.fm-tmpl-detail-header-inner{display:flex;flex-direction:row;align-items:center;padding:16px 16px 16px 0;border-bottom:1px solid #DDD;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-detail-header-inner{border-bottom:none}html:not([data-scale]) .fm-tmpl-detail-header-inner::after{content:'';position:absolute;background-color:#DDD;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-approve-flow-wrapper .fm-approve-flow-item .fm-approve-flow-item-header-icon .header-icon::before,.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar .avatar-icon::before{content:"\e6b4"}.fm-tmpl-detail-header-inner .detail-header--avatar{width:40px;margin-right:10px;border-radius:50%;overflow:hidden}.fm-tmpl-detail-header-inner .detail-header--avatar img{display:block;width:40px;height:40px}.fm-tmpl-detail-header-inner .detail-header--content{flex:1}.fm-tmpl-detail-header-inner .detail-header--content-title{margin-bottom:3px;font-size:15px;color:#333}.fm-tmpl-detail-header-inner .detail-header--content-subtitle{font-size:13px;color:#888}.fm-static-input-list{padding:16px 0 16px 16px;background-color:#fff;margin:0 0 8px}.fm-static-input-list .fm-listview-item:last-child .fm-static-input-info{margin-bottom:0}.fm-static-input-info{display:flex;flex-direction:row;align-items:center;margin-bottom:8px;line-height:20px}.fm-static-input-info .input-info--label{width:92px;font-size:14px;color:#999;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fm-static-input-info .input-info--text{flex-shrink:1;flex-grow:1;flex-basis:0;padding-left:8px;font-size:14px;color:#333}.fm-static-input-info .input-info--accessory{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap}.fm-static-input-info .input-info--accessory-item{flex-shrink:0;width:28px;height:28px;margin-right:12px;border-radius:3px;overflow:hidden}.fm-static-input-info .input-info--accessory-item img{display:block;width:28px}.fm-static-input-info .input-info--accessory-item:last-child{margin-right:0}.fm-approve-flow-wrapper{padding:12px 16px;background-color:#fff}.fm-approve-flow-wrapper .fm-approve-flow-item{padding-left:7px}.fm-approve-flow-wrapper .fm-approve-flow-item-header{position:relative;border-left:1px dashed #D4D4D4}.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner{position:relative;display:flex;flex-direction:row;align-items:center;padding-left:28px}.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon{position:absolute;left:-8px;top:0;z-index:100}.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon .fm-icon{background-color:#fff;font-size:15px;color:#34AAFF;border-radius:50%}.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon img{background:#fff}.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-content{flex-shrink:1;flex-grow:1;flex-basis:0;line-height:21px;font-size:15px;color:#4C4C4C;font-weight:700}.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-right{flex-shrink:0;padding-left:6px}.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-right .fm-icon{color:#979797}.fm-approve-flow-wrapper .fm-approve-flow-item-header-state{margin-top:6px;padding-left:28px;font-size:13px;color:#FF9002}.fm-approve-flow-wrapper .fm-approve-flow-item-content{display:flex;flex-direction:row;align-items:flex-start;padding:12px 0 30px 28px;border-left:1px dashed #D4D4D4}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:row;align-items:flex-start}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar{position:relative;display:flex;flex-direction:row;align-items:center;width:36px;height:36px}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar-img{display:block;width:36px;height:36px;border-radius:50%}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar-icon{position:absolute;right:4px;bottom:-4px;font-size:14px;color:#34AAFF;background-color:#fff;border-radius:50%}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-text{flex-shrink:1;flex-grow:1;flex-basis:0;padding:0 6px 0 9px}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-text-title{font-size:13px;color:rgba(51,51,51,.65)}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-text-subtitle{margin-top:2px;line-height:20px;font-size:14px;color:#333}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-date{font-size:13px;color:rgba(51,51,51,.65)}.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar-icon,.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-header .fm-approve-flow-item-header-icon .fm-icon,.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-header .fm-approve-flow-item-header-state{color:#1AD0C8}.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar .avatar-icon::before,.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-header .fm-approve-flow-item-header-icon .header-icon::before{content:"\e6b3"}.fm-approve-flow-wrapper .fm-approve-flow-item:last-child .fm-approve-flow-item-header{border-left:0}.fm-approve-flow-wrapper .fm-approve-flow-item:last-child .fm-approve-flow-item-header::before{display:none!important}.fm-approve-flow-wrapper .fm-approve-flow-item:last-child .fm-approve-flow-item-content{padding-bottom:12px;border-left:none}.fm-approve-nopass,.fm-approve-pass{position:fixed;top:48px;right:14px;width:110px;height:110px;z-index:1000}.fm-approve--detail-header{padding-left:16px;background-color:#fff}.fm-approve--detail-header-inner{display:flex;flex-direction:row;align-items:center;padding:17px 16px 17px 0;border-bottom:1px solid #DDD;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-approve--detail-header-inner{border-bottom:none}html:not([data-scale]) .fm-approve--detail-header-inner::after{content:'';position:absolute;background-color:#DDD;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-approve--detail-header-inner .detail-header--avatar{width:40px;margin-right:10px;border-radius:50%;overflow:hidden}.fm-approve--detail-header-inner .detail-header--avatar img{display:block;width:40px;height:40px}.fm-approve--detail-header-inner .detail-header---info{flex:1}.fm-approve--detail-header-inner .detail-header---info-title{margin-bottom:3px;font-size:15px;color:#333}.fm-approve--detail-header-inner .detail-header---info-subtitle{font-size:13px;color:#888}.fm-apply-list-wrapper{padding:0 16px 16px;background-color:#fff;margin:0 0 12px}.fm-apply-list-item{display:flex;flex-direction:row;align-items:flex-start;margin-bottom:8px;line-height:20px}.fm-apply-list-item-label{width:92px;font-size:14px;color:#999;text-align:right;word-break:break-all}.fm-apply-list-item-text{flex-shrink:1;flex-grow:1;flex-basis:0;padding-left:14px;font-size:14px;color:#333;word-break:break-all}.fm-apply-list-item-accessory{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap}.fm-apply-list-item-accessory-item{flex-shrink:0;width:28px;height:28px;margin-right:12px;border-radius:3px;overflow:hidden}.fm-apply-list-item-accessory-item img{display:block;width:28px}.fm-apply-list-item-accessory-item:last-child{margin-right:0}.fm-apply-list-item:last-child{margin-bottom:0}.fm-apply-panel-title,.fm-apply-plate-title{height:28px;line-height:28px;padding-left:10px;margin-bottom:0;background:#F6F6F6;border-radius:2px}.fm-apply-panel-action,.fm-apply-plate-action{padding:0 6px;margin:0 0 0 auto;color:#D8D8D8}.fm-apply-panel-action:hover,.fm-apply-plate-action:hover{background:#3A90FF;color:#fff}.fm-apply-panel{padding-top:0}.fm-apply-panel .fm-apply-list{padding-top:10px;padding-bottom:14px}.fm-apply-panel .fm-apply-list+.fm-apply-list{border-top:1px solid #E8E8E8}.fm-apply-panel-list{padding:0 16px;background-color:#fff;margin:0;border-bottom:1px solid #E8E8E8}.fm-apply-panel-list:last-child{border-bottom:none}.fm-apply-panel-list .panel-list--header{height:42px;display:flex;align-items:center}.fm-apply-panel-list .panel-list--header .panel-list--header-title{font-size:15px;line-height:21px;color:#333;padding:0 0 0 10px;position:relative}.fm-apply-panel-list .panel-list--header .panel-list--header-title::before{content:'';position:absolute;left:0;top:50%;width:3px;height:14px;margin:-7px 0 0;background:#55BBF6}.fm-apply-details{margin:0 0 14px;background:#fff}.fm-apply-main{border-bottom:1px solid #E8E8E8}.fm-avatar-with-state{position:relative;display:flex;flex-direction:row;align-items:center;width:36px;height:36px}.fm-avatar-with-state--img{display:block;width:36px;height:36px;border-radius:50%}.fm-avatar-with-state--icon{position:absolute;right:4px;bottom:-4px;font-size:14px;color:#34AAFF;background-color:#fff;border-radius:50%}.fm-avatar-with-state .avatar-icon::before{content:"\e6b3"}.fm-avatar-with-state .fm-round-bg{background:rgba(77,154,255,.6)}.fm-avatar-with-state.fm-state-running .avatar-icon::before{content:"\e6b4"}.fm-feature-select-person{display:flex;flex-direction:row;flex-wrap:wrap;padding:0 0 14px}.fm-feature-select-person .select-person--item{position:relative;display:flex;align-items:center;margin:0 16px 0 0}.fm-feature-select-person .select-person--item .fm-avatar-with-state{width:48px;height:48px}.fm-feature-select-person .select-person--item .fm-avatar-with-state .fm-avatar-with-state--img{width:48px;height:48px;border-radius:24px}.fm-feature-select-person .select-person--item .fm-avatar-with-state .fm-avatar-with-state--icon{right:0;top:0;cursor:pointer}.fm-feature-select-person .select-person--item .fm-avatar-with-state .fm-avatar-with-state--icon::before{content:"\e016"}.fm-feature-select-person .select-person--item .fm-avatar-with-state .fm-avatar-with-state--icon:hover{background:#F24645;color:#fff}.fm-feature-select-person .select-person--item .fm-round-bg{width:48px;height:48px;border-radius:24px;line-height:48px}.fm-feature-select-person .select-person--icon{margin:0 0 0 3px;color:#A6A6A6}.fm-feature-select-person .select-person--icon::before{content:"→"}.fm-tmpl-search-container{position:relative;padding:7px 16px;display:flex;flex-direction:row;align-items:center;background:#fff}.fm-tmpl-search-container .fm-tmpl-search-type{flex-shrink:0;margin:0 10px 0 0}.fm-tmpl-search-container .fm-tmpl-search-type.fm-state-active{color:#3A90FF}.fm-tmpl-search-container .fm-tmpl-search-inner{flex:1 1 0}.fm-tmpl-search-container .fm-tmpl-search-inner .van-search{padding:0}.fm-tmpl-search-container .fm-tmpl-search-tree-select{position:absolute;left:0;right:0;top:100%;z-index:10}.fm-page-listview{display:flex;flex-direction:column}.fm-page-listview .fm-page-main{padding-bottom:0;flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-page-listview .fm-page-main .fm-tmpl-list-extend,.fm-page-listview .fm-page-main .fm-tmpl-search-container{flex-shrink:0}.fm-page-listview .fm-page-main .fm-tmpl-list-container{display:flex;flex-direction:column;flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-list-footer{display:flex;flex-direction:row;align-items:center;height:54px;padding:0 16px;background:#fff;box-shadow:0 -2px 8px 0 rgba(81,120,159,.12)}.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-list-footer .fm-tmpl-list-footer-btn{flex:1;text-align:center}.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-search-tree-overlay{position:absolute;left:0;bottom:0;right:0;top:0;z-index:9;background-color:rgba(0,0,0,.4)}.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-add-btn{position:absolute;right:16px;bottom:50px}.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-add-btn-inner{width:48px;height:48px;text-align:center;line-height:48px;border-radius:50%;background-image:linear-gradient(-45deg,#65A7FF 0,#3A90FF 100%);box-shadow:0 2px 5px 0 rgba(124,163,254,.57)}.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-add-btn-inner .fm-icon{color:#fff;font-size:16px}.fm-page-listview .fm-page-main .fm-tmpl-list-container .van-pull-refresh{display:flex;flex-direction:column;flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-page-listview .fm-page-main .fm-tmpl-list-container .van-pull-refresh .van-pull-refresh__track{display:flex;flex-direction:column;flex-shrink:1;flex-grow:1;flex-basis:0}.fm-page-listview .fm-page-main .fm-tmpl-list-add .fm-tmpl-add-btn{bottom:16px}.fm-page-listview .fm-page-main .fm-tmpl-list-add .fm-listview-container.fm-listview-container-fill .fm-listview-main{padding-bottom:70px}.fm-page-listview .fm-page-main .fm-tmpl-tabs{flex:1;display:flex;flex-direction:column}.fm-page-listview .fm-page-main .fm-tmpl-tabs .fm-tab-bar,.fm-page-listview .fm-page-main .fm-tmpl-tabs .van-tabs__wrap{flex-shrink:0}.fm-page-listview .fm-page-main .fm-tmpl-tabs .fm-tabs-content,.fm-page-listview .fm-page-main .fm-tmpl-tabs .fm-tabs-content .fm-tab-pane,.fm-page-listview .fm-page-main .fm-tmpl-tabs .van-tabs__content{display:flex;flex-direction:column;flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-page-listview .fm-page-main .fm-tmpl-tabs .van-tabs__content .van-tab__pane{display:flex;flex-direction:column;flex:1}.fm-page-listview .fm-page-main .fm-tmpl-tabs .fm-tmpl-tabs-content{display:flex;flex-direction:column;flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-page-card .fm-page-footer,.fm-tmpl-list-extend{flex-shrink:0}.fm-btn-link{color:#3A90FF}.fm-page-card{display:flex;flex-direction:column}.fm-page-card .fm-page-main{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:auto}.fm-page-card .fm-page-main .fm-page-card-btns{padding:30px 16px 0}.fm-tmpl-struct-wrapper{flex-shrink:0;margin-top:12px}.fm-tmpl-struct-wrapper .fm-tmpl-section{margin-top:12px}.fm-tmpl-struct-wrapper .fm-tmpl-section:first-child{margin-top:0}.fm-tmpl-section{background-color:#fff}.fm-title::before,.fm-tmpl-section-header .fm-title::before{content:'';background:#3A90FF}.fm-tmpl-section-header{display:flex;align-items:center;justify-content:space-between;padding:11px 16px 10px}.fm-tmpl-section-header .fm-title{position:relative;padding-left:16px}.fm-tmpl-section-header .fm-title::before{position:absolute;left:0;top:50%;width:3px;height:14px;margin:-7px 0 0}.fm-tmpl-section-header .fm-title-text{font-size:15px;line-height:21px;color:#333}.fm-tmpl-section-header .fm-toolbar{display:flex;align-items:center}.fm-tmpl-section-header .fm-toolbar-item{display:flex;align-items:center;padding-left:16px;font-size:15px;color:#3A90FF}.fm-tmpl-section-header .fm-toolbar-item-text{margin-left:4px}.fm-tmpl-section-header .fm-toolbar-item-icon{font-size:16px}.fm-tmpl-section-content{padding:0 16px}.fm-tmpl-button-wrapper{padding:30px 16px 0;flex-shrink:0}.fm-tmpl-button-wrapper .fm-tmpl-btns{display:flex;align-items:center}.fm-tmpl-button-wrapper .fm-tmpl-btns .fm-button{flex:1;margin-right:11px}.fm-tmpl-button-wrapper .fm-tmpl-btns.fm-button:last-child{margin-right:0}.fm-tmpl-section-btn{display:flex;flex-direction:row;align-items:center;padding:0 16px;border-top:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-section-btn{border-top:none}html:not([data-scale]) .fm-tmpl-section-btn::before{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:100%;height:1PX;transform-origin:50% 50%;transform:scaleY(.5)}}.fm-tmpl-section-btn .fm-button{flex:1;position:relative}.fm-tmpl-section-btn .fm-button::after{position:absolute;right:0;top:50%;width:1px;height:16px;margin-top:-8px;background:#ddd;transform:scaleX(.5);content:''}.fm-tmpl-section-btn .fm-button:last-child::after{display:none}.fm-card-tmpl-header{height:36px;line-height:36px;background-color:#f9f9fb;padding-left:16px}.fm-edit-input-list{position:relative}.fm-banner-warpper{position:relative;background:url(imgs/questionnaire-header.png) center/cover no-repeat;display:flex;flex-direction:column;align-items:center;justify-content:center}.fm-banner-warpper .fm-banner-title,.fm-banner-warpper .fm-banner-title-sub{color:#fff;text-shadow:0 2px 8px rgba(0,26,123,.52)}.fm-banner-warpper .fm-banner-title{font-size:24px;line-height:33px}.fm-banner-warpper .fm-banner-title-sub{font-size:12px;line-height:17px;padding-top:4px}@media screen and (max-width:375px){.fm-banner-warpper{height:98px}}@media screen and (min-width:375px) and (max-width:414px){.fm-banner-warpper{height:116px}}@media screen and (min-width:414px){.fm-banner-warpper{height:128px}}.fm-stamp-wrapper{width:68px;height:68px;position:absolute;right:16px;top:12px;background:url(imgs/questionnaire-submitted.png) center/contain no-repeat;z-index:9}.fm-card-uploader-content{padding:10px 16px}.fm-page-header-staff{background:linear-gradient(90deg,#2899F6 0,#3E76F9 50%,#4384F8 100%)}.fm-page-header-staff .fm-navbar{background:0 0}.fm-page-header-staff .fm-navbar .fm-navbar-left-arrow,.fm-page-header-staff .fm-navbar .fm-navbar-title{color:#fff}.fm-navbar-right-text{color:#333;font-size:16px}.fm-input-wrapper:not(:last-child) .van-cell::after{display:block}.fm-inner-cell .van-checkbox__label::after,.fm-inner-cell .van-radio__label::after,.fm-input-wrapper:last-child .van-cell::after{display:none}.fm-radio-readonly .fm-inner-cell .van-radio .van-radio__icon .van-icon{background-color:#fff}.fm-radio-readonly .fm-inner-cell .van-radio .van-radio__icon--checked .van-icon{background-color:#1989fa;border-color:#1989fa}html:not([data-scale]) .fm-input-wrapper:not(:last-child) .fm-cell:not(.fm-no-hairline)::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1px;transform-origin:50% 100%}.fm-input-wrapper:not(:last-child) .fm-cell::after{left:16px!important}.fm-input-label-tips{display:flex;align-items:center;padding-left:4px}.fm-input-label-tips-content{font-size:14px;color:#333;line-height:20px;padding:6px 16px}.fm-tmpl-listview-timeline{margin-left:5px}.fm-tmpl-listview-timeline .fm-tmpl-timeline-text{position:relative;padding-left:22px;padding-bottom:2px;line-height:20px;font-size:14px;color:#666}.fm-tmpl-listview-timeline .fm-tmpl-timeline-text::after{position:absolute;left:-5px;top:5px;width:10px;height:10px;background-color:#ddd;border-radius:50%;content:''}.fm-tmpl-listview-timeline .fm-tmpl-timeline-text::before{position:absolute;left:0;top:0;bottom:0;width:1px;background-color:#ddd;content:''}.fm-tmpl-listview-timeline .fm-tmpl-timeline-date{padding-bottom:20px;padding-left:22px;font-size:12px;color:#999;border-left:1px solid #ddd}.fm-tmpl-listview-timeline.fm-tmpl-listview-timeline-first .fm-tmpl-timeline-text:before{top:5px}.fm-tmpl-listview-timeline.fm-tmpl-listview-timeline-last .fm-tmpl-timeline-text:before{height:5px}.fm-tmpl-listview-timeline.fm-tmpl-listview-timeline-last .fm-tmpl-timeline-date{border-color:transparent}.fm-tmpl-listview-goods{padding-left:16px;display:flex;padding-top:10px}.fm-tmpl-listview-goods .fm-tmpl-goods-img{flex-shrink:0;width:86px;height:86px;margin-right:10px;overflow:hidden}.fm-tmpl-listview-goods .fm-tmpl-goods-img img{display:block;width:86px;height:86px}.fm-tmpl-listview-goods .fm-tmpl-goods-content{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden;padding-right:16px;padding-bottom:10px;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-input-wrapper:not(:last-child) .fm-cell:not(.fm-no-hairline)::after{transform:scaleY(.5)}html:not([data-scale]) .fm-tmpl-listview-goods .fm-tmpl-goods-content{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-goods .fm-tmpl-goods-content::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-name{position:relative;min-height:40px;padding-right:28px;margin-bottom:4px;line-height:20px;font-size:16px;color:#666}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-name .fm-tmpl-goods-add{position:absolute;right:0;top:30px;width:24px;height:24px;line-height:24px;text-align:center;background-color:#ececec;border-radius:50%}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-name .fm-tmpl-goods-add .fm-icon{font-size:12px;color:#999}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-price{display:flex;align-items:flex-end;line-height:22px;margin-bottom:3px;color:#fa6400}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-price-prefix{font-size:12px}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-price-text{font-size:16px}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-shop{display:flex;align-items:center;line-height:16px;font-size:12px;color:#888}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-shop .fm-icon{margin-right:3px;font-size:12px}.fm-tmpl-listview-order{padding-left:16px}.fm-tmpl-listview-order-inner{padding:12px 16px 12px 0;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-order-inner{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-order-inner::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-order .fm-tmpl-listview-order-name{margin-bottom:3px;line-height:21px;font-size:15px;color:#333}.fm-tmpl-listview-order .order-line-item{display:flex;flex-direction:row;align-items:center}.fm-tmpl-listview-order .order-line-item-left{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-tmpl-listview-order .order-line-item-right{flex-shrink:0}.fm-tmpl-listview-order .fm-tmpl-listview-order-number{line-height:20px;margin-bottom:10px}.fm-tmpl-listview-order .fm-tmpl-listview-order-number .order-number-text{font-size:14px;color:#888}.fm-tmpl-listview-order .fm-tmpl-listview-order-msg{line-height:18px;font-size:13px}.fm-tmpl-listview-order .fm-tmpl-listview-order-msg .order-msg-date{color:#888}.fm-tmpl-listview-order .fm-tmpl-listview-order-msg .order-msg-price{color:#ff7300}.fm-tmpl-listview-shop{padding:0 8px 10px;background:#f9fafb}.fm-tmpl-listview-shop-inner{background:#fff}.fm-tmpl-listview-shop-header{padding:10px 10px 18px;display:flex;flex-direction:row}.fm-tmpl-listview-shop-header .shop-header-img{flex-shrink:0;width:46px;height:46px;margin-right:10px}.fm-tmpl-listview-shop-header .shop-header-img img{display:block;width:100%;height:100%}.fm-tmpl-listview-shop-header .shop-header-msg{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-tmpl-listview-shop-header .shop-header-msg .shop-header-name{display:flex;justify-content:space-between;margin-bottom:6px}.fm-tmpl-listview-shop-header .shop-header-msg .shop-header-name-text{padding-right:6px;line-height:22px;font-size:16px;color:#333}.fm-tmpl-listview-shop .shop-content-item,.fm-tmpl-listview-shop-header .shop-header-msg .shop-header-site{line-height:18px;font-size:13px;color:#999}.fm-tmpl-listview-shop-header .shop-header-msg .shop-header-name-status{flex-shrink:0}.fm-tmpl-listview-shop .shop-content-item{margin-bottom:8px;padding:0 10px}.fm-tmpl-listview-shop-footer{border-top:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-shop-footer{border-top:none}html:not([data-scale]) .fm-tmpl-listview-shop-footer::before{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:100%;height:1PX;transform-origin:50% 50%;transform:scaleY(.5)}.fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item::after{transform:scaleX(.5)}}.fm-tmpl-listview-shop-footer .shop-footer-btns{display:flex;flex-direction:row;align-items:center}.fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item{position:relative;flex:1;height:44px;padding:0 6px;line-height:44px;font-size:12px;color:#999;text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item .fm-icon{font-size:14px;margin-right:4px}.fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item::after{position:absolute;right:0;top:50%;width:1px;height:22px;margin-top:-11px;background-color:#ddd;content:''}.fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item:last-child::after{display:none}.fm-tmpl-listview-shop-first{padding-top:10px}.fm-tmpl-listview-menu{padding-bottom:10px;background:#f9fafb}.fm-tmpl-listview-menu-inner{padding:10px 16px 0;background-color:#fff}.fm-tmpl-listview-menu-text{margin-bottom:10px;line-height:20px;font-size:14px;color:#666}.fm-tmpl-listview-menu-content .menu-list{display:flex;align-items:center;flex-wrap:wrap}.fm-tmpl-listview-menu-content .menu-list-item{flex:0 0 25%;display:flex;flex-direction:column;align-items:center;margin-bottom:10px}.fm-tmpl-listview-menu-content .menu-list-item-icon{width:46px;height:46px;margin-bottom:6px;line-height:46px;text-align:center;color:#fff;border-radius:16px;background-color:#40a9ff}.fm-tmpl-listview-menu-content .menu-list-item-icon .fm-icon{font-size:26px}.fm-tmpl-listview-menu-content .menu-list-item-text{line-height:20px;font-size:14px;color:#666}.fm-tmpl-listview-menu-last{padding-bottom:0}.fm-tmpl-listview-menus.fm-listview-content{display:flex;align-items:center;flex-wrap:wrap}.fm-tmpl-listview-menus .fm-listview-item{flex:0 0 33.3333%}.fm-tmpl-listview-menus-item{display:flex;flex-direction:column;align-items:center;margin-bottom:16px}.fm-tmpl-listview-menus-item .menu-list-item-icon{width:46px;height:46px;margin-bottom:6px;line-height:46px;text-align:center;color:#fff;border-radius:16px;background-color:#40a9ff}.fm-tmpl-listview-menus-item .menu-list-item-icon .fm-icon{font-size:26px}.fm-tmpl-listview-menus-item .menu-list-item-text{line-height:20px;font-size:14px;color:#666}.fm-tmpl-listview-basic{display:flex;align-items:flex-start;padding:0 16px;margin-bottom:8px;font-size:14px;line-height:20px}.fm-tmpl-listview-basic .basic-lable{flex-shrink:0;width:82px;margin-right:14px;color:#999;text-align:right}.fm-tmpl-listview-basic .basic-text{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden;color:#333}.fm-tmpl-listview-basic-last{margin-bottom:0}.fm-tmpl-listview-list{padding-left:16px}.fm-tmpl-listview-list .fm-tmpl-listview-list-inner{display:flex;justify-content:space-between;height:44px;padding-right:16px;font-size:15px;color:#333;line-height:44px;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-list .fm-tmpl-listview-list-inner{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-list .fm-tmpl-listview-list-inner::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-list .fm-tmpl-listview-list-inner .list-text{color:#FBB902}.fm-tmpl-listview-list-last .fm-tmpl-listview-list-inner{border-bottom:0}.fm-tmpl-listview-list-last .fm-tmpl-listview-list-inner::after{display:none!important}.fm-tmpl-listview-sign{padding:0 16px;background:#fff}.fm-tmpl-listview-sign .fm-tmpl-listview-sign-inner{margin-left:12px}.fm-tmpl-listview-sign .fm-tmpl-sign-text{position:relative;padding-left:18px}.fm-tmpl-listview-sign .fm-tmpl-sign-text .fm-tmpl-sign-circle{position:absolute;left:-8px;top:2px;width:18px;height:18px;border-radius:50%;background-color:rgba(54,165,246,.2)}.fm-tmpl-listview-sign .fm-tmpl-sign-text .text{line-height:22px;font-size:16px;color:#333;font-weight:600}.fm-tmpl-listview-sign .fm-tmpl-sign-text::after{position:absolute;left:-5px;top:5px;width:6px;height:6px;border:3px solid #fff;background-color:#36a5f6;border-radius:50%;content:'';box-sizing:content-box}.fm-tmpl-listview-sign .fm-tmpl-sign-text::before{position:absolute;left:-.5px;top:0;bottom:0;width:1px;border:1px dashed #ddd;background-color:transparent;content:'';transform:scaleX(.5)}.fm-tmpl-listview-sign .fm-tmpl-sign-content{padding:10px 0 10px 18px;border-left:1px dashed #ddd}.fm-tmpl-listview-sign .fm-tmpl-sign-content-inner{padding:10px 12px;background:#f4f7f9}.fm-tmpl-listview-sign .fm-tmpl-sign-content-name{display:flex;align-items:center;padding-bottom:6px;line-height:20px}.fm-tmpl-listview-sign .fm-tmpl-sign-content-name .fm-icon{margin-right:6px;font-size:16px;color:#36a5f6}.fm-tmpl-listview-sign .fm-tmpl-sign-content-name .name-text{font-size:15px;color:#333}.fm-tmpl-listview-sign .fm-tmpl-sign-content-label{padding-bottom:10px;font-size:14px;color:#999}.fm-tmpl-listview-sign .fm-tmpl-sign-content-imgs{display:flex;align-items:center;flex-wrap:wrap}.fm-tmpl-listview-sign .fm-tmpl-sign-content-imgs .fm-tmpl-sign-content-img{width:60px;height:60px;margin-right:10px;margin-bottom:10px;overflow:hidden}.fm-tmpl-listview-sign .fm-tmpl-sign-content-imgs .fm-tmpl-sign-content-img img{display:block;width:100%;height:100%;-o-object-fit:scale-down;object-fit:scale-down}.fm-tmpl-listview-sign.fm-tmpl-listview-sign-last{padding-bottom:12px}.fm-tmpl-listview-sign.fm-tmpl-listview-sign-last .fm-tmpl-sign-content{border-left:none}.fm-tmpl-listview-sign.fm-tmpl-listview-sign-last .fm-tmpl-sign-text::before{height:6px}.fm-tmpl-listview-sign.fm-tmpl-listview-sign-first{padding-top:12px}.fm-tmpl-listview-sign.fm-tmpl-listview-sign-first .fm-tmpl-sign-text::before{top:6px}.fm-tmpl-listview-bill{padding-left:12px}.fm-tmpl-listview-bill-content{display:flex}.fm-tmpl-listview-bill-content .bill-img-round-wrapper{padding-top:12px;margin-right:10px}.fm-tmpl-listview-bill-content .bill-img-round-wrapper .bill-img-round-img{width:30px;height:30px;border-radius:50%;text-align:center;color:#fff;background:#3a90ff}.fm-tmpl-listview-bill-content .bill-img-round-wrapper .bill-img-round-img .fm-icon{font-size:18px;line-height:30px}.fm-tmpl-listview-bill-content .bill-detail-content{flex-shrink:1;flex-grow:1;flex-basis:0;padding:12px 16px 8px 0;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-bill-content .bill-detail-content{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-bill-content .bill-detail-content::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-header{display:flex;align-items:center;justify-content:space-between;margin:0 0 6px}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-header .title{line-height:22px;font-weight:400;font-size:16px;color:#333}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-header .time{line-height:18px;color:#999;font-size:13px}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info{display:flex;margin-bottom:4px}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info-text{display:flex;flex-shrink:1;flex-grow:1;flex-basis:0;align-items:flex-start;line-height:18px;font-size:13px;color:#999}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info-text .title{flex-shrink:0}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info-text .text-orange{color:#FF9800}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info-status{padding-left:6px;margin-top:-2px}.fm-tmpl-listview-client{padding:0 8px 10px;background:#f9fafb}.fm-tmpl-listview-client-inner{background:#fff}.fm-tmpl-listview-client-header{padding:10px 10px 18px;display:flex;flex-direction:row}.fm-tmpl-listview-client-header .client-header-icon{flex-shrink:0;width:46px;height:46px;line-height:46px;margin-right:10px;text-align:center;background-color:#3a90ff;border-radius:6px}.fm-tmpl-listview-client-header .client-header-icon .fm-icon{font-size:24px;color:#fff}.fm-tmpl-listview-client-header .client-header-msg{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-tmpl-listview-client-header .client-header-msg .client-header-name{display:flex;justify-content:space-between;margin-bottom:6px}.fm-tmpl-listview-client-header .client-header-msg .client-header-name-text{padding-right:6px;line-height:22px;font-size:16px;color:#333}.fm-tmpl-listview-client-header .client-header-msg .client-header-name-status{flex-shrink:0}.fm-tmpl-listview-client-header .client-header-msg .client-header-name-time{font-size:13px;color:#999}.fm-tmpl-listview-client-header .client-header-msg .client-header-site{line-height:18px;font-size:13px;color:#999}.fm-tmpl-listview-client-content .client-content-info{display:flex;align-items:center}.fm-tmpl-listview-client-content .text-orange{font-size:14px;color:#FF9800}.fm-tmpl-listview-client .client-content-item{display:flex;align-items:center;flex:1;margin-bottom:8px;padding:0 10px;line-height:18px;font-size:13px;color:#999}.fm-tmpl-listview-client .client-content-item .fm-icon{font-size:14px;margin-right:2px}.fm-tmpl-listview-client-first{padding-top:10px}.fm-tmpl-listview-client.fm-tmpl-listview-client-simple .fm-tmpl-listview-client-header{padding-bottom:10px}.fm-tmpl-listview-client.fm-tmpl-listview-client-simple .fm-tmpl-listview-client-header .client-header-msg .client-header-name{margin-bottom:0}.fm-tmpl-listview-client .text-success{color:#5CC171}.fm-tmpl-listview-client .text-warning{color:#FF9800}.fm-tmpl-listview-client .text-danger{color:#F24645}.fm-tmpl-listview-client .text-submit{color:#5AC1C3}.fm-tmpl-listview-client .text-info{color:#4D9AFF}.fm-tmpl-extend-card{padding:12px 16px}.fm-tmpl-extend-card-inner{position:relative;background-image:linear-gradient(152deg,#53bdfd 0,#287cf3 97%);box-shadow:0 2px 4px 0 rgba(57,66,100,.04);border-radius:10px;overflow:hidden}.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list{display:flex;justify-content:space-between;align-items:center;padding:20px}.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item{display:flex;flex-direction:column;align-items:center;flex:1;color:#fff}.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item .extend-card-item-text{display:flex;align-items:baseline}.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item .extend-card-item-text .item-text{display:block;font-size:24px;line-height:32px}.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item .extend-card-item-text .item-text-tip{font-size:12px}.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item .extend-card-item-text .card-item-title{font-size:14px}.fm-tmpl-extend-card-inner::before{right:-7%;top:20%;width:80%;height:340%;border-radius:50%;opacity:.23;background-image:linear-gradient(180deg,#63ccfa 0,#36a5f6 100%);z-index:1}.fm-tmpl-extend-card-inner::after{right:-37%;bottom:-10%;width:60%;height:240%;border-radius:50%;opacity:.15;background-image:linear-gradient(134deg,#3addd5 0,#24c2d8 100%);z-index:0}.fm-tmpl-listview-liaison{padding-left:16px;margin-top:10px;background-color:#fff}.fm-tmpl-listview-liaison .liaison-header{display:flex;flex-direction:row;justify-content:space-between;padding:12px 16px 12px 0;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-liaison .liaison-header{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-liaison .liaison-header::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-liaison .liaison-header-title{flex:1 1 0;padding-right:16px;font-size:16px;color:#333;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-tmpl-listview-liaison .liaison-header-tag{flex-shrink:0}.fm-tmpl-listview-liaison .liaison-content{padding:10px 0}.fm-tmpl-listview-liaison .liaison-content-info{display:flex;flex-direction:row;align-items:center;line-height:18px;color:#999;font-size:13px;margin:0 0 6px}.fm-tmpl-listview-booklist .booklist-btns .fm-button,.fm-tmpl-listview-liaison .liaison-actions .fm-button{margin-left:13px}.fm-tmpl-listview-liaison .liaison-content-info-title{flex-shrink:0;width:100px;padding-right:10px}.fm-tmpl-listview-liaison .liaison-content-info-text{flex:1 1 0;color:#333}.fm-tmpl-listview-liaison .liaison-actions{padding:0 16px 10px;text-align:right}.fm-tmpl-listview-liaison .liaison-actions .fm-button:first-child{margin-left:0}.fm-tmpl-listview-approve{padding:10px 0 10px 16px;background-color:#fff}.fm-tmpl-listview-approve .fm-approve-flow-item{padding-left:7px}.fm-tmpl-listview-approve .fm-approve-flow-item-header{border-left:1px dashed #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-approve .fm-approve-flow-item-header{border-left:none}html:not([data-scale]) .fm-tmpl-listview-approve .fm-approve-flow-item-header::before{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:1PX;height:100%;transform-origin:100% 50%;transform:scaleX(.5)}}.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner{position:relative;display:flex;flex-direction:row;align-items:center;padding-left:20px}.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon{position:absolute;left:-7px;top:0;z-index:100;display:flex;align-items:center;justify-content:center;width:15px;height:15px;background-color:rgba(58,144,255,.4);border-radius:50%}.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon-inner{width:7px;height:7px;background-color:#3a90ff;border-radius:50%}.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-content{flex-shrink:1;flex-grow:1;flex-basis:0;line-height:21px;font-size:15px;color:#4c4c4c;font-weight:700}.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-right{flex-shrink:0;padding-left:6px}.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-right .fm-icon{color:#979797}.fm-tmpl-listview-approve .fm-approve-flow-item-content{padding:12px 0 30px 20px;border-left:1px dashed #d4d4d4;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-approve .fm-approve-flow-item-content{border-left:none}html:not([data-scale]) .fm-tmpl-listview-approve .fm-approve-flow-item-content::before{content:'';position:absolute;background-color:#d4d4d4;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:1PX;height:100%;transform-origin:100% 50%;transform:scaleX(.5)}}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list{display:flex;flex-direction:row;align-items:flex-start;margin-bottom:14px}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list:last-child{margin-bottom:0}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-avatar{position:relative;display:flex;flex-direction:row;align-items:center;width:36px;height:36px}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-avatar-img{display:block;width:36px;height:36px;border-radius:50%}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content{flex:1 1 0;margin-left:10px}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-main{display:flex;align-items:center;justify-content:space-between;height:36px}.fm-tmpl-listview-approve .fm-approve-flow-item-last .fm-approve-flow-item-content::before,.fm-tmpl-listview-approve .fm-approve-flow-item-last .fm-approve-flow-item-header::before{display:none!important}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left,.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-name{font-size:14px;color:#666}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-status{margin-left:8px;color:#3a90ff}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-status-success{color:#5cc171}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-status-apply{color:#3a90ff}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-status-running{color:#ff9800}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-date{flex-shrink:0;font-size:13px;color:#999}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-message{line-height:20px;font-size:14px;color:#333}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-date{font-size:13px;color:rgba(51,51,51,.65)}.fm-tmpl-listview-approve .fm-approve-flow-item-running .fm-approve-flow-item .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon{background-color:rgba(255,152,0,.4)}.fm-tmpl-listview-approve .fm-approve-flow-item-running .fm-approve-flow-item .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon .fm-approve-flow-item-header-icon-inner{background-color:#ff9800}.fm-tmpl-listview-approve .fm-approve-flow-item-last .fm-approve-flow-item-header{border-left:0}.fm-tmpl-listview-approve .fm-approve-flow-item-last .fm-approve-flow-item-content{padding-bottom:12px;border-left:0}.fm-tmpl-listview-product-header{padding:12px 14px;line-height:20px;font-size:14px;color:#3a90ff}.fm-tmpl-listview-product-item .fm-listview-item .fm-listview-item-content{transform:none}.fm-tmpl-listview-product{padding:12px 16px 0}.fm-tmpl-listview-product .fm-tmpl-listview-product-inner{padding-bottom:12px;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-product .fm-tmpl-listview-product-inner{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-product .fm-tmpl-listview-product-inner::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-product .tmpl-product-title{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}.fm-tmpl-listview-product .tmpl-product-title .tmpl-product-title-collect{flex-shrink:0}.fm-tmpl-listview-product .tmpl-product-title-text{font-size:17px;color:#333}.fm-tmpl-listview-product .tmpl-product-title-collect{flex-shrink:0;font-size:14px;color:#666}.fm-tmpl-listview-product .tmpl-product-title-collect .collect-text{margin-left:4px}.fm-tmpl-listview-product .tmpl-product-title-collect.tmpl-product-title-collected .fm-icon{color:#ff9800}.fm-tmpl-listview-product .tmpl-product-content{position:relative;padding-right:40px}.fm-tmpl-listview-product .tmpl-product-content-item{display:flex;align-items:center;margin-bottom:10px;font-size:14px;color:#666}.fm-tmpl-listview-product .tmpl-product-content .tmpl-product-add-btn{position:absolute;right:0;bottom:0}.fm-tmpl-listview-product .tmpl-product-content .tmpl-product-add-btn .fm-button-add{width:30px;height:30px}.fm-tmpl-listview-product .tmpl-product-content .tmpl-product-add-btn .fm-button-add .fm-icon{font-size:14px}.fm-tmpl-listview-product .tmpl-product-footer{display:flex;align-items:center;justify-content:space-between;margin-top:6px}.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-price{margin-right:10px;font-size:17px;color:red;font-weight:600}.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-inner{border-radius:10px;box-shadow:none}.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-arrow,.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-inner{border:1px solid #ddd}.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-inner-wrapper{padding:0}.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-inner-wrapper .fm-popover-item{min-width:50px;height:46px;line-height:46px;text-align:center;font-size:16px;color:#666}.fm-tmpl-listview-product .tmpl-product-footer .fm-overlay{background:0 0}.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-unit{padding:3px 6px;border-radius:6px;background-color:rgba(58,144,255,.2);font-size:14px;color:#333}.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-unit-text{margin-right:4px}.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-unit .fm-icon{font-size:12px;color:#666}.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-footer-right{flex-shrink:0;font-size:12px;color:#666}.fm-tmpl-listview-product.fm-tmpl-listview-product-first{padding-top:0}.fm-card-tmpl-booklist-header{padding:11px 16px;line-height:22px;font-size:16px;color:#333;font-weight:600}.fm-tmpl-listview-booklist{padding:0 16px;color:#333;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-booklist{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-booklist::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-booklist-last{border-bottom:0}.fm-tmpl-listview-booklist-last::after{display:none!important}.fm-tmpl-listview-booklist .booklist-header{display:flex;flex-direction:row;align-items:flex-start;justify-content:space-between;padding:12px 0 6px;line-height:22px;font-size:16px}.fm-tmpl-listview-booklist .booklist-header-price{flex-shrink:0;color:#fa6400}.fm-tmpl-listview-booklist .booklist-main{padding-bottom:8px}.fm-tmpl-listview-booklist .booklist-main-item{line-height:18px;padding-bottom:4px;font-size:13px;color:#999}.fm-tmpl-listview-booklist .booklist-btns{padding:8px 0 6px;text-align:right}.fm-tmpl-dialog-plan,.fm-tmpl-dialog-type{border-radius:5px!important}.fm-tmpl-dialog-plan .fm-dialog-footer,.fm-tmpl-dialog-type .fm-dialog-footer{border-top:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-dialog-plan .fm-dialog-footer,html:not([data-scale]) .fm-tmpl-dialog-type .fm-dialog-footer{border-top:none}html:not([data-scale]) .fm-tmpl-dialog-plan .fm-dialog-footer::before,html:not([data-scale]) .fm-tmpl-dialog-type .fm-dialog-footer::before{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:100%;height:1PX;transform-origin:50% 50%;transform:scaleY(.5)}}.fm-tmpl-dialog-plan .fm-dialog-footer .fm-button,.fm-tmpl-dialog-type .fm-dialog-footer .fm-button{font-size:14px;color:#666}.fm-tmpl-dialog-type-content{padding:20px}.fm-tmpl-dialog-type-content .fm-dialog-type-list{display:flex;align-items:center;justify-content:center}.fm-tmpl-dialog-type-content .fm-dialog-type-list-item{flex:1}.fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-icon{width:60px;height:60px;margin:0 auto;line-height:60px;text-align:center;border:1px solid #3D91FF;border-radius:50%}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-icon{position:relative;border:none}html:not([data-scale]) .fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-icon::before{content:'';position:absolute;left:0;top:0;width:200%;height:200%;border:1px solid #3D91FF;border-radius:100%;transform-origin:0 0;transform:scale(.5);box-sizing:border-box;pointer-events:none}}.fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-icon .fm-icon{font-size:26px;color:#3D91FF}.fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-text{margin-top:12px;font-size:16px;text-align:center;color:#666}.fm-tmpl-dialog-type-content .fm-dialog-type-list-item:active .type-list-item-icon{background-color:#3D91FF}.fm-tmpl-dialog-type-content .fm-dialog-type-list-item:active .type-list-item-icon .fm-icon{color:#fff}.fm-tmpl-dialog-plan-content{padding:20px 30px}.fm-tmpl-dialog-plan-content .fm-dialog-plan-item{display:flex;justify-content:center;height:40px;line-height:40px;margin-bottom:16px;align-items:center;color:#666;border:1px solid #ddd;border-radius:4px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-dialog-plan-content .fm-dialog-plan-item{position:relative;border:none}html:not([data-scale]) .fm-tmpl-dialog-plan-content .fm-dialog-plan-item::before{content:'';position:absolute;left:0;top:0;width:200%;height:200%;border:1px solid #ddd;border-radius:8px;transform-origin:0 0;transform:scale(.5);box-sizing:border-box;pointer-events:none}}.fm-tmpl-dialog-plan-content .fm-dialog-plan-item .plan-item-icon{margin-right:14px}.fm-tmpl-dialog-plan-content .fm-dialog-plan-item .fm-icon{color:#666}.fm-tmpl-dialog-plan-content .fm-dialog-plan-item:active,.fm-tmpl-dialog-plan-content .fm-dialog-plan-item:active .fm-icon{color:#3D91FF}.fm-tmpl-dialog-plan-content .fm-dialog-plan-item:active::before{border-color:#3D91FF!important}.fm-title{position:relative;padding-left:16px}.fm-title::before{position:absolute;left:0;top:50%;width:5px;height:16px;margin:-8px 0 0}.fm-title-text{font-size:16px;line-height:21px;color:#333}.fm-tmpl-search-action{position:relative}.fm-tmpl-search-action .fm-icon{font-size:20px;color:#666}.fm-tmpl-search-action-badge{position:absolute;top:0;right:0;min-width:16px;padding:0 3px;margin-top:4px;color:#fff;font-weight:500;font-size:12px;line-height:14px;text-align:center;background-color:#ee0a24;border:1px solid #fff;border-radius:16px;transform:translate(50%,-50%);transform-origin:100%}.fm-list-view-swipe-toolbar{display:flex;align-items:center;justify-content:center;padding:0 12px;height:100%;background-color:#f24645;font-size:16px;color:#fff}.fm-static-text-common{padding:12px 16px;background-color:#fff;margin-bottom:10px;font-size:13px;line-height:1.42;-moz-tab-size:4;-o-tab-size:4;tab-size:4;text-align:left;white-space:pre-wrap;word-wrap:break-word}.fm-static-text-common p:not(:last-child){padding-bottom:18px}.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:center}.fm-tmpl-listview-common .fm-tmpl-title{line-height:22px}.fm-tmpl-listview-common .fm-tmpl-price{font-size:18px;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;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.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;overflow:hidden}.fm-tmpl-listview-common .fm-tmpl-col-1:not(:last-child){padding-right:10px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-common{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-common::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-cell .fm-tmpl-row:not(:last-child){padding-bottom:3px}.fm-tmpl-listview-cell .fm-tmpl-label{font-size:13px;line-height:18px;color:#999}.fm-tmpl-listview-cell .fm-tmpl-label .fm-tmpl-label-title{width:auto} \ No newline at end of file diff --git a/packages/mobile-render/public/assets/farris-mobile-ui-vue.css b/packages/mobile-render/public/assets/farris-mobile-ui-vue.css new file mode 100644 index 00000000000..f0a165ea7eb --- /dev/null +++ b/packages/mobile-render/public/assets/farris-mobile-ui-vue.css @@ -0,0 +1 @@ +@charset "UTF-8";:root{--fm-black: #000;--fm-white: #fff;--fm-gray-1: #f2f3f5;--fm-gray-2: #eee;--fm-gray-3: #ddd;--fm-gray-4: #ccc;--fm-gray-5: #999;--fm-gray-6: #666;--fm-gray-7: #333;--fm-red: #F24645;--fm-red-light: #f9e8e8;--fm-blue: #3A90FF;--fm-blue-2: #65a7ff;--fm-blue-light: #ecf2fe;--fm-green: #5CC171;--fm-green-2: #5AC1C3;--fm-green-light: #e9f5ed;--fm-orange: #FF9800;--fm-orange-2: #FA6400;--fm-orange-3: #FFB400;--fm-orange-light: #faf0e1;--fm-primary-color: var(--fm-blue);--fm-success-color: var(--fm-green);--fm-danger-color: var(--fm-red);--fm-warning-color: var(--fm-orange);--fm-submit-color: var(--fm-green-2);--fm-primary-color-light: var(--fm-blue-light);--fm-success-color-light: var(--fm-green-light);--fm-danger-color-light: var(--fm-red-light);--fm-warning-color-light: var(--fm-orange-light);--fm-text-color: var(--fm-gray-7);--fm-text-color-light: var(--fm-gray-5);--fm-active-color: var(--fm-gray-1);--fm-disabled-color: var(--fm-gray-4);--fm-readonly-color: var(--fm-gray-6);--fm-active-opacity: .7;--fm-readonly-opacity: .6;--fm-disabled-opacity: .5;--fm-background: var(--fm-gray-1);--fm-background-white: var(--fm-white);--fm-box-shadow-color: var(--fm-gray-1);--fm-padding-base: 4px;--fm-padding-xs: 8px;--fm-padding-sm: 12px;--fm-padding-md: 16px;--fm-padding-lg: 24px;--fm-padding-xl: 32px;--fm-padding-horizontal-xs: 0 var(--fm-padding-xs);--fm-padding-horizontal-sm: 0 var(--fm-padding-sm);--fm-padding-horizontal-md: 0 var(--fm-padding-md);--fm-padding-horizontal-lg: 0 var(--fm-padding-lg);--fm-margin-base: 4px;--fm-margin-xs: 8px;--fm-margin-sm: 12px;--fm-margin-md: 16px;--fm-margin-lg: 24px;--fm-margin-xl: 32px;--fm-margin-horizontal-xs: 0 var(--fm-margin-xs);--fm-margin-horizontal-sm: 0 var(--fm-margin-sm);--fm-margin-horizontal-md: 0 var(--fm-margin-md);--fm-margin-horizontal-lg: 0 var(--fm-margin-lg);--fm-font-bold-light: 500;--fm-font-bold: 600;--fm-font-size: 16px;--fm-line-height: 1.2;--fm-font-size-xs: 10px;--fm-font-size-sm: 12px;--fm-font-size-md: 14px;--fm-font-size-lg: 16px;--fm-gradient-blue: linear-gradient(-45deg,var(--fm-blue-2) 0%, var(--fm-blue) 100%);--fm-gradient-orange: linear-gradient(-45deg,var(--fm-orange) 0%, var(--fm-orange-2) 100%);--fm-base-font: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Segoe UI, Arial, Roboto, "PingFang SC", "miui", "Hiragino Sans GB", "Microsoft Yahei", sans-serif;--fm-price-font: avenir-heavy, "PingFang SC", helvetica neue, arial, sans-serif;--fm-duration-base: .3s;--fm-duration-fast: .2s;--fm-ease-out: ease-out;--fm-ease-in: ease-in;--fm-noborder: none;--fm-radius-sm: 2px;--fm-radius-md: 4px;--fm-radius-lg: 8px;--fm-radius-max: 999px;--fm-zindex-1: 9;--fm-zindex-2: 10;--fm-zindex-3: 99;--fm-zindex-4: 100;--fm-zindex-5: 999;--fm-zindex-6: 1000}*,*:before,*:after{box-sizing:border-box}body,h1,h2,h3,h4,p,figure,blockquote,dl,dd{margin:0}ul[role=list],ol[role=list]{list-style:none}html:focus-within{scroll-behavior:smooth}body{min-height:100vh;text-rendering:optimizeSpeed;line-height:1.5;font-family:-apple-system,Noto Sans,Helvetica Neue,Helvetica,Nimbus Sans L,Arial,Liberation Sans,PingFang SC,Hiragino Sans GB,Noto Sans CJK SC,Source Han Sans SC,Source Han Sans CN,Microsoft YaHei,Wenquanyi Micro Hei,WenQuanYi Zen Hei,ST Heiti,SimHei,WenQuanYi Zen Hei Sharp,sans-serif}a:not([class]){text-decoration-skip-ink:auto}img,picture{max-width:100%;display:block}input,button,textarea,select{font:inherit}@font-face{font-family:farrisMobile;font-style:normal;font-weight:400;src:url(data:font/ttf;base64,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AADmFAAAACUAAOYVAADmFQAAACYAAOYWAADmFgAAACcAAOYXAADmFwAAACgAAOYYAADmGAAAACkAAOYZAADmGQAAAHYAAOYaAADmGgAAAHUAAOYbAADmGwAAAHQAAOYcAADmHAAAAHMAAOYdAADmHQAAACoAAOYeAADmHgAAACsAAOYfAADmHwAAAHAAAOYgAADmIAAAAHEAAOYhAADmIQAAAHIAAOYiAADmIgAAAG8AAOYjAADmIwAAACwAAOYkAADmJAAAAGUAAOYlAADmJQAAAGYAAOYmAADmJgAAAGcAAOYnAADmJwAAAGgAAOYoAADmKAAAAGkAAOYpAADmKQAAAGoAAOYqAADmKgAAAGsAAOYrAADmKwAAAGwAAOYsAADmLAAAAG0AAOYtAADmLQAAAG4AAOYuAADmLgAAAGMAAOYvAADmLwAAAGQAAOYwAADmMAAAAGIAAOYyAADmMgAAADQAAOYzAADmMwAAAC0AAOY0AADmNAAAAC4AAOY2AADmNgAAAC8AAOY3AADmNwAAADAAAOY5AADmOQAAADEAAOY6AADmOgAAADIAAOZVAADmVQAAADUAAOZWAADmVgAAADoAAOZXAADmVwAAADcAAOZYAADmWAAAADgAAOZZAADmWQAAAD0AAOZaAADmWgAAAF4AAOZbAADmWwAAAF8AAOZcAADmXAAAAGAAAOZdAADmXQAAAGEAAOZeAADmXgAAADYAAOZfAADmXwAAADsAAOZgAADmYAAAADwAAOZhAADmYQAAADkAAOZiAADmYgAAAD4AAOZjAADmYwAAAD8AAOZkAADmZAAAAEAAAOZlAADmZQAAAEEAAOZmAADmZgAAAEIAAOZnAADmZwAAAEMAAOZoAADmaAAAAEQAAOZpAADmaQAAAEUAAOZqAADmagAAAEYAAOZrAADmawAAAEcAAOZsAADmbAAAAEgAAOZtAADmbQAAAEkAAOZuAADmbgAAAEoAAOZvAADmbwAAAEsAAOZwAADmcAAAAEwAAOZxAADmcQAAAE0AAOZyAADmcgAAAE4AAOZzAADmcwAAAE8AAOZ0AADmdAAAAFAAAOZ1AADmdQAAAFEAAOZ2AADmdgAAAFIAAOZ3AADmdwAAAFMAAOZ4AADmeAAAAFQAAOZ5AADmeQAAAFUAAOZ6AADmegAAAFYAAOZ7AADmewAAAFcAAOZ8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AV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFzAXQBdQF2AXcBeAF5AXoBewF8AX0BfgF/AYABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+AAlzLW1vcmUtbzEIcy1kZWxldGUIcy1iYWNrLW8Gcy1zY2FuEHMtb3JnYW5pemF0aW9uLW8Jcy1ncm91cC1vCXMtZmlsdGVyMQlzLWNsZWFyLW8Ocy1pbGx1c3RyYXRlLW8Icy1tb21lbnQIcy1zaG9wLW8Kcy1tb21lbnQtbwZzLXNob3AKcy1yZXZva2UtbwpzLXN1Ym1pdC1vB3MtYXBwLW8Gcy1ib29rBXMtYXBwBHMtbXkJcy1jb21tZW50C3MtY29tbWVudC1vCHMtYm9vay1vBnMtbXktbwxzLWxvY2F0aW9uLW8Kcy1sb2NhdGlvbgZzLW5ld3MIcy1uZXdzLW8Jcy1TZW5kaW5nCnMtSW1wb3J0LW8Icy1FZGl0LW8Icy1RUmNvZGULcy1CcmllZmNhc2URcy1Ob3RpZmljYXRpb25vZmYIcy1QZW5jaWwIcy1TdGFyLW8Jcy1CYXJDb2RlD3MtU2FsZU1lc3NhZ2UtbwxzLUxpc3R2aWV3LW8Lcy1QaWN0dXJlLW8Ocy1TYXZlRmlsbGV0LW8Ocy1TaG9wcGluZ2NhcnQJcy1QZW5kaW5nDnMtRXhwYW5kdmlldy1vCHMtTG9jay1vCXMtU2VydmljZQpzLVdhbGxldC1vEHMtU2hvcHBpbmdjYXJ0LW8Lcy1TZXR0aW5nLW8Ncy1VbmZvbGRSZWMtbwlzLVByb2ZpbGUGTGluay1vDVVzZXJTZXR0aW5nLW8Jcy1hZ3JlZS1vDHMtYXJyb3ctZG93bgdzLWFkZC1vB3MtYW5uZXgMcy1hcnJvdy1sZWZ0CnMtYXJyb3ctdXAScy1jaGVja2JveC1jaGVja2VkCnMtY2hlY2tib3gHcy1hcnJvdwpzLWV4Y2hhbmdlB3MtY2xlYXIJcy1jaGVja2VkB3MtZXllLW8Lcy1jbG9zZS1leWUEcy1hdAxzLWZlZWRiYWNrLW8Pcy1mb2xkLWNpcmNsZS1vB3MtY3Jvc3MHcy1taW51cwZzLWZpbGUPcy1mb2xkLXRyaWFuZ2xlCHMtZmlsdGVyCXMtZm9yd29yZAZzLXBsdXMJcy1maWxlZGVsCHMtZm9sZC1vCXMtaW1hZ2UtbwhzLW1vcmUtbw5zLXJlZGlvLWNpcmNsZQpzLXJlamVjdC1vCXMtc3VjY2VzcwlzLXJlZnJlc2gGcy1zdGFyDXMtcHJvY2Vzc2Zsb3cRcy11bmZvbGQtY2lyY2xlLW8Icy1yZXdpbmQKcy11bmZvbGQtbwtzLXdhcm5pbmctbxFzLXVuZm9sZC10cmlhbmdsZQlzLXByaW50LW8Kcy1zZWFyY2gtbwhBaXJwbGFuZQVUcmFpbgNCdXMEVGF4aQxvdmVydGltZW1lYWwTZm0taS10cmFmZmljZGV0YWlscw9mbS1pLXRyYWZmaWNzdWITZm0taS1hY2NvbW1vZGF0aW9uMQ1mbS1pLWJ1c2luZXNzC2ZtLWktYnVkZ2V0CWZtLWktZ2lmdBFmbS1pLWNhbmNlbGxhdGlvbgxmbS1pLWludm9pY2UJZm0taS1saXN0CmZtLWktbWVhbHMIZm0taS1wYXkMZm0taS1zdWJzaWR5B3Nob3V6aGUTZm0taS1jb3N0YWxsb2NhdGlvbgxmbS1pLXBheW1lbnQOZm0taS1JdGluZXJhcnkOZm0taS1tb3JleGUwMmQPZm0taS1pbWFnZXhlMDJlEGZtLWktcmVqZWN0eGUwMmYPZm0taS1hZ3JlZXhlMDMxDWZtLWktY2FyZGZvbGQPZm0taS1jYXJkdW5mb2xkEWZtLWktdHJhZmZpY290aGVyD2ZtLWktYm90dG9tc2F2ZRBmbS1pLXRyYWZmaWNib2F0D2ZtLWktdHJhZmZpY2NhchFmbS1pLXRyYWZmaWNwbGFuZRFmbS1pLXRyYWZmaWN0cmFpbg9mbS1pLXRyYWZmaWNidXMMZm0taS1hZGRncmF5CmZtLWktY2xvc2UIZm0taS1hZGQJZm0taS1tb3JlCmZtLWktY2hlY2sPZm0taS1iYWNrY2lyY2xlCmZtLWktYWdyZWUMZm0taS1sb2FkaW5nDGZtLWktZmlsZWRlbAlmbS1pLWZpbGUQZm0taS1wcm9jZXNzZmxvdwxmbS1pLXJlZHN0YXIQZm0taS1yaWdodGNpcmNsZQ9mbS1pLXRpbWVjaXJjbGUOZm0taS1zY3JlZW5pbmcMZm0taS11bmNoZWNrDmZtLWktb3BlcmF0aW9uE2ZtLWktYXBwcm92YWxhbW91bnQLZm0taS1hZ3JlZWQOZm0taS1pbnByb2Nlc3MNZm0taS1mZWVkYmFjawpmbS1pLXByaW50DmZtLWktaW1wb3J0YW50GmZtLWktYW1vdW50b2ZyZWltYnVyc2VtZW50FGZtLWktc2FmZXR5YXNzaXN0YW50C2ZtLWktcmVtaW5kDWZtLWktZXllb3BwZW4NZm0taS1leWVjbG9zZRBmbS1pLVBob3RvZ3JhcGh5D2ZtLWktcGhvdG9ncmFwaA9mbS1pLWFkZHBpY3R1cmUTZm0taS10b3Bfb3RoZXItZmFjZQ5mbS1pLXRvcF9vdGhlcgtmbS1pLWRlbGV0ZQ1mbS1pLW5leHRwYWdlDmZtLWktYWRkYnV0dG9uFmZtLWktd2FpdGZvcnByb2Nlc3NpbmcTZm0taS13YXJuaW5nbWVzc2FnZRJmbS1pLWZhaWx1cmVwcm9tcHQUZm0taS1zdWNjZXNzZnVsaGludHMKZm0taS1vdGhlcgxmbS1pLXJldHJhY3QOZm0taS1kcm9wLWRvd24LZm0taS1jYW5jZWwLZm0taS1zZWFyY2gTZm0taS1tdWx0aXBsZWNob2ljZRFmbS1pLXNpbmdsZWNob2ljZQ9mbS1pLW1pY3JvcGhvbmUXZm0taS1hcnJvdy1jaGV2cm9uLWxlZnQPZm0taS1oZWxwY2VudGVyDmZtLWktc3dlZXBjb2RlDmZtLWktZ3JvdXBjaGF0DmZtLWktYWRkZnJpZW5kC2ZtLWktdG9wX215EGZtLWktdG9wX215LWZhY2UPZm0taS10b3BfZnJpZW5kFGZtLWktdG9wX2ZyaWVuZC1mYWNlFWZtLWktdG9wX3B1YmxpY3ByYWlzZRpmbS1pLXRvcF9wdWJsaWNwcmFpc2UtZmFjZQ1mbS1pLXRvcF9ob21lEmZtLWktdG9wX2hvbWUtZmFjZQAAAAA=) format("truetype")}@keyframes fm-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fm-fade-out{0%{opacity:1}to{opacity:0}}.fm-fade-enter-active{animation:.3s fm-fade-in both ease-out}.fm-fade-leave-active{animation:.3s fm-fade-out both ease-in}.fm-slide-up-enter-from,.fm-slide-up-leave-to{transform:translate3d(0,100%,0)}.fm-slide-down-enter-from,.fm-slide-down-leave-to{transform:translate3d(0,-100%,0)}.fm-slide-left-enter-from,.fm-slide-left-leave-to{transform:translate3d(-100%,0,0)}.fm-slide-right-enter-from,.fm-slide-right-leave-to{transform:translate3d(100%,0,0)}.fm-slide-up-enter-active,.fm-slide-down-enter-active,.fm-slide-left-enter-active,.fm-slide-right-enter-active{transition-timing-function:ease-out}.fm-slide-up-leave-active,.fm-slide-down-leave-active,.fm-slide-left-leave-active,.fm-slide-right-leave-active{transition-timing-function:ease-in}.fm-slide-in-enter-active,.fm-slide-in-leave-active,.fm-slide-out-enter-active,.fm-slide-out-leave-active{will-change:transform;transition:all .3s;height:100%;width:100%;top:0;position:absolute;backface-visibility:hidden;perspective:1000}.fm-slide-in-leave-to,.fm-slide-out-enter-from{transform:translate(-100%);opacity:0}.fm-slide-in-enter-from,.fm-slide-out-leave-to{transform:translate(100%);opacity:0}@keyframes fm-drop-down-in{0%{height:0;opacity:0}to{opacity:1}}@keyframes fm-drop-down-out{0%{opacity:1}to{height:0;opacity:0}}.fm-drop-down-enter-active{animation:.3s fm-drop-down-in both ease-out}.fm-drop-down-leave-active{animation:.3s fm-drop-down-out both ease-in}@keyframes fm-rotate{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}:root{--fm-button-height: 42px;--fm-button-padding: 0 14px;--fm-button-radius: 2px;--fm-button-border-width: 1px;--fm-button-color: var(--fm-white);--fm-button-line-height: var(--fm-line-height);--fm-button-font-size: var(--fm-font-size);--fm-button-plain-background: var(--fm-white);--fm-button-lg-height: 46px;--fm-button-lg-font-size: 18px;--fm-button-md-height: 38px;--fm-button-md-font-size: 14px;--fm-button-sm-height: 34px;--fm-button-sm-padding: 0 8px;--fm-button-sm-font-size: 12px;--fm-button-xs-height: 28px;--fm-button-xs-font-size: 10px;--fm-button-secondary-color: var(--fm-blue-light)}.fm-button{position:relative;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;text-align:center;margin:0;border:none;transition:opacity .2s;color:var(--fm-button-color);height:var(--fm-button-height);padding:var(--fm-button-padding);font-size:var(--fm-button-font-size);line-height:var(--fm-button-line-height);border-radius:var(--fm-button-radius)}.fm-button--primary,.fm-button--info{background:var(--fm-primary-color)}.fm-button--secondary{color:var(--fm-primary-color);background:var(--fm-button-secondary-color)}.fm-button--danger{background-color:var(--fm-danger-color)}.fm-button--warning{background-color:var(--fm-warning-color)}.fm-button--success{background-color:var(--fm-success-color)}.fm-button--plain{box-shadow:none;background:var(--fm-button-plain-background)}.fm-button--plain.fm-button--primary,.fm-button--plain.fm-button--info{color:var(--fm-primary-color);border:var(--fm-button-border-width) solid var(--fm-primary-color)}.fm-button--plain.fm-button--success{color:var(--fm-success-color);border:var(--fm-button-border-width) solid var(--fm-success-color)}.fm-button--plain.fm-button--danger{color:var(--fm-danger-color);border:var(--fm-button-border-width) solid var(--fm-danger-color)}.fm-button--plain.fm-button--warning{color:var(--fm-button-warning-color);border:var(--fm-button-border-width) solid var(--fm-button-warning-color)}.fm-button--noborder{border:none!important}.fm-button--large{height:var(--fm-button-lg-height);font-size:var(--fm-button-lg-font-size)}.fm-button--normal{height:var(--fm-button-md-height);font-size:var(--fm-button-md-font-size)}.fm-button--small{height:var(--fm-button-sm-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-sm-font-size)}.fm-button--mini{height:var(--fm-button-xs-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-xs-font-size)}.fm-button--block{display:flex;width:100%}.fm-button--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-button--loading:before,.fm-button--disabled:before{display:none}.fm-button--round{border-radius:var(--fm-radius-max)}.fm-button--square{border-radius:0}.fm-button__loading{display:inline-block;width:20px;max-width:100%;height:20px;max-height:100%;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-button__loading circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}.fm-button__loading-icon-circular{color:#fff}.fm-button__loading-text{margin-left:6px}.fm-button__icon:not(:last-child){margin-right:6px}.fm-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;background-color:#000;border:inherit;border-color:#000;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;content:" "}.fm-button:active:before{opacity:.1}.fm-button-edit__tags{min-height:24px;flex:1;display:flex;overflow:auto}.fm-button-edit__tag:not(:last-child){margin-right:6px}:root{--fm-button-group-gap: 16px}.fm-button-group{display:inline-flex;flex-wrap:nowrap;max-width:100%}.fm-button-group+.fm-button-group{margin-left:var(--fm-button-group-gap)}.fm-button-group__item{margin:0;min-width:0;max-width:100%;white-space:nowrap;flex:0 1 auto;user-select:none}.fm-button-group__item--bare-vertical{display:inline-flex;flex-direction:column;align-items:center;justify-content:space-between;color:#666}.fm-button-group__item--bare-vertical .fm-button-group__item-icon{font-size:20px}.fm-button-group__item--bare-vertical .fm-button-group__item-text{font-size:10px;line-height:16px}.fm-button-group__item--bare-vertical.fm-button-group__item--disabled{cursor:not-allowed;opacity:.5}.fm-button-group--block{display:flex}.fm-button-group--vertical{flex-direction:column}.fm-button-group--block .fm-button-group__item{width:auto;flex:10000 1 0%}.fm-button-group--horizontal.fm-button-group--mode-default .fm-button-group__item+.fm-button-group__item{margin-left:var(--fm-button-group-gap)}.fm-button-group--vertical.fm-button-group--mode-default .fm-button-group__item+.fm-button-group__item{margin-top:var(--fm-button-group-gap)}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:not(:first-child):not(:last-child),.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:not(:first-child):not(:last-child){border-radius:0}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:first-child{border-bottom-left-radius:0;border-bottom-right-radius:0}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:last-child{border-top-left-radius:0;border-top-right-radius:0}.fm-button-group--horizontal.fm-button-group--mode-outline .fm-button-group__item:not(:first-child){border-left:0}.fm-button-group--vertical.fm-button-group--mode-outline .fm-button-group__item:not(:first-child){border-top:0}.fm-button-group--horizontal.fm-button-group--mode-text .fm-button-group__item:not(:last-child){border-right:var(--fm-button-border-width) solid currentColor!important}.fm-button-group--vertical.fm-button-group--mode-text .fm-button-group__item:not(:last-child){border-bottom:var(--fm-button-border-width) solid currentColor!important}.fm-button-group--fill{flex:1}:root{--fm-cell-padding: 10px 16px;--fm-cell-margin: 5px;--fm-cell-line-height: 24px;--fm-cell-font-size: var(--fm-font-size);--fm-cell-background: var(--fm-background-white);--fm-cell-color: var(--fm-text-color);--fm-cell-label-font-size: 12px;--fm-cell-label-line-height: 18px;--fm-cell-label-color: var(--fm-text-color-light);--fm-cell-required-color: var(--fm-danger-color)}.fm-cell{width:100%;padding:var(--fm-cell-padding);background-color:var(--fm-cell-background);color:var(--fm-cell-color);font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);position:relative;display:flex;overflow:hidden}.fm-cell--bottom-border,.fm-cell:not(:last-child){border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-cell--bottom-border:after,.fm-cell:not(:last-child):after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-cell--bottom-border:after,.fm-cell:not(:last-child):after{left:16px!important}.fm-cell.fm-cell-all-width:not(:last-child):after{left:0!important}.fm-cell--clickable{cursor:pointer}.fm-cell--clickable:active{background-color:var(--fm-active-color)}.fm-cell--required .fm-cell-title{position:relative}.fm-cell--required .fm-cell-title .fm-cell-title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-cell__title,.fm-cell__value{flex:1;font-size:inherit}.fm-cell__title{display:inline-block;overflow:hidden}.fm-cell__title-text{display:flex;word-break:break-all}.fm-cell__title-text span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-cell__right{display:flex;overflow:hidden;flex-direction:column}.fm-cell__right-content{display:flex;flex:1}.fm-cell__right--fill{flex:1}.fm-cell__value{position:relative;overflow:hidden;text-align:right;vertical-align:middle;word-wrap:break-word}.fm-cell__value--alone{text-align:left}.fm-cell__label{margin-top:var(--fm-cell-margin);color:var(--fm-cell-label-color);font-size:var(--fm-cell-label-font-size);line-height:var(--fm-cell-label-line-height)}.fm-cell--center{align-items:center}.fm-cell__extra,.fm-cell__left-icon,.fm-cell__right-icon{min-width:1em;font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);display:flex;align-items:center}.fm-cell__left-icon{margin-right:var(--fm-cell-margin)}.fm-cell__extra,.fm-cell__right-icon{margin-left:var(--fm-cell-margin)}.fm-cell--noborder .fm-cell:after{display:none!important}.fm-cell--card{padding-left:0;padding-right:0}.fm-checkbox-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-checkbox-group--vertical{flex-direction:column}.fm-checkbox-group--vertical .fm-checkbox:not(:last-child){margin-bottom:8px}.fm-checkbox{margin-top:4px;margin-bottom:4px}:root{--fm-checker-color: var(--fm-text-color);--fm-checker-font-size: var(--fm-font-size);--fm-checker-icon-color: var(--fm-text-color-light);--fm-checker-icon-background: var(--fm-background-white);--fm-checker-icon-radius: var(--fm-radius-md);--fm-checker-checked-icon-color: var(--fm-primary-color);--fm-checker-button-background: var(--fm-gray-2);--fm-checker-disabled-color: var(--fm-disabled-color);--fm-checker-disabled-icon-color: var(--fm-gray-1)}.fm-checker{display:flex;align-items:center;color:var(--fm-checker-color);font-size:var(--fm-checker-font-size)}.fm-checker__icon{display:inline-block;align-items:center}.fm-checker__icon .fm-icon{display:block;height:20px;width:20px;line-height:18px;font-size:14px;text-align:center;border-radius:var(--fm-checker-icon-radius);border:1px solid var(--fm-checker-icon-color);color:var(--fm-checker-icon-background);background-color:var(--fm-checker-icon-background)}.fm-checker__label{margin-left:8px;margin-right:8px;display:inline-block;line-height:20px}.fm-checker:first-child .fm-checker_button{margin-left:0}.fm-checker--round .fm-checker__icon .fm-icon{border-radius:100%}.fm-checker--button .fm-checker__label{font-size:13px;text-align:center;border-radius:14px;line-height:28px;padding:0 12px;min-width:60px;margin-right:0;color:var(--fm-checker-color);background:var(--fm-checker-button-background)}.fm-checker--checked .fm-checker__icon .fm-icon{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-checked-icon-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--checked.fm-checker--button .fm-checker__label{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--readonly{opacity:var(--fm-readonly-opacity)}.fm-checker--disabled{color:var(--fm-checker-disabled-color)}.fm-checker--disabled .fm-checker__icon .fm-icon{border-color:var(--fm-checker-disabled-color);background-color:var(--fm-checker-disabled-icon-color);color:var(--fm-checker-disabled-icon-color)}.fm-checker--disabled.fm-checker--checked .fm-checker__icon .fm-icon{background-color:var(--fm-checker-disabled-color);border-color:var(--fm-checker-disabled-color)}:root{--fm-icon-font-size: 14px;--fm-icon-color: inherit}.fm-icon{font-family:farrisMobile!important;font-size:var(--fm-icon-font-size);font-style:normal;color:var(--fm-icon-color);display:inline-block;width:1em;height:1em;font-weight:400;line-height:1;vertical-align:middle;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fm-icon:before{display:inline-block}.fm-icon-filter:before{content:"\e697"}.fm-icon-cardfold:before{content:"\e6b7"}.fm-icon-cardunfold:before{content:"\e6b8"}.fm-icon-trafficother:before{content:"\e6b9"}.fm-icon-bottomsave:before{content:"\e6ba"}.fm-icon-trafficboat:before{content:"\e6bb"}.fm-icon-trafficcar:before{content:"\e6bc"}.fm-icon-trafficplane:before{content:"\e6bd"}.fm-icon-traffictrain:before{content:"\e6be"}.fm-icon-trafficbus:before{content:"\e6bf"}.fm-icon-addgray:before{content:"\e6a7"}.fm-icon-close:before{content:"\e6a8"}.fm-icon-add-line:before{content:"\e6a9"}.fm-icon-more:before{content:"\e6aa"}.fm-icon-check:before{content:"\e6ab"}.fm-icon-backcircle:before{content:"\e6ac"}.fm-icon-agree:before{content:"\e6ad"}.fm-icon-loading:before{content:"\e6ae"}.fm-icon-filedel:before{content:"\e6af"}.fm-icon-file:before{content:"\e6b0"}.fm-icon-processflow:before{content:"\e6b1"}.fm-icon-redstar:before{content:"\e6b2"}.fm-icon-rightcircle:before{content:"\e6b3"}.fm-icon-timecircle:before{content:"\e6b4"}.fm-icon-screening:before{content:"\e6b5"}.fm-icon-uncheck:before{content:"\e6b6"}.fm-icon-operation:before{content:"\e02c"}.fm-icon-approvalamount:before{content:"\e02b"}.fm-icon-agreed:before{content:"\e02a"}.fm-icon-inprocess:before{content:"\e029"}.fm-icon-feedback:before{content:"\e028"}.fm-icon-print:before{content:"\e027"}.fm-icon-important:before{content:"\e026"}.fm-icon-amountofreimbursement:before{content:"\e025"}.fm-icon-safetyassistant:before{content:"\e024"}.fm-icon-remind:before{content:"\e023"}.fm-icon-eyeoppen:before{content:"\e022"}.fm-icon-eyeclose:before{content:"\e01e"}.fm-icon-photography:before{content:"\e021"}.fm-icon-photograph:before{content:"\e020"}.fm-icon-addpicture:before{content:"\e01f"}.fm-icon-top_other-face:before{content:"\e01d"}.fm-icon-top_other:before{content:"\e01c"}.fm-icon-delete:before{content:"\e01b"}.fm-icon-nextpage:before{content:"\e01a"}.fm-icon-addbutton:before{content:"\e019"}.fm-icon-waitforprocessing:before{content:"\e018"}.fm-icon-warningmessage:before{content:"\e017"}.fm-icon-failureprompt:before{content:"\e016"}.fm-icon-successfulhints:before{content:"\e015"}.fm-icon-other:before{content:"\e014"}.fm-icon-retract:before{content:"\e013"}.fm-icon-drop-down:before{content:"\e012"}.fm-icon-cancel:before{content:"\e011"}.fm-icon-search:before{content:"\e010"}.fm-icon-multiplechoice:before{content:"\e00f"}.fm-icon-singlechoice:before{content:"\e00e"}.fm-icon-microphone:before{content:"\e00d"}.fm-icon-arrow-chevron-left:before{content:"\e00c"}.fm-icon-helpcenter:before{content:"\e00b"}.fm-icon-sweepcode:before{content:"\e00a"}.fm-icon-groupchat:before{content:"\e009"}.fm-icon-addfriend:before{content:"\e008"}.fm-icon-top_my:before{content:"\e007"}.fm-icon-top_my-face:before{content:"\e006"}.fm-icon-top_friend:before{content:"\e005"}.fm-icon-top_friend-face:before{content:"\e004"}.fm-icon-top_publicpraise:before{content:"\e003"}.fm-icon-top_publicpraise-face:before{content:"\e002"}.fm-icon-top_home:before{content:"\e001"}.fm-icon-top_home-face:before{content:"\e000"}.fm-icon-s-agree-o:before{content:"\e655"}.fm-icon-s-arrow-down:before{content:"\e656"}.fm-icon-s-add-o:before{content:"\e657"}.fm-icon-s-annex:before{content:"\e658"}.fm-icon-s-arrow:before{content:"\e659"}.fm-icon-s-arrow-up:before{content:"\e65e"}.fm-icon-s-checkbox-checked:before{content:"\e65f"}.fm-icon-s-checkbox:before{content:"\e660"}.fm-icon-s-arrow-left:before{content:"\e661"}.fm-icon-s-exchange:before{content:"\e662"}.fm-icon-s-clear:before{content:"\e663"}.fm-icon-s-checked:before{content:"\e664"}.fm-icon-s-eye-o:before{content:"\e665"}.fm-icon-s-close-eye:before{content:"\e666"}.fm-icon-s-at:before{content:"\e667"}.fm-icon-s-feedback-o:before{content:"\e668"}.fm-icon-s-fold-circle-o:before{content:"\e669"}.fm-icon-s-cross:before{content:"\e66a"}.fm-icon-s-minus:before{content:"\e66b"}.fm-icon-s-file:before{content:"\e66c"}.fm-icon-s-fold-triangle:before{content:"\e66d"}.fm-icon-s-filter:before{content:"\e66e"}.fm-icon-s-forword:before{content:"\e66f"}.fm-icon-s-plus:before{content:"\e670"}.fm-icon-s-filedel:before{content:"\e671"}.fm-icon-s-fold-o:before{content:"\e672"}.fm-icon-s-image-o:before{content:"\e673"}.fm-icon-s-more-o:before{content:"\e674"}.fm-icon-s-redio-circle:before{content:"\e675"}.fm-icon-s-reject-o:before{content:"\e676"}.fm-icon-s-success:before{content:"\e677"}.fm-icon-s-refresh:before{content:"\e678"}.fm-icon-s-star:before{content:"\e679"}.fm-icon-s-processflow:before{content:"\e67a"}.fm-icon-s-unfold-circle-o:before{content:"\e67b"}.fm-icon-s-rewind:before{content:"\e67c"}.fm-icon-s-unfold-o:before{content:"\e67d"}.fm-icon-s-save-o:before{content:"\e67e"}.fm-icon-s-warning-o:before{content:"\e67f"}.fm-icon-s-unfold-triangle:before{content:"\e680"}.fm-icon-s-print-o:before{content:"\e681"}.fm-icon-s-search-o:before{content:"\e682"}.fm-icon-s-news:before{content:"\e683"}.fm-icon-s-news-o:before{content:"\e684"}.fm-icon-s-shop:before{content:"\e68c"}.fm-icon-s-sending:before{content:"\e60b"}.fm-icon-s-import-o:before{content:"\e60c"}.fm-icon-s-edit-o:before{content:"\e60d"}.fm-icon-s-qrcode:before{content:"\e60e"}.fm-icon-s-briefcase:before{content:"\e60f"}.fm-icon-s-notificationoff:before{content:"\e610"}.fm-icon-s-pencil:before{content:"\e611"}.fm-icon-s-star-o:before{content:"\e612"}.fm-icon-s-barcode:before{content:"\e613"}.fm-icon-s-salemessage-o:before{content:"\e614"}.fm-icon-s-listview-o:before{content:"\e615"}.fm-icon-s-picture-o:before{content:"\e616"}.fm-icon-s-savefillet-o:before{content:"\e617"}.fm-icon-s-shoppingcart:before{content:"\e618"}.fm-icon-s-pending:before{content:"\e61d"}.fm-icon-s-expandview-o:before{content:"\e61e"}.fm-icon-s-lock-o:before{content:"\e623"}.fm-icon-s-my:before{content:"\e692"}.fm-icon-s-service:before{content:"\e633"}.fm-icon-s-wallet-o:before{content:"\e634"}.fm-icon-s-shoppingcart-o:before{content:"\e636"}.fm-icon-s-setting-o:before{content:"\e637"}.fm-icon-s-my-o:before{content:"\e696"}.fm-icon-s-unfoldrec-o:before{content:"\e639"}.fm-icon-s-profile:before{content:"\e63a"}.fm-icon-s-link-o:before{content:"\e609"}.fm-icon-s-usersetting-o:before{content:"\e632"}.fm-icon-s-shop-o:before{content:"\e68a"}.fm-icon-s-list:before{content:"\e62a"}.fm-icon-s-location-o:before{content:"\e685"}.fm-icon-s-location:before{content:"\e686"}.fm-icon-s-moment:before{content:"\e689"}.fm-icon-s-moment-o:before{content:"\e68b"}.fm-icon-s-revoke-o:before{content:"\e687"}.fm-icon-s-submit-o:before{content:"\e688"}.fm-icon-s-app-o:before{content:"\e68f"}.fm-icon-s-app:before{content:"\e691"}.fm-icon-s-book-o:before{content:"\e695"}.fm-icon-s-book:before{content:"\e690"}.fm-icon-s-comment:before{content:"\e693"}.fm-icon-s-comment-o:before{content:"\e694"}.fm-icon-s-illustrate-o:before{content:"\e68d"}.fm-icon-s-clear-o:before{content:"\e68e"}.fm-icon-friend:before{content:"\e005"}.fm-icon-scan:before{content:"\e69a"}.fm-icon-back:before{content:"\e69b"}.fm-icon-menu:before{content:"\e69d"}:root{--fm-navbar-background: var(--fm-background-white);--fm-navbar-color: var(--fm-text-color);--fm-navbar-height: 44px;--fm-navbar-title-size: 17px;--fm-navbar-side-size: 16px;--fm-navbar-arrow-size: 18px}.fm-navbar{position:relative;z-index:9;display:flex;align-items:center;line-height:1.5;text-align:center;user-select:none;height:var(--fm-navbar-height);color:var(--fm-navbar-color);background-color:var(--fm-navbar-background)}.fm-navbar.fm-navbar-fixed{position:fixed;top:0;left:0;width:100%}.fm-navbar.fm-navbar-border-bottom{border-bottom:1px solid #eee;position:relative;border-bottom:none}.fm-navbar.fm-navbar-border-bottom:after{content:"";position:absolute;background-color:#eee;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-navbar-title{max-width:60%;margin:0 auto;font-weight:500;font-size:var(--fm-navbar-title-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-navbar-left,.fm-navbar-right{position:absolute;top:0;bottom:0;display:flex;align-items:center;max-width:30%;padding:0 16px;font-size:var(--fm-navbar-side-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;cursor:pointer}.fm-navbar-left{left:0}.fm-navbar-left:active{opacity:var(--fm-active-opacity)}.fm-navbar-left.fm-navbar-left-padding{padding-left:14px}.fm-navbar-right{right:0}.fm-navbar-right .fm-navbar-text:active{opacity:var(--fm-active-opacity)}.fm-navbar .fm-navbar-left-arrow{min-width:1em;margin-right:4px;font-size:var(--fm-navbar-arrow-size)}:root{--fm-input-group-size: var(--fm-font-size);--fm-input-group-color: var(--fm-text-color);--fm-input-group-sub-size: 13px;--fm-input-group-padding: 10px 16px;--fm-input-group-sub-color: var(--fm-text-color-light);--fm-input-group-border-color: var(--fm-gray-2)}.fm-input-group{display:flex;flex-direction:column;background-color:var(--fm-white)}.fm-input-group--padding{padding:var(--fm-input-group-padding)}.fm-input-group__body{flex:1;display:flex;align-items:center;min-height:24px;color:var(--fm-input-group-color);font-size:var(--fm-input-group-size)}.fm-input-group__body--border{border:1px solid var(--fm-input-group-border-color);padding:4px 8px;border-radius:4px}.fm-input-group__control{display:flex;width:100%;min-width:0;margin:0;padding:0;border:0;resize:none;color:inherit;font-size:inherit;outline:none;line-height:inherit;background-color:transparent}.fm-input-group__control::placeholder{color:var(--fm-input-group-sub-color)}.fm-input-group__control:disabled{opacity:1;cursor:not-allowed;color:var(--fm-disabled-color);-webkit-text-fill-color:currentColor}.fm-input-group__control::-webkit-search-cancel-button{display:none}.fm-input-group__control--readonly{cursor:default;color:var(--fm-readonly-color)}.fm-input-group__control--left{justify-content:flex-start;text-align:left}.fm-input-group__control--center{justify-content:center;text-align:center}.fm-input-group__control--right{justify-content:flex-end;text-align:right}.fm-input-group__clear{cursor:pointer;margin-right:-8px;padding:4px 8px;color:var(--fm-input-group-sub-color);flex-shrink:0;box-sizing:content-box}.fm-input-group__left-icon{margin:auto 4px auto 0}.fm-input-group__right-icon{margin:auto 0 auto 4px}.fm-input-group__word-limit{margin-top:4px;line-height:18px;text-align:right;font-size:var(--fm-input-group-sub-size);color:var(--fm-input-group-sub-color)}.fm-radio-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-radio-group--vertical{flex-direction:column}.fm-radio-group--vertical .fm-radio:not(:last-child){margin-bottom:8px}.fm-radio{margin-top:4px;margin-bottom:4px}:root,:host{--fm-rate-icon-size: 20px;--fm-rate-icon-gutter: var(--fm-padding-base);--fm-rate-icon-void-color: var(--fm-gray-4);--fm-rate-icon-full-color: var(--fm-orange-3);--fm-rate-icon-disabled-color: var(--fm-gray-4)}.fm-rate{display:inline-flex;cursor:pointer;user-select:none;flex-wrap:wrap}.fm-rate__item{position:relative}.fm-rate__item:not(:last-child){padding-right:var(--fm-rate-icon-gutter)}.fm-rate__icon{display:block;width:1em;color:var(--fm-rate-icon-void-color);font-size:var(--fm-rate-icon-size)}.fm-rate__icon--half{position:absolute;top:0;left:0;overflow:hidden;pointer-events:none;color:var(--fm-rate-icon-full-color)}.fm-rate__icon--full{color:var(--fm-rate-icon-full-color)}.fm-rate__icon--disabled{color:var(--fm-rate-icon-disabled-color)}.fm-rate--disabled{cursor:not-allowed}.fm-rate--readonly{cursor:default}:root{--fm-form-item-size: var(--fm-font-size);--fm-form-item-color: var(--fm-text-color);--fm-form-item-label-width: 105px;--fm-form-item-sub-size: 13px}.fm-form-item{font-size:var(--fm-form-item-size);color:var(--fm-form-item-color)}.fm-form-item--vertical{flex-direction:column}.fm-form-item--vertical .fm-form-item__label{margin-bottom:4px}.fm-form-item__label{display:flex;flex:none;align-items:flex-start;text-align:left;width:var(--fm-form-item-label-width);margin-right:4px}.fm-form-item__label--left{justify-content:flex-start}.fm-form-item__label--center{justify-content:center}.fm-form-item__label--right{justify-content:flex-end}.fm-form-item__label--required{position:relative}.fm-form-item__label--required .fm-cell__title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-form-item__content{display:flex}.fm-form-item__content .fm-input-group{padding:0;flex:1}.fm-form-item__content--left{justify-content:flex-start}.fm-form-item__content--left input.fm-input-group__control{justify-content:flex-start;text-align:left}.fm-form-item__content--center{justify-content:center}.fm-form-item__content--center input.fm-input-group__control{justify-content:flex-center;text-align:center}.fm-form-item__content--right{justify-content:flex-end}.fm-form-item__content--right input.fm-input-group__control{justify-content:flex-end;text-align:right}.fm-form-item__error-message{color:var(--fm-danger-color);font-size:var(--fm-form-item-sub-size)}.fm-form-item__error-message--left{text-align:left}.fm-form-item__error-message--center{text-align:center}.fm-form-item__error-message--right{text-align:right}:root{--fm-overlay-background: rgba(0, 0, 0, .4);--fm-overlay-zindex: 98}.fm-overlay{width:100%;position:fixed;top:0;left:0;z-index:var(--fm-overlay-zindex);background-color:var(--fm-overlay-background);bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-overlay{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}:root{--fm-popup-background: var(--fm-white);--fm-popup-zindex: var(--fm-zindex-3);--fm-popup-radius: 16px}.fm-popup{position:fixed;max-height:100%;overflow-y:auto;background-color:var(--fm-popup-background);transition:all var(--fm-duration-base);z-index:var(--fm-popup-zindex)}.fm-popup--center{top:50%;left:50%;transform:translate(-50%,-50%)}.fm-popup--center.fm-popup--round{border-radius:var(--fm-popup-radius)}.fm-popup--top,.fm-popup--bottom{left:0;right:0}.fm-popup--top{top:0}.fm-popup--top.fm-popup--round{border-radius:0 0 var(--fm-popup-radius) var(--fm-popup-radius)}.fm-popup--bottom{bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--bottom{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--bottom.fm-popup--round{border-radius:var(--fm-popup-radius) var(--fm-popup-radius) 0 0}.fm-popup--left,.fm-popup--right{top:0;bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--left,.fm-popup--right{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--left{left:0}.fm-popup--left.fm-popup--round{border-radius:0 var(--fm-popup-radius) var(--fm-popup-radius) 0}.fm-popup--right{right:0}.fm-popup--right.fm-popup--round{border-radius:var(--fm-popup-radius) 0 0 var(--fm-popup-radius)}:root{--fm-popover-zindex: var(--fm-zindex-5);--fm-popover-padding: var(--fm-padding-sm);--fm-popover-border-radius: var(--fm-radius-lg);--fm-popover-arrow-size: 8px;--fm-popover-content-font-size: var(--fm-font-size);--fm-popover-content-line-height: var(--fm-line-height);--fm-popover-light-theme-color: var(--fm-gray-7);--fm-popover-light-theme-background: var(--fm-white);--fm-popover-dark-theme-color: var(--fm-white);--fm-popover-dark-theme-background: var(--fm-gray-7);--fm-popover-shadow: 0 6px 30px 5px rgba(0, 0, 0, .05), 0 16px 24px 2px rgba(0, 0, 0, .04), 0 8px 10px -5px rgba(0, 0, 0, .08)}.fm-popover{position:absolute;overflow:visible;top:0;left:0;transition:opacity .15s;background-color:transparent;z-index:var(--fm-popover-zindex)}.fm-popover__wrapper{display:inline-block}.fm-popover__content{position:relative;padding:var(--fm-popover-padding);border-radius:var(--fm-popover-border-radius);font-size:var(--fm-popover-content-font-size);line-height:var(--fm-popover-content-line-height);word-break:break-all}.fm-popover__arrow{position:absolute;width:0;height:0;z-index:1;border-style:solid;border-color:transparent;border-width:var(--fm-popover-arrow-size, 8px)}.fm-popover__arrow--top{border-bottom-width:0;border-top-color:currentColor;margin-bottom:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--right{border-left-width:0;border-right-color:currentColor;margin-left:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--bottom{border-top-width:0;border-bottom-color:currentColor;margin-top:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--left{border-right-width:0;border-left-color:currentColor;margin-right:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover--light .fm-popover__content{background:var(--fm-popover-light-theme-background);color:var(--fm-popover-light-theme-color);box-shadow:var(--fm-popover-shadow)}.fm-popover--light .fm-popover__arrow{color:var(--fm-popover-light-theme-background)}.fm-popover--dark .fm-popover__content{background:var(--fm-popover-dark-theme-background);color:var(--fm-popover-dark-theme-color);box-shadow:var(--fm-popover-shadow)}.fm-popover--dark .fm-popover__arrow{color:var(--fm-popover-dark-theme-background)}:root{--fm-switch-background: var(--fm-text-color-light);--fm-switch-on-color: var(--fm-primary-color)}.fm-switch{position:relative;cursor:pointer;display:inline-block;transition:background-color var(--fm-duration-base);background-color:var(--fm-switch-background)}.fm-switch--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-switch--readonly{cursor:default;opacity:var(--fm-readonly-opacity)}.fm-switch--loading{cursor:default}.fm-switch--on{background-color:var(--fm-switch-on-color)}.fm-switch--on .fm-switch__loadding{color:var(--fm-switch-on-color)}.fm-switch__node{display:flex;align-items:center;justify-content:center;position:absolute;top:1px;left:1px;z-index:1;width:28px;height:28px;border-radius:100%;background-color:var(--fm-white);transition:transform var(--fm-duration-base) cubic-bezier(.3,1.05,.4,1.05)}:root{--fm-toast-zindex: var(--fm-zindex-5);--fm-toast-color: var(--fm-white);--fm-toast-font-size: 16px;--fm-toast-background: var(--fm-gray-7);--fm-toast-icon-font-size: 48px}.fm-toast{position:fixed;top:50%;left:50%;display:-webkit-box;display:-webkit-flex;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:content-box;max-width:70%;padding:16px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;border-radius:7px;transform:translate(-50%,-50%);color:var(--fm-toast-color);z-index:var(--fm-toast-zindex);font-size:var(--fm-toast-font-size);background-color:var(--fm-toast-background)}.fm-toast--top{top:50px;transform:translate(-50%)}.fm-toast--bottom{top:auto;bottom:50px}.fm-toast--info,.fm-toast--success,.fm-toast--warning,.fm-toast--error{width:88px;min-height:88px}.fm-toast__icon-wrapper{margin-bottom:8px}.fm-toast--default{padding:8px 16px}.fm-toast--loading{min-width:84px;min-height:84px}.fm-toast--loading-icon{position:relative;display:inline-block;width:30px;height:30px;margin-bottom:8px;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-toast--loading-icon circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}:root{--fm-notify-color: var(--fm-white);--fm-notify-zindex: var(--fm-zindex-5);--fm-notify-info-background: var(--fm-primary-color);--fm-notify-success-background: var(--fm-success-color);--fm-notify-warning-background: var(--fm-warning-color);--fm-notify-error-background: var(--fm-danger-color)}.fm-notify{position:fixed;left:0;top:0;z-index:var(--fm-notify-zindex);display:flex;align-items:center;justify-content:center;width:100%;max-height:100%;padding:8px 16px;box-sizing:border-box;color:var(--fm-notify-color);font-size:14px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;overflow-y:auto}.fm-notify--info{background-color:var(--fm-notify-info-background)}.fm-notify--success{background-color:var(--fm-notify-success-background)}.fm-notify--warning{background-color:var(--fm-notify-warning-background)}.fm-notify--error{background-color:var(--fm-notify-error-background)}:root{--fm-dialog-background: var(--fm-background-2);--fm-dialog-padding-top: 24px;--fm-dialog-padding-left: 16px;--fm-dialog-header-font-size: 17px;--fm-dialog-header-line-height: 24px;--fm-dialog-content-font-size: 15px;--fm-dialog-content-line-height: 20px;--fm-dialog-footer-height: 50px;--fm-border-color: var(--fm-gray-4)}@media screen and (min-width: 375px){.fm-dialog{width:320px}}@media screen and (min-width: 280px) and (max-width: 375px){.fm-dialog{width:240px}}.fm-dialog{display:flex;flex-direction:column;background-color:var(--fm-dialog-background);overflow:hidden}.fm-dialog__header{padding-top:var(--fm-dialog-padding-top);padding-left:var(--fm-dialog-header-padding-left);padding-right:var(--fm-dialog-header-padding-left);font-weight:var(--fm-font-bold-light);font-size:var(--fm-dialog-header-font-size);color:var(--fm-text-color);line-height:var(--fm-dialog-header-line-height);text-align:center}.fm-dialog__content{max-height:70vh;overflow-y:auto}.fm-dialog__content__message{padding:var(--fm-dialog-padding-top) var(--fm-dialog-padding-left);font-size:var(--fm-dialog-content-font-size);line-height:var(--fm-dialog-content-line-height);white-space:pre-wrap;text-align:center;word-wrap:break-word}.fm-dialog__content__message--has-title{padding-top:11px;color:var(--fm-text-color-light)}.fm-dialog__content--prompt{padding:14px}.fm-dialog__content--prompt__input{display:block}.fm-dialog__footer{display:flex;flex-direction:row;align-items:center;border-top:1px solid var(--fm-border-color);position:relative;border-top:none}.fm-dialog__footer:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}.fm-dialog__footer .fm-button{border:0;height:var(--fm-dialog-footer-height);border-right:1px solid var(--fm-border-color);position:relative;border-right:none}.fm-dialog__footer .fm-button:after{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 0 auto auto;width:1px;height:100%;background:var(--fm-border-color);transform-origin:100% 50%;transform:scaleX(.5)}.fm-dialog__footer .fm-button:last-child{border-right:0}.fm-dialog__footer .fm-button:last-child:after{display:none!important}.fm-dialog__footer .fm-button--default{color:var(--fm-text-color)}.fm-dialog__footer--is-column{flex-direction:column}.fm-dialog__footer--is-column__button{border-top:1px solid var(--fm-border-color);position:relative;border-top:none}.fm-dialog__footer--is-column__button:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}.fm-dialog__footer--is-column__button:first-child{border-top:0}.fm-dialog__footer--is-column__button:first-child:before{display:none!important}.fm-dialog.fm-dialog--relative{position:relative}.fm-dialog.fm-dialog--relative__header{padding-right:40px}.fm-dialog__close{position:absolute;right:16px;top:16px;width:22px;height:22px;line-height:22px;text-align:center}.fm-dialog__close .fm-icon{font-size:15px;color:var(--fm-text-color-2)}:root,:host{--fm-loading-color: var(--fm-gray-5);--fm-loading-text-font-size: 14px;--fm-loading-text-line-height: 1.4}.fm-loading{display:flex;align-items:center;position:relative;color:var(--fm-loading-color)}.fm-loading__text{color:var(--fm-loading-color);font-size:var(--fm-loading-text-font-size);line-height:var(--fm-loading-text-line-height);margin-left:var(--fm-margin-xs)}.fm-loading--vertical{flex-direction:column}.fm-loading--vertical .fm-loading__text{margin-top:var(--fm-margin-xs);margin-left:0}.fm-loading__circular{display:block;animation:fm-rotate 2s linear infinite}.fm-loading__circular circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:3;stroke-linecap:round}.fm-loading__spinner{display:block;position:relative;animation:fm-rotate 1s linear infinite;animation-timing-function:steps(12)}.fm-loading__line{position:absolute;top:0;left:0;width:100%;height:100%}.fm-loading__line-inner{display:block;width:2px;height:25%;margin:0 auto;background-color:currentColor;border-radius:40%}.fm-loading__ring{display:block;animation:fm-rotate .75s linear infinite;border:4px solid;border-right-color:transparent;border-radius:50%}@keyframes fm-circular{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40}to{stroke-dasharray:90,150;stroke-dashoffset:-120}}.fm-loading__line--1{transform:rotate(30deg);opacity:1}.fm-loading__line--2{transform:rotate(60deg);opacity:.9375}.fm-loading__line--3{transform:rotate(90deg);opacity:.875}.fm-loading__line--4{transform:rotate(120deg);opacity:.8125}.fm-loading__line--5{transform:rotate(150deg);opacity:.75}.fm-loading__line--6{transform:rotate(180deg);opacity:.6875}.fm-loading__line--7{transform:rotate(210deg);opacity:.625}.fm-loading__line--8{transform:rotate(240deg);opacity:.5625}.fm-loading__line--9{transform:rotate(270deg);opacity:.5}.fm-loading__line--10{transform:rotate(300deg);opacity:.4375}.fm-loading__line--11{transform:rotate(330deg);opacity:.375}.fm-loading__line--12{transform:rotate(360deg);opacity:.3125}:root,:host{--fm-pull-refresh-head-height: 50px;--fm-pull-refresh-head-font-size: var(--fm-font-size-md);--fm-pull-refresh-head-text-color: var(--fm-text-color-light);--fm-pull-refresh-animation-duration: .3s}.fm-pull-refresh{overflow:hidden}.fm-pull-refresh__track{position:relative;height:100%}.fm-pull-refresh__track--not-pulling{transition:transform ease var(--fm-pull-refresh-animation-duration)}.fm-pull-refresh__head{position:absolute;left:0;width:100%;height:var(--fm-pull-refresh-head-height);color:var(--fm-pull-refresh-head-text-color);font-size:var(--fm-pull-refresh-head-font-size);line-height:var(--fm-pull-refresh-head-height);text-align:center;transform:translateY(-100%);display:flex;justify-content:center;align-items:center;flex-direction:column;overflow:hidden}:root,:host{--fm-list-text-color: var(--fm-gray-5);--fm-list-text-font-size: var(--fm-font-size-md, 14px);--fm-list-text-line-height: 50px;--fm-list-loading-icon-size: 16px}.fm-list__loading,.fm-list__error,.fm-list__load-more,.fm-list__finished-info{color:var(--fm-list-text-color);font-size:var(--fm-list-text-font-size);line-height:var(--fm-list-text-line-height);text-align:center}.fm-list__loading-container{display:flex;height:var(--fm-list-text-line-height);justify-content:center;align-items:center}:root,:host{--fm-listview-checkbox-container-width: 40px;--fm-listview-toolbar-height: 42px;--fm-listview-split-line-color: rgb(230, 235, 235);--fm-listview-empty-text-color: var(--fm-gray-5);--fm-listview-empty-text-font-size: var(--fm-font-size-md, 14px);--fm-listview-empty-text-line-height: 50px}.fm-list-view--fill{height:100%;flex-grow:1;flex-shrink:1;display:flex;flex-direction:column;overflow:hidden}.fm-list-view--fill .fm-list-view__track{flex:1 1 0;overflow:auto;-webkit-overflow-scrolling:touch}.fm-list-view--fill .fm-pull-refresh{min-height:100%}.fm-list-view .fm-list{user-select:none;-webkit-user-select:none}.fm-list-view__item{display:flex;position:relative;overflow:hidden}.fm-list-view__item-checker{display:flex;position:absolute;height:100%;width:var(--fm-listview-checkbox-container-width);justify-content:center;align-items:center}.fm-list-view__item-content{flex:1;transform:translate(0)}.fm-list-view__content--split .fm-list-view__item:not(:last-child):not(.fm-list-view__item--child){border-bottom:1px solid var(--fm-listview-split-line-color)}.fm-list-view--multi-select .fm-list-view__item-content{transform:translate(var(--fm-listview-checkbox-container-width))}.fm-list-view__item--group{display:block}.fm-list-view__item-group-header{padding:10px 16px;line-height:20px;font-size:var(--fm-font-size-md);color:var(--fm-gray-5)}.fm-list-view__empty-message{display:block;color:var(--fm-listview-empty-text-color);font-size:var(--fm-listview-empty-text-font-size);line-height:var(--fm-listview-empty-text-line-height);text-align:center}.fm-list-view__item-text{padding:13px 20px;color:var(--fm-gray-7);font-size:var(--fm-font-size)}.fm-list-view__toolbar{display:flex;align-items:center;height:var(--fm-listview-toolbar-height)}.fm-list-view__toolbar-item{flex:1}:root,:host{--fm-swipe-cell-button-text-color: var(--fm-white);--fm-swipe-cell-button-bg-color: var(--fm-gray-4);--fm-swipe-cell-button-font-size: var(--fm-font-size);--fm-swipe-cell-button-icon-size: var(--fm-font-size);--fm-swipe-cell-button-padding: var(--fm-padding-md)}.fm-swipe-cell{position:relative;overflow:hidden}.fm-swipe-cell__wrapper{transition-timing-function:cubic-bezier(.18,.89,.32,1);transition-property:transform}.fm-swipe-cell__left,.fm-swipe-cell__right{position:absolute;top:0;height:100%;display:flex}.fm-swipe-cell__left{left:0;transform:translate3d(-100%,0,0);flex-direction:row-reverse}.fm-swipe-cell__right{right:0;transform:translate3d(100%,0,0)}.fm-swipe-cell__button{display:inline-flex;justify-content:center;align-items:center;height:100%;padding:0 var(--fm-swipe-cell-button-padding);color:var(--fm-swipe-cell-button-text-color);background-color:var(--fm-swipe-cell-button-bg-color)}.fm-swipe-cell__icon{font-size:var(--fm-swipe-cell-button-icon-size)}.fm-swipe-cell__text{font-size:var(--fm-swipe-cell-button-font-size)}.fm-swipe-cell__icon+.fm-swipe-cell__text:not(:empty){margin-left:6px}:root,:host{--fm-action-sheet-max-height: 80%;--fm-action-sheet-border-radius: 12px;--fm-action-sheet-description-color: var(--fm-gray-5);--fm-action-sheet-description-line-height: 22px;--fm-action-sheet-description-font-size: var(--fm-font-size-md);--fm-action-sheet-description-padding: 12px 16px;--fm-action-sheet-item-default-background: var(--fm-background-white);--fm-action-sheet-item-active-background: #f2f3f5;--fm-action-sheet-item-padding: 13px 16px;--fm-action-sheet-item-text-color: #1a1a1a;--fm-action-sheet-item-disabled-text-color: #bdbdbd;--fm-action-sheet-item-subtitle-color: var(--fm-gray-5);--fm-action-sheet-item-icon-size: 18px;--fm-action-sheet-item-icon-margin-right: 8px;--fm-action-sheet-item-title-font-size: var(--fm-font-size-lg);--fm-action-sheet-item-title-line-height: 24px;--fm-action-sheet-item-subtitle-font-size: var(--fm-font-size-sm);--fm-action-sheet-item-subtitle-line-height: 18px;--fm-action-sheet-item-subtitle-margin-top: 2px;--fm-action-sheet-footer-gap-color: #f5f5f5;--fm-action-sheet-divider-color: #e7e7e7;--fm-action-sheet-cancel-height: 48px;--fm-action-sheet-cancel-color: #1a1a1a;--fm-action-sheet-cancel-font-size: var(--fm-font-size-lg);--fm-action-sheet-cancel-font-weight: 500}.fm-action-sheet{display:flex;flex-direction:column;max-height:var(--fm-action-sheet-max-height);overflow:hidden;user-select:none}.fm-action-sheet--round{border-top-left-radius:var(--fm-action-sheet-border-radius);border-top-right-radius:var(--fm-action-sheet-border-radius)}.fm-action-sheet__description{flex-shrink:0;color:var(--fm-action-sheet-description-color);line-height:var(--fm-action-sheet-description-line-height);font-size:var(--fm-action-sheet-description-font-size);text-align:center;padding:var(--fm-action-sheet-description-padding);position:relative}.fm-action-sheet__description--left{text-align:left}.fm-action-sheet__content{flex:1 auto;overflow-y:auto;-webkit-overflow-scrolling:touch}.fm-action-sheet__item,.fm-action-sheet__cancel{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__item:active,.fm-action-sheet__cancel:active{background-color:var(--fm-action-sheet-item-active-background)}.fm-action-sheet__item{display:flex;position:relative;flex-wrap:wrap;align-items:center;justify-content:center;text-align:center;padding:var(--fm-action-sheet-item-padding);color:var(--fm-action-sheet-item-text-color);cursor:pointer}.fm-action-sheet__item-icon{font-size:var(--fm-action-sheet-item-icon-size);margin-right:var(--fm-action-sheet-item-icon-margin-right)}.fm-action-sheet__item-title{font-size:var(--fm-action-sheet-item-title-font-size);line-height:var(--fm-action-sheet-item-title-line-height)}.fm-action-sheet__item-subtitle{font-size:var(--fm-action-sheet-item-subtitle-font-size);line-height:var(--fm-action-sheet-item-subtitle-line-height);width:100%;margin-top:var(--fm-action-sheet-item-subtitle-margin-top);color:var(--fm-action-sheet-item-subtitle-color);overflow-wrap:break-word}.fm-action-sheet__item--left{text-align:left;justify-content:flex-start}.fm-action-sheet__item--disabled{color:var(--fm-action-sheet-item-disabled-text-color);cursor:not-allowed}.fm-action-sheet__item--disabled:active{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__description:after,.fm-action-sheet__item:after{content:"";display:block;position:absolute;height:1px;bottom:0;left:0;right:0;transform:scaleY(.5);background-color:var(--fm-action-sheet-divider-color)}.fm-action-sheet__footer-gap{height:8px;background-color:var(--fm-action-sheet-footer-gap-color)}.fm-action-sheet__cancel{display:flex;flex-direction:column;justify-content:center;align-items:center;height:var(--fm-action-sheet-cancel-height);cursor:pointer;color:var(--fm-action-sheet-cancel-color);font-size:var(--fm-action-sheet-cancel-font-size);font-weight:var(--fm-action-sheet-cancel-font-weight)}:root{--fm-tab-bar-item-color: var(--fm-text-color);--fm-tab-bar-item-active-color: var(--fm-primary-color);--fm-tab-bar-item-font-size: 16px}.fm-tab-bar-item{flex:1 0 auto;position:relative;display:inline-flex;align-items:center;justify-content:center;margin:0 12px;line-height:44px}.fm-tab-bar-item--actived{color:var(--fm-tab-bar-item-active-color)}.fm-tab-bar-item--disabled{color:var(--fm-disabled-color)}.fm-tab-bar-item--dot .fm-tab-bar-item__text:after{content:"";position:absolute;top:0;right:0;width:8px;height:8px;background-color:var(--fm-danger-color);border-radius:100%;transform:translate(100%,100%)}.fm-tab-bar-item__text{position:relative;display:flex;justify-content:center;min-width:40px}.fm-tab-bar-item__ink{position:absolute;bottom:0;left:0;right:0;height:4px;background-color:var(--fm-tab-bar-item-active-color);border-radius:2px}.fm-tab-bar-item__badge{position:absolute;top:2px;right:0;padding:0 4px;max-width:28px;font-weight:500;font-size:12px;line-height:14px;border-radius:7px;color:var(--fm-background-white);background-color:var(--fm-danger-color);transform:translate(50%)}.fm-tab-bar-item__icon{position:relative;display:flex;align-items:center;justify-content:center;padding-right:4px}:root{--fm-tab-bar-height: 44px;--fm-tab-bar-background: var(--fm-background-white);--fm-tab-bar-color: var(--fm-text-color);--fm-tab-bar-active-color: var(--fm-primary-color);--fm-tab-bar-font-size: 16px}.fm-tab-bar{position:relative;background:var(--fm-tab-bar-background);color:var(--fm-tab-bar-color);font-size:var(--fm-tab-bar-font-size)}.fm-tab-bar--bottom-line{border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-tab-bar--bottom-line:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-tab-bar__scroll-wrapper{position:relative;width:100%;overflow:hidden}.fm-tab-bar__list{display:flex;justify-content:space-between;min-width:100%;transition:all .3s cubic-bezier(.17,.89,.45,1)}.fm-tab-bar__ink{position:absolute;bottom:0;left:0;display:block;height:4px;background-color:var(--fm-tab-bar-active-color);transition:all var(--fm-duration-base);border-radius:2px}.fm-tab-bar__ink--disabled{background-color:var(--fm-disabled-color)}.fm-tabs{overflow:hidden}.fm-tabs__content{display:flex}.fm-tab{display:block;flex-shrink:0;width:100%;height:100%;overflow:auto;word-break:break-all}.fm-tab--collapse{height:0;overflow:visible}:root{--fm-tag-padding: 0 6px;--fm-tag-height: 18px;--fm-tag-font-size: 12px;--fm-tag-border-radius: 2px;--fm-tag-color: var(--fm-white)}.fm-tag{position:relative;display:inline-flex;align-items:center;white-space:nowrap;padding:0 4px;color:var(--fm-tag-color);font-size:var(--fm-tag-font-size);line-height:var(--fm-tag-height);border-radius:var(--fm-tag-border-radius)}.fm-tag--primary{background-color:var(--fm-primary-color)}.fm-tag--success{background-color:var(--fm-success-color)}.fm-tag--danger{background-color:var(--fm-danger-color)}.fm-tag--warning{background-color:var(--fm-warning-color)}.fm-tag--plain{background-color:var(--fm-white)}.fm-tag--plain.fm-tag--primary{border:1px solid var(--fm-primary-color);color:var(--fm-primary-color)}.fm-tag--plain.fm-tag--success{border:1px solid var(--fm-success-color);color:var(--fm-success-color)}.fm-tag--plain.fm-tag--warning{border:1px solid var(--fm-warning-color);color:var(--fm-warning-color)}.fm-tag--plain.fm-tag--danger{border:1px solid var(--fm-danger-color);color:var(--fm-danger-color)}.fm-tag--medium{padding:2px 6px}.fm-tag--large{padding:4px 8px;font-size:14px;border-radius:4px}.fm-tag--round{border-radius:100px}.fm-tag--mark{border-radius:0 100px 100px 0}.fm-tag__close{font-size:8px;margin-left:4px}.fm-tag--large .fm-tag__close{font-size:10px}: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}.fm-picker-panel__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker-panel__toolbar-left,.fm-picker-panel__toolbar-right{padding:0 16px}.fm-picker-panel__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker-panel__content{position:relative;display:flex;cursor:grab}.fm-picker-panel__columns{display:flex;flex:1;overflow:hidden}.fm-picker-panel__column{flex:1}.fm-picker-panel__column-item{display:flex;align-items:center;justify-content:center;height:44px}.fm-picker-panel__mask{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;background-image:linear-gradient(180deg,#ffffffe6,#fff6),linear-gradient(0deg,#ffffffe6,#fff6);background-repeat:no-repeat;background-position:top,bottom;transform:translateZ(0);pointer-events:none}.fm-picker-panel__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(.5)}.fm-picker-group__header{text-align:left}.fm-picker-group__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker-group__toolbar-left,.fm-picker-group__toolbar-right{padding:0 16px}.fm-picker-group__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker-group__tab-bar{display:inline-block}:root{--fm-lookup-panel-background: var(--fm-background);--fm-lookup-panel-search-list-zindex: var(--fm-zindex-3)}.fm-lookup-panel{height:100%;display:flex;flex-direction:column;overflow:hidden;background-color:var(--fm-lookup-panel-background)}.fm-lookup-panel__header{background-color:var(--fm-background-white)}.fm-lookup-panel__header__search{border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-lookup-panel__header__search:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-lookup-panel__header__selected-wrapper{display:flex;padding:6px 16px;overflow:auto}.fm-lookup-panel__header__selected-item{font-size:14px;line-height:20px;word-break:keep-all;white-space:nowrap;padding:4px 6px;color:var(--fm-primary-color);background-color:var(--fm-primary-color-light);border-radius:4px}.fm-lookup-panel__header__selected-item:not(:last-child){margin-right:8px}.fm-lookup-panel__footer{padding:0 16px;height:48px;display:flex;align-items:center;justify-content:space-between;box-shadow:0 0 7px 0 var(--fm-box-shadow-color);border-top:1px solid var(--fm-gray-1);background-color:var(--fm-background-white)}.fm-lookup-panel__content{flex:1;display:flex;overflow:hidden;margin-top:10px;position:relative}.fm-lookup-panel__list{flex:1;overflow-y:auto;background-color:var(--fm-background-white)}.fm-lookup-panel__list-item{display:flex;align-items:center;background-color:#fff}.fm-lookup-panel__list-checker{padding-left:16px}.fm-lookup-panel__search-list{position:absolute;inset:0;display:none;overflow-y:auto;z-index:var(--fm-lookup-panel-search-list-zindex);background-color:var(--fm-background-white)}.fm-lookup-panel__popup-selected{width:100%;display:flex;flex-direction:column}.fm-lookup-panel__popup-selected__footer-left{color:var(--fm-primary-color)}.fm-lookup-panel__selected-list{flex:1;overflow:auto}.fm-lookup-panel__empty{padding:12px 16px}.fm-lookup-panel__empty__text{text-align:center;color:var(--fm-text-color-light)}.fm-lookup-panel__breadcrumb{display:flex;align-items:center;height:42px;padding:0 16px;overflow:auto;border-bottom:1px solid var(--fm-border-color);position:relative;border-bottom:none}.fm-lookup-panel__breadcrumb:after{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-lookup-panel__breadcrumb__item{display:flex;align-items:center;color:var(--fm-primary-color);padding-right:8px;flex-shrink:0}.fm-lookup-panel__breadcrumb__item:last-child{color:var(--fm-text-color-light)}.fm-lookup-panel__breadcrumb__icon{font-size:10px;padding-left:4px}.fm-lookup-panel__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)}: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)}.fm-search{display:flex;align-items:center;padding:8px 12px;color:var(--fm-search-color);background-color:var(--fm-search-background)}.fm-search__input-wrapper{flex:1;padding:5px 8px;border-radius:17px;background-color:var(--fm-search-input-background)}.fm-search__input{background-color:var(--fm-search-input-background)}.fm-search__search-icon{margin-right:4px;color:var(--fm-text-color-light)}.fm-filter-panel{height:100%;display:flex;flex-direction:column;padding:8px 16px}.fm-filter-panel__content{flex:1}.fm-filter-panel__footer{padding:8px 16px}.fm-filter-panel__field:not(:first-child){margin-top:16px}.fm-filter-panel__field__title{display:flex;align-items:center;justify-content:space-between;line-height:22px}.fm-filter-panel__field__content{padding-top:12px}.fm-filter-panel__field__range{display:flex;align-items:center}.fm-filter-panel__field__range__splitter{width:8px;margin:0 8px;border:1px solid #999}.fm-filter-panel__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}.fm-filter__portal{display:flex;align-items:center;padding:8px 16px}.fm-filter__portal__icon{font-size:20px}.fm-filter__portal__search{flex:1;padding:0 0 0 8px}.fm-page-container{flex:1;display:flex;flex-direction:column;background:#f9fafb;overflow:hidden;-webkit-overflow-scrolling:auto;position:absolute;inset:0}.fm-page-body-container{flex-basis:0;flex-shrink:1;flex-grow:1;padding-bottom:12px;overflow:auto;display:flex;flex-direction:column}.fm-page-header-container{flex-shrink:0}.fm-page-footer-container{background-color:#fff}.fm-float-container{position:absolute!important;bottom:60px;right:30px} diff --git a/packages/mobile-render/scripts/build.sh b/packages/mobile-render/scripts/build.sh index 1c7ef9ce164..284b8ee9c27 100644 --- a/packages/mobile-render/scripts/build.sh +++ b/packages/mobile-render/scripts/build.sh @@ -1,4 +1,3 @@ - # # devkit # cd ../devkit # npm run build:lib @@ -11,14 +10,12 @@ # 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 diff --git a/packages/mobile-render/scripts/publish.sh b/packages/mobile-render/scripts/publish.sh new file mode 100644 index 00000000000..024391d4f69 --- /dev/null +++ b/packages/mobile-render/scripts/publish.sh @@ -0,0 +1,25 @@ + +ROOT_DIR="./publish/web/platform/common/web"; +RENDER_DIR="${ROOT_DIR}/mobile-renderer"; +SCRIPT_DIR="${ROOT_DIR}/@farris" +STYLE_DIR="${ROOT_DIR}/assets" + +# 打包 +npm run build + +# 创建目录 +mkdir -p $STYLE_DIR +mkdir -p $SCRIPT_DIR +mkdir -p $RENDER_DIR + +# 拷贝文件 +cp -r -p ../mobile-ui-vue/package/index.css "${STYLE_DIR}/farris-mobile-ui-vue.css" +cp -r -p ../mobile-ui-vue/public/assets/farris-mobile-page.css "${STYLE_DIR}/farris-mobile-page-vue.css" + +cp -r -p ../mobile-ui-vue/package/index.systemjs.js "${SCRIPT_DIR}/mobile-ui-vue.js" +cp -r -p ../devkit/dist-rollup/@farris/devkit-vue.js "${SCRIPT_DIR}/devkit-vue.js" +cp -r -p ../bef/dist-rollup/@farris/bef-vue.js "${SCRIPT_DIR}/bef-vue.js" +cp -r -p ../mobile-command-services/dist-rollup/@farris/mobile-command-services-vue.js "${SCRIPT_DIR}/mobile-command-services-vue.js" + +cp -p ./index-publish.html "${RENDER_DIR}/index.html" +cp -p ./dist/assets/index-*.js "${RENDER_DIR}/index.js" diff --git a/packages/mobile-render/src/main.ts b/packages/mobile-render/src/main.ts index 1f03eb36d91..4673c409203 100644 --- a/packages/mobile-render/src/main.ts +++ b/packages/mobile-render/src/main.ts @@ -1,6 +1,3 @@ -import '@components/index.scss'; -import './assets/main.scss'; - import { createApp, App as AppInstance } from 'vue'; import MobileUI from '@farris/mobile-ui-vue'; import { registerComponents } from '@farris/mobile-ui-vue'; diff --git a/packages/mobile-render/vite.config.ts b/packages/mobile-render/vite.config.ts index 94675916c38..4c68bb48c60 100644 --- a/packages/mobile-render/vite.config.ts +++ b/packages/mobile-render/vite.config.ts @@ -12,7 +12,7 @@ interface VitestConfigExport extends UserConfig { // https://vitejs.dev/config/ export default defineConfig({ - base: process.env.NODE_ENV === 'production' ? '/platform/common/web/mobile-renderer/' : '/', + // base: process.env.NODE_ENV === 'production' ? '/platform/common/web/mobile-renderer/' : './', build: { minify: false }, -- Gitee From bc0fc0b9a0a2eb1a9f6c2e38c963174e69b126b0 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Thu, 10 Apr 2025 20:15:21 +0800 Subject: [PATCH 207/287] =?UTF-8?q?feature:=20MobileRenderer=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=B8=B2=E6=9F=93default=E6=8F=92=E6=A7=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../button/src/schema/button.schema.json | 3 +++ .../components/button/src/schema/schema-mapper.ts | 14 +++++++++++++- .../src/composition/use-render-component.ts | 11 ++++++----- 3 files changed, 22 insertions(+), 6 deletions(-) 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 index 075e7641fe8..bd4e9c45f1f 100644 --- a/packages/mobile-ui-vue/components/button/src/schema/button.schema.json +++ b/packages/mobile-ui-vue/components/button/src/schema/button.schema.json @@ -73,6 +73,9 @@ "events": [ "onClick" ], + "slots": [ + "text" + ], "required": [ "id", "type" 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 index 1a9e31c13af..eca9607abe4 100644 --- a/packages/mobile-ui-vue/components/button/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/button/src/schema/schema-mapper.ts @@ -1,6 +1,18 @@ import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; +function createTemplatePropResolver(name: string): MapperFunction { + return (key: string, content: string) => { + if (!content) { + return {}; + } + const templateInfo = { name, content }; + + return { text: templateInfo }; + }; +} + export const schemaMapper = new Map([ ['appearance', resolveAppearance], - ['displayType', 'type'] + ['displayType', 'type'], + ['text', createTemplatePropResolver('default')] ]); 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 index 33c2d46af0a..ee6af6218f4 100644 --- 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 @@ -23,9 +23,7 @@ export function useRenderComponent(context: DynamicViewContext) { /** * 处理插槽 */ - function resolveSlots(componentConfig: any): any { - const componentType = componentConfig.type; - const componentSchema = schemaMap[componentType]; + function resolveSlots(componentConfig: any, componentSchema: any): any { if (!componentSchema) { return; } @@ -76,16 +74,19 @@ export function useRenderComponent(context: DynamicViewContext) { */ function renderComponent(componentConfig: any): VNode { const componentType = componentConfig.type; + const Component = componentMap[componentType]; if (!Component) { throw new Error(`Component(type=${componentType}) not found`); } + const componentSchema = schemaMap[componentType]; const resolvedComponentConfig = resolveProps(componentConfig); - const slots = resolveSlots(resolvedComponentConfig) || {}; + const slots = resolveSlots(resolvedComponentConfig, componentSchema) || {}; + const defaultSlot = slots.default ? slots.default : resolveChildren(resolvedComponentConfig); const children = { - default: resolveChildren(resolvedComponentConfig), + default: defaultSlot, ...slots }; -- Gitee From 02e6ca1a0af0d32986d9dd04104cf092bf21e5f1 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Thu, 10 Apr 2025 20:18:36 +0800 Subject: [PATCH 208/287] =?UTF-8?q?fix:=20=E8=A7=84=E8=8C=83=E7=BB=84?= =?UTF-8?q?=E4=BB=B6Schema=E4=B8=AD=E6=8F=92=E6=A7=BD=E7=9A=84=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/button/src/schema/button.schema.json | 2 +- .../dynamic-view/src/composition/use-render-component.ts | 4 ++-- .../components/list-view/src/schema/list-view.schema.json | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) 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 index bd4e9c45f1f..0243498e5cb 100644 --- a/packages/mobile-ui-vue/components/button/src/schema/button.schema.json +++ b/packages/mobile-ui-vue/components/button/src/schema/button.schema.json @@ -73,7 +73,7 @@ "events": [ "onClick" ], - "slots": [ + "templates": [ "text" ], "required": [ 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 index ee6af6218f4..45d32b2260f 100644 --- 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 @@ -27,11 +27,11 @@ export function useRenderComponent(context: DynamicViewContext) { if (!componentSchema) { return; } - if (!Array.isArray(componentSchema.slots)) { + if (!Array.isArray(componentSchema.templates)) { return; } - const slotPropNames = componentSchema.slots; + const slotPropNames = componentSchema.templates; const slots = {}; slotPropNames.map((slotPropName: string) => { const slotTemplateInfo = componentConfig[slotPropName]; 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 0816ea49c4d..97e8fc5145a 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 @@ -47,7 +47,6 @@ "type": "string", "default": "" }, - "itemTemplate": { "description": "列表行模板", "type": "string", @@ -57,7 +56,7 @@ "events": [ "onItemClick" ], - "slots": [ + "templates": [ "itemTemplate" ], "required": [ -- Gitee From e88a9d75356cd6fa6b4d88c601dffb7a082b782e Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Thu, 10 Apr 2025 20:28:43 +0800 Subject: [PATCH 209/287] =?UTF-8?q?feature:=20=E8=AE=BE=E8=AE=A1=E5=99=A8?= =?UTF-8?q?=E9=80=82=E9=85=8D=E7=A7=BB=E5=8A=A8=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/designer/farris.config.mjs | 4 +- packages/designer/index.html | 2 + packages/designer/package.json | 1 + .../public/assets/farris-mobile-page.css | 5124 +++++++++++++++++ .../public/assets/farris-mobile-ui-vue.css | 1 + packages/designer/src/app-providers.ts | 6 +- .../form-designer/form-designer.component.tsx | 33 +- .../composition/use-view-model-list.ts | 24 +- .../command/supported-controller.ts | 436 +- .../mobile-supported-controller.json | 139 + .../pc-supported-controller.json | 452 ++ .../use-mobile-control-creator.ts | 241 + .../use-pc-control-creator.service.ts} | 6 +- .../designer-context/use-designer-context.ts | 23 + .../use-mobile-designer-context.ts | 59 + .../use-pc-designer-context.ts | 50 + .../controller/controller-selector.service.ts | 17 +- .../controller/mobile-categories.ts | 73 + .../{categories.ts => pc-categories.ts} | 0 .../components/composition/use-form-schema.ts | 3 +- .../src/components/designer.component.tsx | 5 +- .../src/components/types/designer-context.ts | 20 + .../types/toolbox/mobile-toolbox.json | 165 + .../components/types/toolbox/pc-toolbox.json} | 0 packages/designer/vite.config.dev.ts | 7 +- .../components/button-group/index.ts | 8 +- .../button-group/src/button-group.props.ts | 7 +- .../mobile-ui-vue/components/button/index.ts | 12 +- .../components/button/src/button.props.ts | 13 +- .../components/checkbox-group/index.ts | 14 +- .../src/checkbox-group.props.ts | 4 +- .../mobile-ui-vue/components/common/types.ts | 8 + .../components/component/index.ts | 12 +- .../component/src/component.props.ts | 4 +- .../components/content-container/index.ts | 11 +- .../src/content-container.props.ts | 4 +- .../components/date-picker-input/index.ts | 14 +- .../src/date-picker-input.props.ts | 4 +- .../src/composition/dg-control.ts | 2 +- .../function/create-design-builder.ts | 52 - .../function/use-designer-component.ts | 4 +- .../function/use-designer-inner-component.ts | 4 +- packages/mobile-ui-vue/components/designer.ts | 1 + .../components/dynamic-resolver/index.ts | 7 +- .../src/property-config-resolver.ts | 248 - .../dynamic-resolver/src/props-resolver.ts | 46 +- .../property-config-resolver-design.ts | 13 + .../property-config-resolver.ts | 10 + .../use-property-config-resolver.ts | 249 + .../resolver/schema/schema-resolver-design.ts | 14 + .../src/resolver/schema/schema-resolver.ts | 10 + .../resolver/schema/use-schema-resolver.ts | 137 + .../dynamic-resolver/src/schema-resolver.ts | 134 - .../components/float-container/index.ts | 12 +- .../src/float-container.props.ts | 4 +- .../components/form-item/index.ts | 14 +- .../designer/form-item.design.component.tsx | 4 +- .../response-form-use-designer-rules.ts | 4 +- .../form-item/src/form-item.props.ts | 4 +- .../components/form-item/src/form.props.ts | 4 +- .../src/schema/form-item.schema.json | 4 +- .../mobile-ui-vue/components/form/index.ts | 12 +- packages/mobile-ui-vue/components/index.ts | 2 +- .../components/input-group/index.ts | 12 +- .../input-group/src/input-group.props.ts | 4 +- .../components/list-view/index.ts | 16 +- .../list-view/src/list-view.props.ts | 4 +- .../mobile-ui-vue/components/navbar/index.ts | 16 +- .../components/navbar/src/navbar.props.ts | 4 +- .../navbar/src/schema/navbar.schema.json | 2 +- .../components/page-body-container/index.ts | 14 +- .../src/page-body-container.props.ts | 4 +- .../components/page-container/index.ts | 14 +- .../src/page-container.props.ts | 4 +- .../page-container/src/page-container.scss | 13 + .../components/page-footer-container/index.ts | 12 +- .../src/page-footer-container.props.ts | 4 +- .../components/page-header-container/index.ts | 13 +- .../src/page-header-container.props.ts | 4 +- .../components/picker-input/index.ts | 14 +- .../picker-input/src/picker-input.props.ts | 4 +- .../components/radio-group/index.ts | 14 +- .../radio-group/src/radio-group.props.ts | 4 +- .../components/register-designer.ts | 31 + .../mobile-ui-vue/components/switch/index.ts | 12 +- .../components/switch/src/switch.props.ts | 4 +- .../components/textarea/index.ts | 14 +- .../components/textarea/src/textarea.props.ts | 4 +- packages/ui-vue/components/common/types.ts | 8 + .../designer-canvas/src/components/maps.ts | 29 +- .../src/composition/class/designer-canvas.css | 8 + .../function/use-designer-component.ts | 4 +- .../function/use-designer-inner-component.ts | 4 +- .../props/designer-canvas.props.ts | 3 + .../src/designer-canvas.component.tsx | 32 +- .../src/composition/use-data-view.ts | 15 +- .../src/toolbox.component.tsx | 3 +- .../designer-toolbox/src/toolbox.props.ts | 2 +- .../designer/form-group.design.component.tsx | 4 +- .../response-form-use-designer-rules.ts | 4 +- .../components/dynamic-resolver/index.ts | 7 +- .../src/property-config-resolver.ts | 246 - .../dynamic-resolver/src/props-resolver.ts | 12 +- .../property-config-resolver-design.ts | 13 + .../property-config-resolver.ts | 10 + .../use-property-config-resolver.ts | 248 + .../resolver/schema/schema-resolver-design.ts | 14 + .../src/resolver/schema/schema-resolver.ts | 10 + .../resolver/schema/use-schema-resolver.ts | 136 + .../dynamic-resolver/src/schema-resolver.ts | 134 - .../src/property-panel.component.tsx | 8 +- .../src/designer/use-designer-item-rules.ts | 4 +- .../designer/tab-header.design.component.tsx | 4 +- .../tabs/src/designer/tabs-use-design.ts | 4 +- 114 files changed, 7699 insertions(+), 1509 deletions(-) create mode 100644 packages/designer/public/assets/farris-mobile-page.css create mode 100644 packages/designer/public/assets/farris-mobile-ui-vue.css create mode 100644 packages/designer/src/components/composition/command/supported-controllers/mobile-supported-controller.json create mode 100644 packages/designer/src/components/composition/command/supported-controllers/pc-supported-controller.json create mode 100644 packages/designer/src/components/composition/control-creator/use-mobile-control-creator.ts rename packages/designer/src/components/composition/{control-creator.service.ts => control-creator/use-pc-control-creator.service.ts} (98%) create mode 100644 packages/designer/src/components/composition/designer-context/use-designer-context.ts create mode 100644 packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts create mode 100644 packages/designer/src/components/composition/designer-context/use-pc-designer-context.ts create mode 100644 packages/designer/src/components/composition/schema-repository/controller/mobile-categories.ts rename packages/designer/src/components/composition/schema-repository/controller/{categories.ts => pc-categories.ts} (100%) create mode 100644 packages/designer/src/components/types/designer-context.ts create mode 100644 packages/designer/src/components/types/toolbox/mobile-toolbox.json rename packages/{ui-vue/components/designer-toolbox/src/toolbox.json => designer/src/components/types/toolbox/pc-toolbox.json} (100%) delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/composition/function/create-design-builder.ts delete mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/property-config-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver-design.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver-design.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts delete mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/schema-resolver.ts create mode 100644 packages/mobile-ui-vue/components/register-designer.ts delete mode 100644 packages/ui-vue/components/dynamic-resolver/src/property-config-resolver.ts create mode 100644 packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver-design.ts create mode 100644 packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver.ts create mode 100644 packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts create mode 100644 packages/ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver-design.ts create mode 100644 packages/ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver.ts create mode 100644 packages/ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts delete mode 100644 packages/ui-vue/components/dynamic-resolver/src/schema-resolver.ts diff --git a/packages/designer/farris.config.mjs b/packages/designer/farris.config.mjs index fab0811a566..e987a543247 100644 --- a/packages/designer/farris.config.mjs +++ b/packages/designer/farris.config.mjs @@ -12,6 +12,7 @@ const replaceUIVueComponentsPath = function () { const chunk = bundle[fileName]; if (chunk.type === 'chunk') { chunk.code = chunk.code.replace(/@farris\/ui-vue\/components/g, '@farris/ui-vue'); + chunk.code = chunk.code.replace(/@farris\/mobile-ui-vue\/components/g, '@farris/mobile-ui-vue'); } } } @@ -23,7 +24,7 @@ export default { // outDir: fileURLToPath(new URL('./dist', import.meta.url)), // 外部依赖排除项 默认值 { include: [], exclude: [] } externals: { - include: ['jsonp', 'echarts', 'lodash-es', 'lodash', 'axios', '@farris/ui-vue', 'vue','rxjs','rxjs/operators'], + include: ['jsonp', 'echarts', 'lodash-es', 'lodash', 'axios', '@farris/ui-vue', '@farris/mobile-ui-vue', 'vue','rxjs','rxjs/operators'], filter: (externals) => { return (id) => { return externals.find((item) => { @@ -38,6 +39,7 @@ export default { alias: [ { find: '@', replacement: fileURLToPath(new URL('./src', import.meta.url)) }, { find: '@farris/ui-vue/components', replacement: fileURLToPath(new URL('../ui-vue/components', import.meta.url)) }, + { find: '@farris/mobile-ui-vue/components', replacement: fileURLToPath(new URL('../mobile-ui-vue/components', import.meta.url)) }, { find: '@farris/code-editor-vue/components', replacement: fileURLToPath(new URL('../code-editor/components', import.meta.url)) } ], // 插件 默认值 [vue(), vueJsx()] 不要重复添加 diff --git a/packages/designer/index.html b/packages/designer/index.html index 7a905fd4018..627d3926d15 100644 --- a/packages/designer/index.html +++ b/packages/designer/index.html @@ -5,6 +5,8 @@ + + Farris Vue Designer diff --git a/packages/designer/package.json b/packages/designer/package.json index ae954e68d4a..12679748b46 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@farris/ui-vue": "workspace:^", + "@farris/mobile-ui-vue": "workspace:^", "@farris/code-editor-vue":"workspace:^", "@monaco-editor/loader": "^1.4.0", "monaco-editor": "^0.52.2", diff --git a/packages/designer/public/assets/farris-mobile-page.css b/packages/designer/public/assets/farris-mobile-page.css new file mode 100644 index 00000000000..6c30cece8c1 --- /dev/null +++ b/packages/designer/public/assets/farris-mobile-page.css @@ -0,0 +1,5124 @@ +@charset "UTF-8"; + +#app, +.fm-page { + position: absolute; + left: 0; + right: 0; + top: 0 +} + +a, +abbr, +acronym, +address, +applet, +article, +aside, +audio, +b, +big, +blockquote, +body, +canvas, +caption, +center, +cite, +code, +dd, +del, +details, +dfn, +div, +dl, +dt, +em, +embed, +fieldset, +figcaption, +figure, +footer, +form, +h1, +h2, +h3, +h4, +h5, +h6, +header, +hgroup, +html, +i, +iframe, +img, +ins, +kbd, +label, +legend, +li, +mark, +menu, +nav, +object, +ol, +output, +p, +pre, +q, +ruby, +s, +samp, +section, +small, +span, +strike, +strong, +sub, +summary, +sup, +table, +tbody, +td, +tfoot, +th, +thead, +time, +tr, +tt, +u, +ul, +var, +video { + margin: 0; + padding: 0 +} + +html { + line-height: 1; + -webkit-tap-highlight-color: transparent +} + +ol, +ul { + list-style: none +} + +table { + border-collapse: collapse; + border-spacing: 0 +} + +caption, +td, +th { + font-weight: 400; + vertical-align: middle +} + +blockquote, +q { + quotes: none +} + +blockquote::after, +blockquote::before, +q::after, +q::before { + content: ''; + content: none +} + +a img { + border: none +} + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section, +summary { + display: block +} + +*, +::after, +::before { + box-sizing: border-box +} + +#app, +body, +html { + overflow: hidden; + -webkit-overflow-scrolling: auto +} + +body { + min-height: 100vh; + display: flex; + color: #333; + background-color: #fff +} + +a { + text-decoration: none; + background: 0 0 +} + +button, +input[type=number], +input[type=text], +input[type=password], +input[type=email], +input[type=search], +select, +textarea { + margin: 0; + font-family: inherit; + -moz-appearance: none; + appearance: none; + -webkit-appearance: none +} + +#app { + bottom: 0 +} + +@supports ((height:constant(safe-area-inset-top)) or (height:env(safe-area-inset-top))) and (-webkit-overflow-scrolling:touch) { + #app { + bottom: 20px + } + + #app #app { + bottom: 0 + } +} + +.fm-text-light { + color: #888 +} + +.fm-text-lighter { + color: #777 +} + +.fm-text-lightest { + color: #666 +} + +.fm-text-emph { + color: #333 +} + +.fm-text-primary { + color: #3A90FF +} + +.fm-utils-clearfix::after { + content: ''; + clear: both; + overflow: hidden +} + +.fm-page { + flex: 1; + display: flex; + flex-direction: column; + background: #f9fafb; + overflow: hidden; + bottom: 0; + -webkit-overflow-scrolling: auto +} + +.fm-page-header { + flex-shrink: 0 +} + +.fm-page-main { + flex-basis: 0; + flex-shrink: 1; + flex-grow: 1; + padding-bottom: 12px; + overflow: auto; + display: flex; + flex-direction: column +} + +.fm-page-main::-webkit-scrollbar { + display: none +} + +.fm-page-navbar { + flex-shrink: 0 +} + +.fm-page-footer { + background-color: #fff +} + +.fm-page-footer-btns { + display: flex; + flex-direction: row; + align-items: center; + height: 100% +} + +.fm-page-footer-btns-item { + flex: 1; + display: flex; + flex-direction: column; + text-align: center; + justify-content: center +} + +.fm-page-footer-btns-item-icon { + margin-bottom: 4px; + font-size: 18px +} + +.fm-page-footer-btns-item-text { + font-size: 12px; + color: #999 +} + +.fm-page-footer-btns-item:hover .fm-page-footer-btns-item-icon { + font-size: 22px; + color: #3a90ff +} + +.fm-page-footer-btns-item:hover .fm-page-footer-btns-item-text { + color: #3a90ff +} + +.fm-form-control { + display: block; + width: 100%; + min-width: 0; + height: 22px; + margin: 0; + padding: 0 4px; + font-size: 14px; + color: #333; + line-height: inherit; + text-align: left; + background-color: transparent; + border: 1px solid #ddd; + border-radius: 3px; + resize: none +} + +.fm-form-control:focus { + border-color: #3499f6 +} + +.fm-textarea { + border-radius: 4px; + padding: 6px 16px; + width: 100%; + border: 1px solid #ddd; + outline: 0; + font-size: 14px; + line-height: 24px; + color: #333; + display: inline-flex; + vertical-align: middle +} + +.fm-textarea:focus { + border-color: #3499f6 +} + +.align-baseline { + vertical-align: baseline !important +} + +.align-top { + vertical-align: top !important +} + +.align-middle { + vertical-align: middle !important +} + +.align-bottom { + vertical-align: bottom !important +} + +.align-text-bottom { + vertical-align: text-bottom !important +} + +.align-text-top { + vertical-align: text-top !important +} + +.bg-info { + background-color: #4D9AFF !important +} + +.bg-submit { + background-color: #5AC1C3 !important +} + +.bg-success { + background-color: #5CC171 !important +} + +.bg-warning { + background-color: #FF9800 !important +} + +.bg-danger { + background-color: #F24645 !important +} + +.bg-white { + background-color: #fff !important +} + +.bg-transparent { + background-color: transparent !important +} + +.border { + border: 1px solid #DDD; + border-radius: 0 +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .border { + position: relative; + border: none + } + + html:not([data-scale]) .border::before { + content: ''; + position: absolute; + left: 0; + top: 0; + width: 200%; + height: 200%; + border: 1px solid #DDD; + border-radius: 0; + transform-origin: 0 0; + transform: scale(.5); + box-sizing: border-box; + pointer-events: none + } +} + +.border-top { + border-top: 1px solid #DDD; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .border-top { + border-top: none + } + + html:not([data-scale]) .border-top::before { + content: ''; + position: absolute; + background-color: #DDD; + display: block; + z-index: 1; + top: 0; + right: auto; + bottom: auto; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 50%; + transform: scaleY(.5) + } +} + +.border-right { + border-right: 1px solid #DDD; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .border-right { + border-right: none + } + + html:not([data-scale]) .border-right::after { + content: ''; + position: absolute; + display: block; + z-index: 1; + top: 0; + right: 0; + bottom: auto; + left: auto; + width: 1PX; + height: 100%; + background: #DDD; + transform-origin: 100% 50%; + transform: scaleX(.5) + } +} + +.border-bottom { + border-bottom: 1px solid #DDD; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .border-bottom { + border-bottom: none + } + + html:not([data-scale]) .border-bottom::after { + content: ''; + position: absolute; + background-color: #DDD; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.border-left { + border-left: 1px solid #DDD; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .border-left { + border-left: none + } + + html:not([data-scale]) .border-left::before { + content: ''; + position: absolute; + background-color: #DDD; + display: block; + z-index: 1; + top: 0; + right: auto; + bottom: auto; + left: 0; + width: 1PX; + height: 100%; + transform-origin: 100% 50%; + transform: scaleX(.5) + } +} + +.border-0::before, +.border-bottom-0::after, +.border-left-0::before, +.border-right-0::after, +.border-top-0::before { + display: none !important +} + +.border-0 { + border: 0 +} + +.border-top-0 { + border-top: 0 +} + +.border-right-0 { + border-right: 0 +} + +.border-bottom-0 { + border-bottom: 0 +} + +.border-left-0 { + border-left: 0 +} + +.clearfix::after { + display: block; + clear: both; + content: "" +} + +.display-none { + display: none !important +} + +.display-inline { + display: inline !important +} + +.display-inline-block { + display: inline-block !important +} + +.d-block, +.display-block { + display: block !important +} + +.display-table { + display: table !important +} + +.display-table-row { + display: table-row !important +} + +.display-table-cell { + display: table-cell !important +} + +.d-flex, +.display-flex, +.fm-utils-flex-column { + display: flex !important +} + +.display-inline-flex { + display: inline-flex !important +} + +.flex-direction-row, +.flex-row { + flex-direction: row !important +} + +.flex-column, +.flex-direction-column { + flex-direction: column !important +} + +.flex-direction-row-reverse, +.flex-row-reverse { + flex-direction: row-reverse !important +} + +.flex-column-reverse, +.flex-direction-column-reverse { + flex-direction: column-reverse !important +} + +.flex-row, +.fm-utils-flex-row { + flex-direction: row !important +} + +.float-left { + float: left !important +} + +.float-right { + float: right !important +} + +.float-none { + float: none !important +} + +.position-static { + position: static !important +} + +.position-relative { + position: relative !important +} + +.position-absolute { + position: absolute !important +} + +.position-fixed { + position: fixed !important +} + +.position-sticky { + position: -webkit-sticky !important; + position: sticky !important +} + +.fixed-bottom, +.fixed-top { + position: fixed; + z-index: 1030; + right: 0; + left: 0 +} + +.fixed-top { + top: 0 +} + +.fixed-bottom { + bottom: 0 +} + +.shadow-none { + box-shadow: none !important +} + +.w-25 { + width: 25% !important +} + +.w-50 { + width: 50% !important +} + +.w-75 { + width: 75% !important +} + +.w-100 { + width: 100% !important +} + +.w-auto { + width: auto !important +} + +.h-25 { + height: 25% !important +} + +.h-50 { + height: 50% !important +} + +.h-75 { + height: 75% !important +} + +.h-100 { + height: 100% !important +} + +.h-auto { + height: auto !important +} + +.mw-100 { + max-width: 100% !important +} + +.mh-100 { + max-height: 100% !important +} + +.m-0 { + margin: 0 !important +} + +.mt-0, +.my-0 { + margin-top: 0 !important +} + +.mr-0, +.mx-0 { + margin-right: 0 !important +} + +.mb-0, +.my-0 { + margin-bottom: 0 !important +} + +.ml-0, +.mx-0 { + margin-left: 0 !important +} + +.p-0 { + padding: 0 !important +} + +.pt-0, +.py-0 { + padding-top: 0 !important +} + +.pr-0, +.px-0 { + padding-right: 0 !important +} + +.pb-0, +.py-0 { + padding-bottom: 0 !important +} + +.pl-0, +.px-0 { + padding-left: 0 !important +} + +.m-base { + margin: 4px !important +} + +.mt-base, +.my-base { + margin-top: 4px !important +} + +.mr-base, +.mx-base { + margin-right: 4px !important +} + +.mb-base, +.my-base { + margin-bottom: 4px !important +} + +.ml-base, +.mx-base { + margin-left: 4px !important +} + +.p-base { + padding: 4px !important +} + +.pt-base, +.py-base { + padding-top: 4px !important +} + +.pr-base, +.px-base { + padding-right: 4px !important +} + +.pb-base, +.py-base { + padding-bottom: 4px !important +} + +.pl-base, +.px-base { + padding-left: 4px !important +} + +.m-xs { + margin: 8px !important +} + +.mt-xs, +.my-xs { + margin-top: 8px !important +} + +.mr-xs, +.mx-xs { + margin-right: 8px !important +} + +.mb-xs, +.my-xs { + margin-bottom: 8px !important +} + +.ml-xs, +.mx-xs { + margin-left: 8px !important +} + +.p-xs { + padding: 8px !important +} + +.pt-xs, +.py-xs { + padding-top: 8px !important +} + +.pr-xs, +.px-xs { + padding-right: 8px !important +} + +.pb-xs, +.py-xs { + padding-bottom: 8px !important +} + +.pl-xs, +.px-xs { + padding-left: 8px !important +} + +.m-sm { + margin: 12px !important +} + +.mt-sm, +.my-sm { + margin-top: 12px !important +} + +.mr-sm, +.mx-sm { + margin-right: 12px !important +} + +.mb-sm, +.my-sm { + margin-bottom: 12px !important +} + +.ml-sm, +.mx-sm { + margin-left: 12px !important +} + +.p-sm { + padding: 12px !important +} + +.pt-sm, +.py-sm { + padding-top: 12px !important +} + +.pr-sm, +.px-sm { + padding-right: 12px !important +} + +.pb-sm, +.py-sm { + padding-bottom: 12px !important +} + +.pl-sm, +.px-sm { + padding-left: 12px !important +} + +.m-md { + margin: 16px !important +} + +.mt-md, +.my-md { + margin-top: 16px !important +} + +.mr-md, +.mx-md { + margin-right: 16px !important +} + +.mb-md, +.my-md { + margin-bottom: 16px !important +} + +.ml-md, +.mx-md { + margin-left: 16px !important +} + +.p-md { + padding: 16px !important +} + +.pt-md, +.py-md { + padding-top: 16px !important +} + +.pr-md, +.px-md { + padding-right: 16px !important +} + +.pb-md, +.py-md { + padding-bottom: 16px !important +} + +.pl-md, +.px-md { + padding-left: 16px !important +} + +.m-lg { + margin: 24px !important +} + +.mt-lg, +.my-lg { + margin-top: 24px !important +} + +.mr-lg, +.mx-lg { + margin-right: 24px !important +} + +.mb-lg, +.my-lg { + margin-bottom: 24px !important +} + +.ml-lg, +.mx-lg { + margin-left: 24px !important +} + +.p-lg { + padding: 24px !important +} + +.pt-lg, +.py-lg { + padding-top: 24px !important +} + +.pr-lg, +.px-lg { + padding-right: 24px !important +} + +.pb-lg, +.py-lg { + padding-bottom: 24px !important +} + +.pl-lg, +.px-lg { + padding-left: 24px !important +} + +.m-xl { + margin: 32px !important +} + +.mt-xl, +.my-xl { + margin-top: 32px !important +} + +.mr-xl, +.mx-xl { + margin-right: 32px !important +} + +.mb-xl, +.my-xl { + margin-bottom: 32px !important +} + +.ml-xl, +.mx-xl { + margin-left: 32px !important +} + +.p-xl { + padding: 32px !important +} + +.pt-xl, +.py-xl { + padding-top: 32px !important +} + +.pr-xl, +.px-xl { + padding-right: 32px !important +} + +.pb-xl, +.py-xl { + padding-bottom: 32px !important +} + +.pl-xl, +.px-xl { + padding-left: 32px !important +} + +.m-auto { + margin: auto !important +} + +.mt-auto, +.my-auto { + margin-top: auto !important +} + +.mr-auto, +.mx-auto { + margin-right: auto !important +} + +.mb-auto, +.my-auto { + margin-bottom: auto !important +} + +.ml-auto, +.mx-auto { + margin-left: auto !important +} + +.text-justify { + text-align: justify !important +} + +.text-nowrap { + white-space: nowrap !important +} + +.text-align-left { + text-align: left !important +} + +.text-align-right { + text-align: right !important +} + +.text-align-center { + text-align: center !important +} + +.text-lowercase { + text-transform: lowercase !important +} + +.text-uppercase { + text-transform: uppercase !important +} + +.text-capitalize { + text-transform: capitalize !important +} + +.font-weight-light { + font-weight: 300 !important +} + +.font-weight-normal { + font-weight: 400 !important +} + +.font-weight-bold { + font-weight: 700 !important +} + +.font-italic { + font-style: italic !important +} + +.text-white { + color: #fff !important +} + +.visible { + visibility: visible +} + +.invisible { + visibility: hidden +} + +.d-flex { + display: flex +} + +.d-inline-flex { + display: inline-flex +} + +.d-block { + display: block +} + +.d-inline-block { + display: inline-block +} + +.d-inline { + display: inline +} + +.flex-column { + flex-direction: column !important +} + +.flex-row-reverse { + flex-direction: row-reverse !important +} + +.flex-column-reverse { + flex-direction: column-reverse !important +} + +.flex-wrap { + flex-wrap: wrap !important +} + +.flex-nowrap { + flex-wrap: nowrap !important +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important +} + +.flex-fill { + flex: 1 1 auto !important +} + +.flex-grow-0 { + flex-grow: 0 !important +} + +.flex-grow-1 { + flex-grow: 1 !important +} + +.flex-shrink-0 { + flex-shrink: 0 !important +} + +.flex-shrink-1 { + flex-shrink: 1 !important +} + +.justify-content-start { + justify-content: flex-start !important +} + +.justify-content-end { + justify-content: flex-end !important +} + +.justify-content-center { + justify-content: center !important +} + +.justify-content-between { + justify-content: space-between !important +} + +.justify-content-around { + justify-content: space-around !important +} + +.align-items-start { + align-items: flex-start !important +} + +.align-items-end { + align-items: flex-end !important +} + +.align-items-center { + align-items: center !important +} + +.align-items-baseline { + align-items: baseline !important +} + +.align-items-stretch { + align-items: stretch !important +} + +.align-content-start { + align-content: flex-start !important +} + +.align-content-end { + align-content: flex-end !important +} + +.align-content-center { + align-content: center !important +} + +.align-content-between { + align-content: space-between !important +} + +.align-content-around { + align-content: space-around !important +} + +.align-content-stretch { + align-content: stretch !important +} + +.align-self-auto { + align-self: auto !important +} + +.align-self-start { + align-self: flex-start !important +} + +.align-self-end { + align-self: flex-end !important +} + +.align-self-center { + align-self: center !important +} + +.align-self-baseline { + align-self: baseline !important +} + +.align-self-stretch { + align-self: stretch !important +} + +.fm-utils-absolute-all { + top: 0; + bottom: 0; + position: absolute; + right: 0; + left: 0 +} + +.fm-utils-flex-column { + flex-direction: column !important; + overflow: hidden +} + +.fm-utils-fill-flex-column, +.fm-utils-fill-flex-row { + flex-shrink: 1; + display: flex !important; + overflow: hidden +} + +.fm-utils-fill-flex-column { + flex-grow: 1; + flex-basis: 0; + flex-direction: column !important +} + +.fm-utils-flex-row { + display: flex !important; + overflow: hidden; + flex-wrap: nowrap +} + +.fm-utils-flex-row-wrap { + display: flex !important; + flex-direction: row !important; + overflow: hidden; + flex-wrap: wrap !important +} + +.fm-utils-fill-flex-row { + flex-grow: 1; + flex-basis: 0; + flex-direction: row !important; + flex-wrap: nowrap !important +} + +.fm-utils-fill-flex-row-wrap { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + display: flex !important; + flex-direction: row !important; + overflow: hidden; + flex-wrap: wrap !important +} + +.fm-utils-fill { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + overflow: hidden +} + +.fm-utils-fill-auto { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + overflow-x: hidden; + overflow-y: auto +} + +.fm-utils-overflow-xhya { + overflow-x: hidden !important; + overflow-y: auto !important +} + +.fm-utils-overflow-xayh { + overflow-y: hidden !important; + overflow-x: auto !important +} + +.fm-utils-overflow-xaya { + overflow: auto !important +} + +.fm-utils-overflow-hidden { + overflow: hidden !important +} + +.fm-utils-overflow-auto { + overflow: auto !important +} + +.fm-overflow-x-auto { + overflow-x: auto !important +} + +.fm-overflow-x-hidden, +.fm-overflow-y-auto, +.fm-overflow-y-hidden { + overflow-x: hidden !important +} + +.fm-overflow-y-auto { + overflow-y: auto !important +} + +.fm-overflow-y-hidden { + overflow-y: hidden !important +} + +.fm-overflow-hidden { + overflow: hidden !important +} + +.fm-utils-text-break { + white-space: normal !important; + word-break: break-all !important +} + +.fm-utils-display-none { + display: none !important +} + +.fm-multi-ellipsis-l2, +.fm-multi-ellipsis-l3 { + display: -webkit-box; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis +} + +.fm-ellipsis { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis +} + +.fm-multi-ellipsis-l2 { + -webkit-line-clamp: 2 +} + +.fm-multi-ellipsis-l3 { + -webkit-line-clamp: 3 +} + +.fm-float-button-wrapper { + position: absolute; + right: 16px; + bottom: 50px +} + +.fm-listview-error { + background: #fff; + box-shadow: 0 2px 6px 0 rgba(0, 0, 0, .12) +} + +.fm-error-cell { + position: relative; + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 16px; + height: 32px +} + +.fm-error-cell:not(:last-child)::after { + content: ''; + height: 1px; + position: absolute; + background-color: #f1f1f1; + display: block; + z-index: 1; + bottom: 0; + left: 16px; + right: 0; + transform: translateY(.5) +} + +.fm-error-text { + font-size: 13px; + color: #f24645; + line-height: 22px +} + +.fm-error-icon { + background: #F24645; + color: #fff; + border-radius: 100%; + margin-right: 4px +} + +.fm-without-last-child .fm-bottom-line { + border-bottom: 1px solid var(--fm-border-color); + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-without-last-child .fm-bottom-line { + border-bottom: none + } + + html:not([data-scale]) .fm-without-last-child .fm-bottom-line::after { + content: ''; + position: absolute; + background-color: var(--fm-border-color); + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.fm-tmpl-single-header { + height: 32px; + display: flex; + align-items: center; + padding: 0 0 0 16px; + background: #F8F9FB +} + +.fm-tmpl-single-header h6 { + color: #999; + font-size: 15px; + font-weight: 400; + margin: 0 +} + +.fm-tmpl-singlelist-with-iconarea { + background: #fff; + overflow: hidden +} + +.fm-tmpl-singlelist-with-iconarea .singlelist--item { + align-items: center; + padding: 0 0 0 16px; + display: flex +} + +.fm-tmpl-singlelist-with-iconarea .singlelist--item:last-child .singlelist--item-title-wrapper { + border-bottom: none +} + +.fm-tmpl-singlelist-with-iconarea .singlelist--item .item-img-round--wrapper .item-img-round--img { + width: 26px; + height: 26px; + border-radius: 13px +} + +.fm-tmpl-singlelist-with-iconarea .singlelist--item .item-img-round--wrapper .item-img-round--img .fm-icon { + line-height: 26px +} + +.fm-tmpl-singlelist-with-iconarea .singlelist--item-title-wrapper { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + color: #333; + font-size: 16px; + line-height: 22px; + padding: 11px 0 10px; + border-bottom: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-singlelist-with-iconarea .singlelist--item-title-wrapper { + border-bottom: none + } + + html:not([data-scale]) .fm-tmpl-singlelist-with-iconarea .singlelist--item-title-wrapper::after { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.item-img-round--wrapper { + margin: 0 10px 0 0 +} + +.item-img-round--wrapper .item-img-round--img { + width: 30px; + height: 30px; + border-radius: 15px; + text-align: center; + color: #fff +} + +.item-img-round--wrapper .item-img-round--img .fm-icon { + font-size: 18px; + line-height: 30px +} + +.item-img-round--wrapper .fm-bg-yellow { + background: #FBB902 +} + +.item-img-round--wrapper .fm-bg-orange { + background: #FF9800 +} + +.item-img-round--wrapper .fm-bg-blue { + background: #4D9AFF +} + +.item-img-round--wrapper .fm-bg-lightblue { + background: #5ACBCD +} + +.item-img-round--wrapper .fm-bg-purple { + background: #817EFF +} + +.item-img-round--wrapper .fm-bg-darkgreen { + background: #51BD78 +} + +.fm-tmpl-header-with-img { + display: flex; + align-items: center +} + +.fm-tmpl-header-with-img h5 { + font-size: 16px; + color: #333; + margin: 0; + font-weight: 400 +} + +.fm-tmpl-header-with-img .header-with-img--img-wrapper { + margin: 0 8px 0 0 +} + +.fm-tmpl-header-with-img .header-with-img--img-wrapper .header-with-img--img { + width: 20px; + height: 20px; + border-radius: 10px; + line-height: 20px; + text-align: center; + color: #fff; + background-image: linear-gradient(180deg, #64CDFB 1%, #3A90FF 100%) +} + +.fm-tmpl-header-with-img .header-with-img--img-wrapper .header-with-img--img .fm-icon { + font-size: 12px +} + +.fm-tmpl-header-with-img .header-with-img--img-wrapper .fm-bg-blue { + color: #fff; + background-image: linear-gradient(180deg, #64CDFB 1%, #3A90FF 100%) +} + +.fm-tmpl-header-with-img .header-with-img--img-wrapper .fm-bg-orange { + color: #fff; + background-image: linear-gradient(180deg, #FFB951 15%, #FF9800 100%) +} + +.fm-tmpl-header-with-img .header-with-img--img-wrapper .fm-bg-green { + color: #fff; + background-image: linear-gradient(180deg, #7ACC8D 15%, #51BD78 100%) +} + +.fm-cmp-collapse-style::after { + display: none +} + +.fm-cmp-collapse-style .van-collapse-item__title { + align-items: center +} + +.fm-cmp-collapse-style .van-collapse-item__content { + padding: 0 +} + +.fm-cmp-collapse-style.van-collapse { + margin: 0 0 12px +} + +.fm-cmp-collapse-style.van-collapse:last-child { + margin-bottom: 0 +} + +.fm-tmpl-collapse-sub::after { + border-bottom: 0 +} + +.fm-tmpl-collapse-sub-header { + display: flex; + flex-direction: column-reverse +} + +.fm-tmpl-collapse-sub-header .van-collapse-item__title .expand, +.fm-tmpl-collapse-sub-header .van-collapse-item__title--expanded .collapse { + display: none +} + +.fm-tmpl-collapse-sub-header .van-collapse-item__title { + color: #888; + flex-direction: row-reverse; + justify-content: center +} + +.fm-tmpl-collapse-sub-header .van-collapse-item__title h6 { + color: #888; + font-size: 13px; + font-weight: 400 +} + +.fm-tmpl-collapse-sub-header .van-collapse-item__title .collapse-icon { + margin: 0 8px; + transition: transform .3s +} + +.fm-tmpl-collapse-sub-header .van-collapse-item__title--expanded .expand { + display: inline-block +} + +.fm-tmpl-collapse-sub-header .van-collapse-item__title--expanded .collapse-icon { + transform: rotate(180deg) +} + +.fm-btn-block-wrapper { + height: 42px; + background: #fff; + display: flex; + align-items: center +} + +.fm-btn-block-wrapper .fm-button { + font-size: 14px !important; + height: 100% +} + +.fm-btn-with-icon .fm-btn-text { + margin: 0 8px +} + +.fm-btn-with-icon .fm-btn-icon { + font-size: 14px +} + +.fm-tmpl-list-with-img-detail.fm-tmpl-list-with-border { + margin-bottom: 12px +} + +.fm-tmpl-list-with-img-detail.fm-tmpl-list-with-border .img-detail--item { + margin-bottom: 0; + border-bottom: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-list-with-img-detail.fm-tmpl-list-with-border .img-detail--item { + border-bottom: none + } + + html:not([data-scale]) .fm-tmpl-list-with-img-detail.fm-tmpl-list-with-border .img-detail--item::after { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.fm-round-bg { + margin: 4px auto 0; + width: 36px; + height: 36px; + background: #3A90FF; + border-radius: 20px; + line-height: 36px; + font-size: 13px; + text-align: center; + overflow: hidden; + white-space: nowrap +} + +.fm-round-bg-text { + color: #FFF +} + +.fm-tmpl-list-with-img-detail .img-detail--item { + padding: 12px 16px; + background: #fff; + border-bottom: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-list-with-img-detail .img-detail--item { + border-bottom: none + } + + html:not([data-scale]) .fm-tmpl-list-with-img-detail .img-detail--item::after { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--item-content { + display: flex; + position: relative +} + +.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--status { + position: absolute; + right: 0; + top: 23px +} + +.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--content { + position: relative; + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0 +} + +.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--header { + display: flex; + align-items: center; + justify-content: space-between; + margin: 0 0 6px +} + +.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--header .title { + line-height: 22px; + font-weight: 400; + font-size: 16px; + color: #333 +} + +.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--header .time { + line-height: 18px; + color: #999; + font-size: 13px +} + +.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--info { + line-height: 18px; + color: #999; + font-size: 13px; + margin: 0 0 4px +} + +.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--info>.gutter { + margin: 0 14px 0 0 +} + +.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--actions { + padding: 18px 0 0; + text-align: right +} + +.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--actions .fm-button { + margin-left: 13px +} + +.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--actions .fm-button:first-child { + margin-left: 0 +} + +.fm-tmpl-result { + display: flex; + flex-direction: column; + padding-top: 40px; + align-items: center +} + +.fm-tmpl-result-header .fm-result-title { + display: flex; + flex-direction: row; + font-size: 20px; + color: #333 +} + +.fm-tmpl-result-header .fm-result-title .fm-result-title-number { + color: #FF9800 +} + +.fm-tmpl-result-content { + max-width: 84%; + padding-top: 30px; + padding-bottom: 30px; + text-align: center +} + +.fm-tmpl-result-content .fm-result-img { + width: 140px; + height: 140px; + margin: 0 auto +} + +.fm-tmpl-result-content .fm-result-img img { + display: block; + width: 140px; + height: 140px +} + +.fm-tmpl-result-content .fm-result-text { + padding-top: 30px; + padding-bottom: 10px; + font-size: 16px; + color: #333; + text-align: center +} + +.fm-tmpl-result-content .fm-result-tip { + line-height: 22px; + font-size: 16px; + color: #888; + text-align: center +} + +.fm-tmpl-result-footer { + width: 140px; + margin: 0 auto +} + +.fm-tmpl-result-footer .fm-result-btn { + margin-bottom: 16px +} + +.fm-tmpl-result-footer .fm-result-btn:last-child { + margin-bottom: 0 +} + +.fm-tabbar-style { + border-top: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tabbar-style { + border-top: none + } + + html:not([data-scale]) .fm-tabbar-style::before { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: 0; + right: auto; + bottom: auto; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 50%; + transform: scaleY(.5) + } +} + +.fm-tabbar-style .show-fixed-width { + padding: 0 17px; + flex-shrink: 0; + flex-grow: 0; + flex-basis: auto +} + +.fm-tabbar-style .show-fixed-width+.show-left-width { + padding: 7px 16px 7px 0 +} + +.fm-tabbar-style .show-fixed-width .van-tabbar-item__icon .fm-icon { + font-size: 19px +} + +.fm-tabbar-style .show-fixed-width .van-tabbar-item__text { + font-size: 12px; + transform: scale(.8333) +} + +.fm-tabbar-style .show-left-width { + padding: 7px 16px +} + +.fm-tabbar-style .show-left-width .fm-button { + height: 100% +} + +.fm-tmpl-detail-header { + padding-left: 16px; + background-color: #fff +} + +.fm-tmpl-detail-header-inner { + display: flex; + flex-direction: row; + align-items: center; + padding: 16px 16px 16px 0; + border-bottom: 1px solid #DDD; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-detail-header-inner { + border-bottom: none + } + + html:not([data-scale]) .fm-tmpl-detail-header-inner::after { + content: ''; + position: absolute; + background-color: #DDD; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.fm-approve-flow-wrapper .fm-approve-flow-item .fm-approve-flow-item-header-icon .header-icon::before, +.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar .avatar-icon::before { + content: "\e6b4" +} + +.fm-tmpl-detail-header-inner .detail-header--avatar { + width: 40px; + margin-right: 10px; + border-radius: 50%; + overflow: hidden +} + +.fm-tmpl-detail-header-inner .detail-header--avatar img { + display: block; + width: 40px; + height: 40px +} + +.fm-tmpl-detail-header-inner .detail-header--content { + flex: 1 +} + +.fm-tmpl-detail-header-inner .detail-header--content-title { + margin-bottom: 3px; + font-size: 15px; + color: #333 +} + +.fm-tmpl-detail-header-inner .detail-header--content-subtitle { + font-size: 13px; + color: #888 +} + +.fm-static-input-list { + padding: 16px 0 16px 16px; + background-color: #fff; + margin: 0 0 8px +} + +.fm-static-input-list .fm-listview-item:last-child .fm-static-input-info { + margin-bottom: 0 +} + +.fm-static-input-info { + display: flex; + flex-direction: row; + align-items: center; + margin-bottom: 8px; + line-height: 20px +} + +.fm-static-input-info .input-info--label { + width: 92px; + font-size: 14px; + color: #999; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap +} + +.fm-static-input-info .input-info--text { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + padding-left: 8px; + font-size: 14px; + color: #333 +} + +.fm-static-input-info .input-info--accessory { + display: flex; + flex-direction: row; + align-items: center; + flex-wrap: wrap +} + +.fm-static-input-info .input-info--accessory-item { + flex-shrink: 0; + width: 28px; + height: 28px; + margin-right: 12px; + border-radius: 3px; + overflow: hidden +} + +.fm-static-input-info .input-info--accessory-item img { + display: block; + width: 28px +} + +.fm-static-input-info .input-info--accessory-item:last-child { + margin-right: 0 +} + +.fm-approve-flow-wrapper { + padding: 12px 16px; + background-color: #fff +} + +.fm-approve-flow-wrapper .fm-approve-flow-item { + padding-left: 7px +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-header { + position: relative; + border-left: 1px dashed #D4D4D4 +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner { + position: relative; + display: flex; + flex-direction: row; + align-items: center; + padding-left: 28px +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon { + position: absolute; + left: -8px; + top: 0; + z-index: 100 +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon .fm-icon { + background-color: #fff; + font-size: 15px; + color: #34AAFF; + border-radius: 50% +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon img { + background: #fff +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-content { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + line-height: 21px; + font-size: 15px; + color: #4C4C4C; + font-weight: 700 +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-right { + flex-shrink: 0; + padding-left: 6px +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-right .fm-icon { + color: #979797 +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-header-state { + margin-top: 6px; + padding-left: 28px; + font-size: 13px; + color: #FF9002 +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-content { + display: flex; + flex-direction: row; + align-items: flex-start; + padding: 12px 0 30px 28px; + border-left: 1px dashed #D4D4D4 +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + display: flex; + flex-direction: row; + align-items: flex-start +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar { + position: relative; + display: flex; + flex-direction: row; + align-items: center; + width: 36px; + height: 36px +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar-img { + display: block; + width: 36px; + height: 36px; + border-radius: 50% +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar-icon { + position: absolute; + right: 4px; + bottom: -4px; + font-size: 14px; + color: #34AAFF; + background-color: #fff; + border-radius: 50% +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-text { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + padding: 0 6px 0 9px +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-text-title { + font-size: 13px; + color: rgba(51, 51, 51, .65) +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-text-subtitle { + margin-top: 2px; + line-height: 20px; + font-size: 14px; + color: #333 +} + +.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-date { + font-size: 13px; + color: rgba(51, 51, 51, .65) +} + +.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar-icon, +.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-header .fm-approve-flow-item-header-icon .fm-icon, +.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-header .fm-approve-flow-item-header-state { + color: #1AD0C8 +} + +.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar .avatar-icon::before, +.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-header .fm-approve-flow-item-header-icon .header-icon::before { + content: "\e6b3" +} + +.fm-approve-flow-wrapper .fm-approve-flow-item:last-child .fm-approve-flow-item-header { + border-left: 0 +} + +.fm-approve-flow-wrapper .fm-approve-flow-item:last-child .fm-approve-flow-item-header::before { + display: none !important +} + +.fm-approve-flow-wrapper .fm-approve-flow-item:last-child .fm-approve-flow-item-content { + padding-bottom: 12px; + border-left: none +} + +.fm-approve-nopass, +.fm-approve-pass { + position: fixed; + top: 48px; + right: 14px; + width: 110px; + height: 110px; + z-index: 1000 +} + +.fm-approve--detail-header { + padding-left: 16px; + background-color: #fff +} + +.fm-approve--detail-header-inner { + display: flex; + flex-direction: row; + align-items: center; + padding: 17px 16px 17px 0; + border-bottom: 1px solid #DDD; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-approve--detail-header-inner { + border-bottom: none + } + + html:not([data-scale]) .fm-approve--detail-header-inner::after { + content: ''; + position: absolute; + background-color: #DDD; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.fm-approve--detail-header-inner .detail-header--avatar { + width: 40px; + margin-right: 10px; + border-radius: 50%; + overflow: hidden +} + +.fm-approve--detail-header-inner .detail-header--avatar img { + display: block; + width: 40px; + height: 40px +} + +.fm-approve--detail-header-inner .detail-header---info { + flex: 1 +} + +.fm-approve--detail-header-inner .detail-header---info-title { + margin-bottom: 3px; + font-size: 15px; + color: #333 +} + +.fm-approve--detail-header-inner .detail-header---info-subtitle { + font-size: 13px; + color: #888 +} + +.fm-apply-list-wrapper { + padding: 0 16px 16px; + background-color: #fff; + margin: 0 0 12px +} + +.fm-apply-list-item { + display: flex; + flex-direction: row; + align-items: flex-start; + margin-bottom: 8px; + line-height: 20px +} + +.fm-apply-list-item-label { + width: 92px; + font-size: 14px; + color: #999; + text-align: right; + word-break: break-all +} + +.fm-apply-list-item-text { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + padding-left: 14px; + font-size: 14px; + color: #333; + word-break: break-all +} + +.fm-apply-list-item-accessory { + display: flex; + flex-direction: row; + align-items: center; + flex-wrap: wrap +} + +.fm-apply-list-item-accessory-item { + flex-shrink: 0; + width: 28px; + height: 28px; + margin-right: 12px; + border-radius: 3px; + overflow: hidden +} + +.fm-apply-list-item-accessory-item img { + display: block; + width: 28px +} + +.fm-apply-list-item-accessory-item:last-child { + margin-right: 0 +} + +.fm-apply-list-item:last-child { + margin-bottom: 0 +} + +.fm-apply-panel-title, +.fm-apply-plate-title { + height: 28px; + line-height: 28px; + padding-left: 10px; + margin-bottom: 0; + background: #F6F6F6; + border-radius: 2px +} + +.fm-apply-panel-action, +.fm-apply-plate-action { + padding: 0 6px; + margin: 0 0 0 auto; + color: #D8D8D8 +} + +.fm-apply-panel-action:hover, +.fm-apply-plate-action:hover { + background: #3A90FF; + color: #fff +} + +.fm-apply-panel { + padding-top: 0 +} + +.fm-apply-panel .fm-apply-list { + padding-top: 10px; + padding-bottom: 14px +} + +.fm-apply-panel .fm-apply-list+.fm-apply-list { + border-top: 1px solid #E8E8E8 +} + +.fm-apply-panel-list { + padding: 0 16px; + background-color: #fff; + margin: 0; + border-bottom: 1px solid #E8E8E8 +} + +.fm-apply-panel-list:last-child { + border-bottom: none +} + +.fm-apply-panel-list .panel-list--header { + height: 42px; + display: flex; + align-items: center +} + +.fm-apply-panel-list .panel-list--header .panel-list--header-title { + font-size: 15px; + line-height: 21px; + color: #333; + padding: 0 0 0 10px; + position: relative +} + +.fm-apply-panel-list .panel-list--header .panel-list--header-title::before { + content: ''; + position: absolute; + left: 0; + top: 50%; + width: 3px; + height: 14px; + margin: -7px 0 0; + background: #55BBF6 +} + +.fm-apply-details { + margin: 0 0 14px; + background: #fff +} + +.fm-apply-main { + border-bottom: 1px solid #E8E8E8 +} + +.fm-avatar-with-state { + position: relative; + display: flex; + flex-direction: row; + align-items: center; + width: 36px; + height: 36px +} + +.fm-avatar-with-state--img { + display: block; + width: 36px; + height: 36px; + border-radius: 50% +} + +.fm-avatar-with-state--icon { + position: absolute; + right: 4px; + bottom: -4px; + font-size: 14px; + color: #34AAFF; + background-color: #fff; + border-radius: 50% +} + +.fm-avatar-with-state .avatar-icon::before { + content: "\e6b3" +} + +.fm-avatar-with-state .fm-round-bg { + background: rgba(77, 154, 255, .6) +} + +.fm-avatar-with-state.fm-state-running .avatar-icon::before { + content: "\e6b4" +} + +.fm-feature-select-person { + display: flex; + flex-direction: row; + flex-wrap: wrap; + padding: 0 0 14px +} + +.fm-feature-select-person .select-person--item { + position: relative; + display: flex; + align-items: center; + margin: 0 16px 0 0 +} + +.fm-feature-select-person .select-person--item .fm-avatar-with-state { + width: 48px; + height: 48px +} + +.fm-feature-select-person .select-person--item .fm-avatar-with-state .fm-avatar-with-state--img { + width: 48px; + height: 48px; + border-radius: 24px +} + +.fm-feature-select-person .select-person--item .fm-avatar-with-state .fm-avatar-with-state--icon { + right: 0; + top: 0; + cursor: pointer +} + +.fm-feature-select-person .select-person--item .fm-avatar-with-state .fm-avatar-with-state--icon::before { + content: "\e016" +} + +.fm-feature-select-person .select-person--item .fm-avatar-with-state .fm-avatar-with-state--icon:hover { + background: #F24645; + color: #fff +} + +.fm-feature-select-person .select-person--item .fm-round-bg { + width: 48px; + height: 48px; + border-radius: 24px; + line-height: 48px +} + +.fm-feature-select-person .select-person--icon { + margin: 0 0 0 3px; + color: #A6A6A6 +} + +.fm-feature-select-person .select-person--icon::before { + content: "→" +} + +.fm-tmpl-search-container { + position: relative; + padding: 7px 16px; + display: flex; + flex-direction: row; + align-items: center; + background: #fff +} + +.fm-tmpl-search-container .fm-tmpl-search-type { + flex-shrink: 0; + margin: 0 10px 0 0 +} + +.fm-tmpl-search-container .fm-tmpl-search-type.fm-state-active { + color: #3A90FF +} + +.fm-tmpl-search-container .fm-tmpl-search-inner { + flex: 1 1 0 +} + +.fm-tmpl-search-container .fm-tmpl-search-inner .van-search { + padding: 0 +} + +.fm-tmpl-search-container .fm-tmpl-search-tree-select { + position: absolute; + left: 0; + right: 0; + top: 100%; + z-index: 10 +} + +.fm-page-listview { + display: flex; + flex-direction: column +} + +.fm-page-listview .fm-page-main { + padding-bottom: 0; + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + overflow: hidden +} + +.fm-page-listview .fm-page-main .fm-tmpl-list-extend, +.fm-page-listview .fm-page-main .fm-tmpl-search-container { + flex-shrink: 0 +} + +.fm-page-listview .fm-page-main .fm-tmpl-list-container { + display: flex; + flex-direction: column; + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + overflow: hidden +} + +.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-list-footer { + display: flex; + flex-direction: row; + align-items: center; + height: 54px; + padding: 0 16px; + background: #fff; + box-shadow: 0 -2px 8px 0 rgba(81, 120, 159, .12) +} + +.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-list-footer .fm-tmpl-list-footer-btn { + flex: 1; + text-align: center +} + +.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-search-tree-overlay { + position: absolute; + left: 0; + bottom: 0; + right: 0; + top: 0; + z-index: 9; + background-color: rgba(0, 0, 0, .4) +} + +.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-add-btn { + position: absolute; + right: 16px; + bottom: 50px +} + +.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-add-btn-inner { + width: 48px; + height: 48px; + text-align: center; + line-height: 48px; + border-radius: 50%; + background-image: linear-gradient(-45deg, #65A7FF 0, #3A90FF 100%); + box-shadow: 0 2px 5px 0 rgba(124, 163, 254, .57) +} + +.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-add-btn-inner .fm-icon { + color: #fff; + font-size: 16px +} + +.fm-page-listview .fm-page-main .fm-tmpl-list-container .van-pull-refresh { + display: flex; + flex-direction: column; + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + overflow: hidden +} + +.fm-page-listview .fm-page-main .fm-tmpl-list-container .van-pull-refresh .van-pull-refresh__track { + display: flex; + flex-direction: column; + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0 +} + +.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-listview-wrapper .van-pull-refresh { + overflow: inherit +} + +.fm-page-listview .fm-page-main .fm-tmpl-list-add .fm-tmpl-add-btn { + bottom: 16px +} + +.fm-page-listview .fm-page-main .fm-tmpl-list-add .fm-listview-container.fm-listview-container-fill .fm-listview-main { + padding-bottom: 70px +} + +.fm-page-listview .fm-page-main .fm-tmpl-tabs { + flex: 1; + display: flex; + flex-direction: column +} + +.fm-page-listview .fm-page-main .fm-tmpl-tabs .fm-tab-bar, +.fm-page-listview .fm-page-main .fm-tmpl-tabs .van-tabs__wrap { + flex-shrink: 0 +} + +.fm-page-listview .fm-page-main .fm-tmpl-tabs .fm-tabs-content, +.fm-page-listview .fm-page-main .fm-tmpl-tabs .fm-tabs-content .fm-tab-pane, +.fm-page-listview .fm-page-main .fm-tmpl-tabs .van-tabs__content { + display: flex; + flex-direction: column; + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + overflow: hidden +} + +.fm-page-listview .fm-page-main .fm-tmpl-tabs .van-tabs__content .van-tab__pane { + display: flex; + flex-direction: column; + flex: 1 +} + +.fm-page-listview .fm-page-main .fm-tmpl-tabs .fm-tmpl-tabs-content { + display: flex; + flex-direction: column; + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + overflow: hidden +} + +.fm-page-card .fm-page-footer, +.fm-tmpl-list-extend { + flex-shrink: 0 +} + +.fm-btn-link { + color: #3A90FF +} + +.fm-page-card { + display: flex; + flex-direction: column +} + +.fm-page-card .fm-page-main { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + overflow: auto +} + +.fm-page-card .fm-page-main .fm-page-card-btns { + padding: 30px 16px 0 +} + +.fm-tmpl-struct-wrapper { + flex-shrink: 0; + margin-top: 12px +} + +.fm-tmpl-section-header, +.fm-tmpl-section-header .fm-toolbar { + align-items: center; + display: flex +} + +.fm-tmpl-struct-wrapper .fm-tmpl-section { + margin-top: 12px +} + +.fm-tmpl-struct-wrapper .fm-tmpl-section:first-child { + margin-top: 0 +} + +.fm-tmpl-section { + background-color: #fff +} + +.fm-tmpl-section-header { + justify-content: space-between; + padding: 11px 16px 10px +} + +.fm-tmpl-section-header .fm-title { + position: relative; + padding-left: 16px +} + +.fm-tmpl-section-header .fm-title::before { + content: ''; + position: absolute; + left: 0; + top: 50%; + width: 3px; + height: 14px; + margin: -7px 0 0; + background: #3A90FF +} + +.fm-tmpl-listview-product .tmpl-product-title-collect .collect-text, +.fm-tmpl-section-header .fm-toolbar-item-text { + margin-left: 4px +} + +.fm-tmpl-section-header .fm-title-text { + font-size: 15px; + line-height: 21px; + color: #333 +} + +.fm-tmpl-section-header .fm-toolbar-item { + display: flex; + align-items: center; + padding-left: 16px; + font-size: 15px; + color: #3A90FF +} + +.fm-tmpl-section-header .fm-toolbar-item-icon { + font-size: 16px +} + +.fm-tmpl-section-content { + padding: 0 16px +} + +.fm-tmpl-button-wrapper { + padding: 30px 16px 0; + flex-shrink: 0 +} + +.fm-tmpl-button-wrapper .fm-tmpl-btns { + display: flex; + align-items: center +} + +.fm-tmpl-button-wrapper .fm-tmpl-btns .fm-button { + flex: 1; + margin-right: 11px +} + +.fm-tmpl-button-wrapper .fm-tmpl-btns.fm-button:last-child { + margin-right: 0 +} + +.fm-tmpl-section-btn { + display: flex; + flex-direction: row; + align-items: center; + padding: 0 16px; + border-top: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-section-btn { + border-top: none + } + + html:not([data-scale]) .fm-tmpl-section-btn::before { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: 0; + right: auto; + bottom: auto; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 50%; + transform: scaleY(.5) + } +} + +.fm-tmpl-section-btn .fm-button { + flex: 1; + position: relative +} + +.fm-tmpl-section-btn .fm-button::after { + position: absolute; + right: 0; + top: 50%; + width: 1px; + height: 16px; + margin-top: -8px; + background: #ddd; + transform: scaleX(.5); + content: '' +} + +.fm-tmpl-section-btn .fm-button:last-child::after { + display: none +} + +.fm-card-tmpl-header { + height: 36px; + line-height: 36px; + background-color: #f9f9fb; + padding-left: 16px +} + +.fm-edit-input-list { + position: relative +} + +.fm-banner-warpper { + position: relative; + background: url(imgs/questionnaire-header.png) center/cover no-repeat; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + flex-shrink: 0 +} + +.fm-banner-warpper .fm-banner-title, +.fm-banner-warpper .fm-banner-title-sub { + color: #fff; + text-shadow: 0 2px 8px rgba(0, 26, 123, .52) +} + +.fm-banner-warpper .fm-banner-title { + font-size: 24px; + line-height: 33px +} + +.fm-banner-warpper .fm-banner-title-sub { + font-size: 12px; + line-height: 17px; + padding-top: 4px +} + +@media screen and (max-width:375px) { + .fm-banner-warpper { + height: 98px + } +} + +@media screen and (min-width:375px) and (max-width:414px) { + .fm-banner-warpper { + height: 116px + } +} + +@media screen and (min-width:414px) { + .fm-banner-warpper { + height: 128px + } +} + +.fm-stamp-wrapper { + width: 68px; + height: 68px; + position: absolute; + right: 16px; + top: 12px; + background: url(imgs/questionnaire-submitted.png) center/contain no-repeat; + z-index: 9 +} + +.fm-card-uploader-content { + padding: 10px 16px +} + +.fm-page-header-staff { + background: linear-gradient(90deg, #2899F6 0, #3E76F9 50%, #4384F8 100%) +} + +.fm-page-header-staff .fm-navbar { + background: 0 0 +} + +.fm-page-header-staff .fm-navbar .fm-navbar-left-arrow, +.fm-page-header-staff .fm-navbar .fm-navbar-title { + color: #fff +} + +.fm-navbar-right-text { + color: #333; + font-size: 16px +} + +.fm-input-wrapper:not(:last-child) .van-cell::after { + display: block +} + +.fm-inner-cell .van-checkbox__label::after, +.fm-inner-cell .van-radio__label::after, +.fm-input-wrapper:last-child .van-cell::after { + display: none +} + +.fm-radio-readonly .fm-inner-cell .van-radio .van-radio__icon .van-icon { + background-color: #fff +} + +.fm-radio-readonly .fm-inner-cell .van-radio .van-radio__icon--checked .van-icon { + background-color: #1989fa; + border-color: #1989fa +} + +.fm-form-item-wrapper { + position: relative; +} + +html:not([data-scale]) .fm-input-wrapper:not(:last-child) .fm-cell:not(.fm-no-hairline)::after, +html:not([data-scale]) .fm-form-item-wrapper:not(:last-child):not(.fm-no-hairline)::after, +html:not([data-scale]) .fm-form-designer-item-wrapper:not(:last-child) .fm-form-item-wrapper:not(.fm-no-hairline)::after { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1px; + transform-origin: 50% 100%; +} + +.fm-input-wrapper:not(:last-child) .fm-cell::after, +.fm-form-item-wrapper:not(:last-child)::after, +.fm-form-designer-item-wrapper:not(:last-child) .fm-form-item-wrapper::after { + left: 16px !important; +} + +.fm-input-label-tips { + display: flex; + align-items: center; + padding-left: 4px +} + +.fm-input-label-tips-content { + font-size: 14px; + color: #333; + line-height: 20px; + padding: 6px 16px +} + +.fm-tmpl-listview-timeline { + margin-left: 5px +} + +.fm-tmpl-listview-timeline .fm-tmpl-timeline-text { + position: relative; + padding-left: 22px; + padding-bottom: 2px; + line-height: 20px; + font-size: 14px; + color: #666 +} + +.fm-tmpl-listview-timeline .fm-tmpl-timeline-text::after { + position: absolute; + left: -5px; + top: 5px; + width: 10px; + height: 10px; + background-color: #ddd; + border-radius: 50%; + content: '' +} + +.fm-tmpl-listview-timeline .fm-tmpl-timeline-text::before { + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 1px; + background-color: #ddd; + content: '' +} + +.fm-tmpl-listview-timeline .fm-tmpl-timeline-date { + padding-bottom: 20px; + padding-left: 22px; + font-size: 12px; + color: #999; + border-left: 1px solid #ddd +} + +.fm-tmpl-listview-timeline.fm-tmpl-listview-timeline-first .fm-tmpl-timeline-text:before { + top: 5px +} + +.fm-tmpl-listview-timeline.fm-tmpl-listview-timeline-last .fm-tmpl-timeline-text:before { + height: 5px +} + +.fm-tmpl-listview-timeline.fm-tmpl-listview-timeline-last .fm-tmpl-timeline-date { + border-color: transparent +} + +.fm-tmpl-listview-goods { + padding-left: 16px; + display: flex; + padding-top: 10px +} + +.fm-tmpl-listview-goods .fm-tmpl-goods-img { + flex-shrink: 0; + width: 86px; + height: 86px; + margin-right: 10px; + overflow: hidden +} + +.fm-tmpl-listview-goods .fm-tmpl-goods-img img { + display: block; + width: 86px; + height: 86px +} + +.fm-tmpl-listview-goods .fm-tmpl-goods-content { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + overflow: hidden; + padding-right: 16px; + padding-bottom: 10px; + border-bottom: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-input-wrapper:not(:last-child) .fm-cell:not(.fm-no-hairline)::after { + transform: scaleY(.5) + } + + html:not([data-scale]) .fm-tmpl-listview-goods .fm-tmpl-goods-content { + border-bottom: none + } + + html:not([data-scale]) .fm-tmpl-listview-goods .fm-tmpl-goods-content::after { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-name { + position: relative; + min-height: 40px; + padding-right: 28px; + margin-bottom: 4px; + line-height: 20px; + font-size: 16px; + color: #666 +} + +.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-name .fm-tmpl-goods-add { + position: absolute; + right: 0; + top: 30px; + width: 24px; + height: 24px; + line-height: 24px; + text-align: center; + background-color: #ececec; + border-radius: 50% +} + +.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-name .fm-tmpl-goods-add .fm-icon { + font-size: 12px; + color: #999 +} + +.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-price { + display: flex; + align-items: flex-end; + line-height: 22px; + margin-bottom: 3px; + color: #fa6400 +} + +.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-price-prefix { + font-size: 12px +} + +.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-price-text { + font-size: 16px +} + +.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-shop { + display: flex; + align-items: center; + line-height: 16px; + font-size: 12px; + color: #888 +} + +.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-shop .fm-icon { + margin-right: 3px; + font-size: 12px +} + +.fm-tmpl-listview-order { + padding-left: 16px +} + +.fm-tmpl-listview-order-inner { + padding: 12px 16px 12px 0; + border-bottom: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-listview-order-inner { + border-bottom: none + } + + html:not([data-scale]) .fm-tmpl-listview-order-inner::after { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.fm-tmpl-listview-order .fm-tmpl-listview-order-name { + margin-bottom: 3px; + line-height: 21px; + font-size: 15px; + color: #333 +} + +.fm-tmpl-listview-order .order-line-item { + display: flex; + flex-direction: row; + align-items: center +} + +.fm-tmpl-listview-order .order-line-item-left { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + overflow: hidden +} + +.fm-tmpl-listview-order .order-line-item-right { + flex-shrink: 0 +} + +.fm-tmpl-listview-order .fm-tmpl-listview-order-number { + line-height: 20px; + margin-bottom: 10px +} + +.fm-tmpl-listview-order .fm-tmpl-listview-order-number .order-number-text { + font-size: 14px; + color: #888 +} + +.fm-tmpl-listview-order .fm-tmpl-listview-order-msg { + line-height: 18px; + font-size: 13px +} + +.fm-tmpl-listview-order .fm-tmpl-listview-order-msg .order-msg-date { + color: #888 +} + +.fm-tmpl-listview-order .fm-tmpl-listview-order-msg .order-msg-price { + color: #ff7300 +} + +.fm-tmpl-listview-shop { + padding: 0 8px 10px; + background: #f9fafb +} + +.fm-tmpl-listview-shop-inner { + background: #fff +} + +.fm-tmpl-listview-shop-header { + padding: 10px 10px 18px; + display: flex; + flex-direction: row +} + +.fm-tmpl-listview-shop-header .shop-header-img { + flex-shrink: 0; + width: 46px; + height: 46px; + margin-right: 10px +} + +.fm-tmpl-listview-shop-header .shop-header-img img { + display: block; + width: 100%; + height: 100% +} + +.fm-tmpl-listview-shop-header .shop-header-msg { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + overflow: hidden +} + +.fm-tmpl-listview-shop-header .shop-header-msg .shop-header-name { + display: flex; + justify-content: space-between; + margin-bottom: 6px +} + +.fm-tmpl-listview-shop-header .shop-header-msg .shop-header-name-text { + padding-right: 6px; + line-height: 22px; + font-size: 16px; + color: #333 +} + +.fm-tmpl-listview-shop .shop-content-item, +.fm-tmpl-listview-shop-header .shop-header-msg .shop-header-site { + line-height: 18px; + font-size: 13px; + color: #999 +} + +.fm-tmpl-listview-shop-header .shop-header-msg .shop-header-name-status { + flex-shrink: 0 +} + +.fm-tmpl-listview-shop .shop-content-item { + margin-bottom: 8px; + padding: 0 10px +} + +.fm-tmpl-listview-shop-footer { + border-top: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-listview-shop-footer { + border-top: none + } + + html:not([data-scale]) .fm-tmpl-listview-shop-footer::before { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: 0; + right: auto; + bottom: auto; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 50%; + transform: scaleY(.5) + } + + .fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item::after { + transform: scaleX(.5) + } +} + +.fm-tmpl-listview-shop-footer .shop-footer-btns { + display: flex; + flex-direction: row; + align-items: center +} + +.fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item { + position: relative; + flex: 1; + height: 44px; + padding: 0 6px; + line-height: 44px; + font-size: 12px; + color: #999; + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap +} + +.fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item .fm-icon { + font-size: 14px; + margin-right: 4px +} + +.fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item::after { + position: absolute; + right: 0; + top: 50%; + width: 1px; + height: 22px; + margin-top: -11px; + background-color: #ddd; + content: '' +} + +.fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item:last-child::after { + display: none +} + +.fm-tmpl-listview-shop-first { + padding-top: 10px +} + +.fm-tmpl-listview-menu { + padding-bottom: 10px; + background: #f9fafb +} + +.fm-tmpl-listview-menu-inner { + padding: 10px 16px 0; + background-color: #fff +} + +.fm-tmpl-listview-menu-text { + margin-bottom: 10px; + line-height: 20px; + font-size: 14px; + color: #666 +} + +.fm-tmpl-listview-menu-content .menu-list { + display: flex; + align-items: center; + flex-wrap: wrap +} + +.fm-tmpl-listview-menu-content .menu-list-item { + flex: 0 0 25%; + display: flex; + flex-direction: column; + align-items: center; + margin-bottom: 10px +} + +.fm-tmpl-listview-menu-content .menu-list-item-icon { + width: 46px; + height: 46px; + margin-bottom: 6px; + line-height: 46px; + text-align: center; + color: #fff; + border-radius: 16px; + background-color: #40a9ff +} + +.fm-tmpl-listview-menu-content .menu-list-item-icon .fm-icon { + font-size: 26px +} + +.fm-tmpl-listview-menu-content .menu-list-item-text { + line-height: 20px; + font-size: 14px; + color: #666 +} + +.fm-tmpl-listview-menu-last { + padding-bottom: 0 +} + +.fm-tmpl-listview-menus.fm-listview-content { + display: flex; + align-items: center; + flex-wrap: wrap +} + +.fm-tmpl-listview-menus .fm-listview-item { + flex: 0 0 33.3333% +} + +.fm-tmpl-listview-menus-item { + display: flex; + flex-direction: column; + align-items: center; + margin-bottom: 16px +} + +.fm-tmpl-listview-menus-item .menu-list-item-icon { + width: 46px; + height: 46px; + margin-bottom: 6px; + line-height: 46px; + text-align: center; + color: #fff; + border-radius: 16px; + background-color: #40a9ff +} + +.fm-tmpl-listview-menus-item .menu-list-item-icon .fm-icon { + font-size: 26px +} + +.fm-tmpl-listview-menus-item .menu-list-item-text { + line-height: 20px; + font-size: 14px; + color: #666 +} + +.fm-tmpl-listview-basic { + display: flex; + align-items: flex-start; + padding: 0 16px; + margin-bottom: 8px; + font-size: 14px; + line-height: 20px +} + +.fm-tmpl-listview-basic .basic-lable { + flex-shrink: 0; + width: 82px; + margin-right: 14px; + color: #999; + text-align: right +} + +.fm-tmpl-listview-basic .basic-text { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + overflow: hidden; + color: #333 +} + +.fm-tmpl-listview-basic-last { + margin-bottom: 0 +} + +.fm-tmpl-listview-list { + padding-left: 16px +} + +.fm-tmpl-listview-list .fm-tmpl-listview-list-inner { + display: flex; + justify-content: space-between; + height: 44px; + padding-right: 16px; + font-size: 15px; + color: #333; + line-height: 44px; + border-bottom: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-listview-list .fm-tmpl-listview-list-inner { + border-bottom: none + } + + html:not([data-scale]) .fm-tmpl-listview-list .fm-tmpl-listview-list-inner::after { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.fm-tmpl-listview-list .fm-tmpl-listview-list-inner .list-text { + color: #FBB902 +} + +.fm-tmpl-listview-list-last .fm-tmpl-listview-list-inner { + border-bottom: 0 +} + +.fm-tmpl-listview-list-last .fm-tmpl-listview-list-inner::after { + display: none !important +} + +.fm-tmpl-listview-sign { + padding: 0 16px; + background: #fff +} + +.fm-tmpl-listview-sign .fm-tmpl-listview-sign-inner { + margin-left: 12px +} + +.fm-tmpl-listview-sign .fm-tmpl-sign-text { + position: relative; + padding-left: 18px +} + +.fm-tmpl-listview-sign .fm-tmpl-sign-text .fm-tmpl-sign-circle { + position: absolute; + left: -8px; + top: 2px; + width: 18px; + height: 18px; + border-radius: 50%; + background-color: rgba(54, 165, 246, .2) +} + +.fm-tmpl-listview-sign .fm-tmpl-sign-text .text { + line-height: 22px; + font-size: 16px; + color: #333; + font-weight: 600 +} + +.fm-tmpl-listview-sign .fm-tmpl-sign-text::after { + position: absolute; + left: -5px; + top: 5px; + width: 6px; + height: 6px; + border: 3px solid #fff; + background-color: #36a5f6; + border-radius: 50%; + content: ''; + box-sizing: content-box +} + +.fm-tmpl-listview-sign .fm-tmpl-sign-text::before { + position: absolute; + left: -.5px; + top: 0; + bottom: 0; + width: 1px; + border: 1px dashed #ddd; + background-color: transparent; + content: ''; + transform: scaleX(.5) +} + +.fm-tmpl-listview-sign .fm-tmpl-sign-content { + padding: 10px 0 10px 18px; + border-left: 1px dashed #ddd +} + +.fm-tmpl-listview-sign .fm-tmpl-sign-content-inner { + padding: 10px 12px; + background: #f4f7f9 +} + +.fm-tmpl-listview-sign .fm-tmpl-sign-content-name { + display: flex; + align-items: center; + padding-bottom: 6px; + line-height: 20px +} + +.fm-tmpl-listview-sign .fm-tmpl-sign-content-name .fm-icon { + margin-right: 6px; + font-size: 16px; + color: #36a5f6 +} + +.fm-tmpl-listview-sign .fm-tmpl-sign-content-name .name-text { + font-size: 15px; + color: #333 +} + +.fm-tmpl-listview-sign .fm-tmpl-sign-content-label { + padding-bottom: 10px; + font-size: 14px; + color: #999 +} + +.fm-tmpl-listview-sign .fm-tmpl-sign-content-imgs { + display: flex; + align-items: center; + flex-wrap: wrap +} + +.fm-tmpl-listview-sign .fm-tmpl-sign-content-imgs .fm-tmpl-sign-content-img { + width: 60px; + height: 60px; + margin-right: 10px; + margin-bottom: 10px; + overflow: hidden +} + +.fm-tmpl-listview-sign .fm-tmpl-sign-content-imgs .fm-tmpl-sign-content-img img { + display: block; + width: 100%; + height: 100%; + -o-object-fit: scale-down; + object-fit: scale-down +} + +.fm-tmpl-listview-sign.fm-tmpl-listview-sign-last { + padding-bottom: 12px +} + +.fm-tmpl-listview-sign.fm-tmpl-listview-sign-last .fm-tmpl-sign-content { + border-left: none +} + +.fm-tmpl-listview-sign.fm-tmpl-listview-sign-last .fm-tmpl-sign-text::before { + height: 6px +} + +.fm-tmpl-listview-sign.fm-tmpl-listview-sign-first { + padding-top: 12px +} + +.fm-tmpl-listview-sign.fm-tmpl-listview-sign-first .fm-tmpl-sign-text::before { + top: 6px +} + +.fm-tmpl-listview-bill { + padding-left: 12px +} + +.fm-tmpl-listview-bill-content { + display: flex +} + +.fm-tmpl-listview-bill-content .bill-img-round-wrapper { + padding-top: 12px; + margin-right: 10px +} + +.fm-tmpl-listview-bill-content .bill-img-round-wrapper .bill-img-round-img { + width: 30px; + height: 30px; + border-radius: 50%; + text-align: center; + color: #fff; + background: #3a90ff +} + +.fm-tmpl-listview-bill-content .bill-img-round-wrapper .bill-img-round-img .fm-icon { + font-size: 18px; + line-height: 30px +} + +.fm-tmpl-listview-bill-content .bill-detail-content { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + padding: 12px 16px 8px 0; + border-bottom: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-listview-bill-content .bill-detail-content { + border-bottom: none + } + + html:not([data-scale]) .fm-tmpl-listview-bill-content .bill-detail-content::after { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-header { + display: flex; + align-items: center; + justify-content: space-between; + margin: 0 0 6px +} + +.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-header .title { + line-height: 22px; + font-weight: 400; + font-size: 16px; + color: #333 +} + +.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-header .time { + line-height: 18px; + color: #999; + font-size: 13px +} + +.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info { + display: flex; + margin-bottom: 4px +} + +.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info-text { + display: flex; + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + align-items: flex-start; + line-height: 18px; + font-size: 13px; + color: #999 +} + +.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info-text .title { + flex-shrink: 0 +} + +.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info-text .text-orange { + color: #FF9800 +} + +.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info-status { + padding-left: 6px; + margin-top: -2px +} + +.fm-tmpl-listview-client { + padding: 0 8px 10px; + background: #f9fafb +} + +.fm-tmpl-listview-client-inner { + background: #fff +} + +.fm-tmpl-listview-client-header { + padding: 10px 10px 18px; + display: flex; + flex-direction: row +} + +.fm-tmpl-listview-client-header .client-header-icon { + flex-shrink: 0; + width: 46px; + height: 46px; + line-height: 46px; + margin-right: 10px; + text-align: center; + background-color: #3a90ff; + border-radius: 6px +} + +.fm-tmpl-listview-client-header .client-header-icon .fm-icon { + font-size: 24px; + color: #fff +} + +.fm-tmpl-listview-client-header .client-header-msg { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + overflow: hidden +} + +.fm-tmpl-listview-client-header .client-header-msg .client-header-name { + display: flex; + justify-content: space-between; + margin-bottom: 6px +} + +.fm-tmpl-listview-client-header .client-header-msg .client-header-name-status, +.fm-tmpl-listview-liaison .liaison-header-tag { + flex-shrink: 0 +} + +.fm-tmpl-listview-client-header .client-header-msg .client-header-name-text { + padding-right: 6px; + line-height: 22px; + font-size: 16px; + color: #333 +} + +.fm-tmpl-listview-client-header .client-header-msg .client-header-name-time { + font-size: 13px; + color: #999 +} + +.fm-tmpl-listview-client-header .client-header-msg .client-header-site { + line-height: 18px; + font-size: 13px; + color: #999 +} + +.fm-tmpl-listview-client-content .client-content-info { + display: flex; + align-items: center +} + +.fm-tmpl-listview-client-content .text-orange { + font-size: 14px; + color: #FF9800 +} + +.fm-tmpl-listview-client .client-content-item { + display: flex; + align-items: center; + flex: 1; + margin-bottom: 8px; + padding: 0 10px; + line-height: 18px; + font-size: 13px; + color: #999 +} + +.fm-tmpl-listview-client .client-content-item .fm-icon { + font-size: 14px; + margin-right: 2px +} + +.fm-tmpl-listview-client-first { + padding-top: 10px +} + +.fm-tmpl-listview-client.fm-tmpl-listview-client-simple .fm-tmpl-listview-client-header { + padding-bottom: 10px +} + +.fm-tmpl-listview-client.fm-tmpl-listview-client-simple .fm-tmpl-listview-client-header .client-header-msg .client-header-name { + margin-bottom: 0 +} + +.fm-tmpl-listview-client .text-success { + color: #5CC171 +} + +.fm-tmpl-listview-client .text-warning { + color: #FF9800 +} + +.fm-tmpl-listview-client .text-danger { + color: #F24645 +} + +.fm-tmpl-listview-client .text-submit { + color: #5AC1C3 +} + +.fm-tmpl-listview-client .text-info { + color: #4D9AFF +} + +.fm-tmpl-extend-card { + padding: 12px 16px +} + +.fm-tmpl-extend-card-inner { + position: relative; + background-image: linear-gradient(152deg, #53bdfd 0, #287cf3 97%); + box-shadow: 0 2px 4px 0 rgba(57, 66, 100, .04); + border-radius: 10px; + overflow: hidden +} + +.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list { + display: flex; + justify-content: space-between; + align-items: center; + padding: 20px +} + +.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item { + display: flex; + flex-direction: column; + align-items: center; + flex: 1; + color: #fff +} + +.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item .extend-card-item-text { + display: flex; + align-items: baseline +} + +.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item .extend-card-item-text .item-text { + display: block; + font-size: 24px; + line-height: 32px +} + +.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item .extend-card-item-text .item-text-tip { + font-size: 12px +} + +.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item .extend-card-item-text .card-item-title { + font-size: 14px +} + +.fm-tmpl-extend-card-inner::before { + right: -7%; + top: 20%; + width: 80%; + height: 340%; + border-radius: 50%; + opacity: .23; + background-image: linear-gradient(180deg, #63ccfa 0, #36a5f6 100%); + z-index: 1 +} + +.fm-tmpl-extend-card-inner::after { + right: -37%; + bottom: -10%; + width: 60%; + height: 240%; + border-radius: 50%; + opacity: .15; + background-image: linear-gradient(134deg, #3addd5 0, #24c2d8 100%); + z-index: 0 +} + +.fm-tmpl-listview-liaison { + padding-left: 16px; + margin-top: 10px; + background-color: #fff +} + +.fm-tmpl-listview-liaison .liaison-header { + display: flex; + flex-direction: row; + justify-content: space-between; + padding: 12px 16px 12px 0; + border-bottom: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-listview-liaison .liaison-header { + border-bottom: none + } + + html:not([data-scale]) .fm-tmpl-listview-liaison .liaison-header::after { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.fm-tmpl-listview-liaison .liaison-header-title { + flex: 1 1 0; + padding-right: 16px; + font-size: 16px; + color: #333; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis +} + +.fm-tmpl-listview-liaison .liaison-content { + padding: 10px 0 +} + +.fm-tmpl-listview-liaison .liaison-content-info { + display: flex; + flex-direction: row; + align-items: center; + line-height: 18px; + color: #999; + font-size: 13px; + margin: 0 0 6px +} + +.fm-tmpl-listview-booklist .booklist-btns .fm-button, +.fm-tmpl-listview-liaison .liaison-actions .fm-button { + margin-left: 13px +} + +.fm-tmpl-listview-liaison .liaison-content-info-title { + flex-shrink: 0; + width: 100px; + padding-right: 10px +} + +.fm-tmpl-listview-liaison .liaison-content-info-text { + flex: 1 1 0; + color: #333 +} + +.fm-tmpl-listview-liaison .liaison-actions { + padding: 0 16px 10px; + text-align: right +} + +.fm-tmpl-listview-liaison .liaison-actions .fm-button:first-child { + margin-left: 0 +} + +.fm-tmpl-listview-approve { + padding: 10px 0 10px 16px; + background-color: #fff +} + +.fm-tmpl-listview-approve .fm-approve-flow-item { + padding-left: 7px +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-header { + border-left: 1px dashed #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-listview-approve .fm-approve-flow-item-header { + border-left: none + } + + html:not([data-scale]) .fm-tmpl-listview-approve .fm-approve-flow-item-header::before { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: 0; + right: auto; + bottom: auto; + left: 0; + width: 1PX; + height: 100%; + transform-origin: 100% 50%; + transform: scaleX(.5) + } +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner { + position: relative; + display: flex; + flex-direction: row; + align-items: center; + padding-left: 20px +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon { + position: absolute; + left: -7px; + top: 0; + z-index: 100; + display: flex; + align-items: center; + justify-content: center; + width: 15px; + height: 15px; + background-color: rgba(58, 144, 255, .4); + border-radius: 50% +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon-inner { + width: 7px; + height: 7px; + background-color: #3a90ff; + border-radius: 50% +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-content { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + line-height: 21px; + font-size: 15px; + color: #4c4c4c; + font-weight: 700 +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-right { + flex-shrink: 0; + padding-left: 6px +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-right .fm-icon { + color: #979797 +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content { + padding: 12px 0 30px 20px; + border-left: 1px dashed #d4d4d4; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-listview-approve .fm-approve-flow-item-content { + border-left: none + } + + html:not([data-scale]) .fm-tmpl-listview-approve .fm-approve-flow-item-content::before { + content: ''; + position: absolute; + background-color: #d4d4d4; + display: block; + z-index: 1; + top: 0; + right: auto; + bottom: auto; + left: 0; + width: 1PX; + height: 100%; + transform-origin: 100% 50%; + transform: scaleX(.5) + } +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list { + display: flex; + flex-direction: row; + align-items: flex-start; + margin-bottom: 14px +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list:last-child { + margin-bottom: 0 +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-avatar { + position: relative; + display: flex; + flex-direction: row; + align-items: center; + width: 36px; + height: 36px +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-avatar-img { + display: block; + width: 36px; + height: 36px; + border-radius: 50% +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content { + flex: 1 1 0; + margin-left: 10px +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-main { + display: flex; + align-items: center; + justify-content: space-between; + height: 36px +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-last .fm-approve-flow-item-content::before, +.fm-tmpl-listview-approve .fm-approve-flow-item-last .fm-approve-flow-item-header::before { + display: none !important +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left, +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-name { + font-size: 14px; + color: #666 +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-status { + margin-left: 8px; + color: #3a90ff +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-status-success { + color: #5cc171 +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-status-apply { + color: #3a90ff +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-status-running { + color: #ff9800 +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-date { + flex-shrink: 0; + font-size: 13px; + color: #999 +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-message { + line-height: 20px; + font-size: 14px; + color: #333 +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-date { + font-size: 13px; + color: rgba(51, 51, 51, .65) +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-running .fm-approve-flow-item .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon { + background-color: rgba(255, 152, 0, .4) +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-running .fm-approve-flow-item .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon .fm-approve-flow-item-header-icon-inner { + background-color: #ff9800 +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-last .fm-approve-flow-item-header { + border-left: 0 +} + +.fm-tmpl-listview-approve .fm-approve-flow-item-last .fm-approve-flow-item-content { + padding-bottom: 12px; + border-left: 0 +} + +.fm-tmpl-listview-product-header { + padding: 12px 14px; + line-height: 20px; + font-size: 14px; + color: #3a90ff +} + +.fm-tmpl-listview-product-item .fm-listview-item .fm-listview-item-content { + transform: none +} + +.fm-tmpl-listview-product { + padding: 12px 16px 0 +} + +.fm-tmpl-listview-product .fm-tmpl-listview-product-inner { + padding-bottom: 12px; + border-bottom: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-listview-product .fm-tmpl-listview-product-inner { + border-bottom: none + } + + html:not([data-scale]) .fm-tmpl-listview-product .fm-tmpl-listview-product-inner::after { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.fm-tmpl-listview-product .tmpl-product-title { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 12px +} + +.fm-tmpl-listview-product .tmpl-product-title .tmpl-product-title-collect { + flex-shrink: 0 +} + +.fm-tmpl-listview-product .tmpl-product-title-text { + font-size: 17px; + color: #333 +} + +.fm-tmpl-listview-product .tmpl-product-title-collect { + flex-shrink: 0; + font-size: 14px; + color: #666 +} + +.fm-tmpl-listview-product .tmpl-product-title-collect.tmpl-product-title-collected .fm-icon { + color: #ff9800 +} + +.fm-tmpl-listview-product .tmpl-product-content { + position: relative; + padding-right: 40px +} + +.fm-tmpl-listview-product .tmpl-product-content-item { + display: flex; + align-items: center; + margin-bottom: 10px; + font-size: 14px; + color: #666 +} + +.fm-tmpl-listview-product .tmpl-product-content .tmpl-product-add-btn { + position: absolute; + right: 0; + bottom: 0 +} + +.fm-tmpl-listview-product .tmpl-product-content .tmpl-product-add-btn .fm-button-add { + width: 30px; + height: 30px +} + +.fm-tmpl-listview-product .tmpl-product-content .tmpl-product-add-btn .fm-button-add .fm-icon { + font-size: 14px +} + +.fm-tmpl-listview-product .tmpl-product-footer { + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 6px +} + +.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-price { + margin-right: 10px; + font-size: 17px; + color: red; + font-weight: 600 +} + +.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-inner { + border-radius: 10px; + box-shadow: none +} + +.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-arrow, +.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-inner { + border: 1px solid #ddd +} + +.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-inner-wrapper { + padding: 0 +} + +.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-inner-wrapper .fm-popover-item { + min-width: 50px; + height: 46px; + line-height: 46px; + text-align: center; + font-size: 16px; + color: #666 +} + +.fm-tmpl-listview-product .tmpl-product-footer .fm-overlay { + background: 0 0 +} + +.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-unit { + padding: 3px 6px; + border-radius: 6px; + background-color: rgba(58, 144, 255, .2); + font-size: 14px; + color: #333 +} + +.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-unit-text { + margin-right: 4px +} + +.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-unit .fm-icon { + font-size: 12px; + color: #666 +} + +.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-footer-right { + flex-shrink: 0; + font-size: 12px; + color: #666 +} + +.fm-tmpl-listview-product.fm-tmpl-listview-product-first { + padding-top: 0 +} + +.fm-card-tmpl-booklist-header { + padding: 11px 16px; + line-height: 22px; + font-size: 16px; + color: #333; + font-weight: 600 +} + +.fm-tmpl-listview-booklist { + padding: 0 16px; + color: #333; + border-bottom: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-listview-booklist { + border-bottom: none + } + + html:not([data-scale]) .fm-tmpl-listview-booklist::after { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.fm-tmpl-listview-booklist-last { + border-bottom: 0 +} + +.fm-tmpl-listview-booklist-last::after { + display: none !important +} + +.fm-tmpl-listview-booklist .booklist-header { + display: flex; + flex-direction: row; + align-items: flex-start; + justify-content: space-between; + padding: 12px 0 6px; + line-height: 22px; + font-size: 16px +} + +.fm-tmpl-listview-booklist .booklist-header-price { + flex-shrink: 0; + color: #fa6400 +} + +.fm-tmpl-listview-booklist .booklist-main { + padding-bottom: 8px +} + +.fm-tmpl-listview-booklist .booklist-main-item { + line-height: 18px; + padding-bottom: 4px; + font-size: 13px; + color: #999 +} + +.fm-tmpl-listview-booklist .booklist-btns { + padding: 8px 0 6px; + text-align: right +} + +.fm-tmpl-dialog-plan, +.fm-tmpl-dialog-type { + border-radius: 5px !important +} + +.fm-tmpl-dialog-plan .fm-dialog-footer, +.fm-tmpl-dialog-type .fm-dialog-footer { + border-top: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + + html:not([data-scale]) .fm-tmpl-dialog-plan .fm-dialog-footer, + html:not([data-scale]) .fm-tmpl-dialog-type .fm-dialog-footer { + border-top: none + } + + html:not([data-scale]) .fm-tmpl-dialog-plan .fm-dialog-footer::before, + html:not([data-scale]) .fm-tmpl-dialog-type .fm-dialog-footer::before { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: 0; + right: auto; + bottom: auto; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 50%; + transform: scaleY(.5) + } +} + +.fm-tmpl-dialog-plan .fm-dialog-footer .fm-button, +.fm-tmpl-dialog-type .fm-dialog-footer .fm-button { + font-size: 14px; + color: #666 +} + +.fm-tmpl-dialog-type-content { + padding: 20px +} + +.fm-tmpl-dialog-type-content .fm-dialog-type-list { + display: flex; + align-items: center; + justify-content: center +} + +.fm-tmpl-dialog-type-content .fm-dialog-type-list-item { + flex: 1 +} + +.fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-icon { + width: 60px; + height: 60px; + margin: 0 auto; + line-height: 60px; + text-align: center; + border: 1px solid #3D91FF; + border-radius: 50% +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-icon { + position: relative; + border: none + } + + html:not([data-scale]) .fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-icon::before { + content: ''; + position: absolute; + left: 0; + top: 0; + width: 200%; + height: 200%; + border: 1px solid #3D91FF; + border-radius: 100%; + transform-origin: 0 0; + transform: scale(.5); + box-sizing: border-box; + pointer-events: none + } +} + +.fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-icon .fm-icon { + font-size: 26px; + color: #3D91FF +} + +.fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-text { + margin-top: 12px; + font-size: 16px; + text-align: center; + color: #666 +} + +.fm-tmpl-dialog-type-content .fm-dialog-type-list-item:active .type-list-item-icon { + background-color: #3D91FF +} + +.fm-tmpl-dialog-type-content .fm-dialog-type-list-item:active .type-list-item-icon .fm-icon { + color: #fff +} + +.fm-tmpl-dialog-plan-content { + padding: 20px 30px +} + +.fm-tmpl-dialog-plan-content .fm-dialog-plan-item { + display: flex; + justify-content: center; + height: 40px; + line-height: 40px; + margin-bottom: 16px; + align-items: center; + color: #666; + border: 1px solid #ddd; + border-radius: 4px +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-dialog-plan-content .fm-dialog-plan-item { + position: relative; + border: none + } + + html:not([data-scale]) .fm-tmpl-dialog-plan-content .fm-dialog-plan-item::before { + content: ''; + position: absolute; + left: 0; + top: 0; + width: 200%; + height: 200%; + border: 1px solid #ddd; + border-radius: 8px; + transform-origin: 0 0; + transform: scale(.5); + box-sizing: border-box; + pointer-events: none + } +} + +.fm-tmpl-dialog-plan-content .fm-dialog-plan-item .plan-item-icon { + margin-right: 14px +} + +.fm-tmpl-dialog-plan-content .fm-dialog-plan-item .fm-icon { + color: #666 +} + +.fm-tmpl-dialog-plan-content .fm-dialog-plan-item:active, +.fm-tmpl-dialog-plan-content .fm-dialog-plan-item:active .fm-icon { + color: #3D91FF +} + +.fm-tmpl-dialog-plan-content .fm-dialog-plan-item:active::before { + border-color: #3D91FF !important +} + +.fm-title { + position: relative; + padding-left: 16px +} + +.fm-title::before { + content: ''; + position: absolute; + left: 0; + top: 50%; + width: 5px; + height: 16px; + margin: -8px 0 0; + background: #3A90FF +} + +.fm-title-text { + font-size: 16px; + line-height: 21px; + color: #333 +} + +.fm-tmpl-search-action { + position: relative +} + +.fm-tmpl-search-action .fm-icon { + font-size: 20px; + color: #666 +} + +.fm-tmpl-search-action-badge { + position: absolute; + top: 0; + right: 0; + min-width: 16px; + padding: 0 3px; + margin-top: 4px; + color: #fff; + font-weight: 500; + font-size: 12px; + line-height: 14px; + text-align: center; + background-color: #ee0a24; + border: 1px solid #fff; + border-radius: 16px; + transform: translate(50%, -50%); + transform-origin: 100% +} + +.fm-list-view-swipe-toolbar { + display: flex; + align-items: center; + justify-content: center; + padding: 0 12px; + height: 100%; + background-color: #f24645; + font-size: 16px; + color: #fff +} + +.fm-static-text-common { + padding: 12px 16px; + background-color: #fff; + margin-bottom: 10px; + font-size: 13px; + line-height: 1.42; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + text-align: left; + white-space: pre-wrap; + word-wrap: break-word +} + +.fm-static-text-common p { + margin-top: 0; + margin-bottom: 0; +} + +.fm-static-text-common p:not(:last-child) { + padding-bottom: 18px +} + +.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 +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-listview-common { + border-bottom: none + } + + html:not([data-scale]) .fm-tmpl-listview-common::after { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: auto; + right: auto; + bottom: 0; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 100%; + transform: scaleY(.5) + } +} + +.fm-tmpl-listview-cell .fm-tmpl-row:not(:last-child) { + padding-bottom: 3px +} + +.fm-tmpl-listview-cell .fm-tmpl-label { + font-size: 13px; + line-height: 18px; + color: #999 +} + +.fm-tmpl-listview-cell .fm-tmpl-label .fm-tmpl-label-title { + width: auto +} + +.fm-tmpl-listview-card { + margin: 10px 12px 10px; + 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-common-footer { + border-top: 1px solid #ddd; + position: relative +} + +@media (-webkit-min-device-pixel-ratio:2), +(min-resolution:2dppx) { + html:not([data-scale]) .fm-tmpl-listview-card .fm-tmpl-listview-common-footer { + border-top: none + } + + html:not([data-scale]) .fm-tmpl-listview-card .fm-tmpl-listview-common-footer::before { + content: ''; + position: absolute; + background-color: #ddd; + display: block; + z-index: 1; + top: 0; + right: auto; + bottom: auto; + left: 0; + width: 100%; + height: 1PX; + transform-origin: 50% 50%; + transform: scaleY(.5) + } +} + +.fm-listview-item:last-child .fm-tmpl-listview-card { + margin-bottom: 10px +} + +.fm-common-text { + display: inline; + color: #666; + word-break: break-all; +} + +.fm-common-label { + display: inline-block; + white-space: nowrap; +} + +.fm-common-content {} + +.fm-common-title { + display: inline; + color: #333; + word-break: break-all; + font-weight: 500; +} + + +.fm-title-sm { + font-size: 15px; + line-height: 22px; +} + +.fm-title-md { + font-size: 16px; + line-height: 24px; +} + +.fm-title-lg { + font-size: 17px; + line-height: 26px; +} + +.fm-title-xl { + font-size: 22px; + line-height: 32px; +} + +.fm-text-xs { + font-size: 12px; + line-height: 20px +} + +.fm-text-sm { + font-size: 13px; + line-height: 20px +} + +.fm-text-md { + font-size: 14px; + line-height: 22px +} + +.fm-text-lg { + font-size: 15px; + line-height: 22px +} + +.fm-text-xl { + font-size: 16px; + line-height: 24px +} + +.layout-bordered { + border-bottom: 1px solid #E6E6E6; +} + +.layout-bordered .layout-bordered { + border-bottom: none; +} + +.fm-listview-item:last-child .layout-bordered { + border-bottom: none; +} diff --git a/packages/designer/public/assets/farris-mobile-ui-vue.css b/packages/designer/public/assets/farris-mobile-ui-vue.css new file mode 100644 index 00000000000..7f49e0efccb --- /dev/null +++ b/packages/designer/public/assets/farris-mobile-ui-vue.css @@ -0,0 +1 @@ +@charset "UTF-8";:root{--fm-black: #000;--fm-white: #fff;--fm-gray-1: #f2f3f5;--fm-gray-2: #eee;--fm-gray-3: #ddd;--fm-gray-4: #ccc;--fm-gray-5: #999;--fm-gray-6: #666;--fm-gray-7: #333;--fm-red: #F24645;--fm-red-light: #f9e8e8;--fm-blue: #3A90FF;--fm-blue-2: #65a7ff;--fm-blue-light: #ecf2fe;--fm-green: #5CC171;--fm-green-2: #5AC1C3;--fm-green-light: #e9f5ed;--fm-orange: #FF9800;--fm-orange-2: #FA6400;--fm-orange-3: #FFB400;--fm-orange-light: #faf0e1;--fm-primary-color: var(--fm-blue);--fm-success-color: var(--fm-green);--fm-danger-color: var(--fm-red);--fm-warning-color: var(--fm-orange);--fm-submit-color: var(--fm-green-2);--fm-primary-color-light: var(--fm-blue-light);--fm-success-color-light: var(--fm-green-light);--fm-danger-color-light: var(--fm-red-light);--fm-warning-color-light: var(--fm-orange-light);--fm-text-color: var(--fm-gray-7);--fm-text-color-light: var(--fm-gray-5);--fm-active-color: var(--fm-gray-1);--fm-disabled-color: var(--fm-gray-4);--fm-readonly-color: var(--fm-gray-6);--fm-active-opacity: .7;--fm-readonly-opacity: .6;--fm-disabled-opacity: .5;--fm-background: var(--fm-gray-1);--fm-background-white: var(--fm-white);--fm-box-shadow-color: var(--fm-gray-1);--fm-padding-base: 4px;--fm-padding-xs: 8px;--fm-padding-sm: 12px;--fm-padding-md: 16px;--fm-padding-lg: 24px;--fm-padding-xl: 32px;--fm-padding-horizontal-xs: 0 var(--fm-padding-xs);--fm-padding-horizontal-sm: 0 var(--fm-padding-sm);--fm-padding-horizontal-md: 0 var(--fm-padding-md);--fm-padding-horizontal-lg: 0 var(--fm-padding-lg);--fm-margin-base: 4px;--fm-margin-xs: 8px;--fm-margin-sm: 12px;--fm-margin-md: 16px;--fm-margin-lg: 24px;--fm-margin-xl: 32px;--fm-margin-horizontal-xs: 0 var(--fm-margin-xs);--fm-margin-horizontal-sm: 0 var(--fm-margin-sm);--fm-margin-horizontal-md: 0 var(--fm-margin-md);--fm-margin-horizontal-lg: 0 var(--fm-margin-lg);--fm-font-bold-light: 500;--fm-font-bold: 600;--fm-font-size: 16px;--fm-line-height: 1.2;--fm-font-size-xs: 10px;--fm-font-size-sm: 12px;--fm-font-size-md: 14px;--fm-font-size-lg: 16px;--fm-gradient-blue: linear-gradient(-45deg,var(--fm-blue-2) 0%, var(--fm-blue) 100%);--fm-gradient-orange: linear-gradient(-45deg,var(--fm-orange) 0%, var(--fm-orange-2) 100%);--fm-base-font: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Segoe UI, Arial, Roboto, "PingFang SC", "miui", "Hiragino Sans GB", "Microsoft Yahei", sans-serif;--fm-price-font: avenir-heavy, "PingFang SC", helvetica neue, arial, sans-serif;--fm-duration-base: .3s;--fm-duration-fast: .2s;--fm-ease-out: ease-out;--fm-ease-in: ease-in;--fm-noborder: none;--fm-radius-sm: 2px;--fm-radius-md: 4px;--fm-radius-lg: 8px;--fm-radius-max: 999px;--fm-zindex-1: 9;--fm-zindex-2: 10;--fm-zindex-3: 99;--fm-zindex-4: 100;--fm-zindex-5: 999;--fm-zindex-6: 1000}*,*:before,*:after{box-sizing:border-box}body,h1,h2,h3,h4,p,figure,blockquote,dl,dd{margin:0}ul[role=list],ol[role=list]{list-style:none}html:focus-within{scroll-behavior:smooth}body{min-height:100vh;text-rendering:optimizeSpeed;line-height:1.5;font-family:-apple-system,Noto Sans,Helvetica Neue,Helvetica,Nimbus Sans L,Arial,Liberation Sans,PingFang SC,Hiragino Sans GB,Noto Sans CJK SC,Source Han Sans SC,Source Han Sans CN,Microsoft YaHei,Wenquanyi Micro Hei,WenQuanYi Zen Hei,ST Heiti,SimHei,WenQuanYi Zen Hei Sharp,sans-serif}a:not([class]){text-decoration-skip-ink:auto}img,picture{max-width:100%;display:block}input,button,textarea,select{font:inherit}@font-face{font-family:farrisMobile;font-style:normal;font-weight:400;src:url(data:font/ttf;base64,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AADmFAAAACUAAOYVAADmFQAAACYAAOYWAADmFgAAACcAAOYXAADmFwAAACgAAOYYAADmGAAAACkAAOYZAADmGQAAAHYAAOYaAADmGgAAAHUAAOYbAADmGwAAAHQAAOYcAADmHAAAAHMAAOYdAADmHQAAACoAAOYeAADmHgAAACsAAOYfAADmHwAAAHAAAOYgAADmIAAAAHEAAOYhAADmIQAAAHIAAOYiAADmIgAAAG8AAOYjAADmIwAAACwAAOYkAADmJAAAAGUAAOYlAADmJQAAAGYAAOYmAADmJgAAAGcAAOYnAADmJwAAAGgAAOYoAADmKAAAAGkAAOYpAADmKQAAAGoAAOYqAADmKgAAAGsAAOYrAADmKwAAAGwAAOYsAADmLAAAAG0AAOYtAADmLQAAAG4AAOYuAADmLgAAAGMAAOYvAADmLwAAAGQAAOYwAADmMAAAAGIAAOYyAADmMgAAADQAAOYzAADmMwAAAC0AAOY0AADmNAAAAC4AAOY2AADmNgAAAC8AAOY3AADmNwAAADAAAOY5AADmOQAAADEAAOY6AADmOgAAADIAAOZVAADmVQAAADUAAOZWAADmVgAAADoAAOZXAADmVwAAADcAAOZYAADmWAAAADgAAOZZAADmWQAAAD0AAOZaAADmWgAAAF4AAOZbAADmWwAAAF8AAOZcAADmXAAAAGAAAOZdAADmXQAAAGEAAOZeAADmXgAAADYAAOZfAADmXwAAADsAAOZgAADmYAAAADwAAOZhAADmYQAAADkAAOZiAADmYgAAAD4AAOZjAADmYwAAAD8AAOZkAADmZAAAAEAAAOZlAADmZQAAAEEAAOZmAADmZgAAAEIAAOZnAADmZwAAAEMAAOZoAADmaAAAAEQAAOZpAADmaQAAAEUAAOZqAADmagAAAEYAAOZrAADmawAAAEcAAOZsAADmbAAAAEgAAOZtAADmbQAAAEkAAOZuAADmbgAAAEoAAOZvAADmbwAAAEsAAOZwAADmcAAAAEwAAOZxAADmcQAAAE0AAOZyAADmcgAAAE4AAOZzAADmcwAAAE8AAOZ0AADmdAAAAFAAAOZ1AADmdQAAAFEAAOZ2AADmdgAAAFIAAOZ3AADmdwAAAFMAAOZ4AADmeAAAAFQAAOZ5AADmeQAAAFUAAOZ6AADmegAAAFYAAOZ7AADmewAAAFcAAOZ8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AV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFzAXQBdQF2AXcBeAF5AXoBewF8AX0BfgF/AYABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+AAlzLW1vcmUtbzEIcy1kZWxldGUIcy1iYWNrLW8Gcy1zY2FuEHMtb3JnYW5pemF0aW9uLW8Jcy1ncm91cC1vCXMtZmlsdGVyMQlzLWNsZWFyLW8Ocy1pbGx1c3RyYXRlLW8Icy1tb21lbnQIcy1zaG9wLW8Kcy1tb21lbnQtbwZzLXNob3AKcy1yZXZva2UtbwpzLXN1Ym1pdC1vB3MtYXBwLW8Gcy1ib29rBXMtYXBwBHMtbXkJcy1jb21tZW50C3MtY29tbWVudC1vCHMtYm9vay1vBnMtbXktbwxzLWxvY2F0aW9uLW8Kcy1sb2NhdGlvbgZzLW5ld3MIcy1uZXdzLW8Jcy1TZW5kaW5nCnMtSW1wb3J0LW8Icy1FZGl0LW8Icy1RUmNvZGULcy1CcmllZmNhc2URcy1Ob3RpZmljYXRpb25vZmYIcy1QZW5jaWwIcy1TdGFyLW8Jcy1CYXJDb2RlD3MtU2FsZU1lc3NhZ2UtbwxzLUxpc3R2aWV3LW8Lcy1QaWN0dXJlLW8Ocy1TYXZlRmlsbGV0LW8Ocy1TaG9wcGluZ2NhcnQJcy1QZW5kaW5nDnMtRXhwYW5kdmlldy1vCHMtTG9jay1vCXMtU2VydmljZQpzLVdhbGxldC1vEHMtU2hvcHBpbmdjYXJ0LW8Lcy1TZXR0aW5nLW8Ncy1VbmZvbGRSZWMtbwlzLVByb2ZpbGUGTGluay1vDVVzZXJTZXR0aW5nLW8Jcy1hZ3JlZS1vDHMtYXJyb3ctZG93bgdzLWFkZC1vB3MtYW5uZXgMcy1hcnJvdy1sZWZ0CnMtYXJyb3ctdXAScy1jaGVja2JveC1jaGVja2VkCnMtY2hlY2tib3gHcy1hcnJvdwpzLWV4Y2hhbmdlB3MtY2xlYXIJcy1jaGVja2VkB3MtZXllLW8Lcy1jbG9zZS1leWUEcy1hdAxzLWZlZWRiYWNrLW8Pcy1mb2xkLWNpcmNsZS1vB3MtY3Jvc3MHcy1taW51cwZzLWZpbGUPcy1mb2xkLXRyaWFuZ2xlCHMtZmlsdGVyCXMtZm9yd29yZAZzLXBsdXMJcy1maWxlZGVsCHMtZm9sZC1vCXMtaW1hZ2UtbwhzLW1vcmUtbw5zLXJlZGlvLWNpcmNsZQpzLXJlamVjdC1vCXMtc3VjY2VzcwlzLXJlZnJlc2gGcy1zdGFyDXMtcHJvY2Vzc2Zsb3cRcy11bmZvbGQtY2lyY2xlLW8Icy1yZXdpbmQKcy11bmZvbGQtbwtzLXdhcm5pbmctbxFzLXVuZm9sZC10cmlhbmdsZQlzLXByaW50LW8Kcy1zZWFyY2gtbwhBaXJwbGFuZQVUcmFpbgNCdXMEVGF4aQxvdmVydGltZW1lYWwTZm0taS10cmFmZmljZGV0YWlscw9mbS1pLXRyYWZmaWNzdWITZm0taS1hY2NvbW1vZGF0aW9uMQ1mbS1pLWJ1c2luZXNzC2ZtLWktYnVkZ2V0CWZtLWktZ2lmdBFmbS1pLWNhbmNlbGxhdGlvbgxmbS1pLWludm9pY2UJZm0taS1saXN0CmZtLWktbWVhbHMIZm0taS1wYXkMZm0taS1zdWJzaWR5B3Nob3V6aGUTZm0taS1jb3N0YWxsb2NhdGlvbgxmbS1pLXBheW1lbnQOZm0taS1JdGluZXJhcnkOZm0taS1tb3JleGUwMmQPZm0taS1pbWFnZXhlMDJlEGZtLWktcmVqZWN0eGUwMmYPZm0taS1hZ3JlZXhlMDMxDWZtLWktY2FyZGZvbGQPZm0taS1jYXJkdW5mb2xkEWZtLWktdHJhZmZpY290aGVyD2ZtLWktYm90dG9tc2F2ZRBmbS1pLXRyYWZmaWNib2F0D2ZtLWktdHJhZmZpY2NhchFmbS1pLXRyYWZmaWNwbGFuZRFmbS1pLXRyYWZmaWN0cmFpbg9mbS1pLXRyYWZmaWNidXMMZm0taS1hZGRncmF5CmZtLWktY2xvc2UIZm0taS1hZGQJZm0taS1tb3JlCmZtLWktY2hlY2sPZm0taS1iYWNrY2lyY2xlCmZtLWktYWdyZWUMZm0taS1sb2FkaW5nDGZtLWktZmlsZWRlbAlmbS1pLWZpbGUQZm0taS1wcm9jZXNzZmxvdwxmbS1pLXJlZHN0YXIQZm0taS1yaWdodGNpcmNsZQ9mbS1pLXRpbWVjaXJjbGUOZm0taS1zY3JlZW5pbmcMZm0taS11bmNoZWNrDmZtLWktb3BlcmF0aW9uE2ZtLWktYXBwcm92YWxhbW91bnQLZm0taS1hZ3JlZWQOZm0taS1pbnByb2Nlc3MNZm0taS1mZWVkYmFjawpmbS1pLXByaW50DmZtLWktaW1wb3J0YW50GmZtLWktYW1vdW50b2ZyZWltYnVyc2VtZW50FGZtLWktc2FmZXR5YXNzaXN0YW50C2ZtLWktcmVtaW5kDWZtLWktZXllb3BwZW4NZm0taS1leWVjbG9zZRBmbS1pLVBob3RvZ3JhcGh5D2ZtLWktcGhvdG9ncmFwaA9mbS1pLWFkZHBpY3R1cmUTZm0taS10b3Bfb3RoZXItZmFjZQ5mbS1pLXRvcF9vdGhlcgtmbS1pLWRlbGV0ZQ1mbS1pLW5leHRwYWdlDmZtLWktYWRkYnV0dG9uFmZtLWktd2FpdGZvcnByb2Nlc3NpbmcTZm0taS13YXJuaW5nbWVzc2FnZRJmbS1pLWZhaWx1cmVwcm9tcHQUZm0taS1zdWNjZXNzZnVsaGludHMKZm0taS1vdGhlcgxmbS1pLXJldHJhY3QOZm0taS1kcm9wLWRvd24LZm0taS1jYW5jZWwLZm0taS1zZWFyY2gTZm0taS1tdWx0aXBsZWNob2ljZRFmbS1pLXNpbmdsZWNob2ljZQ9mbS1pLW1pY3JvcGhvbmUXZm0taS1hcnJvdy1jaGV2cm9uLWxlZnQPZm0taS1oZWxwY2VudGVyDmZtLWktc3dlZXBjb2RlDmZtLWktZ3JvdXBjaGF0DmZtLWktYWRkZnJpZW5kC2ZtLWktdG9wX215EGZtLWktdG9wX215LWZhY2UPZm0taS10b3BfZnJpZW5kFGZtLWktdG9wX2ZyaWVuZC1mYWNlFWZtLWktdG9wX3B1YmxpY3ByYWlzZRpmbS1pLXRvcF9wdWJsaWNwcmFpc2UtZmFjZQ1mbS1pLXRvcF9ob21lEmZtLWktdG9wX2hvbWUtZmFjZQAAAAA=) format("truetype")}@keyframes fm-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fm-fade-out{0%{opacity:1}to{opacity:0}}.fm-fade-enter-active{animation:.3s fm-fade-in both ease-out}.fm-fade-leave-active{animation:.3s fm-fade-out both ease-in}.fm-slide-up-enter-from,.fm-slide-up-leave-to{transform:translate3d(0,100%,0)}.fm-slide-down-enter-from,.fm-slide-down-leave-to{transform:translate3d(0,-100%,0)}.fm-slide-left-enter-from,.fm-slide-left-leave-to{transform:translate3d(-100%,0,0)}.fm-slide-right-enter-from,.fm-slide-right-leave-to{transform:translate3d(100%,0,0)}.fm-slide-up-enter-active,.fm-slide-down-enter-active,.fm-slide-left-enter-active,.fm-slide-right-enter-active{transition-timing-function:ease-out}.fm-slide-up-leave-active,.fm-slide-down-leave-active,.fm-slide-left-leave-active,.fm-slide-right-leave-active{transition-timing-function:ease-in}.fm-slide-in-enter-active,.fm-slide-in-leave-active,.fm-slide-out-enter-active,.fm-slide-out-leave-active{will-change:transform;transition:all .3s;height:100%;width:100%;top:0;position:absolute;backface-visibility:hidden;perspective:1000}.fm-slide-in-leave-to,.fm-slide-out-enter-from{transform:translate(-100%);opacity:0}.fm-slide-in-enter-from,.fm-slide-out-leave-to{transform:translate(100%);opacity:0}@keyframes fm-drop-down-in{0%{height:0;opacity:0}to{opacity:1}}@keyframes fm-drop-down-out{0%{opacity:1}to{height:0;opacity:0}}.fm-drop-down-enter-active{animation:.3s fm-drop-down-in both ease-out}.fm-drop-down-leave-active{animation:.3s fm-drop-down-out both ease-in}@keyframes fm-rotate{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}:root{--fm-button-height: 42px;--fm-button-padding: 0 14px;--fm-button-radius: 2px;--fm-button-border-width: 1px;--fm-button-color: var(--fm-white);--fm-button-line-height: var(--fm-line-height);--fm-button-font-size: var(--fm-font-size);--fm-button-plain-background: var(--fm-white);--fm-button-lg-height: 46px;--fm-button-lg-font-size: 18px;--fm-button-md-height: 38px;--fm-button-md-font-size: 14px;--fm-button-sm-height: 34px;--fm-button-sm-padding: 0 8px;--fm-button-sm-font-size: 12px;--fm-button-xs-height: 28px;--fm-button-xs-font-size: 10px;--fm-button-secondary-color: var(--fm-blue-light)}.fm-button{position:relative;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;text-align:center;margin:0;border:none;transition:opacity .2s;color:var(--fm-button-color);height:var(--fm-button-height);padding:var(--fm-button-padding);font-size:var(--fm-button-font-size);line-height:var(--fm-button-line-height);border-radius:var(--fm-button-radius)}.fm-button--primary,.fm-button--info{background:var(--fm-primary-color)}.fm-button--secondary{color:var(--fm-primary-color);background:var(--fm-button-secondary-color)}.fm-button--danger{background-color:var(--fm-danger-color)}.fm-button--warning{background-color:var(--fm-warning-color)}.fm-button--success{background-color:var(--fm-success-color)}.fm-button--plain{box-shadow:none;background:var(--fm-button-plain-background)}.fm-button--plain.fm-button--primary,.fm-button--plain.fm-button--info{color:var(--fm-primary-color);border:var(--fm-button-border-width) solid var(--fm-primary-color)}.fm-button--plain.fm-button--success{color:var(--fm-success-color);border:var(--fm-button-border-width) solid var(--fm-success-color)}.fm-button--plain.fm-button--danger{color:var(--fm-danger-color);border:var(--fm-button-border-width) solid var(--fm-danger-color)}.fm-button--plain.fm-button--warning{color:var(--fm-button-warning-color);border:var(--fm-button-border-width) solid var(--fm-button-warning-color)}.fm-button--noborder{border:none!important}.fm-button--large{height:var(--fm-button-lg-height);font-size:var(--fm-button-lg-font-size)}.fm-button--normal{height:var(--fm-button-md-height);font-size:var(--fm-button-md-font-size)}.fm-button--small{height:var(--fm-button-sm-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-sm-font-size)}.fm-button--mini{height:var(--fm-button-xs-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-xs-font-size)}.fm-button--block{display:flex;width:100%}.fm-button--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-button--loading:before,.fm-button--disabled:before{display:none}.fm-button--round{border-radius:var(--fm-radius-max)}.fm-button--square{border-radius:0}.fm-button__loading{display:inline-block;width:20px;max-width:100%;height:20px;max-height:100%;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-button__loading circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}.fm-button__loading-icon-circular{color:#fff}.fm-button__loading-text{margin-left:6px}.fm-button__icon:not(:last-child){margin-right:6px}.fm-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;background-color:#000;border:inherit;border-color:#000;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;content:" "}.fm-button:active:before{opacity:.1}.fm-button-edit__tags{min-height:24px;flex:1;display:flex;overflow:auto}.fm-button-edit__tag:not(:last-child){margin-right:6px}.fm-button-group{display:flex;padding:8px 16px}.fm-button-group__item{display:flex;flex:1}:root{--fm-cell-padding: 10px 16px;--fm-cell-margin: 5px;--fm-cell-line-height: 24px;--fm-cell-font-size: var(--fm-font-size);--fm-cell-background: var(--fm-background-white);--fm-cell-color: var(--fm-text-color);--fm-cell-label-font-size: 12px;--fm-cell-label-line-height: 18px;--fm-cell-label-color: var(--fm-text-color-light);--fm-cell-required-color: var(--fm-danger-color)}.fm-cell{width:100%;padding:var(--fm-cell-padding);background-color:var(--fm-cell-background);color:var(--fm-cell-color);font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);position:relative;display:flex;overflow:hidden}.fm-cell-bottom-border,.fm-cell:not(:last-child){border-bottom:1px solid #ddd;position:relative}@media (min-resolution: 1dppx){html:not([data-scale]) .fm-cell-bottom-border,html:not([data-scale]) .fm-cell:not(:last-child){border-bottom:none}html:not([data-scale]) .fm-cell-bottom-border:after,html:not([data-scale]) .fm-cell:not(:last-child):after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-cell-bottom-border:after,.fm-cell:not(:last-child):after{left:16px!important}.fm-cell.fm-cell-all-width:not(:last-child):after{left:0!important}.fm-cell--clickable{cursor:pointer}.fm-cell--clickable:active{background-color:var(--fm-active-color)}.fm-cell--required .fm-cell-title{position:relative}.fm-cell--required .fm-cell-title .fm-cell-title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-cell__title,.fm-cell__value{flex:1;font-size:inherit}.fm-cell__title{display:inline-block;overflow:hidden}.fm-cell__title-text{display:flex;word-break:break-all}.fm-cell__title-text span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-cell__right{display:flex;overflow:hidden;flex-direction:column}.fm-cell__right-content{display:flex;flex:1}.fm-cell__right--fill{flex:1}.fm-cell__value{position:relative;overflow:hidden;text-align:right;vertical-align:middle;word-wrap:break-word}.fm-cell__value--alone{text-align:left}.fm-cell__label{margin-top:var(--fm-cell-margin);color:var(--fm-cell-label-color);font-size:var(--fm-cell-label-font-size);line-height:var(--fm-cell-label-line-height)}.fm-cell--center{align-items:center}.fm-cell__extra,.fm-cell__left-icon,.fm-cell__right-icon{min-width:1em;font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);display:flex;align-items:center}.fm-cell__left-icon{margin-right:var(--fm-cell-margin)}.fm-cell__extra,.fm-cell__right-icon{margin-left:var(--fm-cell-margin)}.fm-cell--noborder .fm-cell:after{display:none!important}.fm-cell--card{padding-left:0;padding-right:0}.fm-checkbox-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-checkbox-group--vertical{flex-direction:column}.fm-checkbox-group--vertical .fm-checkbox:not(:last-child){margin-bottom:8px}.fm-checkbox{margin-top:4px;margin-bottom:4px}:root{--fm-checker-color: var(--fm-text-color);--fm-checker-font-size: var(--fm-font-size);--fm-checker-icon-color: var(--fm-text-color-light);--fm-checker-icon-background: var(--fm-background-white);--fm-checker-icon-radius: var(--fm-radius-md);--fm-checker-checked-icon-color: var(--fm-primary-color);--fm-checker-button-background: var(--fm-gray-2);--fm-checker-disabled-color: var(--fm-disabled-color);--fm-checker-disabled-icon-color: var(--fm-gray-1)}.fm-checker{display:flex;align-items:center;color:var(--fm-checker-color);font-size:var(--fm-checker-font-size)}.fm-checker__icon{display:inline-block;align-items:center}.fm-checker__icon .fm-icon{display:block;height:20px;width:20px;line-height:18px;font-size:14px;text-align:center;border-radius:var(--fm-checker-icon-radius);border:1px solid var(--fm-checker-icon-color);color:var(--fm-checker-icon-background);background-color:var(--fm-checker-icon-background)}.fm-checker__label{margin-left:8px;margin-right:8px;display:inline-block;line-height:20px}.fm-checker:first-child .fm-checker_button{margin-left:0}.fm-checker--round .fm-checker__icon .fm-icon{border-radius:100%}.fm-checker--button .fm-checker__label{font-size:13px;text-align:center;border-radius:14px;line-height:28px;padding:0 12px;min-width:60px;margin-right:0;color:var(--fm-checker-color);background:var(--fm-checker-button-background)}.fm-checker--checked .fm-checker__icon .fm-icon{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-checked-icon-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--checked.fm-checker--button .fm-checker__label{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--readonly{opacity:var(--fm-readonly-opacity)}.fm-checker--disabled{color:var(--fm-checker-disabled-color)}.fm-checker--disabled .fm-checker__icon .fm-icon{border-color:var(--fm-checker-disabled-color);background-color:var(--fm-checker-disabled-icon-color);color:var(--fm-checker-disabled-icon-color)}.fm-checker--disabled.fm-checker--checked .fm-checker__icon .fm-icon{background-color:var(--fm-checker-disabled-color);border-color:var(--fm-checker-disabled-color)}:root{--fm-icon-font-size: 14px;--fm-icon-color: inherit}.fm-icon{font-family:farrisMobile!important;font-size:var(--fm-icon-font-size);font-style:normal;color:var(--fm-icon-color);display:inline-block;width:1em;height:1em;font-weight:400;line-height:1;vertical-align:middle;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fm-icon:before{display:inline-block}.fm-icon-filter:before{content:"\e697"}.fm-icon-cardfold:before{content:"\e6b7"}.fm-icon-cardunfold:before{content:"\e6b8"}.fm-icon-trafficother:before{content:"\e6b9"}.fm-icon-bottomsave:before{content:"\e6ba"}.fm-icon-trafficboat:before{content:"\e6bb"}.fm-icon-trafficcar:before{content:"\e6bc"}.fm-icon-trafficplane:before{content:"\e6bd"}.fm-icon-traffictrain:before{content:"\e6be"}.fm-icon-trafficbus:before{content:"\e6bf"}.fm-icon-addgray:before{content:"\e6a7"}.fm-icon-close:before{content:"\e6a8"}.fm-icon-add-line:before{content:"\e6a9"}.fm-icon-more:before{content:"\e6aa"}.fm-icon-check:before{content:"\e6ab"}.fm-icon-backcircle:before{content:"\e6ac"}.fm-icon-agree:before{content:"\e6ad"}.fm-icon-loading:before{content:"\e6ae"}.fm-icon-filedel:before{content:"\e6af"}.fm-icon-file:before{content:"\e6b0"}.fm-icon-processflow:before{content:"\e6b1"}.fm-icon-redstar:before{content:"\e6b2"}.fm-icon-rightcircle:before{content:"\e6b3"}.fm-icon-timecircle:before{content:"\e6b4"}.fm-icon-screening:before{content:"\e6b5"}.fm-icon-uncheck:before{content:"\e6b6"}.fm-icon-operation:before{content:"\e02c"}.fm-icon-approvalamount:before{content:"\e02b"}.fm-icon-agreed:before{content:"\e02a"}.fm-icon-inprocess:before{content:"\e029"}.fm-icon-feedback:before{content:"\e028"}.fm-icon-print:before{content:"\e027"}.fm-icon-important:before{content:"\e026"}.fm-icon-amountofreimbursement:before{content:"\e025"}.fm-icon-safetyassistant:before{content:"\e024"}.fm-icon-remind:before{content:"\e023"}.fm-icon-eyeoppen:before{content:"\e022"}.fm-icon-eyeclose:before{content:"\e01e"}.fm-icon-photography:before{content:"\e021"}.fm-icon-photograph:before{content:"\e020"}.fm-icon-addpicture:before{content:"\e01f"}.fm-icon-top_other-face:before{content:"\e01d"}.fm-icon-top_other:before{content:"\e01c"}.fm-icon-delete:before{content:"\e01b"}.fm-icon-nextpage:before{content:"\e01a"}.fm-icon-addbutton:before{content:"\e019"}.fm-icon-waitforprocessing:before{content:"\e018"}.fm-icon-warningmessage:before{content:"\e017"}.fm-icon-failureprompt:before{content:"\e016"}.fm-icon-successfulhints:before{content:"\e015"}.fm-icon-other:before{content:"\e014"}.fm-icon-retract:before{content:"\e013"}.fm-icon-drop-down:before{content:"\e012"}.fm-icon-cancel:before{content:"\e011"}.fm-icon-search:before{content:"\e010"}.fm-icon-multiplechoice:before{content:"\e00f"}.fm-icon-singlechoice:before{content:"\e00e"}.fm-icon-microphone:before{content:"\e00d"}.fm-icon-arrow-chevron-left:before{content:"\e00c"}.fm-icon-helpcenter:before{content:"\e00b"}.fm-icon-sweepcode:before{content:"\e00a"}.fm-icon-groupchat:before{content:"\e009"}.fm-icon-addfriend:before{content:"\e008"}.fm-icon-top_my:before{content:"\e007"}.fm-icon-top_my-face:before{content:"\e006"}.fm-icon-top_friend:before{content:"\e005"}.fm-icon-top_friend-face:before{content:"\e004"}.fm-icon-top_publicpraise:before{content:"\e003"}.fm-icon-top_publicpraise-face:before{content:"\e002"}.fm-icon-top_home:before{content:"\e001"}.fm-icon-top_home-face:before{content:"\e000"}.fm-icon-s-agree-o:before{content:"\e655"}.fm-icon-s-arrow-down:before{content:"\e656"}.fm-icon-s-add-o:before{content:"\e657"}.fm-icon-s-annex:before{content:"\e658"}.fm-icon-s-arrow:before{content:"\e659"}.fm-icon-s-arrow-up:before{content:"\e65e"}.fm-icon-s-checkbox-checked:before{content:"\e65f"}.fm-icon-s-checkbox:before{content:"\e660"}.fm-icon-s-arrow-left:before{content:"\e661"}.fm-icon-s-exchange:before{content:"\e662"}.fm-icon-s-clear:before{content:"\e663"}.fm-icon-s-checked:before{content:"\e664"}.fm-icon-s-eye-o:before{content:"\e665"}.fm-icon-s-close-eye:before{content:"\e666"}.fm-icon-s-at:before{content:"\e667"}.fm-icon-s-feedback-o:before{content:"\e668"}.fm-icon-s-fold-circle-o:before{content:"\e669"}.fm-icon-s-cross:before{content:"\e66a"}.fm-icon-s-minus:before{content:"\e66b"}.fm-icon-s-file:before{content:"\e66c"}.fm-icon-s-fold-triangle:before{content:"\e66d"}.fm-icon-s-filter:before{content:"\e66e"}.fm-icon-s-forword:before{content:"\e66f"}.fm-icon-s-plus:before{content:"\e670"}.fm-icon-s-filedel:before{content:"\e671"}.fm-icon-s-fold-o:before{content:"\e672"}.fm-icon-s-image-o:before{content:"\e673"}.fm-icon-s-more-o:before{content:"\e674"}.fm-icon-s-redio-circle:before{content:"\e675"}.fm-icon-s-reject-o:before{content:"\e676"}.fm-icon-s-success:before{content:"\e677"}.fm-icon-s-refresh:before{content:"\e678"}.fm-icon-s-star:before{content:"\e679"}.fm-icon-s-processflow:before{content:"\e67a"}.fm-icon-s-unfold-circle-o:before{content:"\e67b"}.fm-icon-s-rewind:before{content:"\e67c"}.fm-icon-s-unfold-o:before{content:"\e67d"}.fm-icon-s-save-o:before{content:"\e67e"}.fm-icon-s-warning-o:before{content:"\e67f"}.fm-icon-s-unfold-triangle:before{content:"\e680"}.fm-icon-s-print-o:before{content:"\e681"}.fm-icon-s-search-o:before{content:"\e682"}.fm-icon-s-news:before{content:"\e683"}.fm-icon-s-news-o:before{content:"\e684"}.fm-icon-s-shop:before{content:"\e68c"}.fm-icon-s-sending:before{content:"\e60b"}.fm-icon-s-import-o:before{content:"\e60c"}.fm-icon-s-edit-o:before{content:"\e60d"}.fm-icon-s-qrcode:before{content:"\e60e"}.fm-icon-s-briefcase:before{content:"\e60f"}.fm-icon-s-notificationoff:before{content:"\e610"}.fm-icon-s-pencil:before{content:"\e611"}.fm-icon-s-star-o:before{content:"\e612"}.fm-icon-s-barcode:before{content:"\e613"}.fm-icon-s-salemessage-o:before{content:"\e614"}.fm-icon-s-listview-o:before{content:"\e615"}.fm-icon-s-picture-o:before{content:"\e616"}.fm-icon-s-savefillet-o:before{content:"\e617"}.fm-icon-s-shoppingcart:before{content:"\e618"}.fm-icon-s-pending:before{content:"\e61d"}.fm-icon-s-expandview-o:before{content:"\e61e"}.fm-icon-s-lock-o:before{content:"\e623"}.fm-icon-s-my:before{content:"\e692"}.fm-icon-s-service:before{content:"\e633"}.fm-icon-s-wallet-o:before{content:"\e634"}.fm-icon-s-shoppingcart-o:before{content:"\e636"}.fm-icon-s-setting-o:before{content:"\e637"}.fm-icon-s-my-o:before{content:"\e696"}.fm-icon-s-unfoldrec-o:before{content:"\e639"}.fm-icon-s-profile:before{content:"\e63a"}.fm-icon-s-link-o:before{content:"\e609"}.fm-icon-s-usersetting-o:before{content:"\e632"}.fm-icon-s-shop-o:before{content:"\e68a"}.fm-icon-s-list:before{content:"\e62a"}.fm-icon-s-location-o:before{content:"\e685"}.fm-icon-s-location:before{content:"\e686"}.fm-icon-s-moment:before{content:"\e689"}.fm-icon-s-moment-o:before{content:"\e68b"}.fm-icon-s-revoke-o:before{content:"\e687"}.fm-icon-s-submit-o:before{content:"\e688"}.fm-icon-s-app-o:before{content:"\e68f"}.fm-icon-s-app:before{content:"\e691"}.fm-icon-s-book-o:before{content:"\e695"}.fm-icon-s-book:before{content:"\e690"}.fm-icon-s-comment:before{content:"\e693"}.fm-icon-s-comment-o:before{content:"\e694"}.fm-icon-s-illustrate-o:before{content:"\e68d"}.fm-icon-s-clear-o:before{content:"\e68e"}.fm-icon-friend:before{content:"\e005"}.fm-icon-scan:before{content:"\e69a"}.fm-icon-back:before{content:"\e69b"}.fm-icon-menu:before{content:"\e69d"}:root{--fm-navbar-background: var(--fm-background-white);--fm-navbar-color: var(--fm-text-color);--fm-navbar-height: 44px;--fm-navbar-title-size: 17px;--fm-navbar-side-size: 16px;--fm-navbar-arrow-size: 18px}.fm-navbar{position:relative;z-index:9;display:flex;align-items:center;line-height:1.5;text-align:center;user-select:none;height:var(--fm-navbar-height);color:var(--fm-navbar-color);background-color:var(--fm-navbar-background)}.fm-navbar.fm-navbar-fixed{position:fixed;top:0;left:0;width:100%}.fm-navbar.fm-navbar-border-bottom{border-bottom:1px solid #eee;position:relative}@media (min-resolution: 1dppx){html:not([data-scale]) .fm-navbar.fm-navbar-border-bottom{border-bottom:none}html:not([data-scale]) .fm-navbar.fm-navbar-border-bottom:after{content:"";position:absolute;background-color:#eee;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-navbar-title{max-width:60%;margin:0 auto;font-weight:500;font-size:var(--fm-navbar-title-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-navbar-left,.fm-navbar-right{position:absolute;top:0;bottom:0;display:flex;align-items:center;max-width:30%;padding:0 16px;font-size:var(--fm-navbar-side-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;cursor:pointer}.fm-navbar-left{left:0}.fm-navbar-left:active{opacity:var(--fm-active-opacity)}.fm-navbar-left.fm-navbar-left-padding{padding-left:14px}.fm-navbar-right{right:0}.fm-navbar-right .fm-navbar-text:active{opacity:var(--fm-active-opacity)}.fm-navbar .fm-navbar-left-arrow{min-width:1em;margin-right:4px;font-size:var(--fm-navbar-arrow-size)}:root{--fm-input-group-size: var(--fm-font-size);--fm-input-group-color: var(--fm-text-color);--fm-input-group-sub-size: 13px;--fm-input-group-padding: 10px 16px;--fm-input-group-sub-color: var(--fm-text-color-light);--fm-input-group-border-color: var(--fm-gray-2)}.fm-input-group{display:flex;flex-direction:column;background-color:var(--fm-white)}.fm-input-group--padding{padding:var(--fm-input-group-padding)}.fm-input-group__body{flex:1;display:flex;align-items:center;min-height:24px}.fm-input-group__body--border{border:1px solid var(--fm-input-group-border-color);padding:4px 8px;border-radius:4px}.fm-input-group__control{display:flex;width:100%;min-width:0;margin:0;padding:0;border:0;resize:none;line-height:inherit;background-color:transparent;color:var(--fm-input-group-color);font-size:var(--fm-input-group-size);outline:none}.fm-input-group__control::placeholder{color:var(--fm-input-group-sub-color)}.fm-input-group__control:disabled{opacity:1;cursor:not-allowed;color:var(--fm-disabled-color);-webkit-text-fill-color:currentColor}.fm-input-group__control::-webkit-search-cancel-button{display:none}.fm-input-group__control--readonly{cursor:default;color:var(--fm-readonly-color)}.fm-input-group__control--left{justify-content:flex-start;text-align:left}.fm-input-group__control--center{justify-content:center;text-align:center}.fm-input-group__control--right{justify-content:flex-end;text-align:right}.fm-input-group__clear{cursor:pointer;margin-right:-8px;padding:4px 8px;color:var(--fm-input-group-sub-color);flex-shrink:0;box-sizing:content-box}.fm-input-group__left-icon{margin:auto 4px auto 0}.fm-input-group__right-icon{margin:auto 0 auto 4px}.fm-input-group__word-limit{margin-top:4px;line-height:18px;text-align:right;font-size:var(--fm-input-group-sub-size);color:var(--fm-input-group-sub-color)}.fm-radio-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-radio-group--vertical{flex-direction:column}.fm-radio-group--vertical .fm-radio:not(:last-child){margin-bottom:8px}.fm-radio{margin-top:4px;margin-bottom:4px}:root,:host{--fm-rate-icon-size: 20px;--fm-rate-icon-gutter: var(--fm-padding-base);--fm-rate-icon-void-color: var(--fm-gray-4);--fm-rate-icon-full-color: var(--fm-orange-3);--fm-rate-icon-disabled-color: var(--fm-gray-4)}.fm-rate{display:inline-flex;cursor:pointer;user-select:none;flex-wrap:wrap}.fm-rate__item{position:relative}.fm-rate__item:not(:last-child){padding-right:var(--fm-rate-icon-gutter)}.fm-rate__icon{display:block;width:1em;color:var(--fm-rate-icon-void-color);font-size:var(--fm-rate-icon-size)}.fm-rate__icon--half{position:absolute;top:0;left:0;overflow:hidden;pointer-events:none;color:var(--fm-rate-icon-full-color)}.fm-rate__icon--full{color:var(--fm-rate-icon-full-color)}.fm-rate__icon--disabled{color:var(--fm-rate-icon-disabled-color)}.fm-rate--disabled{cursor:not-allowed}.fm-rate--readonly{cursor:default}:root{--fm-form-item-size: var(--fm-font-size);--fm-form-item-color: var(--fm-text-color);--fm-form-item-label-width: 105px;--fm-form-item-sub-size: 13px}.fm-form-item{font-size:var(--fm-form-item-size);color:var(--fm-form-item-color)}.fm-form-item--vertical{flex-direction:column}.fm-form-item--vertical .fm-form-item__label{margin-bottom:4px}.fm-form-item__label{display:flex;flex:none;align-items:flex-start;text-align:left;width:var(--fm-form-item-label-width);margin-right:4px}.fm-form-item__label--left{justify-content:flex-start}.fm-form-item__label--center{justify-content:center}.fm-form-item__label--right{justify-content:flex-end}.fm-form-item__label--required{position:relative}.fm-form-item__label--required .fm-cell__title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-form-item__content{display:flex}.fm-form-item__content .fm-input-group{padding:0;flex:1}.fm-form-item__content--left{justify-content:flex-start}.fm-form-item__content--left input.fm-input-group__control{justify-content:flex-start;text-align:left}.fm-form-item__content--center{justify-content:center}.fm-form-item__content--center input.fm-input-group__control{justify-content:flex-center;text-align:center}.fm-form-item__content--right{justify-content:flex-end}.fm-form-item__content--right input.fm-input-group__control{justify-content:flex-end;text-align:right}.fm-form-item__error-message{color:var(--fm-danger-color);font-size:var(--fm-form-item-sub-size)}.fm-form-item__error-message--left{text-align:left}.fm-form-item__error-message--center{text-align:center}.fm-form-item__error-message--right{text-align:right}.fm-form{display:flex;flex-direction:column}.fm-form .farris-component.can-move{padding:0!important}.fm-input-wrapper:not(:last-child) .fm-cell:not(.fm-no-hairline):after,.fm-form-item-wrapper:not(:last-child):not(.fm-no-hairline):after,.fm-form-designer-item-wrapper:not(:last-child) .fm-form-item-wrapper:not(.fm-no-hairline):after{transform:scaleY(.5)}:root{--fm-overlay-background: rgba(0, 0, 0, .4);--fm-overlay-zindex: 98}.fm-overlay{width:100%;position:fixed;top:0;left:0;z-index:var(--fm-overlay-zindex);background-color:var(--fm-overlay-background);bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-overlay{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}:root{--fm-popup-background: var(--fm-white);--fm-popup-zindex: var(--fm-zindex-3);--fm-popup-radius: 16px}.fm-popup{position:fixed;max-height:100%;overflow-y:auto;background-color:var(--fm-popup-background);transition:all var(--fm-duration-base);z-index:var(--fm-popup-zindex)}.fm-popup--center{top:50%;left:50%;transform:translate(-50%,-50%)}.fm-popup--center.fm-popup--round{border-radius:var(--fm-popup-radius)}.fm-popup--top,.fm-popup--bottom{left:0;right:0}.fm-popup--top{top:0}.fm-popup--top.fm-popup--round{border-radius:0 0 var(--fm-popup-radius) var(--fm-popup-radius)}.fm-popup--bottom{bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--bottom{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--bottom.fm-popup--round{border-radius:var(--fm-popup-radius) var(--fm-popup-radius) 0 0}.fm-popup--left,.fm-popup--right{top:0;bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--left,.fm-popup--right{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--left{left:0}.fm-popup--left.fm-popup--round{border-radius:0 var(--fm-popup-radius) var(--fm-popup-radius) 0}.fm-popup--right{right:0}.fm-popup--right.fm-popup--round{border-radius:var(--fm-popup-radius) 0 0 var(--fm-popup-radius)}:root{--fm-switch-background: var(--fm-text-color-light);--fm-switch-on-color: var(--fm-primary-color)}.fm-switch{position:relative;cursor:pointer;display:inline-block;transition:background-color var(--fm-duration-base);background-color:var(--fm-switch-background)}.fm-switch--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-switch--readonly{cursor:default;opacity:var(--fm-readonly-opacity)}.fm-switch--loading{cursor:default}.fm-switch--on{background-color:var(--fm-switch-on-color)}.fm-switch--on .fm-switch__loadding{color:var(--fm-switch-on-color)}.fm-switch__node{display:flex;align-items:center;justify-content:center;position:absolute;top:1px;left:1px;z-index:1;width:28px;height:28px;border-radius:100%;background-color:var(--fm-white);transition:transform var(--fm-duration-base) cubic-bezier(.3,1.05,.4,1.05)}:root{--fm-toast-zindex: var(--fm-zindex-5);--fm-toast-color: var(--fm-white);--fm-toast-font-size: 16px;--fm-toast-background: var(--fm-gray-7);--fm-toast-icon-font-size: 48px}.fm-toast{position:fixed;top:50%;left:50%;display:-webkit-box;display:-webkit-flex;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:content-box;max-width:70%;padding:16px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;border-radius:7px;transform:translate(-50%,-50%);color:var(--fm-toast-color);z-index:var(--fm-toast-zindex);font-size:var(--fm-toast-font-size);background-color:var(--fm-toast-background)}.fm-toast--top{top:50px;transform:translate(-50%)}.fm-toast--bottom{top:auto;bottom:50px}.fm-toast--info,.fm-toast--success,.fm-toast--warning,.fm-toast--error{width:88px;min-height:88px}.fm-toast__icon-wrapper{margin-bottom:8px}.fm-toast--default{padding:8px 16px}.fm-toast--loading{min-width:84px;min-height:84px}.fm-toast--loading-icon{position:relative;display:inline-block;width:30px;height:30px;margin-bottom:8px;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-toast--loading-icon circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}:root{--fm-notify-color: var(--fm-white);--fm-notify-zindex: var(--fm-zindex-5);--fm-notify-info-background: var(--fm-primary-color);--fm-notify-success-background: var(--fm-success-color);--fm-notify-warning-background: var(--fm-warning-color);--fm-notify-error-background: var(--fm-danger-color)}.fm-notify{position:fixed;left:0;top:0;z-index:var(--fm-notify-zindex);display:flex;align-items:center;justify-content:center;width:100%;max-height:100%;padding:8px 16px;box-sizing:border-box;color:var(--fm-notify-color);font-size:14px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;overflow-y:auto}.fm-notify--info{background-color:var(--fm-notify-info-background)}.fm-notify--success{background-color:var(--fm-notify-success-background)}.fm-notify--warning{background-color:var(--fm-notify-warning-background)}.fm-notify--error{background-color:var(--fm-notify-error-background)}:root{--fm-dialog-background: var(--fm-background-2);--fm-dialog-padding-top: 24px;--fm-dialog-padding-left: 16px;--fm-dialog-header-font-size: 17px;--fm-dialog-header-line-height: 24px;--fm-dialog-content-font-size: 15px;--fm-dialog-content-line-height: 20px;--fm-dialog-footer-height: 50px;--fm-border-color: var(--fm-gray-4)}@media screen and (min-width: 375px){.fm-dialog{width:320px}}@media screen and (min-width: 280px) and (max-width: 375px){.fm-dialog{width:240px}}.fm-dialog{display:flex;flex-direction:column;background-color:var(--fm-dialog-background);overflow:hidden}.fm-dialog__header{padding-top:var(--fm-dialog-padding-top);padding-left:var(--fm-dialog-header-padding-left);padding-right:var(--fm-dialog-header-padding-left);font-weight:var(--fm-font-bold-light);font-size:var(--fm-dialog-header-font-size);color:var(--fm-text-color);line-height:var(--fm-dialog-header-line-height);text-align:center}.fm-dialog__content{max-height:70vh;overflow-y:auto}.fm-dialog__content__message{padding:var(--fm-dialog-padding-top) var(--fm-dialog-padding-left);font-size:var(--fm-dialog-content-font-size);line-height:var(--fm-dialog-content-line-height);white-space:pre-wrap;text-align:center;word-wrap:break-word}.fm-dialog__content__message--has-title{padding-top:11px;color:var(--fm-text-color-light)}.fm-dialog__content--prompt{padding:14px}.fm-dialog__content--prompt__input{display:block}.fm-dialog__footer{display:flex;flex-direction:row;align-items:center;border-top:1px solid var(--fm-border-color);position:relative}@media (min-resolution: 1dppx){html:not([data-scale]) .fm-dialog__footer{border-top:none}html:not([data-scale]) .fm-dialog__footer:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}}.fm-dialog__footer .fm-button{border:0;height:var(--fm-dialog-footer-height);border-right:1px solid var(--fm-border-color);position:relative}@media (min-resolution: 1dppx){html:not([data-scale]) .fm-dialog__footer .fm-button{border-right:none}html:not([data-scale]) .fm-dialog__footer .fm-button:after{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 0 auto auto;width:1px;height:100%;background:var(--fm-border-color);transform-origin:100% 50%;transform:scaleX(.5)}}.fm-dialog__footer .fm-button:last-child{border-right:0}.fm-dialog__footer .fm-button:last-child:after{display:none!important}.fm-dialog__footer .fm-button--default{color:var(--fm-text-color)}.fm-dialog__footer--is-column{flex-direction:column}.fm-dialog__footer--is-column__button{border-top:1px solid var(--fm-border-color);position:relative}@media (min-resolution: 1dppx){html:not([data-scale]) .fm-dialog__footer--is-column__button{border-top:none}html:not([data-scale]) .fm-dialog__footer--is-column__button:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}}.fm-dialog__footer--is-column__button:first-child{border-top:0}.fm-dialog__footer--is-column__button:first-child:before{display:none!important}.fm-dialog.fm-dialog--relative{position:relative}.fm-dialog.fm-dialog--relative__header{padding-right:40px}.fm-dialog__close{position:absolute;right:16px;top:16px;width:22px;height:22px;line-height:22px;text-align:center}.fm-dialog__close .fm-icon{font-size:15px;color:var(--fm-text-color-2)}:root,:host{--fm-loading-color: var(--fm-gray-5);--fm-loading-text-font-size: 14px;--fm-loading-text-line-height: 1.4}.fm-loading{display:flex;align-items:center;position:relative;color:var(--fm-loading-color)}.fm-loading__text{color:var(--fm-loading-color);font-size:var(--fm-loading-text-font-size);line-height:var(--fm-loading-text-line-height);margin-left:var(--fm-margin-xs)}.fm-loading--vertical{flex-direction:column}.fm-loading--vertical .fm-loading__text{margin-top:var(--fm-margin-xs);margin-left:0}.fm-loading__circular{display:block;animation:fm-rotate 2s linear infinite}.fm-loading__circular circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:3;stroke-linecap:round}.fm-loading__spinner{display:block;position:relative;animation:fm-rotate 1s linear infinite;animation-timing-function:steps(12)}.fm-loading__line{position:absolute;top:0;left:0;width:100%;height:100%}.fm-loading__line-inner{display:block;width:2px;height:25%;margin:0 auto;background-color:currentColor;border-radius:40%}.fm-loading__ring{display:block;animation:fm-rotate .75s linear infinite;border:4px solid;border-right-color:transparent;border-radius:50%}@keyframes fm-circular{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40}to{stroke-dasharray:90,150;stroke-dashoffset:-120}}.fm-loading__line--1{transform:rotate(30deg);opacity:1}.fm-loading__line--2{transform:rotate(60deg);opacity:.9375}.fm-loading__line--3{transform:rotate(90deg);opacity:.875}.fm-loading__line--4{transform:rotate(120deg);opacity:.8125}.fm-loading__line--5{transform:rotate(150deg);opacity:.75}.fm-loading__line--6{transform:rotate(180deg);opacity:.6875}.fm-loading__line--7{transform:rotate(210deg);opacity:.625}.fm-loading__line--8{transform:rotate(240deg);opacity:.5625}.fm-loading__line--9{transform:rotate(270deg);opacity:.5}.fm-loading__line--10{transform:rotate(300deg);opacity:.4375}.fm-loading__line--11{transform:rotate(330deg);opacity:.375}.fm-loading__line--12{transform:rotate(360deg);opacity:.3125}:root,:host{--fm-pull-refresh-head-height: 50px;--fm-pull-refresh-head-font-size: var(--fm-font-size-md);--fm-pull-refresh-head-text-color: var(--fm-text-color-light);--fm-pull-refresh-animation-duration: .3s}.fm-pull-refresh{overflow:hidden}.fm-pull-refresh__track{position:relative;height:100%}.fm-pull-refresh__track--not-pulling{transition:transform ease var(--fm-pull-refresh-animation-duration)}.fm-pull-refresh__head{position:absolute;left:0;width:100%;height:var(--fm-pull-refresh-head-height);color:var(--fm-pull-refresh-head-text-color);font-size:var(--fm-pull-refresh-head-font-size);line-height:var(--fm-pull-refresh-head-height);text-align:center;transform:translateY(-100%);display:flex;justify-content:center;align-items:center;flex-direction:column;overflow:hidden}:root,:host{--fm-list-text-color: var(--fm-gray-5);--fm-list-text-font-size: var(--fm-font-size-md, 14px);--fm-list-text-line-height: 50px;--fm-list-loading-icon-size: 16px}.fm-list__loading,.fm-list__error,.fm-list__load-more,.fm-list__finished-info{color:var(--fm-list-text-color);font-size:var(--fm-list-text-font-size);line-height:var(--fm-list-text-line-height);text-align:center}.fm-list__loading-container{display:flex;height:var(--fm-list-text-line-height);justify-content:center;align-items:center}:root,:host{--fm-listview-checkbox-container-width: 40px;--fm-listview-toolbar-height: 42px;--fm-listview-split-line-color: rgb(230, 235, 235);--fm-listview-empty-text-color: var(--fm-gray-5);--fm-listview-empty-text-font-size: var(--fm-font-size-md, 14px);--fm-listview-empty-text-line-height: 50px}.fm-list-view--fill{height:100%;flex-grow:1;flex-shrink:1;display:flex;flex-direction:column;overflow:hidden}.fm-list-view--fill .fm-list-view__track{flex:1 1 0;overflow:auto;-webkit-overflow-scrolling:touch}.fm-list-view--fill .fm-pull-refresh{min-height:100%}.fm-list-view .fm-list{user-select:none;-webkit-user-select:none}.fm-list-view__item{display:flex;position:relative;overflow:hidden}.fm-list-view__item-checker{display:flex;position:absolute;height:100%;width:var(--fm-listview-checkbox-container-width);justify-content:center;align-items:center}.fm-list-view__item-content{flex:1;transform:translate(0)}.fm-list-view__content--split .fm-list-view__item:not(:last-child):not(.fm-list-view__item--child){border-bottom:1px solid var(--fm-listview-split-line-color)}.fm-list-view--multi-select .fm-list-view__item-content{transform:translate(var(--fm-listview-checkbox-container-width))}.fm-list-view__item--group{display:block}.fm-list-view__item-group-header{padding:10px 16px;line-height:20px;font-size:var(--fm-font-size-md);color:var(--fm-gray-5)}.fm-list-view__empty-message{display:block;color:var(--fm-listview-empty-text-color);font-size:var(--fm-listview-empty-text-font-size);line-height:var(--fm-listview-empty-text-line-height);text-align:center}.fm-list-view__item-text{padding:13px 20px;color:var(--fm-gray-7);font-size:var(--fm-font-size)}.fm-list-view__toolbar{display:flex;align-items:center;height:var(--fm-listview-toolbar-height)}.fm-list-view__toolbar-item{flex:1}:root,:host{--fm-swipe-cell-button-text-color: var(--fm-white);--fm-swipe-cell-button-bg-color: var(--fm-gray-4);--fm-swipe-cell-button-font-size: var(--fm-font-size);--fm-swipe-cell-button-icon-size: var(--fm-font-size);--fm-swipe-cell-button-padding: var(--fm-padding-md)}.fm-swipe-cell{position:relative;overflow:hidden}.fm-swipe-cell__wrapper{transition-timing-function:cubic-bezier(.18,.89,.32,1);transition-property:transform}.fm-swipe-cell__left,.fm-swipe-cell__right{position:absolute;top:0;height:100%;display:flex}.fm-swipe-cell__left{left:0;transform:translate3d(-100%,0,0);flex-direction:row-reverse}.fm-swipe-cell__right{right:0;transform:translate3d(100%,0,0)}.fm-swipe-cell__button{display:inline-flex;justify-content:center;align-items:center;height:100%;padding:0 var(--fm-swipe-cell-button-padding);color:var(--fm-swipe-cell-button-text-color);background-color:var(--fm-swipe-cell-button-bg-color)}.fm-swipe-cell__icon{font-size:var(--fm-swipe-cell-button-icon-size)}.fm-swipe-cell__text{font-size:var(--fm-swipe-cell-button-font-size)}.fm-swipe-cell__icon+.fm-swipe-cell__text:not(:empty){margin-left:6px}:root,:host{--fm-action-sheet-max-height: 80%;--fm-action-sheet-border-radius: 12px;--fm-action-sheet-description-color: var(--fm-gray-5);--fm-action-sheet-description-line-height: 22px;--fm-action-sheet-description-font-size: var(--fm-font-size-md);--fm-action-sheet-description-padding: 12px 16px;--fm-action-sheet-item-default-background: var(--fm-background-white);--fm-action-sheet-item-active-background: #f2f3f5;--fm-action-sheet-item-padding: 13px 16px;--fm-action-sheet-item-text-color: #1a1a1a;--fm-action-sheet-item-disabled-text-color: #bdbdbd;--fm-action-sheet-item-subtitle-color: var(--fm-gray-5);--fm-action-sheet-item-icon-size: 18px;--fm-action-sheet-item-icon-margin-right: 8px;--fm-action-sheet-item-title-font-size: var(--fm-font-size-lg);--fm-action-sheet-item-title-line-height: 24px;--fm-action-sheet-item-subtitle-font-size: var(--fm-font-size-sm);--fm-action-sheet-item-subtitle-line-height: 18px;--fm-action-sheet-item-subtitle-margin-top: 2px;--fm-action-sheet-footer-gap-color: #f5f5f5;--fm-action-sheet-divider-color: #e7e7e7;--fm-action-sheet-cancel-height: 48px;--fm-action-sheet-cancel-color: #1a1a1a;--fm-action-sheet-cancel-font-size: var(--fm-font-size-lg);--fm-action-sheet-cancel-font-weight: 500}.fm-action-sheet{display:flex;flex-direction:column;max-height:var(--fm-action-sheet-max-height);overflow:hidden;user-select:none}.fm-action-sheet--round{border-top-left-radius:var(--fm-action-sheet-border-radius);border-top-right-radius:var(--fm-action-sheet-border-radius)}.fm-action-sheet__description{flex-shrink:0;color:var(--fm-action-sheet-description-color);line-height:var(--fm-action-sheet-description-line-height);font-size:var(--fm-action-sheet-description-font-size);text-align:center;padding:var(--fm-action-sheet-description-padding);position:relative}.fm-action-sheet__description--left{text-align:left}.fm-action-sheet__content{flex:1 auto;overflow-y:auto;-webkit-overflow-scrolling:touch}.fm-action-sheet__item,.fm-action-sheet__cancel{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__item:active,.fm-action-sheet__cancel:active{background-color:var(--fm-action-sheet-item-active-background)}.fm-action-sheet__item{display:flex;position:relative;flex-wrap:wrap;align-items:center;justify-content:center;text-align:center;padding:var(--fm-action-sheet-item-padding);color:var(--fm-action-sheet-item-text-color);cursor:pointer}.fm-action-sheet__item-icon{font-size:var(--fm-action-sheet-item-icon-size);margin-right:var(--fm-action-sheet-item-icon-margin-right)}.fm-action-sheet__item-title{font-size:var(--fm-action-sheet-item-title-font-size);line-height:var(--fm-action-sheet-item-title-line-height)}.fm-action-sheet__item-subtitle{font-size:var(--fm-action-sheet-item-subtitle-font-size);line-height:var(--fm-action-sheet-item-subtitle-line-height);width:100%;margin-top:var(--fm-action-sheet-item-subtitle-margin-top);color:var(--fm-action-sheet-item-subtitle-color);overflow-wrap:break-word}.fm-action-sheet__item--left{text-align:left;justify-content:flex-start}.fm-action-sheet__item--disabled{color:var(--fm-action-sheet-item-disabled-text-color);cursor:not-allowed}.fm-action-sheet__item--disabled:active{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__description:after,.fm-action-sheet__item:after{content:"";display:block;position:absolute;height:1px;bottom:0;left:0;right:0;transform:scaleY(.5);background-color:var(--fm-action-sheet-divider-color)}.fm-action-sheet__footer-gap{height:8px;background-color:var(--fm-action-sheet-footer-gap-color)}.fm-action-sheet__cancel{display:flex;flex-direction:column;justify-content:center;align-items:center;height:var(--fm-action-sheet-cancel-height);cursor:pointer;color:var(--fm-action-sheet-cancel-color);font-size:var(--fm-action-sheet-cancel-font-size);font-weight:var(--fm-action-sheet-cancel-font-weight)}:root{--fm-tab-bar-item-color: var(--fm-text-color);--fm-tab-bar-item-active-color: var(--fm-primary-color);--fm-tab-bar-item-font-size: 16px}.fm-tab-bar-item{flex:1 0 auto;position:relative;display:inline-flex;align-items:center;justify-content:center;margin:0 12px;line-height:44px}.fm-tab-bar-item--actived{color:var(--fm-tab-bar-item-active-color)}.fm-tab-bar-item--disabled{color:var(--fm-disabled-color)}.fm-tab-bar-item--dot .fm-tab-bar-item__text:after{content:"";position:absolute;top:0;right:0;width:8px;height:8px;background-color:var(--fm-danger-color);border-radius:100%;transform:translate(100%,100%)}.fm-tab-bar-item__text{position:relative;display:flex;justify-content:center;min-width:40px}.fm-tab-bar-item__ink{position:absolute;bottom:0;left:0;right:0;height:4px;background-color:var(--fm-tab-bar-item-active-color);border-radius:2px}.fm-tab-bar-item__badge{position:absolute;top:2px;right:0;padding:0 4px;max-width:28px;font-weight:500;font-size:12px;line-height:14px;border-radius:7px;color:var(--fm-background-white);background-color:var(--fm-danger-color);transform:translate(50%)}.fm-tab-bar-item__icon{position:relative;display:flex;align-items:center;justify-content:center;padding-right:4px}:root{--fm-tab-bar-height: 44px;--fm-tab-bar-background: var(--fm-background-white);--fm-tab-bar-color: var(--fm-text-color);--fm-tab-bar-active-color: var(--fm-primary-color);--fm-tab-bar-font-size: 16px}.fm-tab-bar{position:relative;background:var(--fm-tab-bar-background);color:var(--fm-tab-bar-color);font-size:var(--fm-tab-bar-font-size)}.fm-tab-bar--bottom-line{border-bottom:1px solid #ddd;position:relative}@media (min-resolution: 1dppx){html:not([data-scale]) .fm-tab-bar--bottom-line{border-bottom:none}html:not([data-scale]) .fm-tab-bar--bottom-line:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tab-bar__scroll-wrapper{position:relative;width:100%;overflow:hidden}.fm-tab-bar__list{display:flex;justify-content:space-between;min-width:100%;transition:all .3s cubic-bezier(.17,.89,.45,1)}.fm-tab-bar__ink{position:absolute;bottom:0;left:0;display:block;height:4px;background-color:var(--fm-tab-bar-active-color);transition:all var(--fm-duration-base);border-radius:2px}.fm-tab-bar__ink--disabled{background-color:var(--fm-disabled-color)}.fm-tabs{overflow:hidden}.fm-tabs__content{display:flex}.fm-tab{display:block;flex-shrink:0;width:100%;height:100%;overflow:auto;word-break:break-all}.fm-tab--collapse{height:0;overflow:visible}:root{--fm-tag-padding: 0 6px;--fm-tag-height: 18px;--fm-tag-font-size: 12px;--fm-tag-border-radius: 2px;--fm-tag-color: var(--fm-white)}.fm-tag{position:relative;display:inline-flex;align-items:center;white-space:nowrap;padding:0 4px;color:var(--fm-tag-color);font-size:var(--fm-tag-font-size);line-height:var(--fm-tag-height);border-radius:var(--fm-tag-border-radius)}.fm-tag--primary{background-color:var(--fm-primary-color)}.fm-tag--success{background-color:var(--fm-success-color)}.fm-tag--danger{background-color:var(--fm-danger-color)}.fm-tag--warning{background-color:var(--fm-warning-color)}.fm-tag--plain{background-color:var(--fm-white)}.fm-tag--plain.fm-tag--primary{border:1px solid var(--fm-primary-color);color:var(--fm-primary-color)}.fm-tag--plain.fm-tag--success{border:1px solid var(--fm-success-color);color:var(--fm-success-color)}.fm-tag--plain.fm-tag--warning{border:1px solid var(--fm-warning-color);color:var(--fm-warning-color)}.fm-tag--plain.fm-tag--danger{border:1px solid var(--fm-danger-color);color:var(--fm-danger-color)}.fm-tag--medium{padding:2px 6px}.fm-tag--large{padding:4px 8px;font-size:14px;border-radius:4px}.fm-tag--round{border-radius:100px}.fm-tag--mark{border-radius:0 100px 100px 0}.fm-tag__close{font-size:8px;margin-left:4px}.fm-tag--large .fm-tag__close{font-size:10px}: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}.fm-picker__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker__toolbar-left,.fm-picker__toolbar-right{padding:0 16px}.fm-picker__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker__content{position:relative;display:flex;cursor:grab}.fm-picker__columns{display:flex;flex:1;overflow:hidden}.fm-picker__column{flex:1}.fm-picker__column-item{display:flex;align-items:center;justify-content:center;height:44px}.fm-picker__mask{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;background-image:linear-gradient(180deg,#ffffffe6,#fff6),linear-gradient(0deg,#ffffffe6,#fff6);background-repeat:no-repeat;background-position:top,bottom;transform:translateZ(0);pointer-events:none}.fm-picker__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(.5)}.fm-picker-group__header{text-align:left}.fm-picker-group__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker-group__toolbar-left,.fm-picker-group__toolbar-right{padding:0 16px}.fm-picker-group__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker-group__tab-bar{display:inline-block}.fm-page-container{flex:1;display:flex;flex-direction:column;background:#f9fafb;overflow:hidden;-webkit-overflow-scrolling:auto;position:absolute;inset:0}.fm-page-container .drag-container{display:inherit;flex-direction:inherit;flex-shrink:1;flex-grow:1;flex-basis:0%;flex-wrap:inherit;justify-content:inherit;align-items:inherit;width:100%;overflow:inherit}.fm-page-body-container{flex-basis:0;flex-shrink:1;flex-grow:1;padding-bottom:12px;overflow:auto;display:flex;flex-direction:column}.fm-page-header-container{flex-shrink:0}.fm-page-footer-container{background-color:#fff}.fm-float-container{position:absolute!important;bottom:60px;right:30px} diff --git a/packages/designer/src/app-providers.ts b/packages/designer/src/app-providers.ts index b1e68e40518..ffd9aed5702 100644 --- a/packages/designer/src/app-providers.ts +++ b/packages/designer/src/app-providers.ts @@ -6,9 +6,13 @@ import { MetadataPathToken, MetadataServiceToken } from "./components/types"; import { LookupFieldSelectorService, LookupSchemaService } from "./components/composition/schema-repository"; import { ControllerSelectorSchemaService } from "./components/composition/schema-repository/controller/controller-selector.service"; import { FormSelectorSchemaService } from "./components/composition/schema-repository/form/form-selector.service"; +import { useDesignerContext } from "./components/composition/designer-context/use-designer-context"; + +const designerContext = useDesignerContext(); export default { install(app: App): void { + app.provide('designerContext', designerContext); app.provide(F_MODAL_SERVICE_TOKEN, new FModalService(app)); app.provide('FLoadingService', FLoadingService); @@ -23,7 +27,7 @@ export default { app.provide(LookupSchemaRepositoryToken, new LookupSchemaService(metadataService)); app.provide(FieldSelectorRepositoryToken, new LookupFieldSelectorService(metadataService)); app.provide(F_NOTIFY_SERVICE_TOKEN, new FNotifyService()); - app.provide(ControllerSchemaRepositorySymbol, new ControllerSelectorSchemaService(metadataService)); + app.provide(ControllerSchemaRepositorySymbol, new ControllerSelectorSchemaService(metadataService,designerContext)); app.provide(FormSchemaRepositorySymbol, new FormSelectorSchemaService(metadataService)); app.directive('tooltip', FTooltipDirective); diff --git a/packages/designer/src/components/components/form-designer/form-designer.component.tsx b/packages/designer/src/components/components/form-designer/form-designer.component.tsx index 19248af8a6b..339ec344900 100644 --- a/packages/designer/src/components/components/form-designer/form-designer.component.tsx +++ b/packages/designer/src/components/components/form-designer/form-designer.component.tsx @@ -1,5 +1,5 @@ import { Ref, computed, defineComponent, inject, onMounted, provide, ref, nextTick } from "vue"; -import { ComponentSchema, DesignerComponentInstance, FDesignerCanvas, FTabs, FTabPage, propertyConfigSchemaMap, FSplitter, FSplitterPane, FDesignerToolbox, FPropertyPanel, FDesignerOutline } from "@farris/ui-vue/components"; +import { ComponentSchema, DesignerComponentInstance, FDesignerCanvas, FTabs, FTabPage, propertyConfigSchemaMapForDesigner, FSplitter, FSplitterPane, FDesignerToolbox, FPropertyPanel, FDesignerOutline } from "@farris/ui-vue/components"; import { FormDesignerProps, formDesignerProps } from "./form-designer.props"; import { useComponentSchemaService } from '../../composition/component-schema.service'; import MonacoEditor from '../monaco-editor/monaco-editor.component'; @@ -9,12 +9,15 @@ import { afterPropeControlPropertyChangedService } from "../../composition/contr import { UseDesignViewModel, UseFormSchema, UseSchemaService } from "../../types"; import FCustomClassEditor from './components/custom-class-editor/custom-class-editor.component'; import FExternalComponentPanpel from './components/external-component-panpel/external-component-panpel.component'; +import { UseDesignerContext } from "../../types/designer-context"; + export default defineComponent({ name: 'FFormDesigner', props: formDesignerProps, emits: [], setup(props: FormDesignerProps, context) { + const designerContext = inject('designerContext') as UseDesignerContext; const propertyPanelInstance = ref(); const schema = ref(props.schema); const componentSchema = schema.value.module ? ref(schema.value.module.components[0]) : ref(schema.value); @@ -25,8 +28,7 @@ export default defineComponent({ const entityTreeRef = ref(); const monacoEditorRef = ref(); const customClassEditorRef = ref(); - - + const { toolboxItems, componentsToRegister, designerMode} = designerContext; function onCanvasInitialized(dragula: any) { dragulaCompostion.value = dragula; } @@ -129,7 +131,22 @@ export default defineComponent({ }; }); - propertyConfigSchemaMap['Module'] = modulePropertyConfig; + propertyConfigSchemaMapForDesigner['Module'] = modulePropertyConfig; + + /** + * 切换不同的页面 + * @param selectionNode + * @returns + */ + function changePageComponent(selectionNode: any) { + const isPageChanged = selectionNode.componentId && componentId.value !== selectionNode.componentId; + if (isPageChanged) { + componentId.value = selectionNode.componentId; + const selectPageComponent = useFormSchema.getComponentById(componentId.value); + componentSchema.value = selectPageComponent; + } + } + function onOutlineChanged(selectionNode: any) { const selectionSchema = selectionNode.rawSchema; @@ -150,6 +167,10 @@ export default defineComponent({ if (activeDesignerView.value === 'formDesignerCode' && selectionSchema) { monacoEditorRef.value?.setPosition(selectionSchema.id); } + + // 切换了页面 + changePageComponent(selectionNode); + } function reloadPropertyPanel() { @@ -195,7 +216,7 @@ export default defineComponent({ - + @@ -214,6 +235,8 @@ export default defineComponent({ onCanvasChanged={onCanvasChanged} componentId={componentId.value} onDragEnd={onCanvasDragEnd} + components={componentsToRegister} + canvasMode={designerMode} > {/* diff --git a/packages/designer/src/components/components/view-model-designer/method-manager/composition/use-view-model-list.ts b/packages/designer/src/components/components/view-model-designer/method-manager/composition/use-view-model-list.ts index a3f1cb54b89..44633387a58 100644 --- a/packages/designer/src/components/components/view-model-designer/method-manager/composition/use-view-model-list.ts +++ b/packages/designer/src/components/components/view-model-designer/method-manager/composition/use-view-model-list.ts @@ -1,6 +1,7 @@ import { inject } from 'vue'; import { ComponentType, FormViewModel, UseFormSchema } from '../../../../types'; import { useViewModelName } from './use-view-model-name'; +import { UseDesignerContext } from '../../../../../components/types/designer-context'; /** * 按照组件引用顺序构造视图模型列表 @@ -10,6 +11,8 @@ export function useViewModelNavigation() { const viewModelNameBuilder = useViewModelName(); let componentListInModalFrame: any[] = []; const useFormSchema = inject('useFormSchema') as UseFormSchema; + const designerContext = inject('designerContext') as UseDesignerContext; + const formSchema = useFormSchema.getFormSchema(); function getAllComponentIdsBySort(componentSchema: any, componentIdList: string[], isInModalFrame = false) { @@ -53,19 +56,24 @@ export function useViewModelNavigation() { * 按照组件引用的顺序排列ViewModel节点 */ function sortViewModels() { - const rootComponent = useFormSchema.getComponentById('root-component'); - if (!rootComponent) { + const pageComponents = designerContext.getPageComponents(useFormSchema); + + if (!pageComponents) { return []; } const componentIdList: string[] = []; - getAllComponentIdsBySort(rootComponent, componentIdList); + const sortedViewModels: FormViewModel[] = []; + + pageComponents.forEach(pageComponent => { + getAllComponentIdsBySort(pageComponent, componentIdList); + + const pageViewModel = useFormSchema.getViewModelById(pageComponent.viewModel); + if (pageViewModel) { + sortedViewModels.push(pageViewModel); + } + }) const components = formSchema.module.components.filter(component => component.componentType !== ComponentType.Frame); - const sortedViewModels: FormViewModel[] = []; - const rootViewModel = useFormSchema.getViewModelById(rootComponent.viewModel); - if (rootViewModel) { - sortedViewModels.push(rootViewModel); - } componentIdList.forEach(componentId => { const targetComponent = components.find(component => component.id === componentId); if (targetComponent) { diff --git a/packages/designer/src/components/composition/command/supported-controller.ts b/packages/designer/src/components/composition/command/supported-controller.ts index 31ee3b95cf0..760577e6e0a 100644 --- a/packages/designer/src/components/composition/command/supported-controller.ts +++ b/packages/designer/src/components/composition/command/supported-controller.ts @@ -1,438 +1,16 @@ -const supportedControllers = { - "d7de1993-d500-44fd-9922-43c78d477aa3": [ - { - "id": "dba10520-f564-31a4-13ac-f07709402304", - "code": "LoadNavTree" - }, - { - "id": "b9241e0d-90d1-72e7-c9b6-8f08caaef8ad", - "code": "LoadSubList" - }, - { - "id": "ae60fedd-e0e7-ac7a-eaa9-430833dbefc7", - "code": "RouteToAdd" - }, - { - "id": "8b6f29b4-7326-f9f8-0625-3954a71f3595", - "code": "RouteToEdit" - }, - { - "id": "74cda30e-6abb-5269-64a4-0f43c189ed74", - "code": "RouteToView" - }, - { - "id": "4c183907-66c4-1b02-c8ab-aa13a4efc8f3", - "code": "Remove" - }, - { - "id": "294afc8c-bea9-658c-81f0-42982f8c7eb0", - "code": "Close" - } - ], - "8172a979-2c80-4637-ace7-b13074d3f393": [ - { - "id": "0c67fafb-3bb7-d0a5-d546-3dae63434212", - "code": "Load" - }, - { - "id": "05c445e5-4e18-f4e6-2dc8-997228dc36a7", - "code": "LoadAndAdd" - }, - { - "id": "052104fd-3f13-0738-058e-4945b5f95c27", - "code": "LoadAndView" - }, - { - "id": "2ecf6524-ffc0-ada5-2765-2103c597f880", - "code": "LoadAndEdit" - }, - { - "id": "363d6a62-afb8-6789-39ef-cae0a5c4ae9d", - "code": "Add" - }, - { - "id": "63bc76df-1626-eff7-ab55-03ed9b44750d", - "code": "Edit" - }, - { - "id": "bd081bfc-7ce8-979e-e54c-3b01fc8ffc96", - "code": "Cancel" - }, - { - "id": "c22ff5a0-cfeb-aab1-ac01-937cfcd80c6a", - "code": "Save" - }, - { - "id": "eeb436cf-6684-874f-3ca7-d42aec83730d", - "code": "Close" - }, - { - "id": "6f987222-ebe2-0f3c-1594-a12408b22801", - "code": "AddItem" - }, - { - "id": "0cdeddcc-8332-f13f-be96-b5eeac84a334", - "code": "RemoveItem" - }, - { - "id": "af181469-5bda-7c9f-e187-dc173cfd7356", - "code": "LoadAndCascadeAdd" - }, - { - "id": "89904e71-5b79-9caf-b9d6-77e878cc1552", - "code": "cascadeAdd" - } - ], - "26436aa8-88a7-4aee-bf0b-9843c1e8afbf": [ - { - "id": "f7dd2c84-7abd-d4bf-6b31-71d96035c034", - "code": "LoadNavList" - }, - { - "id": "e8e6433a-7c00-1773-0f0d-b4f9c3060e56", - "code": "LoadSubList" - }, - { - "id": "59858a08-f940-413c-4717-2c65212c9303", - "code": "RouteToAdd" - }, - { - "id": "b448888e-7200-e9d6-ec51-23257a61904f", - "code": "RouteToEdit" - }, - { - "id": "ea5e9181-70e6-5344-536f-e586f0f1c00a", - "code": "RouteToView" - }, - { - "id": "5d2c531e-f0f4-7330-e627-52745352117d", - "code": "Remove" - }, - { - "id": "0f69d3b4-a81e-b98f-d7a1-e18810dbc98f", - "code": "Close" - }, - { - "id": "c0a61c65-f3f2-95f3-2672-aa52d18ad047", - "code": "ChangePage" - } - ], - "eb07c2e4-7cc1-4d95-aad0-410823006d71": [ - { - "id": "acd815d6-a80a-e617-962f-37b445a15fb1", - "code": "execute" - } - ], - "70b4abd4-9f2c-4b7c-90e9-6ac6f4b74c72": [ - { - "id": "86c9f281-e5bc-5d5c-1b86-d1e17ab2e850", - "code": "Load" - }, - { - "id": "0430f234-634a-0b1d-878f-706d06c53948", - "code": "Remove" - }, - { - "id": "b7da52d1-761c-6263-08d4-30a0061c922c", - "code": "Add" - }, - { - "id": "1d2b8b9b-7a7d-f807-6e51-9ea6e945635a", - "code": "View" - }, - { - "id": "405ec4c7-21f6-bffb-a2d0-edbeb47a042c", - "code": "Edit" - }, - { - "id": "b5103abd-bd9c-2f56-9b56-68c94959f757", - "code": "Close" - }, - { - "id": "e86b4c09-d3d7-0f5a-1d03-17d4da6603e4", - "code": "RemoveRows" - }, - { - "id": "62d673bf-6219-a55b-1080-a4116ca1058c", - "code": "ChangePage" - }, - { - "id": "d7c77f23-fca6-8a90-8e20-8f84f5709663", - "code": "refresh" - } - ], - "d7ce1ba6-49c7-4a27-805f-f78f42e72725": [ - { - "id": "f80e026b-bd9b-002b-d2aa-52c44a633bec", - "code": "Load" - }, - { - "id": "8a19b303-4e75-c267-e42a-b56d059577a9", - "code": "Add" - }, - { - "id": "79aa9a7b-1189-8cba-dcad-2089d95aee72", - "code": "Edit" - }, - { - "id": "8253428a-0287-8390-0ea1-a31eefa1a057", - "code": "Save" - }, - { - "id": "6118693c-9d5c-f401-7101-8344744183f2", - "code": "Cancel" - }, - { - "id": "a82e6e67-ff48-05ce-a780-26a10b83253b", - "code": "Remove" - }, - { - "id": "8034cae9-ecd7-e6ab-22c2-0cdf7cfd536f", - "code": "Close" - }, - { - "id": "6bf1ed43-a493-f2dd-de19-77ebfb79916a", - "code": "ChangePage" - }, - { - "id": "dfd86e25-5cfa-313c-617a-8fd5e2eb8fc9", - "code": "RemoveRows" - } - ], - "45be24f9-c1f7-44f7-b447-fe2ada458a61": [ - { - "id": "17021da1-61a5-a90a-072c-6dda3bad01a7", - "code": "LoadList" - }, - { - "id": "5fb563aa-e860-b439-bf64-39c9cdc341db", - "code": "LoadCard" - }, - { - "id": "90603e99-8f81-968e-ca25-a6017fd874d5", - "code": "Add" - }, - { - "id": "87d3f0aa-f087-c806-466f-cda147730eb0", - "code": "Edit" - }, - { - "id": "fa100da6-83a0-e552-2aa9-415c8c27c3dd", - "code": "Save" - }, - { - "id": "1a373dee-261d-0824-9c99-a158eb376864", - "code": "Cancel" - }, - { - "id": "f9f05646-5c0d-c5d3-5218-d9acf49ebe16", - "code": "Close" - }, - { - "id": "250cd2a2-9995-4c01-64aa-5029afba08ca", - "code": "AddItem" - }, - { - "id": "a2c06958-29b1-0582-5f3e-c3cfcc741f8f", - "code": "RemoveItem" - }, - { - "id": "1425afaa-d91a-9e64-39cd-c4a0bb98e336", - "code": "ChangePage" - }, - { - "id": "1cde1e30-3c4e-2695-e2b6-7a0229368a58", - "code": "Remove" - } - ], - "7c48ef46-339c-42d4-8365-a21236c63044": [ - { - "id": "e573d6a2-8261-9ad4-c9f1-2e59af53302d", - "code": "loadList" - }, - { - "id": "d1054fa5-d18e-c22c-ed3f-2f13b4692702", - "code": "loadCard" - }, - { - "id": "6b9556d9-f510-2484-07b8-e1e190f03169", - "code": "add" - }, - { - "id": "ca451c36-4ab8-5576-545f-0bd13c1cb320", - "code": "edit" - }, - { - "id": "dbc290b7-8f64-1ce3-862f-d63e4c6db956", - "code": "save" - }, - { - "id": "5c3f88c9-52b2-bddb-b4ab-a975ec0e48d7", - "code": "cancel" - }, - { - "id": "3e722416-f1e4-d795-0194-0b876adfa253", - "code": "close" - }, - { - "id": "aae5dda3-7941-6d19-dab5-c4126d20e457", - "code": "remove" - }, - { - "id": "40302ced-33be-8d2f-9c4b-023b90351206", - "code": "changePage" - } - ], - "8fe977a1-2b32-4f0f-a6b3-2657c4d03574": [ - { - "id": "0970ba99-fe9f-c08c-81bb-60841ca94b8f", - "code": "LoadTree" - }, - { - "id": "ecd91cda-e8c0-bc59-b454-78b4027b9f9b", - "code": "LoadCard" - }, - { - "id": "57f3d943-2daf-39aa-5087-58efe7708d38", - "code": "AddSibling" - }, - { - "id": "e470716b-a104-5637-357f-ae6fa92cba05", - "code": "AddChild" - }, - { - "id": "963ed4ff-b425-d832-e887-3968feae44b4", - "code": "Remove" - }, - { - "id": "aeb647c7-8a0a-e02b-9c7a-8fd785da4b63", - "code": "Edit" - }, - { - "id": "531835dc-7c8a-5f52-7912-2c69744f8496", - "code": "Save" - }, - { - "id": "0a2a4b5c-3624-9d55-417e-10247271b556", - "code": "Cancel" - }, - { - "id": "21b0c3af-3caf-b11d-2360-d9af20016501", - "code": "AddItem" - }, - { - "id": "113f1d77-65a4-63bf-3973-80dd15f294d1", - "code": "RemoveItem" - }, - { - "id": "52334335-4e0f-dc9d-2bff-fb09cd479dcf", - "code": "Close" - } - ], - "54bddc89-5f7e-4b91-9c45-80dd6606cfe9": [ - { - "id": "92cd8b0e-4d95-3976-f0aa-c4a4cde1a60b", - "code": "Filter" - } - ], - "26e6016a-ef26-4682-bcdb-84114e934696": [{ - id: "062fa90d-76c1-8e99-5931-9aa0fa60e25d", - code: "openDialog" - }, { - id: "70582221-f092-9809-85ff-17c01b0f4ee9", - code: "openApp" - } - ], - "9280ec35-9194-4c8c-9020-37329f064876": [{ - id: "eab03d67-c390-2e2e-e252-99446062d76f", - code: "getSlimBillCreationProcessEntityExById" - }, { - id: "42079fe1-c0ff-7457-ba94-c9cb38975d5a", - code: "getFormSettingsById" - }, { - id: "cdf4352a-fd35-ff71-963e-10b3c079bd0f", - code: "executeBillCreationProcess" - }, { - id: "30ddac60-12cc-a3c0-ca68-3bde93247313", - code: "createEntityDatas" - }, { - id: "9d72dad6-2f5d-dd60-b064-16d0f993e9a2", - code: "updateEntityDatas" - }, { - id: "1a57e83b-8c27-246d-aa23-6bcfe6dce064", - code: "pushTaskCenter" - }, { - id: "93358329-127c-a470-6893-74f3c30ef3b8", - code: "getCreationResultById" - }, { - id: "27f7cfd4-a916-d2db-4b08-f05d1d28e7a9", - code: "addFormBillCreationProcessExecutorResult" - } - ], - "9bb60b70-6653-430f-a88a-768cc8204f85": [{ - id: "694a8da6-181a-76bf-17e3-ebc638c1e3be", - code: "pushByCreationProcessId" - }, { - id: "65f76fe3-ca5b-8aed-85ad-4a922d699012", - code: "openBillCreationProcessSelector4Push" - }, { - id: "ef5be4c9-9e0b-ad6d-be04-d8512a36439d", - code: "openBillCreationProcessSelector4SpecificPush" - }, { - id: "106c22a1-9972-1de7-381c-f2f19f543ecb", - code: "openTargetApp" - }, { - id: "082b705e-f43b-3ab2-257f-0d990ae82709", - code: "pushBySourceCmId" - }, { - id: "91963fe4-cb21-2eb9-0e7d-c7731d723837", - code: "pushBySourceCmIdAndTargetCmId" - } - ], - "eae0e38a-9456-4186-af17-f8113b369989": [{ - id: "57e67070-efa9-8988-5bf0-c8b5d5eb9618", - code: "bifLoad" - }, { - id: "9437aa86-1100-0f60-cded-016116c190bb", - code: "referByCreationProcessId" - }, { - id: "81f7d111-903a-180b-5157-d8c4271c47e3", - code: "openBillCreationProcessSelector4Pull" - }, { - id: "1f012cd9-483a-b93b-eee4-5256e1579d08", - code: "openBillCreationProcessSelector4SpecificPull" - }, { - id: "2a1f1c6d-569d-e1d6-04da-798b1df3ddc9", - code: "openSourceDataSelector4Pull" - }, { - id: "fc0be3b1-0273-1c84-a872-69bb1362b15e", - code: "getCreationResult" - }, { - id: "dd847401-5e8c-c0e0-7465-5cb2c50652c2", - code: "referByTargetCmId" - }, { - id: "64a9ce2a-4586-cf2f-22d2-8338b67119e0", - code: "referBySourceCmIdAndTargetCmId" - } - ], - "824361ac-8baf-4742-8843-ddab5182a342": [{ - id: "7a71f224-0465-4bda-b507-6bee22a44c00", - code: "startProcess" - }, { - id: "852cac4c-2689-42bb-a5c4-71bb16b327c0", - code: "viewProcessInstance" - } - ] -}; +import { useDesignerContext } from "../designer-context/use-designer-context"; + +export function getAllSupportedControllers() { + const designerContext = useDesignerContext(); + return designerContext.supportedControllers; +} export function getSupportedControllerMethods(controllerId, commandList) { if (!controllerId || !commandList) { return []; } + const supportedControllers = getAllSupportedControllers(); const supportedCommands = supportedControllers[controllerId] || []; const supportedCommandIds = supportedCommands.map(command => command.id); return commandList.filter(command => supportedCommandIds.includes(command.Id)); } -export function getAllSupportedControllers() { - return supportedControllers; -} diff --git a/packages/designer/src/components/composition/command/supported-controllers/mobile-supported-controller.json b/packages/designer/src/components/composition/command/supported-controllers/mobile-supported-controller.json new file mode 100644 index 00000000000..264ee50e48c --- /dev/null +++ b/packages/designer/src/components/composition/command/supported-controllers/mobile-supported-controller.json @@ -0,0 +1,139 @@ +{ + "910661bd-963a-4287-aa32-441c95b8720f": [ + { + "id": "973bb999-b8dc-0ff5-0ba1-5cd7b816eba9", + "code": "Navigate" + }, + { + "id": "4dd30b6a-f0d7-0799-7c04-593e5b71fd7b", + "code": "NavigateForRtc" + }, + { + "id": "9dca239c-9153-70f9-e522-5ba2c384aa4f", + "code": "GoBack" + }, + { + "id": "632f46ae-620e-3bb7-a75e-c43473624c49", + "code": "GoBackAndCheck" + }, + { + "id": "34c9cb64-0ea0-f483-2d51-c36ff0ee6cb2", + "code": "GoBackForChildCard" + }, + { + "id": "9740b808-9900-f494-516c-08e89640f5af", + "code": "CloseWindow" + }, + { + "id": "66371216-60d9-f2c3-734e-6b56b6e71d27", + "code": "NavigateAndCheck" + }, + { + "id": "b0d557ac-1ee8-8afe-73ea-006c43bd10d1", + "code": "NavigateForChildCard" + } + ], + "cf5e568a-5243-4539-94ea-e195eb4d6736": [ + { + "id": "e875be9f-07b8-b8ac-e20b-53e6b3e7894d", + "code": "LoadPage" + }, + { + "id": "98b8d9a5-dc18-77e8-7bdf-7ea191c6bc8d", + "code": "LoadPageForList" + }, + { + "id": "dd80df23-0cd7-b11c-1fa5-df8a8847b81b", + "code": "LoadPageForCard" + }, + { + "id": "54f3153f-e646-e185-b403-5467b9984a78", + "code": "LoadPageForChildCard" + }, + { + "id": "6441c6c5-4f8d-e53e-2db0-639b4c81e418", + "code": "LoadListPage" + }, + { + "id": "53827e22-6f6f-e0f3-e4a2-9ca3e6b8f568", + "code": "LoadCardPage" + } + ], + + "0a68799b-48c6-4c9f-b0d7-140683c62b58": [ + { + "id": "06351c11-ec4b-f7b0-d9b4-e8bca9202b86", + "code": "LoadForList" + }, + { + "id": "cb7f4216-0eb4-26a0-80b5-a38448e393c1", + "code": "LoadForCard" + }, + { + "id": "67edc617-d63a-b4f5-cdc7-4adba1b6e48b", + "code": "LoadAndAddForCard" + }, + { + "id": "33e538a8-717d-00ad-4cb6-a575f4b151c7", + "code": "LoadAndEditForCard" + }, + { + "id": "d868341e-5eff-2a65-ba96-8b4fe5b243d7", + "code": "LoadAndViewForCard" + }, + { + "id": "afc70350-24fc-9879-9505-689f57575ec2", + "code": "LoadAndAddForChildCard" + }, + { + "id": "4a7b5ccb-f61a-ac4f-e308-c00f6b52860b", + "code": "LoadAndEditForChildCard" + }, + { + "id": "9272925f-38d0-d814-2161-605f75240169", + "code": "LoadAndViewForChildCard" + } + ], + "dab6b7f1-f56f-490a-879c-3d74232cd3ba": [ + { + "id": "eca45728-53c9-ca70-14ca-ec8eb468ee44", + "code": "RemoveById" + }, + { + "id": "6036c9c0-1ee6-ab06-e311-78f5becca6b4", + "code": "RemoveByIds" + }, + { + "id": "a35467a1-4ca7-5655-cd2a-18ce42a3097a", + "code": "RemoveByPathAndId" + } + ], + "f863c66a-bf93-4d1f-9f99-bcd76009609d": [ + { + "id": "129fb301-123d-6011-755d-c1aad5bf1dd3", + "code": "SaveForCard" + }, + { + "id": "2ade863f-4b38-7d2b-ca9f-87f1e18d8692", + "code": "SaveForChildCard" + }, + { + "id": "f7ebeab7-0481-041a-2cc4-d524840c6468", + "code": "SaveAndGoBackForChildCard" + }, + { + "id": "7eab8d99-4698-c0d4-4d2b-08bf724ed439", + "code": "Save" + }, + { + "id": "55eb3067-d220-56dd-41b3-2228db302ae0", + "code": "SaveAndValidateDataForCard" + } + ], + "05592163-fd45-474e-b0ab-61d7dc02e5c0": [ + { + "id": "d5b847bd-ceb3-1b27-ed7f-b6b1e38088cd", + "code": "Cancel" + } + ] +} \ No newline at end of file diff --git a/packages/designer/src/components/composition/command/supported-controllers/pc-supported-controller.json b/packages/designer/src/components/composition/command/supported-controllers/pc-supported-controller.json new file mode 100644 index 00000000000..c38384f406a --- /dev/null +++ b/packages/designer/src/components/composition/command/supported-controllers/pc-supported-controller.json @@ -0,0 +1,452 @@ +{ + "d7de1993-d500-44fd-9922-43c78d477aa3": [ + { + "id": "dba10520-f564-31a4-13ac-f07709402304", + "code": "LoadNavTree" + }, + { + "id": "b9241e0d-90d1-72e7-c9b6-8f08caaef8ad", + "code": "LoadSubList" + }, + { + "id": "ae60fedd-e0e7-ac7a-eaa9-430833dbefc7", + "code": "RouteToAdd" + }, + { + "id": "8b6f29b4-7326-f9f8-0625-3954a71f3595", + "code": "RouteToEdit" + }, + { + "id": "74cda30e-6abb-5269-64a4-0f43c189ed74", + "code": "RouteToView" + }, + { + "id": "4c183907-66c4-1b02-c8ab-aa13a4efc8f3", + "code": "Remove" + }, + { + "id": "294afc8c-bea9-658c-81f0-42982f8c7eb0", + "code": "Close" + } + ], + "8172a979-2c80-4637-ace7-b13074d3f393": [ + { + "id": "0c67fafb-3bb7-d0a5-d546-3dae63434212", + "code": "Load" + }, + { + "id": "05c445e5-4e18-f4e6-2dc8-997228dc36a7", + "code": "LoadAndAdd" + }, + { + "id": "052104fd-3f13-0738-058e-4945b5f95c27", + "code": "LoadAndView" + }, + { + "id": "2ecf6524-ffc0-ada5-2765-2103c597f880", + "code": "LoadAndEdit" + }, + { + "id": "363d6a62-afb8-6789-39ef-cae0a5c4ae9d", + "code": "Add" + }, + { + "id": "63bc76df-1626-eff7-ab55-03ed9b44750d", + "code": "Edit" + }, + { + "id": "bd081bfc-7ce8-979e-e54c-3b01fc8ffc96", + "code": "Cancel" + }, + { + "id": "c22ff5a0-cfeb-aab1-ac01-937cfcd80c6a", + "code": "Save" + }, + { + "id": "eeb436cf-6684-874f-3ca7-d42aec83730d", + "code": "Close" + }, + { + "id": "6f987222-ebe2-0f3c-1594-a12408b22801", + "code": "AddItem" + }, + { + "id": "0cdeddcc-8332-f13f-be96-b5eeac84a334", + "code": "RemoveItem" + }, + { + "id": "af181469-5bda-7c9f-e187-dc173cfd7356", + "code": "LoadAndCascadeAdd" + }, + { + "id": "89904e71-5b79-9caf-b9d6-77e878cc1552", + "code": "cascadeAdd" + } + ], + "26436aa8-88a7-4aee-bf0b-9843c1e8afbf": [ + { + "id": "f7dd2c84-7abd-d4bf-6b31-71d96035c034", + "code": "LoadNavList" + }, + { + "id": "e8e6433a-7c00-1773-0f0d-b4f9c3060e56", + "code": "LoadSubList" + }, + { + "id": "59858a08-f940-413c-4717-2c65212c9303", + "code": "RouteToAdd" + }, + { + "id": "b448888e-7200-e9d6-ec51-23257a61904f", + "code": "RouteToEdit" + }, + { + "id": "ea5e9181-70e6-5344-536f-e586f0f1c00a", + "code": "RouteToView" + }, + { + "id": "5d2c531e-f0f4-7330-e627-52745352117d", + "code": "Remove" + }, + { + "id": "0f69d3b4-a81e-b98f-d7a1-e18810dbc98f", + "code": "Close" + }, + { + "id": "c0a61c65-f3f2-95f3-2672-aa52d18ad047", + "code": "ChangePage" + } + ], + "eb07c2e4-7cc1-4d95-aad0-410823006d71": [ + { + "id": "acd815d6-a80a-e617-962f-37b445a15fb1", + "code": "execute" + } + ], + "70b4abd4-9f2c-4b7c-90e9-6ac6f4b74c72": [ + { + "id": "86c9f281-e5bc-5d5c-1b86-d1e17ab2e850", + "code": "Load" + }, + { + "id": "0430f234-634a-0b1d-878f-706d06c53948", + "code": "Remove" + }, + { + "id": "b7da52d1-761c-6263-08d4-30a0061c922c", + "code": "Add" + }, + { + "id": "1d2b8b9b-7a7d-f807-6e51-9ea6e945635a", + "code": "View" + }, + { + "id": "405ec4c7-21f6-bffb-a2d0-edbeb47a042c", + "code": "Edit" + }, + { + "id": "b5103abd-bd9c-2f56-9b56-68c94959f757", + "code": "Close" + }, + { + "id": "e86b4c09-d3d7-0f5a-1d03-17d4da6603e4", + "code": "RemoveRows" + }, + { + "id": "62d673bf-6219-a55b-1080-a4116ca1058c", + "code": "ChangePage" + }, + { + "id": "d7c77f23-fca6-8a90-8e20-8f84f5709663", + "code": "refresh" + } + ], + "d7ce1ba6-49c7-4a27-805f-f78f42e72725": [ + { + "id": "f80e026b-bd9b-002b-d2aa-52c44a633bec", + "code": "Load" + }, + { + "id": "8a19b303-4e75-c267-e42a-b56d059577a9", + "code": "Add" + }, + { + "id": "79aa9a7b-1189-8cba-dcad-2089d95aee72", + "code": "Edit" + }, + { + "id": "8253428a-0287-8390-0ea1-a31eefa1a057", + "code": "Save" + }, + { + "id": "6118693c-9d5c-f401-7101-8344744183f2", + "code": "Cancel" + }, + { + "id": "a82e6e67-ff48-05ce-a780-26a10b83253b", + "code": "Remove" + }, + { + "id": "8034cae9-ecd7-e6ab-22c2-0cdf7cfd536f", + "code": "Close" + }, + { + "id": "6bf1ed43-a493-f2dd-de19-77ebfb79916a", + "code": "ChangePage" + }, + { + "id": "dfd86e25-5cfa-313c-617a-8fd5e2eb8fc9", + "code": "RemoveRows" + } + ], + "45be24f9-c1f7-44f7-b447-fe2ada458a61": [ + { + "id": "17021da1-61a5-a90a-072c-6dda3bad01a7", + "code": "LoadList" + }, + { + "id": "5fb563aa-e860-b439-bf64-39c9cdc341db", + "code": "LoadCard" + }, + { + "id": "90603e99-8f81-968e-ca25-a6017fd874d5", + "code": "Add" + }, + { + "id": "87d3f0aa-f087-c806-466f-cda147730eb0", + "code": "Edit" + }, + { + "id": "fa100da6-83a0-e552-2aa9-415c8c27c3dd", + "code": "Save" + }, + { + "id": "1a373dee-261d-0824-9c99-a158eb376864", + "code": "Cancel" + }, + { + "id": "f9f05646-5c0d-c5d3-5218-d9acf49ebe16", + "code": "Close" + }, + { + "id": "250cd2a2-9995-4c01-64aa-5029afba08ca", + "code": "AddItem" + }, + { + "id": "a2c06958-29b1-0582-5f3e-c3cfcc741f8f", + "code": "RemoveItem" + }, + { + "id": "1425afaa-d91a-9e64-39cd-c4a0bb98e336", + "code": "ChangePage" + }, + { + "id": "1cde1e30-3c4e-2695-e2b6-7a0229368a58", + "code": "Remove" + } + ], + "7c48ef46-339c-42d4-8365-a21236c63044": [ + { + "id": "e573d6a2-8261-9ad4-c9f1-2e59af53302d", + "code": "loadList" + }, + { + "id": "d1054fa5-d18e-c22c-ed3f-2f13b4692702", + "code": "loadCard" + }, + { + "id": "6b9556d9-f510-2484-07b8-e1e190f03169", + "code": "add" + }, + { + "id": "ca451c36-4ab8-5576-545f-0bd13c1cb320", + "code": "edit" + }, + { + "id": "dbc290b7-8f64-1ce3-862f-d63e4c6db956", + "code": "save" + }, + { + "id": "5c3f88c9-52b2-bddb-b4ab-a975ec0e48d7", + "code": "cancel" + }, + { + "id": "3e722416-f1e4-d795-0194-0b876adfa253", + "code": "close" + }, + { + "id": "aae5dda3-7941-6d19-dab5-c4126d20e457", + "code": "remove" + }, + { + "id": "40302ced-33be-8d2f-9c4b-023b90351206", + "code": "changePage" + } + ], + "8fe977a1-2b32-4f0f-a6b3-2657c4d03574": [ + { + "id": "0970ba99-fe9f-c08c-81bb-60841ca94b8f", + "code": "LoadTree" + }, + { + "id": "ecd91cda-e8c0-bc59-b454-78b4027b9f9b", + "code": "LoadCard" + }, + { + "id": "57f3d943-2daf-39aa-5087-58efe7708d38", + "code": "AddSibling" + }, + { + "id": "e470716b-a104-5637-357f-ae6fa92cba05", + "code": "AddChild" + }, + { + "id": "963ed4ff-b425-d832-e887-3968feae44b4", + "code": "Remove" + }, + { + "id": "aeb647c7-8a0a-e02b-9c7a-8fd785da4b63", + "code": "Edit" + }, + { + "id": "531835dc-7c8a-5f52-7912-2c69744f8496", + "code": "Save" + }, + { + "id": "0a2a4b5c-3624-9d55-417e-10247271b556", + "code": "Cancel" + }, + { + "id": "21b0c3af-3caf-b11d-2360-d9af20016501", + "code": "AddItem" + }, + { + "id": "113f1d77-65a4-63bf-3973-80dd15f294d1", + "code": "RemoveItem" + }, + { + "id": "52334335-4e0f-dc9d-2bff-fb09cd479dcf", + "code": "Close" + } + ], + "54bddc89-5f7e-4b91-9c45-80dd6606cfe9": [ + { + "id": "92cd8b0e-4d95-3976-f0aa-c4a4cde1a60b", + "code": "Filter" + } + ], + "26e6016a-ef26-4682-bcdb-84114e934696": [ + { + "id": "062fa90d-76c1-8e99-5931-9aa0fa60e25d", + "code": "openDialog" + }, + { + "id": "70582221-f092-9809-85ff-17c01b0f4ee9", + "code": "openApp" + } + ], + "9280ec35-9194-4c8c-9020-37329f064876": [ + { + "id": "eab03d67-c390-2e2e-e252-99446062d76f", + "code": "getSlimBillCreationProcessEntityExById" + }, + { + "id": "42079fe1-c0ff-7457-ba94-c9cb38975d5a", + "code": "getFormSettingsById" + }, + { + "id": "cdf4352a-fd35-ff71-963e-10b3c079bd0f", + "code": "executeBillCreationProcess" + }, + { + "id": "30ddac60-12cc-a3c0-ca68-3bde93247313", + "code": "createEntityDatas" + }, + { + "id": "9d72dad6-2f5d-dd60-b064-16d0f993e9a2", + "code": "updateEntityDatas" + }, + { + "id": "1a57e83b-8c27-246d-aa23-6bcfe6dce064", + "code": "pushTaskCenter" + }, + { + "id": "93358329-127c-a470-6893-74f3c30ef3b8", + "code": "getCreationResultById" + }, + { + "id": "27f7cfd4-a916-d2db-4b08-f05d1d28e7a9", + "code": "addFormBillCreationProcessExecutorResult" + } + ], + "9bb60b70-6653-430f-a88a-768cc8204f85": [ + { + "id": "694a8da6-181a-76bf-17e3-ebc638c1e3be", + "code": "pushByCreationProcessId" + }, + { + "id": "65f76fe3-ca5b-8aed-85ad-4a922d699012", + "code": "openBillCreationProcessSelector4Push" + }, + { + "id": "ef5be4c9-9e0b-ad6d-be04-d8512a36439d", + "code": "openBillCreationProcessSelector4SpecificPush" + }, + { + "id": "106c22a1-9972-1de7-381c-f2f19f543ecb", + "code": "openTargetApp" + }, + { + "id": "082b705e-f43b-3ab2-257f-0d990ae82709", + "code": "pushBySourceCmId" + }, + { + "id": "91963fe4-cb21-2eb9-0e7d-c7731d723837", + "code": "pushBySourceCmIdAndTargetCmId" + } + ], + "eae0e38a-9456-4186-af17-f8113b369989": [ + { + "id": "57e67070-efa9-8988-5bf0-c8b5d5eb9618", + "code": "bifLoad" + }, + { + "id": "9437aa86-1100-0f60-cded-016116c190bb", + "code": "referByCreationProcessId" + }, + { + "id": "81f7d111-903a-180b-5157-d8c4271c47e3", + "code": "openBillCreationProcessSelector4Pull" + }, + { + "id": "1f012cd9-483a-b93b-eee4-5256e1579d08", + "code": "openBillCreationProcessSelector4SpecificPull" + }, + { + "id": "2a1f1c6d-569d-e1d6-04da-798b1df3ddc9", + "code": "openSourceDataSelector4Pull" + }, + { + "id": "fc0be3b1-0273-1c84-a872-69bb1362b15e", + "code": "getCreationResult" + }, + { + "id": "dd847401-5e8c-c0e0-7465-5cb2c50652c2", + "code": "referByTargetCmId" + }, + { + "id": "64a9ce2a-4586-cf2f-22d2-8338b67119e0", + "code": "referBySourceCmIdAndTargetCmId" + } + ], + "824361ac-8baf-4742-8843-ddab5182a342": [ + { + "id": "7a71f224-0465-4bda-b507-6bee22a44c00", + "code": "startProcess" + }, + { + "id": "852cac4c-2689-42bb-a5c4-71bb16b327c0", + "code": "viewProcessInstance" + } + ] +} \ No newline at end of file diff --git a/packages/designer/src/components/composition/control-creator/use-mobile-control-creator.ts b/packages/designer/src/components/composition/control-creator/use-mobile-control-creator.ts new file mode 100644 index 00000000000..18808919572 --- /dev/null +++ b/packages/designer/src/components/composition/control-creator/use-mobile-control-creator.ts @@ -0,0 +1,241 @@ +import { getSchemaByType } from "@farris/mobile-ui-vue/components"; +import { FormBindingType, FormSchemaEntityField, FormSchemaEntityFieldTypeName, UseControlCreator } from "../../types"; +import { FormMetadataConverter } from "../form-metadata-converter"; + +export function useMobileControlCreator(): UseControlCreator { + /** + * 配置输入控件属性 + * @param field schema字段 + * @param editorType 编辑器类型 + * @param controlClass 输入控件样式 + * @returns + */ + function setFormFieldProperty(field: FormSchemaEntityField, editorType?: string, controlClass = ''): any { + const formGroupMetadata = getSchemaByType('form-group') || {}; + formGroupMetadata.id = field.id.length > 8 ? field.id.slice(0, 8) : field.id; + formGroupMetadata.id = field.bindingField + '_' + formGroupMetadata.id.replace(/-/g, '_') + '_' + Math.random().toString(36).substr(2, 4); + formGroupMetadata.label = field.name; + formGroupMetadata.appearance = { class: controlClass || '' }; + formGroupMetadata.binding = { + type: FormBindingType.Form, + path: field.bindingField, + field: field.id, + fullPath: field.path + }; + formGroupMetadata.path = field.bindingPath; + const metadataConverter = new FormMetadataConverter(); + const resolvedEditorType = editorType || metadataConverter.getRealEditorType(field?.editor?.$type || ''); + const formEditor = getSchemaByType(resolvedEditorType) || {}; + + formGroupMetadata.editor = formEditor; + if (field.require) { + formEditor.required = field.require; + } + + // 只读属性:若字段本身为只读,则取字段属性;若非只读,则设置为状态机 + formEditor.readonly = field.readonly ? true : false; + const fieldTypeInSchema = field.type && field.type.$type; + if (!fieldTypeInSchema) { + return; + } + // 枚举类型 或者是字符串但是指定了编辑器是枚举类的 + if (fieldTypeInSchema === 'EnumType' || fieldTypeInSchema === 'StringType' && ['radio-group', 'check-group', 'combo-list'].find(type => type === formEditor.type)) { + formEditor.data = field.type.enumValues || []; + formEditor.idField = 'value'; + formEditor.valueField = 'value'; + formEditor.textField = 'name'; + } + // 数字类型 + if (fieldTypeInSchema === 'NumericType') { + formEditor.precision = field.type.precision; + formEditor.nullable = true; + } + // 数字、字符串、备注 :设置最大长度 + if (['NumericType', 'StringType', 'TextType'].includes(fieldTypeInSchema)) { + formEditor.maxLength = field.type.length; + } + // 日期类型 + if (formEditor.type === 'date-picker') { + formEditor.fieldType = field.type.name; + + // 日期时间类型字段:启用时间选择属性 + if (fieldTypeInSchema === 'DateTimeType') { + formEditor.showTime = true; + formEditor.displayFormat = 'yyyy-MM-dd HH:mm:ss'; + formEditor.valueFormat = 'yyyy-MM-dd HH:mm:ss'; + + } + } + + return formGroupMetadata; + } + + /** + * 字段类型是文本,切换成其他控件类型 + * @param editorType + * @returns + */ + function getRealGridTypeByEditorType(editorType) { + switch (editorType) { + case 'combo-list': + case 'radio-group': + case 'check-group': + return 'enum'; + case 'date-picker': + return 'date'; + default: + return 'string'; + } + } + /** + * 将控件类型映射为表单表格列上的类型 + * param field + */ + function mapControlType2GridFieldType(field: FormSchemaEntityField): string { + if (!field.editor) { + return ''; + } + switch (field.type.name) { + case FormSchemaEntityFieldTypeName.Enum: return 'enum'; + case FormSchemaEntityFieldTypeName.String: + return getRealGridTypeByEditorType(field.editor.$type); + case FormSchemaEntityFieldTypeName.Text: return 'string'; + case FormSchemaEntityFieldTypeName.Number: return 'number'; + case FormSchemaEntityFieldTypeName.Date: return 'date'; + case FormSchemaEntityFieldTypeName.DateTime: return 'datetime'; + case FormSchemaEntityFieldTypeName.Boolean: return 'boolean'; + } + + return ''; + } + /** + * 设置列格式 + * @param gridFieldType 列类型 + * @param metadata 元数据 + * @param schemaField schemaField + */ + function setGridFieldFormatter(gridFieldType: string, metadata: any, schemaField: any) { + switch (gridFieldType) { + case 'number': { + metadata.formatter = { + type: 'number', + precision: schemaField.type.precision, + thousand: ',', + decimal: '.' + }; + break; + } + case 'date': { + metadata.formatter = { + type: 'date', + dateFormat: 'yyyy-MM-dd' + }; + break; + } + case 'datetime': { + metadata.formatter = { + type: 'date', + dateFormat: 'yyyy-MM-dd HH:mm:ss' + }; + break; + } + case 'boolean': { + metadata.formatter = { + type: 'boolean', + trueText: '是', + falseText: '否' + }; + break; + } + case 'enum': { + metadata.formatter = { + type: 'enum', + data: schemaField.type.enumValues || [] + }; + break; + } + } + } + /** + * 配置列属性 + * @param field schema字段 + * @param metadata 列元数据 + * @param neddInlineEditor 是否需要列编辑器 + */ + function setGridFieldProperty(gridType: string, field: FormSchemaEntityField, metadata: any, needInlineEditor = false): any { + const metadataConverter = new FormMetadataConverter(); + if (!metadata) { + metadata = getSchemaByType(gridType, {}); + } + if (!metadata || !field) { + return; + } + + metadata.id = field.id.length > 8 ? field.id.slice(0, 8) : field.id; + metadata.id = field.bindingField + '_' + metadata.id.replace(/-/g, '_') + '_' + Math.random().toString(36).substr(2, 4); + metadata.title = field.name; + + // 关联字段dataField绑定主表字段的label + '.' + 关联字段的label + metadata.field = field.bindingPath; + + metadata.binding = { + type: FormBindingType.Form, + path: field.bindingField, + field: field.id, + fullPath: field.path + }; + + // 设置列类型. 若是枚举类型再设置enumData;若是日期类型,设置默认格式;数字类型设置格式、精度 + metadata.dataType = mapControlType2GridFieldType(field); + + // 枚举类型 设置enumData + // if (metadata.dataType === 'enum' && field.type) { + // metadata.enumData = field.type.enumValues; + // metadata.idField = 'value'; + // metadata.valueField = 'value'; + // metadata.textField = 'name'; + // } + metadata.multiLanguage = field.multiLanguage; + + // 日期类型字段:增加数据国际化配置 + if (field.type.name === FormSchemaEntityFieldTypeName.Date || + field.type.name === FormSchemaEntityFieldTypeName.DateTime) { + metadata.localization = false; + metadata.localizationType = field.type.name; + } + + // 列格式 + setGridFieldFormatter(metadata.dataType, metadata, field); + + // 列编辑器 + if (needInlineEditor) { + const realEditor = metadataConverter.getRealEditorType(field?.editor?.$type || ''); + const fieldEditor = setFormFieldProperty(field, realEditor, ''); + metadata.editor = fieldEditor.editor; + } + + return metadata; + } + + /** + * 配置输入控件属性(控件无绑定信息) + * @param editorType 编辑器类型 + * @param controlClass 输入控件样式 + */ + function createFormGroupWithoutField(editorType = 'input-group', controlClass = '') { + const formGroupMetadata = getSchemaByType('form-group') || {}; + formGroupMetadata.id = `${editorType}_${Math.random().toString(36).substr(2, 4)}`; + formGroupMetadata.appearance = { class: controlClass || '' }; + formGroupMetadata.binding = null; + + const formEditor = getSchemaByType(editorType) || {}; + + formGroupMetadata.editor = formEditor; + return formGroupMetadata; + } + return { + setFormFieldProperty, + setGridFieldProperty, + createFormGroupWithoutField + }; +} diff --git a/packages/designer/src/components/composition/control-creator.service.ts b/packages/designer/src/components/composition/control-creator/use-pc-control-creator.service.ts similarity index 98% rename from packages/designer/src/components/composition/control-creator.service.ts rename to packages/designer/src/components/composition/control-creator/use-pc-control-creator.service.ts index 004994bc2ef..6cbe536c018 100644 --- a/packages/designer/src/components/composition/control-creator.service.ts +++ b/packages/designer/src/components/composition/control-creator/use-pc-control-creator.service.ts @@ -1,8 +1,8 @@ import { getSchemaByType } from "@farris/ui-vue/components"; -import { FormBindingType, FormSchemaEntityField, FormSchemaEntityFieldTypeName, UseControlCreator } from "../types"; -import { FormMetadataConverter } from "./form-metadata-converter"; +import { FormBindingType, FormSchemaEntityField, FormSchemaEntityFieldTypeName, UseControlCreator } from "../../types"; +import { FormMetadataConverter } from "../form-metadata-converter"; -export function useControlCreator(): UseControlCreator { +export function usePCControlCreator(): UseControlCreator { /** * 配置输入控件属性 * @param field schema字段 diff --git a/packages/designer/src/components/composition/designer-context/use-designer-context.ts b/packages/designer/src/components/composition/designer-context/use-designer-context.ts new file mode 100644 index 00000000000..a71ba23d892 --- /dev/null +++ b/packages/designer/src/components/composition/designer-context/use-designer-context.ts @@ -0,0 +1,23 @@ +import { DesignerMode, UseDesignerContext } from "../../types/designer-context"; +import { MetadataService } from "../metadata.service"; +import { useMobileDesignerContext } from "./use-mobile-designer-context"; +import { usePCDesignerContext } from "./use-pc-designer-context"; + +/** + * 设计器上下文 + * @returns + */ +export function useDesignerContext(): UseDesignerContext { + function getDesignerMode(): DesignerMode { + const metadataService = new MetadataService(); + const metadataPath = metadataService.getMetadataPath(); + if (metadataPath && metadataPath.includes('.mfrm')) { + return DesignerMode.Mobile; + } + return DesignerMode.PC; + } + + const designerMode = getDesignerMode(); + + return designerMode === DesignerMode.Mobile ? useMobileDesignerContext() : usePCDesignerContext(); +} \ No newline at end of file diff --git a/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts b/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts new file mode 100644 index 00000000000..b69bd7a9667 --- /dev/null +++ b/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts @@ -0,0 +1,59 @@ +import { DesignerMode, UseDesignerContext } from "../../types/designer-context"; +import ToolboxItems from '../../types/toolbox/mobile-toolbox.json'; +import SupportedControllers from '../../composition/command/supported-controllers/mobile-supported-controller.json'; + +import { + Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, + ContentContainer, FloatContainer, Navbar, ListView, Form, FormItem, InputGroup, Button, registerDesignerComponents +} from '@farris/mobile-ui-vue/components'; +import { useMobileControlCreator } from "../control-creator/use-mobile-control-creator"; +import { FormComponent, UseFormSchema } from "../../../components/types"; +import ControllCategories from '../schema-repository/controller/mobile-categories'; + +export function useMobileDesignerContext(): UseDesignerContext { + + /** 设计器模式 */ + const designerMode: DesignerMode = DesignerMode.Mobile; + + /** 工具箱的数据 */ + const toolboxItems: any[] = ToolboxItems; + + /** 要注册的UI组件 */ + const componentsToRegister: any[] = [ + Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, + ContentContainer, FloatContainer, + Navbar, ListView, + Form, FormItem, InputGroup, + Button + ]; + registerDesignerComponents(componentsToRegister); + + /** 支持的控制器 */ + const supportedControllers: any = SupportedControllers; + + const controllCategories: any = ControllCategories; + + + /** 控件创建服务 */ + const useControlCreator = useMobileControlCreator; + + /** + * 获取所有的页面组件 + * @returns + */ + function getPageComponents(useFormSchema:UseFormSchema):FormComponent[]{ + const predicateFunction = (component: any) => component.componentType && component.componentType.toLowerCase() === 'page'; + const pageComponents = useFormSchema.getComponetsByPredicate(predicateFunction); + return pageComponents; + } + + return { + designerMode, + toolboxItems, + componentsToRegister, + supportedControllers, + controllCategories, + useControlCreator, + getPageComponents + } +} \ No newline at end of file diff --git a/packages/designer/src/components/composition/designer-context/use-pc-designer-context.ts b/packages/designer/src/components/composition/designer-context/use-pc-designer-context.ts new file mode 100644 index 00000000000..282da41d910 --- /dev/null +++ b/packages/designer/src/components/composition/designer-context/use-pc-designer-context.ts @@ -0,0 +1,50 @@ +import { DesignerMode, UseDesignerContext } from "../../types/designer-context"; +import ToolboxItems from '../../types/toolbox/pc-toolbox.json'; +import { usePCControlCreator } from "../control-creator/use-pc-control-creator.service"; +import SupportedControllers from '../../composition/command/supported-controllers/pc-supported-controller.json'; +import { FormComponent, UseFormSchema } from "../../../components/types"; +import ControllCategories from '../schema-repository/controller/pc-categories'; + +export function usePCDesignerContext(): UseDesignerContext { + + /** 设计器模式 */ + const designerMode: DesignerMode = DesignerMode.PC; + + /** 工具箱的数据 */ + const toolboxItems: any[] = ToolboxItems; + + /** 要注册的UI组件 */ + const componentsToRegister: any = null; + + /** 支持的控制器 */ + const supportedControllers: any = SupportedControllers; + + /** 控制器分类 */ + const controllCategories: any = ControllCategories; + + /** 控件创建服务 */ + const useControlCreator = usePCControlCreator; + + /** + * 获取所有的页面组件 + * @returns + */ + function getPageComponents(useFormSchema: UseFormSchema): FormComponent[] { + const pageComponents: FormComponent[] = []; + const pageComponent = useFormSchema.getComponentById('root-component'); + if (pageComponent) { + pageComponents.push(pageComponent); + } + return pageComponents; + } + + return { + designerMode, + toolboxItems, + componentsToRegister, + supportedControllers, + controllCategories, + useControlCreator, + getPageComponents + } +} \ No newline at end of file diff --git a/packages/designer/src/components/composition/schema-repository/controller/controller-selector.service.ts b/packages/designer/src/components/composition/schema-repository/controller/controller-selector.service.ts index d54af5217d5..ccdcaedefbd 100644 --- a/packages/designer/src/components/composition/schema-repository/controller/controller-selector.service.ts +++ b/packages/designer/src/components/composition/schema-repository/controller/controller-selector.service.ts @@ -1,15 +1,15 @@ import { MetadataService } from "../../metadata.service"; import { SchemaItem, SchemaRepositoryPagination, SchemaCategory } from "@farris/ui-vue/components"; -import controllCategories from './categories'; -import { getAllSupportedControllers } from "../../command/supported-controller"; +import { UseDesignerContext } from "../../../../components/types/designer-context"; export class ControllerSelectorSchemaService { private metadataType = '.webcmd'; - constructor(private metadataService: MetadataService) { + + constructor(private metadataService: MetadataService, private designerContext: UseDesignerContext) { } - public getNavigationData(searchingText: string, pagination: SchemaRepositoryPagination): SchemaCategory[] { - return controllCategories; + public getNavigationData = (searchingText: string, pagination: SchemaRepositoryPagination): SchemaCategory[] => { + return this.designerContext.controllCategories; } public getRecentlyData(searchingText: string, pagination: SchemaRepositoryPagination): SchemaItem[] { @@ -21,12 +21,9 @@ export class ControllerSelectorSchemaService { } private metadata2SchemaItem(metadata: any[], category: string): SchemaItem[] { - const supportedControllers = getAllSupportedControllers(); + const { supportedControllers } = this.designerContext; + return metadata.filter((metadataItem) => { - // 移除移动控制器 - if (metadataItem.nameSpace.includes('Inspur.GS.Gsp.Mobile')) { - return false; - } // 支持自定义构件 if (metadataItem.nameSpace.includes('.Front')) { return true; diff --git a/packages/designer/src/components/composition/schema-repository/controller/mobile-categories.ts b/packages/designer/src/components/composition/schema-repository/controller/mobile-categories.ts new file mode 100644 index 00000000000..31ba4f36c74 --- /dev/null +++ b/packages/designer/src/components/composition/schema-repository/controller/mobile-categories.ts @@ -0,0 +1,73 @@ +export default [ + { + id: "all", + code: "all", + name: "全部", + active: true, + contains: [] + }, + { + id: "data", + code: "data", + name: "数据", + active: false, + contains: ['AddCommands','RemoveCommands', 'EditCommands','UpdateCommands','ViewCommands', 'SaveCommands','LoadCommands','CancelCommands'] + }, + { + id: "navigate", + code: "navigate", + name: "路由", + active: false, + contains: ['NavigateCommands'] + }, + { + id: "flow", + code: "flow", + name: "流程", + active: false, + contains: ['ApproveService'] + }, + { + id: "file", + code: "file", + name: "附件", + active: false, + contains: ['MobileAttachmentCmd'] + }, + { + id: "stateMachine", + code: "stateMachine", + name: "状态机", + active: false, + contains: ['StateMachineCommands'] + }, + { + id: "discussion", + code: "discussion", + name: "评论区", + active: false, + contains: ['DiscussionGroupCommands'] + }, + { + id: "ui", + code: "ui", + name: "UI相关", + active: false, + contains: ['UICommands'] + }, + { + id: "loadPage", + code: "loadPage", + name: "页面加载", + active: false, + contains: ['LoadPageCommands'] + }, + { + id: "other", + code: "other", + name: "其他", + active: false, + contains: ['VoVariableService'] + } + +]; diff --git a/packages/designer/src/components/composition/schema-repository/controller/categories.ts b/packages/designer/src/components/composition/schema-repository/controller/pc-categories.ts similarity index 100% rename from packages/designer/src/components/composition/schema-repository/controller/categories.ts rename to packages/designer/src/components/composition/schema-repository/controller/pc-categories.ts diff --git a/packages/designer/src/components/composition/use-form-schema.ts b/packages/designer/src/components/composition/use-form-schema.ts index 182bf3363f6..f7d85db9d07 100644 --- a/packages/designer/src/components/composition/use-form-schema.ts +++ b/packages/designer/src/components/composition/use-form-schema.ts @@ -1292,6 +1292,7 @@ export function useFormSchema(): UseFormSchema { updateRemoteVariables, getRootViewModelId, getSchemaEntities, - externalFormSchema + externalFormSchema, + getComponetsByPredicate }; } diff --git a/packages/designer/src/components/designer.component.tsx b/packages/designer/src/components/designer.component.tsx index 0b015c12e6e..ece9834bcb4 100644 --- a/packages/designer/src/components/designer.component.tsx +++ b/packages/designer/src/components/designer.component.tsx @@ -13,13 +13,13 @@ import { useEventsEditor } from "./composition/use-events-editor"; import { useEventsEditorUtils } from "./composition/events-editor-utils"; import { useDesignViewModel } from "./composition/design-viewmodel.service"; import { useSchemaService } from "./composition/schema.service"; -import { useControlCreator } from "./composition/control-creator.service"; import { FormMetadataConverter } from "./composition/form-metadata-converter"; import FCodeViewDesign from "./components/code-view/components/code-view.component"; import { useCommandBuilderService } from "./composition/command-builder.service"; import useFormStateMachine from './composition/use-form-statemachine'; import { MetadataService } from "./composition/metadata.service"; +import { UseDesignerContext } from "./types/designer-context"; export default defineComponent({ name: 'FDesigner', @@ -41,6 +41,7 @@ export default defineComponent({ const currentViewType = ref('designer'); const codeViewComponent = ref(); const metadataService = new MetadataService(); + const designerContext = inject('designerContext') as UseDesignerContext; // 注册 formSchema服务 const useFormSchemaComposition = useFormSchema(); provide('useFormSchema', useFormSchemaComposition); @@ -64,7 +65,7 @@ export default defineComponent({ // metadatFullPath const metadataPath: string = inject(MetadataPathToken, ''); // 控件创建服务 - const controlCreatorService = useControlCreator(); + const controlCreatorService = designerContext.useControlCreator(); provide('controlCreatorUtils', controlCreatorService); provide('formMetadataConverter', new FormMetadataConverter()); const { eventBetweenDesignerAndCodeView } = commandBuilderService; diff --git a/packages/designer/src/components/types/designer-context.ts b/packages/designer/src/components/types/designer-context.ts new file mode 100644 index 00000000000..33747fbee93 --- /dev/null +++ b/packages/designer/src/components/types/designer-context.ts @@ -0,0 +1,20 @@ +import { FormComponent, UseControlCreator, UseFormSchema } from "../types"; + +/** 设计器模式 */ +export enum DesignerMode { + /** PC设计器 */ + PC = 'PC', + + /** 移动设计器 */ + Mobile = 'Mobile', +} + +export interface UseDesignerContext { + designerMode: DesignerMode; + toolboxItems: any[]; + componentsToRegister: any[]; + supportedControllers: any; + controllCategories:any; + useControlCreator: () => UseControlCreator; + getPageComponents: (useFormSchema: UseFormSchema) => FormComponent[]; +} \ No newline at end of file diff --git a/packages/designer/src/components/types/toolbox/mobile-toolbox.json b/packages/designer/src/components/types/toolbox/mobile-toolbox.json new file mode 100644 index 00000000000..e160cd632e8 --- /dev/null +++ b/packages/designer/src/components/types/toolbox/mobile-toolbox.json @@ -0,0 +1,165 @@ +[ + { + "type": "basic", + "name": "基础类控件", + "items": [ + { + "id": "Button", + "type": "button", + "name": "按钮", + "category": "basic", + "icon": "button" + }, + { + "id": "ButtonGroup", + "type": "button-group", + "name": "按钮组", + "category": "basic", + "icon": "button-group" + } + ] + }, + { + "type": "input", + "name": "输入类控件", + "items": [ + { + "id": "TextBox", + "type": "input-group", + "name": "文本框", + "category": "input", + "icon": "input-group" + }, + { + "id": "MultiTextBox", + "type": "textarea", + "name": "多行文本", + "category": "input", + "icon": "textarea" + }, + { + "id": "DateBox", + "type": "date-picker", + "name": "日期选择", + "category": "input", + "icon": "date-picker" + }, + { + "id": "EnumField", + "type": "enum-field", + "name": "选择器", + "category": "input", + "icon": "input-group" + }, + { + "id": "NumericBox", + "type": "number-spinner", + "name": "数值", + "category": "input", + "icon": "number-spinner" + }, + { + "id": "RadioGroup", + "type": "radio-group", + "name": "单选组", + "category": "input", + "icon": "radio-group" + }, + { + "id": "CheckBoxGroup", + "type": "check-group", + "name": "复选框组", + "category": "input", + "icon": "check-group" + }, + { + "id": "SwitchField", + "type": "switch", + "name": "开关", + "category": "input", + "icon": "switch" + } + ] + }, + { + "type": "navigation", + "name": "导航类控件", + "items": [ + { + "id": "NavigationBar", + "type": "navigation-bar", + "name": "导航栏", + "category": "navigation", + "icon": "nav-tab" + } + ] + }, + { + "type": "container", + "name": "容器类控件", + "items": [ + { + "id": "PageHeaderContainer", + "type": "page-header-container", + "name": "页头容器", + "category": "container", + "icon": "content-container" + }, + { + "id": "PageBodyContainer", + "type": "page-body-container", + "name": "页面主体容器", + "category": "container", + "icon": "content-container" + }, + { + "id": "PageFooterContainer", + "type": "page-footer-container", + "name": "页尾容器", + "category": "container", + "icon": "content-container" + }, + { + "id": "ContentContainer", + "type": "content-container", + "name": "通用容器", + "category": "container", + "icon": "content-container" + }, + { + "id": "FloatContainer", + "type": "float-container", + "name": "浮动容器", + "category": "container", + "icon": "content-container" + }, + { + "id": "Form", + "type": "form", + "name": "字段卡片", + "category": "container", + "icon": "response-form" + }, + { + "id": "Card", + "type": "card", + "name": "卡片", + "category": "container", + "icon": "section" + } + ] + }, + { + "type": "display", + "name": "展示类控件", + "items": [ + { + "id": "ListView", + "type": "list-view", + "name": "列表", + "category": "display", + "icon": "list-view" + } + ] + } +] \ No newline at end of file diff --git a/packages/ui-vue/components/designer-toolbox/src/toolbox.json b/packages/designer/src/components/types/toolbox/pc-toolbox.json similarity index 100% rename from packages/ui-vue/components/designer-toolbox/src/toolbox.json rename to packages/designer/src/components/types/toolbox/pc-toolbox.json diff --git a/packages/designer/vite.config.dev.ts b/packages/designer/vite.config.dev.ts index cefa3ba76e9..84e85c8bdbc 100644 --- a/packages/designer/vite.config.dev.ts +++ b/packages/designer/vite.config.dev.ts @@ -17,9 +17,12 @@ export default defineConfig({ }, resolve: { alias: { - '@': resolve(__dirname, '../'), '@farris/ui-vue': resolve(__dirname, '../ui-vue'), - '@farris/code-editor-vue': resolve(__dirname, '../code-editor') + '@farris/code-editor-vue': resolve(__dirname, '../code-editor'), + '@farris/mobile-ui-vue': resolve(__dirname, '../mobile-ui-vue'), + '@components': resolve(__dirname, '../mobile-ui-vue/components'), + '@/components': resolve(__dirname, '../mobile-ui-vue/components'), + '@': resolve(__dirname, '../') } } }); diff --git a/packages/mobile-ui-vue/components/button-group/index.ts b/packages/mobile-ui-vue/components/button-group/index.ts index 3f23dc6f68c..577e882ce55 100644 --- a/packages/mobile-ui-vue/components/button-group/index.ts +++ b/packages/mobile-ui-vue/components/button-group/index.ts @@ -1,17 +1,17 @@ import { Plugin } from 'vue'; -import { withInstall } from '@components/common'; +import { RegisterContext, withInstall } from '@components/common'; import ButtonGroupInstallless from './src/button-group.component'; -import { propsResolver } from './src/button-group.props'; +import { propsResolverGenerator } 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 + configResolverMap: Record, resolverMap: Record, registerContext: RegisterContext ) => { componentMap[BUTTON_GROUP_REGISTERED_NAME] = ButtonGroup; - propsResolverMap[BUTTON_GROUP_REGISTERED_NAME] = propsResolver; + propsResolverMap[BUTTON_GROUP_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; export * from './src/button-group.props'; 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 index 1c053e9fc56..917fc66da2c 100644 --- 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 @@ -1,6 +1,6 @@ import { ExtractPropTypes, PropType } from 'vue'; -import { createPropsResolver } from '@components/dynamic-resolver'; import { ButtonProps, ButtonSize, ButtonType } from '@components/button/src/button.props'; +import { getPropsResolverGenerator } from '@components/dynamic-resolver'; import buttonSchema from './schema/button-group.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; @@ -43,7 +43,10 @@ export const buttonGroupProps = { vertical: { type: Boolean, default: false }, }; -export const propsResolver = createPropsResolver( +/** + * 按钮组属性处理器 + */ +export const propsResolverGenerator = getPropsResolverGenerator( buttonGroupProps, buttonSchema, schemaMapper, diff --git a/packages/mobile-ui-vue/components/button/index.ts b/packages/mobile-ui-vue/components/button/index.ts index 2c5790ae860..9bacbabdeab 100644 --- a/packages/mobile-ui-vue/components/button/index.ts +++ b/packages/mobile-ui-vue/components/button/index.ts @@ -1,7 +1,7 @@ import { Plugin } from 'vue'; -import { withInstall, } from '@components/common'; +import { RegisterContext, withInstall } from '@components/common'; import ButtonInstallless from './src/button.component'; -import { propsResolver } from './src/button.props'; +import { propsResolverGenerator } from './src/button.props'; import ButtonDesign from './src/designer/button.design.component'; const BUTTON_REGISTERED_NAME = 'button'; @@ -9,18 +9,18 @@ const BUTTON_REGISTERED_NAME = 'button'; const Button = withInstall(ButtonInstallless); Button.register = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configResolverMap: Record, resolverMap: Record, registerContext: RegisterContext ) => { componentMap[BUTTON_REGISTERED_NAME] = Button; - propsResolverMap[BUTTON_REGISTERED_NAME] = propsResolver; + propsResolverMap[BUTTON_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; Button.registerDesigner = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configResolverMap: Record, registerContext: RegisterContext ) => { componentMap[BUTTON_REGISTERED_NAME] = ButtonDesign; - propsResolverMap[BUTTON_REGISTERED_NAME] = propsResolver; + propsResolverMap[BUTTON_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; 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 08f95e4d48f..003aed6d557 100644 --- a/packages/mobile-ui-vue/components/button/src/button.props.ts +++ b/packages/mobile-ui-vue/components/button/src/button.props.ts @@ -1,5 +1,5 @@ import { ExtractPropTypes, PropType } from 'vue'; -import { createPropsResolver } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '../../dynamic-resolver'; import buttonSchema from './schema/button.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; @@ -58,9 +58,10 @@ export const buttonProps = { export type ButtonProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( - buttonProps, - buttonSchema, - schemaMapper, - schemaResolver + +export const propsResolverGenerator = getPropsResolverGenerator( + buttonProps, + buttonSchema, + schemaMapper, + schemaResolver ); diff --git a/packages/mobile-ui-vue/components/checkbox-group/index.ts b/packages/mobile-ui-vue/components/checkbox-group/index.ts index 98107fb53f8..7cf70a9ef50 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/index.ts +++ b/packages/mobile-ui-vue/components/checkbox-group/index.ts @@ -1,6 +1,6 @@ -import { withInstall } from '@components/common'; +import { withInstall, RegisterContext } from '@components/common'; import CheckboxGroupInstallless from './src/checkbox-group.component'; -import { propsResolver } from './src/checkbox-group.props'; +import { propsResolverGenerator } from './src/checkbox-group.props'; import CheckBoxGroupDesign from './src/designer/checkbox-group.design.component'; export * from './src/composition'; @@ -11,13 +11,15 @@ const CHECH_GROUP_REGISTERED_NAME = 'check-group'; const CheckboxGroup = withInstall(CheckboxGroupInstallless); -CheckboxGroup.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { +CheckboxGroup.register = (componentMap: Record, propsResolverMap: Record, + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext) => { componentMap[CHECH_GROUP_REGISTERED_NAME] = CheckboxGroup; - propsResolverMap[CHECH_GROUP_REGISTERED_NAME] = propsResolver; + propsResolverMap[CHECH_GROUP_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; -CheckboxGroup.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record) => { +CheckboxGroup.registerDesigner = (componentMap: Record, propsResolverMap: Record, + configresolverMap: Record, registerContext: RegisterContext) => { componentMap[CHECH_GROUP_REGISTERED_NAME] = CheckBoxGroupDesign; - propsResolverMap[CHECH_GROUP_REGISTERED_NAME] = propsResolver; + propsResolverMap[CHECH_GROUP_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; export { CheckboxGroup }; diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.props.ts b/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.props.ts index 2a9cf19699d..b223361dd13 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.props.ts +++ b/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.props.ts @@ -3,7 +3,7 @@ import { CheckerShape, CheckerShapeMap, CheckerType, CheckerTypeMap } from '@com import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; import inputSchema from './schema/checkbox-group.schema.json'; -import { createPropsResolver } from '@/components/dynamic-resolver'; +import { getPropsResolverGenerator } from '@/components/dynamic-resolver'; export type CheckboxItem = { disabled: boolean; @@ -50,5 +50,5 @@ export type CheckboxGroupContext = { updateChecked: (value: string | number, checked: boolean) => void; }; -export const propsResolver = createPropsResolver(checkboxGroupProps, inputSchema, schemaMapper, schemaResolver); +export const propsResolverGenerator = getPropsResolverGenerator(checkboxGroupProps, inputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/common/types.ts b/packages/mobile-ui-vue/components/common/types.ts index 317a5cf3020..351245ac179 100644 --- a/packages/mobile-ui-vue/components/common/types.ts +++ b/packages/mobile-ui-vue/components/common/types.ts @@ -1,4 +1,5 @@ import { ComputedRef, Ref } from "vue"; +import { EffectFunction, SchemaResolverFunction } from "../dynamic-resolver"; export interface TextBoxProps { @@ -129,3 +130,10 @@ export type TimeAgoOptions = { export interface UseTimeAgoFormat { formatTo(date: TimeAgoDate, opts?: TimeAgoOptions): string } + +export interface RegisterContext { + schemaMap: Record; + schemaResolverMap: Record; + propertyConfigSchemaMap: Record; + propertyEffectMap: Record; +} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/component/index.ts b/packages/mobile-ui-vue/components/component/index.ts index bed6e3bd70c..30d05baa8f4 100644 --- a/packages/mobile-ui-vue/components/component/index.ts +++ b/packages/mobile-ui-vue/components/component/index.ts @@ -15,9 +15,9 @@ * limitations under the License. */ import type { Plugin } from 'vue'; -import { withInstall } from '@components/common'; +import { RegisterContext, withInstall } from '@components/common'; import ComponentInstallless from './src/component.component'; -import { propsResolver } from './src/component.props'; +import { propsResolverGenerator } from './src/component.props'; import ComponentDesign from './src/designer/component.design.component'; const COMPONENT_REGISTERED_NAME = 'component'; @@ -25,18 +25,18 @@ const COMPONENT_REGISTERED_NAME = 'component'; const Component = withInstall(ComponentInstallless); Component.register = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext ) => { componentMap[COMPONENT_REGISTERED_NAME] = Component; - propsResolverMap[COMPONENT_REGISTERED_NAME] = propsResolver; + propsResolverMap[COMPONENT_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; Component.registerDesigner = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record, registerContext: RegisterContext ) => { componentMap[COMPONENT_REGISTERED_NAME] = ComponentDesign; - propsResolverMap[COMPONENT_REGISTERED_NAME] = propsResolver; + propsResolverMap[COMPONENT_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; diff --git a/packages/mobile-ui-vue/components/component/src/component.props.ts b/packages/mobile-ui-vue/components/component/src/component.props.ts index ab01ca66a48..43d758ae9bc 100644 --- a/packages/mobile-ui-vue/components/component/src/component.props.ts +++ b/packages/mobile-ui-vue/components/component/src/component.props.ts @@ -1,6 +1,6 @@ import { ExtractPropTypes } from 'vue'; -import { createPropsResolver } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '../../dynamic-resolver'; import { schemaMapper } from './schema/schema-mapper'; import componentSchema from './schema/component.schema.json'; import { schemaResolver } from './schema/schema-resolver'; @@ -32,7 +32,7 @@ export const componentProps = { export type ComponentPropsType = ExtractPropTypes; // 属性处理器 -export const propsResolver = createPropsResolver(componentProps, componentSchema, schemaMapper, schemaResolver); +export const propsResolverGenerator = getPropsResolverGenerator(componentProps, componentSchema, schemaMapper, schemaResolver); // 设计时属性 export const componentDesignProps = Object.assign({}, componentProps, { componentId: { type: String, default: '' } }); diff --git a/packages/mobile-ui-vue/components/content-container/index.ts b/packages/mobile-ui-vue/components/content-container/index.ts index c14dc398ca2..d6c256518cf 100644 --- a/packages/mobile-ui-vue/components/content-container/index.ts +++ b/packages/mobile-ui-vue/components/content-container/index.ts @@ -1,7 +1,8 @@ import { App, Plugin } from 'vue'; import FContentContainer from './src/content-container.component'; -import { propsResolver } from './src/content-container.props'; +import { propsResolverGenerator } from './src/content-container.props'; import ContentContainerDesign from './src/designer/content-container.design.component'; +import { RegisterContext } from '../common'; const CONTENT_CONTAINER_REGISTERED_NAME = 'content-container'; @@ -11,18 +12,18 @@ FContentContainer.install = (app: App) => { FContentContainer.register = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext ) => { componentMap[CONTENT_CONTAINER_REGISTERED_NAME] = FContentContainer; - propsResolverMap[CONTENT_CONTAINER_REGISTERED_NAME] = propsResolver; + propsResolverMap[CONTENT_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; FContentContainer.registerDesigner = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record,registerContext: RegisterContext ) => { componentMap[CONTENT_CONTAINER_REGISTERED_NAME] = ContentContainerDesign; - propsResolverMap[CONTENT_CONTAINER_REGISTERED_NAME] = propsResolver; + propsResolverMap[CONTENT_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; 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 index b356d338f5d..213f331a3db 100644 --- 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 @@ -1,5 +1,5 @@ import { ExtractPropTypes } from 'vue'; -import { createPropsResolver } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '../../dynamic-resolver'; import contentContainerSchema from './schema/content-container.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; @@ -13,7 +13,7 @@ export const contentContainerProps = { export type ContentContainerProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( +export const propsResolverGenerator = getPropsResolverGenerator( contentContainerProps, contentContainerSchema, schemaMapper, diff --git a/packages/mobile-ui-vue/components/date-picker-input/index.ts b/packages/mobile-ui-vue/components/date-picker-input/index.ts index ec026ee8f75..fcdad8cc434 100644 --- a/packages/mobile-ui-vue/components/date-picker-input/index.ts +++ b/packages/mobile-ui-vue/components/date-picker-input/index.ts @@ -1,19 +1,21 @@ -import { withInstall } from '@components/common'; +import { RegisterContext, 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'; +import { propsResolverGenerator } 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) => { +DatePickerInput.register = (componentMap: Record, propsResolverMap: Record, + configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext) => { componentMap[DATE_PICKER_REGISTERED_NAME] = DatePickerInput; - propsResolverMap[DATE_PICKER_REGISTERED_NAME] = propsResolver; + propsResolverMap[DATE_PICKER_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; -DatePickerInput.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record) => { +DatePickerInput.registerDesigner = (componentMap: Record, propsResolverMap: Record, + configresolverMap: Record,registerContext: RegisterContext) => { componentMap[DATE_PICKER_REGISTERED_NAME] = DatePickerDesign; - propsResolverMap[DATE_PICKER_REGISTERED_NAME] = propsResolver; + propsResolverMap[DATE_PICKER_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; 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..257ffa0c982 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 @@ -4,7 +4,7 @@ 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'; +import { getPropsResolverGenerator } 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 propsResolverGenerator = getPropsResolverGenerator(datePickerInputProps, inputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts index bc35a129a09..6e44a4bd847 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts @@ -41,7 +41,7 @@ export const DgControl = { 'form': { type: 'form', name: '卡片面板', icon: 'Form' }, - 'navigation-bar': { type: 'navigation-bar', name: '导航栏', icon: 'NavBar' }, + 'navbar': { type: 'navbar', name: '导航栏', icon: 'NavBar' }, 'enum-field': { type: 'enum-field', name: '选择器', icon: 'EnumField' }, diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/create-design-builder.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/create-design-builder.ts deleted file mode 100644 index 7d950952527..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/create-design-builder.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { SetupContext } from 'vue'; -import { DesignerOutlineProps } from '../../../../designer-outline/src/designer-outline.props'; - -/** 创建设计器 */ -export function createDesigner(props: DesignerOutlineProps, context: SetupContext) { - - function createDesignBuilder(domJson: any) { - // 画布渲染过程中,可能会在控件上补充属性,这种变更用户不感知,所以不需要通知IDE框架 - // window.suspendChangesOnForm = true; - - const elements = document.getElementsByClassName('editorPanel'); - let rootElement; - if (elements && elements.length) { - rootElement = elements[0]; - } - - // if (!DesignerBuilder) { - // return; - // } - - // addServiceToDevkit(); - // const designerHost = addServiceToUI(); - - const childComponents = domJson.module.components.slice(1); - const rootComponent = domJson.module.components[0]; - const designerSchema = { - contents: [rootComponent] - }; - // designBuilder = new DesignerBuilder(rootElement, designerSchema, childComponents, AllComponents, designerHost); - // designBuilder.instance.ready.then(() => { - // onBuilderReady(); - - // 加载控件工具箱 - // controlBox.getDisplayedControls(); - - // 设计器渲染完毕,开始监听DOM变更 - // window.suspendChangesOnForm = false; - // }); - - // designBuilder.instance.on('change', () => { - // onComponentChanged(); - // }); - // designBuilder.instance.on('removeComponent', () => { - // updatePropertyPanel(null); - // onComponentChanged(); - // }); - } - - return { - }; - -}; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-component.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-component.ts index fe7cd6300d1..8d6342d347d 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-component.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-component.ts @@ -1,7 +1,7 @@ import { Ref, ref } from "vue"; import { DesignerHostService, DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../types"; import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from "../../types"; -import { getSchemaByType } from '../../../../dynamic-resolver/src/schema-resolver'; +import { getSchemaByTypeForDesigner } from '../../../../dynamic-resolver/src/resolver/schema/schema-resolver-design'; export function useDesignerComponent( elementRef: Ref, @@ -126,7 +126,7 @@ export function useDesignerComponent( */ function addNewChildComponentSchema(resolveContext: DraggingResolveContext, designerHostService: DesignerHostService) { const { componentType } = resolveContext; - let componentSchema = getSchemaByType(componentType, resolveContext, designerHostService) as ComponentSchema; + let componentSchema = getSchemaByTypeForDesigner(componentType, resolveContext, designerHostService) as ComponentSchema; if (designerRules && designerRules.onResolveNewComponentSchema) { componentSchema = designerRules.onResolveNewComponentSchema(resolveContext, componentSchema); } diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-inner-component.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-inner-component.ts index d0858e64716..ac207a9f511 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-inner-component.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-inner-component.ts @@ -1,7 +1,7 @@ import { inject, Ref, ref } from "vue"; import { DesignerHostService, DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../types"; import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from "../../types"; -import { getSchemaByType } from '../../../../dynamic-resolver/src/schema-resolver'; +import { getSchemaByTypeForDesigner } from '../../../../dynamic-resolver/src/resolver/schema/schema-resolver-design'; export function useDesignerInnerComponent( elementRef: Ref, @@ -117,7 +117,7 @@ export function useDesignerInnerComponent( function addNewChildComponentSchema(resolveContext: DraggingResolveContext) { const { componentType } = resolveContext; const designerHostServer = inject('designer-host-service') as DesignerHostService; - let componentSchema = getSchemaByType(componentType, resolveContext, designerHostServer) as ComponentSchema; + let componentSchema = getSchemaByTypeForDesigner(componentType, resolveContext, designerHostServer) as ComponentSchema; if (designerRules && designerRules.onResolveNewComponentSchema) { componentSchema = designerRules.onResolveNewComponentSchema(resolveContext, componentSchema); } diff --git a/packages/mobile-ui-vue/components/designer.ts b/packages/mobile-ui-vue/components/designer.ts index 6118ec98be8..81ea1c807dd 100644 --- a/packages/mobile-ui-vue/components/designer.ts +++ b/packages/mobile-ui-vue/components/designer.ts @@ -3,3 +3,4 @@ export * from './dynamic-resolver'; export { FDesignerToolbox } from './designer-toolbox'; export { default as FModal, FModalService, FM_MODAL_SERVICE_TOKEN } from './modal'; export { FM_UI_PROVIDER_SERVICE_TOKEN } from './common'; +export * from './register-designer'; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/index.ts b/packages/mobile-ui-vue/components/dynamic-resolver/index.ts index 78edba9a400..bab138a7793 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/index.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/index.ts @@ -9,7 +9,8 @@ export * from './src/selection-item-resolver'; export * from './src/editor-resolver'; export * from './src/visible-prop-resolver'; export * from './src/event-handler-resolver'; -export * from './src/schema-resolver'; +export * from './src/resolver/schema/schema-resolver'; +export * from './src/resolver/schema/schema-resolver-design'; export * from './src/update-columns-resolver'; - -export { propertyConfigSchemaMap,getPropertyConfigBySchema } from './src/property-config-resolver'; +export { propertyConfigSchemaMap, getPropertyConfigBySchema } from './src/resolver/property-config/property-config-resolver'; +export { propertyConfigSchemaMapForDesigner, getPropertyConfigBySchemaForDesigner } from './src/resolver/property-config/property-config-resolver-design'; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/property-config-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/property-config-resolver.ts deleted file mode 100644 index e28ab5abe92..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/property-config-resolver.ts +++ /dev/null @@ -1,248 +0,0 @@ -import { computed, ref } from "vue"; -import { EffectFunction, PropertyConverter, SchemaService } from './types'; -import { EditorConfig } from "../../dynamic-form"; -import { useObjectExpression } from './object-expression'; -import { ComponentSchema } from "../../designer-canvas/src/types"; -import { resolveSchemaWithDefaultValue } from "./schema-resolver"; -import appearanceConverter from './converter/appearance.converter'; -import buttonsConverter from "./converter/buttons.converter"; -import propertyEditorConverter from "./converter/property-editor.converter"; -import typeConverter from "./converter/type.converter"; -import changeEditorConverter from "./converter/change-editor.converter"; -import fieldSelectorConverter from "./converter/field-selector.converter"; -import paginationConverter from "./converter/pagination.converter"; -import rowNumberConverter from "./converter/row-number.converter"; -import gridSelectionConverter from "./converter/grid-selection.converter"; -import itemsCountConverter from "./converter/items-count.converter"; -import enumDataConverter from "./converter/enum-data.converter"; -import formGroupLabelConverter from "./converter/form-group-label.converter"; -import { ElementPropertyConfig, PropertyEntity } from "@/components/property-panel"; - -const propertyConfigSchemaMap = {} as Record; -const propertyConverterMap = new Map([ - ['/converter/appearance.converter', appearanceConverter], - ['/converter/buttons.converter', buttonsConverter], - ['/converter/property-editor.converter', propertyEditorConverter], - ['/converter/items-count.converter', itemsCountConverter], - ['/converter/type.converter', typeConverter], - ['/converter/change-editor.converter', changeEditorConverter], - ['/converter/form-group-label.converter', formGroupLabelConverter], - ['/converter/field-selector.converter', fieldSelectorConverter], - ['/converter/pagination.converter', paginationConverter], - ['/converter/row-number.converter', rowNumberConverter], - ['/converter/grid-selection.converter', gridSelectionConverter], - ['/converter/enum-data.converter',enumDataConverter] -]); -const propertyEffectMap = {} as Record; -const propertyEditorMap = new Map([ - ['string', { type: 'input-group', enableClear: false }], - ['boolean', { - "type": "combo-list", - "textField": "name", - "valueField": "value", - "idField": "value", - "enableClear": false, - "editable": false, - "maxHeight": 64, - "data": [ - { - "value": true, - "name": "是" - }, - { - "value": false, - "name": "否" - } - ] - }], - ['enum', { "type": "combo-list", "maxHeight": 128, "enableClear": false, "editable": false }], - ['array', { "type": "button-edit" }], - ['number', { "type": "number-spinner","placeholder":"" }], - ['events-editor', { "type": "events-editor", hide: true }] -]); - -const useObjectExpressionComponstion = useObjectExpression(); - -function generateBooleanValue(pvalueSchema: Record, propertyConfigMap: Record) { - return () => useObjectExpressionComponstion.parseValueSchema(pvalueSchema, propertyConfigMap); -} - -function isVisible(propertySchemaKeys: string[], propertySchema: Record, propertyConfigMap: Record) - : boolean | (() => boolean) { - if (propertySchemaKeys.includes('visible') && propertySchema.visible !== undefined) { - return typeof propertySchema.visible === 'boolean' ? - () => Boolean(propertySchema.visible) : - propertySchema.visible === undefined ? true : generateBooleanValue(propertySchema.visible, propertyConfigMap); - } - return () => true; -} - -function isReadonly(propertySchemaKeys: string[], propertySchema: Record, propertyConfigMap: Record) { - if (propertySchemaKeys.includes('readonly') && propertySchema.readonly !== undefined) { - return typeof propertySchema.readonly === 'boolean' ? - () => Boolean(propertySchema.readonly) : - generateBooleanValue(propertySchema.readonly, propertyConfigMap); - } - return () => false; -} - -function tryGetPropertyConverter(propertySchema: Record, categoryConverter): PropertyConverter | null { - const $converter = propertySchema['$converter'] || categoryConverter; - if (typeof $converter === 'string') { - if ($converter && propertyConverterMap.has($converter)) { - return propertyConverterMap.get($converter) || null; - } - } - return $converter || null; -} - -/** - * - * @param propertiesInCategory - * 举例: - * visible: { - description: "运行时组件是否可见", - title: "是否可见", - type: "boolean" - } - 其中type属性 这个属性用来控制编辑器是哪一种,对应关系在propertyEditorMap中定义,boolean指定了下拉 - * @param propertyConfigMap - * @param editingSchema - * @param rawSchema - * @param schemaService - * @returns - */ -function getPropertyEntities( - propertiesInCategory: Record, - propertyConfigMap: Record, - editingSchema: ComponentSchema, - rawSchema: ComponentSchema, - schemaService: SchemaService, - componentId = '', - categoryConverter: any = '' -): PropertyEntity[] { - const propertyEntities = Object.keys(propertiesInCategory).map((propertyKey: string) => { - const updateCount = ref(1); - const propertyID = propertyKey; - const propertySchema = propertiesInCategory[propertyKey]; - const propertySchemaKeys = Object.keys(propertySchema); - const propertyName = propertySchema.title; - const propertyType = propertySchema.type; - const defaultEditor = propertyEditorMap.get(propertyType) || { type: 'input-group', enableClear: false }; - const editor = propertySchema.editor ? Object.assign({}, defaultEditor, propertySchema.editor) as EditorConfig : Object.assign({}, defaultEditor); - const visible = isVisible(propertySchemaKeys, propertySchema, propertyConfigMap); - const readonly = isReadonly(propertySchemaKeys, propertySchema, propertyConfigMap); - editor.readonly = editor.readonly===undefined?readonly():editor.readonly; - const cascadeConfig = propertySchema.type === 'cascade' ? getPropertyEntities(propertySchema.properties, propertyConfigMap, editingSchema, rawSchema, schemaService, componentId, categoryConverter) : []; - const hideCascadeTitle = true; - let converter = tryGetPropertyConverter(propertySchema, categoryConverter); - // const propertyValue = ref(converter ? converter.convertFrom(schema, propertyKey) : schema[propertyKey]); - const propertyValue = computed({ - get() { - if (updateCount.value) { - // class、style 统一处理 - if (['class', 'style'].find(id => id === propertyID) && !converter) { - converter = propertyConverterMap.get('/converter/appearance.converter') || null; - } - if (converter && converter.convertFrom) { - return converter.convertFrom(editingSchema, propertyKey, schemaService, componentId); - } - // 获取属性时,如果没有convertForm,并且通过在Schema上获取得值是空,那就获取defaultValue属性值或者是空 - const editingSchemaValue = editingSchema[propertyKey]; - return typeof editingSchemaValue == 'string' && editingSchemaValue === '' ? propertySchema['defaultValue'] || '' : editingSchemaValue; - } - return null; - }, - set(newValue) { - updateCount.value += 1; - if (converter && converter.convertTo) { - converter.convertTo(rawSchema, propertyKey, newValue, schemaService, componentId); - converter.convertTo(editingSchema, propertyKey, newValue, schemaService, componentId); - } else { - rawSchema[propertyKey] = newValue; - editingSchema[propertyKey] = newValue; - } - } - }); - const { refreshPanelAfterChanged } = propertySchema; - const propertyEntity = { propertyID, propertyName, propertyType, propertyValue, editor, visible, readonly, cascadeConfig, hideCascadeTitle, refreshPanelAfterChanged }; - propertyConfigMap[propertyID] = propertyEntity; - return propertyEntity; - }); - return propertyEntities; -} - -function getPropertyConfigByType(schemaType: string, schemaService: SchemaService, schema = {} as ComponentSchema): ElementPropertyConfig[] { - const propertyConfigMap = {} as Record; - const propertyConfigSchema = propertyConfigSchemaMap[schemaType]; - if (propertyConfigSchema && propertyConfigSchema.categories) { - const propertyConfigs = Object.keys(propertyConfigSchema.categories).map((categoryId: string) => { - const propertyCategory = propertyConfigSchema.categories[categoryId]; - const categoryName = propertyCategory?.title; - const properties = getPropertyEntities(propertyCategory.properties || {}, propertyConfigMap, {} as ComponentSchema, schema, schemaService); - return { categoryId, categoryName, properties }; - }); - return propertyConfigs; - } - return []; -} - -function tryToResolveReference(categoryId: string, propertyCategory: Record, rawSchema: ComponentSchema, schemaService: SchemaService, componentId = '') { - const refSchemaPath = propertyCategory.$ref.schema; - const $converter = propertyCategory.$ref.converter; - const refSchema = rawSchema[refSchemaPath]; - - const schemaType = refSchema.type; - const editingSchema = resolveSchemaWithDefaultValue(refSchema) as ComponentSchema; - const propertyConfigMap = {} as Record; - const propertyConfigSchema = propertyConfigSchemaMap[schemaType]; - if (propertyConfigSchema && propertyConfigSchema.categories) { - const propertyCategory = propertyConfigSchema.categories[categoryId]; - const categoryName = propertyCategory?.title; - if ($converter) { - Object.keys(propertyCategory.properties).forEach((propertyKey: any) => { - propertyCategory.properties[propertyKey].$converter = $converter; - }); - } - const propertiesInCategory = propertyCategory?.properties || {}; - const properties = getPropertyEntities(propertiesInCategory, propertyConfigMap, editingSchema, refSchema, schemaService, componentId); - return { categoryId, categoryName, properties }; - - } - return { categoryId, categoryName: '', properties: [] }; -} - -// jumphere -function getPropertyConfigBySchema(rawSchema: ComponentSchema, schemaService: SchemaService, designerItem: any, componentId: string, propertyConfig?: Record): ElementPropertyConfig[] { - const schemaType = rawSchema.type; - const editingSchema = resolveSchemaWithDefaultValue(rawSchema) as ComponentSchema; - const propertyConfigMap = {} as Record; - - // 先从ConfigMap中取简单类属性,若找不到,则在控件实例中取复杂属性 - let propertyConfigSchema = propertyConfig || propertyConfigSchemaMap[schemaType]; - if (propertyConfigSchema && Object.keys(propertyConfigSchema).length === 0 && designerItem && designerItem.getPropConfig) { - propertyConfigSchema = designerItem.getPropConfig(componentId); - } - if (propertyConfigSchema && propertyConfigSchema.categories) { - const propertyConfigs = [] as Array; - Object.keys(propertyConfigSchema.categories).map((categoryId: string) => { - const propertyCategory = propertyConfigSchema.categories[categoryId]; - if (propertyCategory.$ref) { - propertyConfigs.push(tryToResolveReference(categoryId, propertyCategory, rawSchema, schemaService, componentId) as ElementPropertyConfig); - return; - } - const categoryName = propertyCategory?.title; - const tabId = propertyCategory?.tabId; - const tabName = propertyCategory?.tabName; - const hide = propertyCategory?.hide; - const hideTitle = propertyCategory?.hideTitle; - const properties = getPropertyEntities(propertyCategory.properties || {}, propertyConfigMap, editingSchema, rawSchema, schemaService, componentId, propertyCategory['$converter']); - const { setPropertyRelates } = propertyCategory; - propertyConfigs.push({ categoryId, categoryName, tabId, tabName, hide, properties, hideTitle, setPropertyRelates }); - }); - return propertyConfigs; - } - return []; -} - -export { getPropertyConfigBySchema, getPropertyConfigByType, propertyConfigSchemaMap, propertyConverterMap, propertyEffectMap }; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts index c1d99b457bf..7334627b13f 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts @@ -1,9 +1,26 @@ import { DesignerHostService } from './../../designer-canvas/src/composition/types'; -import { resolveSchemaToProps, schemaMap, schemaResolverMap } from './schema-resolver'; +import { resolveSchemaToProps } from './resolver/schema/schema-resolver'; import { DynamicResolver, EffectFunction, MapperFunction, SchemaResolverFunction } from './types'; -import { propertyConfigSchemaMap, propertyEffectMap } from './property-config-resolver'; +import { RegisterContext } from '@/components/common'; -export function createPropsResolver>( +/** + * 注册schema和props + */ +function registerSchemaAndProps( + defaultSchema: Record, + schemaResolver: SchemaResolverFunction, + propertyConfig: Record, + propertyEffect: EffectFunction, + registerContext: any +) { + const { schemaMap, schemaResolverMap, propertyConfigSchemaMap, propertyEffectMap } = registerContext; + schemaMap[defaultSchema.title] = defaultSchema; + schemaResolverMap[defaultSchema.title] = schemaResolver; + propertyConfigSchemaMap[defaultSchema.title] = propertyConfig; + propertyEffectMap[defaultSchema.title] = propertyEffect; +} + +export function getPropsResolverGenerator>( componentPropsObject: T, defaultSchema: Record, schemaMapper: Map = new Map(), @@ -16,16 +33,17 @@ export function createPropsResolver>( propertyConfig: Record = {}, propertyEffect: EffectFunction = (properties: Record) => properties ) { - schemaMap[defaultSchema.title] = defaultSchema; - schemaResolverMap[defaultSchema.title] = schemaResolver; - propertyConfigSchemaMap[defaultSchema.title] = propertyConfig; - propertyEffectMap[defaultSchema.title] = propertyEffect; - return (schemaValue: Record = {}) => { - const resolvedPropsValue = resolveSchemaToProps(schemaValue, defaultSchema, schemaMapper); - const defaultProps = Object.keys(componentPropsObject).reduce((propsObject: Record, propKey: string) => { - propsObject[propKey] = componentPropsObject[propKey].default; - return propsObject; - }, {}); - return Object.assign(defaultProps, resolvedPropsValue); + + return (registerContext: RegisterContext) => { + registerSchemaAndProps(defaultSchema, schemaResolver, propertyConfig, propertyEffect, registerContext); + + return (schemaValue: Record = {}) => { + const resolvedPropsValue = resolveSchemaToProps(schemaValue, defaultSchema, schemaMapper); + const defaultProps = Object.keys(componentPropsObject).reduce((propsObject: Record, propKey: string) => { + propsObject[propKey] = componentPropsObject[propKey].default; + return propsObject; + }, {}); + return Object.assign(defaultProps, resolvedPropsValue); + } }; } diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver-design.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver-design.ts new file mode 100644 index 00000000000..e4fba29a4a8 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver-design.ts @@ -0,0 +1,13 @@ +import { EffectFunction } from '../../types'; +import { usePropertyConfigResolver } from './use-property-config-resolver'; + +const propertyConfigSchemaMapForDesigner = {} as Record; +const propertyEffectMapForDesigner = {} as Record; + +const { getPropertyConfigBySchema, getPropertyConfigByType, propertyConverterMap } = + usePropertyConfigResolver(propertyConfigSchemaMapForDesigner, propertyEffectMapForDesigner); + +export { + getPropertyConfigBySchema as getPropertyConfigBySchemaForDesigner, getPropertyConfigByType as getPropertyConfigByTypeForDesigner, + propertyConfigSchemaMapForDesigner, propertyConverterMap as propertyConverterMapForDesigner, propertyEffectMapForDesigner +}; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver.ts new file mode 100644 index 00000000000..199cbf45c5e --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver.ts @@ -0,0 +1,10 @@ +import { EffectFunction} from '../../types'; +import { usePropertyConfigResolver } from './use-property-config-resolver'; + +const propertyConfigSchemaMap = {} as Record; +const propertyEffectMap = {} as Record; + +const { getPropertyConfigBySchema, getPropertyConfigByType, propertyConverterMap } = + usePropertyConfigResolver(propertyConfigSchemaMap, propertyEffectMap); + +export { getPropertyConfigBySchema, getPropertyConfigByType, propertyConfigSchemaMap, propertyConverterMap, propertyEffectMap }; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts new file mode 100644 index 00000000000..6318ea0dc45 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts @@ -0,0 +1,249 @@ +import { computed, ref } from "vue"; +import { EffectFunction, PropertyConverter, SchemaService } from '../../types'; +import { EditorConfig } from "../../../../dynamic-form"; +import { useObjectExpression } from '../../object-expression'; +import { ComponentSchema } from "../../../../designer-canvas/src/types"; +import { resolveSchemaWithDefaultValue } from "../schema/schema-resolver"; +import appearanceConverter from '../../converter/appearance.converter'; +import buttonsConverter from "../../converter/buttons.converter"; +import propertyEditorConverter from "../../converter/property-editor.converter"; +import typeConverter from "../../converter/type.converter"; +import changeEditorConverter from "../../converter/change-editor.converter"; +import fieldSelectorConverter from "../../converter/field-selector.converter"; +import paginationConverter from "../../converter/pagination.converter"; +import rowNumberConverter from "../../converter/row-number.converter"; +import gridSelectionConverter from "../../converter/grid-selection.converter"; +import { ElementPropertyConfig, PropertyEntity } from "../../../../property-panel/src/composition/entity/property-entity"; +import itemsCountConverter from "../../converter/items-count.converter"; +import formGroupLabelConverter from "../../converter/form-group-label.converter"; + +export function usePropertyConfigResolver(propertyConfigSchemaMap: Record, propertyEffectMap: Record) { + const propertyConverterMap = new Map([ + ['/converter/appearance.converter', appearanceConverter], + ['/converter/buttons.converter', buttonsConverter], + ['/converter/property-editor.converter', propertyEditorConverter], + ['/converter/items-count.converter', itemsCountConverter], + ['/converter/type.converter', typeConverter], + ['/converter/change-editor.converter', changeEditorConverter], + ['/converter/form-group-label.converter', formGroupLabelConverter], + ['/converter/field-selector.converter', fieldSelectorConverter], + ['/converter/pagination.converter', paginationConverter], + ['/converter/row-number.converter', rowNumberConverter], + ['/converter/grid-selection.converter', gridSelectionConverter] + ]); + const propertyEditorMap = new Map([ + ['string', { type: 'input-group', enableClear: false }], + ['boolean', { + "type": "combo-list", + "textField": "name", + "valueField": "value", + "idField": "value", + "enableClear": false, + "editable": false, + "maxHeight": 64, + "data": [ + { + "value": true, + "name": "是" + }, + { + "value": false, + "name": "否" + } + ] + }], + ['enum', { "type": "combo-list", "maxHeight": 128, "enableClear": false, "editable": false }], + ['array', { "type": "button-edit" }], + ['number', { "type": "number-spinner", "placeholder": "" }], + ['events-editor', { "type": "events-editor", hide: true }] + ]); + + const useObjectExpressionComponstion = useObjectExpression(); + + function generateBooleanValue(pvalueSchema: Record, propertyConfigMap: Record) { + return () => useObjectExpressionComponstion.parseValueSchema(pvalueSchema, propertyConfigMap); + } + + function isVisible(propertySchemaKeys: string[], propertySchema: Record, propertyConfigMap: Record) + : boolean | (() => boolean) { + if (propertySchemaKeys.includes('visible') && propertySchema.visible !== undefined) { + return typeof propertySchema.visible === 'boolean' ? + () => Boolean(propertySchema.visible) : + propertySchema.visible === undefined ? true : generateBooleanValue(propertySchema.visible, propertyConfigMap); + } + return () => true; + } + + function isReadonly(propertySchemaKeys: string[], propertySchema: Record, propertyConfigMap: Record) { + if (propertySchemaKeys.includes('readonly') && propertySchema.readonly !== undefined) { + return typeof propertySchema.readonly === 'boolean' ? + () => Boolean(propertySchema.readonly) : + generateBooleanValue(propertySchema.readonly, propertyConfigMap); + } + return () => false; + } + + function tryGetPropertyConverter(propertySchema: Record, categoryConverter): PropertyConverter | null { + const $converter = propertySchema['$converter'] || categoryConverter; + if (typeof $converter === 'string') { + if ($converter && propertyConverterMap.has($converter)) { + return propertyConverterMap.get($converter) || null; + } + } + return $converter || null; + } + + /** + * + * @param propertiesInCategory + * 举例: + * visible: { + description: "运行时组件是否可见", + title: "是否可见", + type: "boolean" + } + 其中type属性 这个属性用来控制编辑器是哪一种,对应关系在propertyEditorMap中定义,boolean指定了下拉 + * @param propertyConfigMap + * @param editingSchema + * @param rawSchema + * @param schemaService + * @returns + */ + function getPropertyEntities( + propertiesInCategory: Record, + propertyConfigMap: Record, + editingSchema: ComponentSchema, + rawSchema: ComponentSchema, + schemaService: SchemaService, + componentId = '', + categoryConverter: any = '' + ): PropertyEntity[] { + const propertyEntities = Object.keys(propertiesInCategory).map((propertyKey: string) => { + const updateCount = ref(1); + const propertyID = propertyKey; + const propertySchema = propertiesInCategory[propertyKey]; + const propertySchemaKeys = Object.keys(propertySchema); + const propertyName = propertySchema.title; + const propertyType = propertySchema.type; + const defaultEditor = propertyEditorMap.get(propertyType) || { type: 'input-group', enableClear: false }; + const editor = propertySchema.editor ? Object.assign({}, defaultEditor, propertySchema.editor) as EditorConfig : Object.assign({}, defaultEditor); + const visible = isVisible(propertySchemaKeys, propertySchema, propertyConfigMap); + const readonly = isReadonly(propertySchemaKeys, propertySchema, propertyConfigMap); + editor.readonly = editor.readonly === undefined ? readonly() : editor.readonly; + const cascadeConfig = propertySchema.type === 'cascade' ? getPropertyEntities(propertySchema.properties, propertyConfigMap, editingSchema, rawSchema, schemaService, componentId, categoryConverter) : []; + const hideCascadeTitle = true; + let converter = tryGetPropertyConverter(propertySchema, categoryConverter); + // const propertyValue = ref(converter ? converter.convertFrom(schema, propertyKey) : schema[propertyKey]); + const propertyValue = computed({ + get() { + if (updateCount.value) { + // class、style 统一处理 + if (['class', 'style'].find(id => id === propertyID) && !converter) { + converter = propertyConverterMap.get('/converter/appearance.converter') || null; + } + if (converter && converter.convertFrom) { + return converter.convertFrom(editingSchema, propertyKey, schemaService, componentId); + } + // 获取属性时,如果没有convertForm,并且通过在Schema上获取得值是空,那就获取defaultValue属性值或者是空 + const editingSchemaValue = editingSchema[propertyKey]; + return Object.prototype.hasOwnProperty.call(propertySchema, 'defaultValue') && (editingSchemaValue === undefined || typeof editingSchemaValue == 'string' && editingSchemaValue === '') ? propertySchema['defaultValue'] || '' : editingSchemaValue; + } + return null; + }, + set(newValue) { + updateCount.value += 1; + if (converter && converter.convertTo) { + converter.convertTo(rawSchema, propertyKey, newValue, schemaService, componentId); + converter.convertTo(editingSchema, propertyKey, newValue, schemaService, componentId); + } else { + rawSchema[propertyKey] = newValue; + editingSchema[propertyKey] = newValue; + } + } + }); + const { refreshPanelAfterChanged, description, isExpand } = propertySchema; + const propertyEntity = { propertyID, propertyName, propertyType, propertyValue, editor, visible, readonly, cascadeConfig, hideCascadeTitle, refreshPanelAfterChanged, description, isExpand }; + propertyConfigMap[propertyID] = propertyEntity; + return propertyEntity; + }); + return propertyEntities; + } + + function getPropertyConfigByType(schemaType: string, schemaService: SchemaService, schema = {} as ComponentSchema): ElementPropertyConfig[] { + const propertyConfigMap = {} as Record; + const propertyConfigSchema = propertyConfigSchemaMap[schemaType]; + if (propertyConfigSchema && propertyConfigSchema.categories) { + const propertyConfigs = Object.keys(propertyConfigSchema.categories).map((categoryId: string) => { + const propertyCategory = propertyConfigSchema.categories[categoryId]; + const categoryName = propertyCategory?.title; + const properties = getPropertyEntities(propertyCategory.properties || {}, propertyConfigMap, {} as ComponentSchema, schema, schemaService); + return { categoryId, categoryName, properties }; + }); + return propertyConfigs; + } + return []; + } + + function tryToResolveReference(categoryId: string, propertyCategory: Record, rawSchema: ComponentSchema, schemaService: SchemaService, componentId = '') { + const refSchemaPath = propertyCategory.$ref.schema; + const $converter = propertyCategory.$ref.converter; + const refSchema = rawSchema[refSchemaPath]; + + const schemaType = refSchema.type; + const editingSchema = resolveSchemaWithDefaultValue(refSchema) as ComponentSchema; + const propertyConfigMap = {} as Record; + const propertyConfigSchema = propertyConfigSchemaMap[schemaType]; + if (propertyConfigSchema && propertyConfigSchema.categories) { + const propertyCategory = propertyConfigSchema.categories[categoryId]; + const categoryName = propertyCategory?.title; + if ($converter) { + Object.keys(propertyCategory.properties).forEach((propertyKey: any) => { + propertyCategory.properties[propertyKey].$converter = $converter; + }); + } + const propertiesInCategory = propertyCategory?.properties || {}; + const properties = getPropertyEntities(propertiesInCategory, propertyConfigMap, editingSchema, refSchema, schemaService, componentId); + return { categoryId, categoryName, properties }; + + } + return { categoryId, categoryName: '', properties: [] }; + } + + // jumphere + function getPropertyConfigBySchema(rawSchema: ComponentSchema, schemaService: SchemaService, designerItem: any, componentId: string, propertyConfig?: Record): ElementPropertyConfig[] { + const schemaType = rawSchema.type; + const editingSchema = resolveSchemaWithDefaultValue(rawSchema) as ComponentSchema; + const propertyConfigMap = {} as Record; + + // 先从ConfigMap中取简单类属性,若找不到,则在控件实例中取复杂属性 + let propertyConfigSchema = propertyConfig || propertyConfigSchemaMap[schemaType]; + if (propertyConfigSchema && Object.keys(propertyConfigSchema).length === 0 && designerItem && designerItem.getPropConfig) { + propertyConfigSchema = designerItem.getPropConfig(componentId); + } + if (propertyConfigSchema && propertyConfigSchema.categories) { + const propertyConfigs = [] as Array; + Object.keys(propertyConfigSchema.categories).map((categoryId: string) => { + const propertyCategory = propertyConfigSchema.categories[categoryId]; + if (propertyCategory.$ref) { + propertyConfigs.push(tryToResolveReference(categoryId, propertyCategory, rawSchema, schemaService, componentId) as ElementPropertyConfig); + return; + } + const categoryName = propertyCategory?.title; + const tabId = propertyCategory?.tabId; + const tabName = propertyCategory?.tabName; + const hide = propertyCategory?.hide; + const hideTitle = propertyCategory?.hideTitle; + const properties = getPropertyEntities(propertyCategory.properties || {}, propertyConfigMap, editingSchema, rawSchema, schemaService, componentId, propertyCategory['$converter']); + const { setPropertyRelates } = propertyCategory; + propertyConfigs.push({ categoryId, categoryName, tabId, tabName, hide, properties, hideTitle, setPropertyRelates }); + }); + return propertyConfigs; + } + return []; + } + + return { + getPropertyConfigBySchema, getPropertyConfigByType, propertyConverterMap + }; +} + diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver-design.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver-design.ts new file mode 100644 index 00000000000..d5fe3e93162 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver-design.ts @@ -0,0 +1,14 @@ +import { SchemaResolverFunction } from "../../types"; +import { useSchemaResolver } from "./use-schema-resolver"; + +const schemaMapForDesigner = {} as Record; +const schemaResolverMapForDesigner = {} as Record; + +const { getSchemaByType, resolveSchemaWithDefaultValue, resolveSchemaToProps, mappingSchemaToProps } = + useSchemaResolver(schemaMapForDesigner, schemaResolverMapForDesigner); + +export { + getSchemaByType as getSchemaByTypeForDesigner, resolveSchemaWithDefaultValue as resolveSchemaWithDefaultValueForDesigner, + resolveSchemaToProps as resolveSchemaToPropsForDesigner, schemaMapForDesigner, schemaResolverMapForDesigner, + mappingSchemaToProps as mappingSchemaToPropsForDesigner +}; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver.ts new file mode 100644 index 00000000000..083e2015cd3 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver.ts @@ -0,0 +1,10 @@ +import { SchemaResolverFunction } from "../../types"; +import { useSchemaResolver } from "./use-schema-resolver"; + +const schemaMap = {} as Record; +const schemaResolverMap = {} as Record; + +const { getSchemaByType, resolveSchemaWithDefaultValue, resolveSchemaToProps, mappingSchemaToProps } = + useSchemaResolver(schemaMap, schemaResolverMap); + +export { getSchemaByType, resolveSchemaWithDefaultValue, resolveSchemaToProps, schemaMap, schemaResolverMap, mappingSchemaToProps }; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts new file mode 100644 index 00000000000..96fb6a51599 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts @@ -0,0 +1,137 @@ +import { cloneDeep, isPlainObject } from "lodash-es"; +import { MapperFunction, SchemaResolverFunction } from "../../types"; +import { DesignerHostService } from "@components/designer-canvas"; + + +export function useSchemaResolver(schemaMap: Record, schemaResolverMap: Record) { + + function getSchemaValueByDefault(defaultSchema: Record): Record { + const { properties, title, ignore: ignoreList } = defaultSchema as Record; + const canIgnoreProperty = ignoreList && Array.isArray(ignoreList); + const resolvedSchema = Object.keys(properties).reduce((propsObject: Record, propKey: string) => { + if (!canIgnoreProperty || !ignoreList.find(item => item === propKey)) { + propsObject[propKey] = (properties[propKey].type === 'object' && !!properties[propKey].properties) ? + getSchemaValueByDefault(properties[propKey]) : cloneDeep(properties[propKey].default); + } + return propsObject; + }, {}); + if (title && (!canIgnoreProperty || !ignoreList.find(item => item === 'id'))) { + const typePrefix = title.toLowerCase().replace(/-/g, '_'); + resolvedSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; + } + return resolvedSchema; + } + + /** + * 获取控件元数据,只组装必填的字段 + */ + function getRequiredSchemaValueByDefault(defaultSchema: Record): Record { + const { properties, title, required: requiredProperty } = defaultSchema as Record; + if (requiredProperty && Array.isArray(requiredProperty)) { + const resolvedSchema = requiredProperty.reduce((propsObject: Record, propKey: string) => { + + propsObject[propKey] = (properties[propKey].type === 'object' && !!properties[propKey].properties) ? + getSchemaValueByDefault(properties[propKey]) : cloneDeep(properties[propKey].default); + + return propsObject; + }, {}); + if (title && requiredProperty.find(item => item === 'id')) { + const typePrefix = title.toLowerCase().replace(/-/g, '_'); + resolvedSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; + } + return resolvedSchema; + } + return { + type: title + }; + + } + + function getSchemaByType(componentType: string, resolveContext: Record = {}, designerHostService?: DesignerHostService) + : Record | null { + const defaultSchema = schemaMap[componentType]; + if (defaultSchema) { + let componentSchema = getRequiredSchemaValueByDefault(defaultSchema); + const schemaResolver = schemaResolverMap[componentType]; + componentSchema = schemaResolver ? schemaResolver({ getSchemaByType }, componentSchema, resolveContext, designerHostService) + : componentSchema; + return componentSchema; + } + return null; + } + + function resolveSchema(schemaValue: Record, defaultSchema: Record): Record { + + const resolvedSchema = getSchemaValueByDefault(defaultSchema); + + Object.keys(resolvedSchema).reduce((resolvedSchema: Record, propKey: string) => { + if (Object.prototype.hasOwnProperty.call(schemaValue, propKey)) { + // 解决属性是对象类型,默认值被冲掉的情况 + // 增加非判断,解决针对属性时对象,但是schemaValue=null或者undefined情况 + if (resolvedSchema[propKey] && isPlainObject(resolvedSchema[propKey]) && (isPlainObject(schemaValue[propKey] || !schemaValue[propKey]))) { + Object.assign(resolvedSchema[propKey], schemaValue[propKey] || {}); + } else { + resolvedSchema[propKey] = schemaValue[propKey]; + } + } + + return resolvedSchema; + }, resolvedSchema); + + return resolvedSchema; + }; + + function mappingSchemaToProps(resolvedSchema: Record, schemaMapper: Map) { + const props = Object.keys(resolvedSchema) + .filter((propKey: string) => resolvedSchema[propKey] != null) + .reduce((resolvedProps: Record, propKey: string) => { + if (schemaMapper.has(propKey)) { + const mapper = schemaMapper.get(propKey) as string | MapperFunction; + if (typeof mapper === 'string') { + resolvedProps[mapper] = resolvedSchema[propKey]; + } else { + const mapperResult = (mapper as MapperFunction)(propKey, resolvedSchema[propKey], resolvedSchema); + Object.assign(resolvedProps, mapperResult); + } + } else { + resolvedProps[propKey] = resolvedSchema[propKey]; + } + return resolvedProps; + }, {}); + return props; + } + + function resolveSchemaToProps( + schemaValue: Record, + defaultSchema: Record, + schemaMapper: Map = new Map() + ): Record { + const resolvedSchema = resolveSchema(schemaValue, defaultSchema); + const props = mappingSchemaToProps(resolvedSchema, schemaMapper); + return props; + } + + function resolveSchemaWithDefaultValue(schemaValue: Record): Record { + const componentType = schemaValue.type; + if (componentType) { + const defaultSchema = schemaMap[componentType]; + if (!defaultSchema) { + return schemaValue; + } + const resolvedSchema = resolveSchema(schemaValue, defaultSchema); + const editorType = schemaValue.editor?.type || ''; + /* 解决schemeValue结构如下图场景,在editor下,获取不到date-picker类型的默认值的问题 + * {type:'input-group',...,editor:{type:'date-picker',...}} + */ + if (editorType) { + const defaulEditorSchema = schemaMap[editorType]; + const resolvedEditorSchema = resolveSchema(schemaValue.editor, defaulEditorSchema); + resolvedSchema.editor = resolvedEditorSchema; + } + return resolvedSchema; + } + return schemaValue; + } + + return { getSchemaByType, resolveSchemaWithDefaultValue, resolveSchemaToProps, mappingSchemaToProps }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/schema-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/schema-resolver.ts deleted file mode 100644 index d2dada2e4dc..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/schema-resolver.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { cloneDeep, isPlainObject } from "lodash-es"; -import { DesignerHostService } from "../../designer-canvas/src/composition/types"; -import { MapperFunction, SchemaResolverFunction } from "./types"; - -const schemaMap = {} as Record; -const schemaResolverMap = {} as Record; - -function getSchemaValueByDefault(defaultSchema: Record): Record { - const { properties, title, ignore: ignoreList } = defaultSchema as Record; - const canIgnoreProperty = ignoreList && Array.isArray(ignoreList); - const resolvedSchema = Object.keys(properties).reduce((propsObject: Record, propKey: string) => { - if (!canIgnoreProperty || !ignoreList.find(item => item === propKey)) { - propsObject[propKey] = (properties[propKey].type === 'object' && !!properties[propKey].properties) ? - getSchemaValueByDefault(properties[propKey]) : cloneDeep(properties[propKey].default); - } - return propsObject; - }, {}); - if (title && (!canIgnoreProperty || !ignoreList.find(item => item === 'id'))) { - const typePrefix = title.toLowerCase().replace(/-/g, '_'); - resolvedSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; - } - return resolvedSchema; -} -/** - * 获取控件元数据,只组装必填的字段 - */ -function getRequiredSchemaValueByDefault(defaultSchema: Record): Record { - const { properties, title, required: requiredProperty } = defaultSchema as Record; - if (requiredProperty && Array.isArray(requiredProperty)) { - const resolvedSchema = requiredProperty.reduce((propsObject: Record, propKey: string) => { - - propsObject[propKey] = (properties[propKey].type === 'object' && !!properties[propKey].properties) ? - getSchemaValueByDefault(properties[propKey]) : cloneDeep(properties[propKey].default); - - return propsObject; - }, {}); - if (title && requiredProperty.find(item => item === 'id')) { - const typePrefix = title.toLowerCase().replace(/-/g, '_'); - resolvedSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; - } - return resolvedSchema; - } - return { - type: title - }; - -} -function getSchemaByType(componentType: string, resolveContext: Record = {}, designerHostService?: DesignerHostService) - : Record | null { - const defaultSchema = schemaMap[componentType]; - if (defaultSchema) { - let componentSchema = getRequiredSchemaValueByDefault(defaultSchema); - const schemaResolver = schemaResolverMap[componentType]; - componentSchema = schemaResolver ? schemaResolver({ getSchemaByType }, componentSchema, resolveContext, designerHostService) - : componentSchema; - return componentSchema; - } - return null; -} - -function resolveSchema(schemaValue: Record, defaultSchema: Record): Record { - - const resolvedSchema = getSchemaValueByDefault(defaultSchema); - - Object.keys(resolvedSchema).reduce((resolvedSchema: Record, propKey: string) => { - if (Object.prototype.hasOwnProperty.call(schemaValue, propKey)) { - // 解决属性是对象类型,默认值被冲掉的情况 - // 增加非判断,解决针对属性时对象,但是schemaValue=null或者undefined情况 - if (resolvedSchema[propKey] && isPlainObject(resolvedSchema[propKey]) && (isPlainObject(schemaValue[propKey] || !schemaValue[propKey]))) { - Object.assign(resolvedSchema[propKey], schemaValue[propKey] || {}); - } else { - resolvedSchema[propKey] = schemaValue[propKey]; - } - } - - return resolvedSchema; - }, resolvedSchema); - - return resolvedSchema; -}; - -function mappingSchemaToProps(resolvedSchema: Record, schemaMapper: Map) { - const props = Object.keys(resolvedSchema) - .filter((propKey: string) => resolvedSchema[propKey] != null) - .reduce((resolvedProps: Record, propKey: string) => { - if (schemaMapper.has(propKey)) { - const mapper = schemaMapper.get(propKey) as string | MapperFunction; - if (typeof mapper === 'string') { - resolvedProps[mapper] = resolvedSchema[propKey]; - } else { - const mapperResult = (mapper as MapperFunction)(propKey, resolvedSchema[propKey], resolvedSchema); - Object.assign(resolvedProps, mapperResult); - } - } else { - resolvedProps[propKey] = resolvedSchema[propKey]; - } - return resolvedProps; - }, {}); - return props; -} - -function resolveSchemaToProps( - schemaValue: Record, - defaultSchema: Record, - schemaMapper: Map = new Map() -): Record { - const resolvedSchema = resolveSchema(schemaValue, defaultSchema); - const props = mappingSchemaToProps(resolvedSchema, schemaMapper); - return props; -} - -function resolveSchemaWithDefaultValue(schemaValue: Record): Record { - const componentType = schemaValue.type; - if (componentType) { - const defaultSchema = schemaMap[componentType]; - if (!defaultSchema) { - return schemaValue; - } - const resolvedSchema = resolveSchema(schemaValue, defaultSchema); - const editorType = schemaValue.editor?.type || ''; - /* 解决schemeValue结构如下图场景,在editor下,获取不到date-picker类型的默认值的问题 - * {type:'input-group',...,editor:{type:'date-picker',...}} - */ - if (editorType) { - const defaulEditorSchema = schemaMap[editorType]; - const resolvedEditorSchema = resolveSchema(schemaValue.editor, defaulEditorSchema); - resolvedSchema.editor = resolvedEditorSchema; - } - return resolvedSchema; - } - return schemaValue; -} - -export { getSchemaByType, resolveSchemaWithDefaultValue, resolveSchemaToProps, schemaMap, schemaResolverMap }; diff --git a/packages/mobile-ui-vue/components/float-container/index.ts b/packages/mobile-ui-vue/components/float-container/index.ts index 3b6178781c2..e11c0591c1d 100644 --- a/packages/mobile-ui-vue/components/float-container/index.ts +++ b/packages/mobile-ui-vue/components/float-container/index.ts @@ -1,6 +1,6 @@ import { Plugin } from 'vue'; -import { withInstall } from '@components/common'; -import { propsResolver } from './src/float-container.props'; +import { RegisterContext, withInstall } from '@components/common'; +import { propsResolverGenerator } from './src/float-container.props'; import FloatContainerInstallless from './src/float-container.component'; import FloatContainerDesign from './src/designer/float-container.design.component'; @@ -10,18 +10,18 @@ const FloatContainer = withInstall(FloatContainerInstallless); FloatContainer.register = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext ) => { componentMap[FLOAT_CONTAINER_REGISTERED_NAME] = FloatContainer; - propsResolverMap[FLOAT_CONTAINER_REGISTERED_NAME] = propsResolver; + propsResolverMap[FLOAT_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; FloatContainer.registerDesigner = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record,registerContext: RegisterContext ) => { componentMap[FLOAT_CONTAINER_REGISTERED_NAME] = FloatContainerDesign; - propsResolverMap[FLOAT_CONTAINER_REGISTERED_NAME] = propsResolver; + propsResolverMap[FLOAT_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; 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 index e3d5c77dd14..c5da6f3797f 100644 --- 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 @@ -1,5 +1,5 @@ import { ExtractPropTypes } from 'vue'; -import { createPropsResolver } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '../../dynamic-resolver'; import floatContainerSchema from './schema/float-container.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; @@ -12,7 +12,7 @@ export const floatContainerProps = { export type FloatContainerProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( +export const propsResolverGenerator = getPropsResolverGenerator( floatContainerProps, floatContainerSchema, schemaMapper, diff --git a/packages/mobile-ui-vue/components/form-item/index.ts b/packages/mobile-ui-vue/components/form-item/index.ts index c52eef2821f..c5a5f4b57a6 100644 --- a/packages/mobile-ui-vue/components/form-item/index.ts +++ b/packages/mobile-ui-vue/components/form-item/index.ts @@ -1,26 +1,26 @@ -import { withInstall } from '@components/common'; -import { propsResolver } from './src/form-item.props'; +import { RegisterContext, withInstall } from '@components/common'; +import { propsResolverGenerator } from './src/form-item.props'; import FormItemInstallless from './src/form-item.component'; import FormItemDesign from './src/designer/form-item.design.component'; -const FORM_REGISTERED_NAME = 'form-item'; +const FORM_REGISTERED_NAME = 'form-group'; const FormItem = withInstall(FormItemInstallless); FormItem.register = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext ) => { componentMap[FORM_REGISTERED_NAME] = FormItem; - propsResolverMap[FORM_REGISTERED_NAME] = propsResolver; + propsResolverMap[FORM_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; FormItem.registerDesigner = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record,registerContext: RegisterContext ) => { componentMap[FORM_REGISTERED_NAME] = FormItemDesign; - propsResolverMap[FORM_REGISTERED_NAME] = propsResolver; + propsResolverMap[FORM_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; export * from './src/form-item.props'; diff --git a/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx b/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx index 09d05afe132..ae06684c0af 100644 --- a/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx +++ b/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx @@ -18,7 +18,7 @@ import { useBem } from '@components/common'; import FmCell from '@components/cell'; import { FORM_ITEM_NAME, FormItemProps, formItemProps } from '../form-item.props'; import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@/components/designer-canvas';; -import { propertyConfigSchemaMap } from '@/components/dynamic-resolver'; +import { propertyConfigSchemaMapForDesigner } from '@/components/dynamic-resolver/src/resolver/property-config/property-config-resolver-design'; import { useDesignerRulesForFormItem } from './form-item-use-designer-rules'; import { useTypeResolverDesign } from '@/components/dynamic-form/src/composition/use-type-resolver-design'; @@ -94,7 +94,7 @@ export default defineComponent({ elementRef.value.componentInstance = componentInstance; componentInstance.value.getPropConfig = (...args) => { - let propertyConfigSchema = propertyConfigSchemaMap[props.editor.type]; + let propertyConfigSchema = propertyConfigSchemaMapForDesigner[props.editor.type]; if (propertyConfigSchema && Object.keys(propertyConfigSchema).length === 0 && editorRef && editorRef.value && editorRef.value?.getPropConfig) { propertyConfigSchema = editorRef.value.getPropConfig(...args, componentInstance.value); } diff --git a/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts b/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts index c6badd84df8..f9fa5175688 100644 --- a/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts @@ -1,6 +1,6 @@ import { ComponentSchema, DesignerComponentInstance, DesignerHostService, DesignerItemContext, UseDesignerRules } from "@/components/designer-canvas"; import { DraggingResolveContext } from "@/components/designer-canvas/src/composition/types"; -import { getSchemaByType } from "@/components/dynamic-resolver"; +import { getSchemaByTypeForDesigner } from "@/components/dynamic-resolver/src/resolver/schema/schema-resolver-design"; import { ref } from "vue"; import { ResponseFormProperty } from "../property-config/response-form.property-config"; @@ -60,7 +60,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe const controlCreatorUtils = designerHostService?.controlCreatorUtils; formGroupElementSchema = controlCreatorUtils.setFormFieldProperty(resolveContext.bindingSourceContext?.entityFieldNode, componentSchema.type); } else { - formGroupElementSchema = getSchemaByType('form-item') as ComponentSchema; + formGroupElementSchema = getSchemaByTypeForDesigner('form-group') as ComponentSchema; formGroupElementSchema.editor = componentSchema; formGroupElementSchema.label = label; } 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 2952c339967..4f362f26471 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,5 +1,5 @@ import { ExtractPropTypes, PropType } from 'vue'; -import { createPropsResolver } from '@components/dynamic-resolver'; +import { getPropsResolverGenerator } 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'; @@ -43,7 +43,7 @@ export const formItemProps = { export type FormItemProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( +export const propsResolverGenerator = getPropsResolverGenerator( formItemProps, formItemSchema, schemaMapper, 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 f5000a12301..23c3de720ad 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,7 +1,7 @@ import { ExtractPropTypes, PropType } from 'vue'; 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 { getPropsResolverGenerator } 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'; @@ -38,7 +38,7 @@ export const formProps = { export type FormProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( +export const propsResolverGenerator = getPropsResolverGenerator( formProps, formSchema, schemaMapper, 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..ce6baae533e 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 @@ -1,7 +1,7 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://farris-design.gitee.io/form-item.schema.json", - "title": "form-item", + "title": "form-group", "description": "", "type": "object", "properties": { @@ -12,7 +12,7 @@ "type": { "description": "", "type": "string", - "default": "form-item" + "default": "form-group" }, "appearance": { "description": "", diff --git a/packages/mobile-ui-vue/components/form/index.ts b/packages/mobile-ui-vue/components/form/index.ts index f7cb3ad778c..fc8f862f307 100644 --- a/packages/mobile-ui-vue/components/form/index.ts +++ b/packages/mobile-ui-vue/components/form/index.ts @@ -15,8 +15,8 @@ * limitations under the License. */ import { Plugin } from 'vue'; -import { withInstall } from '@components/common'; -import { propsResolver } from '@components/form-item/src/form.props'; +import { RegisterContext, withInstall } from '@components/common'; +import { propsResolverGenerator } from '@components/form-item/src/form.props'; import FormInstallless from '@components/form-item/src/form.component'; import FormInstalllessDesign from '../form-item/src/designer/response-form.design.component'; @@ -26,18 +26,18 @@ const Form = withInstall(FormInstallless); Form.register = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext ) => { componentMap[FORM_REGISTERED_NAME] = Form; - propsResolverMap[FORM_REGISTERED_NAME] = propsResolver; + propsResolverMap[FORM_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; Form.registerDesigner = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record,registerContext: RegisterContext ) => { componentMap[FORM_REGISTERED_NAME] = FormInstalllessDesign; - propsResolverMap[FORM_REGISTERED_NAME] = propsResolver; + propsResolverMap[FORM_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; export * from '@components/form-item/src/form.props'; diff --git a/packages/mobile-ui-vue/components/index.ts b/packages/mobile-ui-vue/components/index.ts index 1de9986d9c6..135bbb9dbe9 100644 --- a/packages/mobile-ui-vue/components/index.ts +++ b/packages/mobile-ui-vue/components/index.ts @@ -48,7 +48,7 @@ import TimePickerInput from './time-picker-input'; import Loading from './loading'; import PullRefresh from './pull-refresh'; import List from './list'; -import { ListView } from './list-view'; +import ListView from './list-view'; import TabBar from "./tab-bar"; import SwipeCell from './swipe-cell'; import ActionSheet from './action-sheet'; diff --git a/packages/mobile-ui-vue/components/input-group/index.ts b/packages/mobile-ui-vue/components/input-group/index.ts index 30385677fe3..7f927bd834a 100644 --- a/packages/mobile-ui-vue/components/input-group/index.ts +++ b/packages/mobile-ui-vue/components/input-group/index.ts @@ -1,5 +1,5 @@ -import { withInstall } from '@components/common'; -import { propsResolver } from './src/input-group.props'; +import { RegisterContext, withInstall } from '@components/common'; +import { propsResolverGenerator } from './src/input-group.props'; import InputGroupInstallless from './src/input-group.component'; import InputGroupDesign from './src/designer/input-group.design.component'; @@ -9,18 +9,18 @@ const InputGroup = withInstall(InputGroupInstallless); InputGroup.register = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext ) => { componentMap[INPUT_GROUP_REGISTERED_NAME] = InputGroup; - propsResolverMap[INPUT_GROUP_REGISTERED_NAME] = propsResolver; + propsResolverMap[INPUT_GROUP_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; InputGroup.registerDesigner = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record,registerContext: RegisterContext ) => { componentMap[INPUT_GROUP_REGISTERED_NAME] = InputGroupDesign; - propsResolverMap[INPUT_GROUP_REGISTERED_NAME] = propsResolver; + propsResolverMap[INPUT_GROUP_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; export * from './src/input-group.props'; 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..29eee188420 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,6 +1,6 @@ import { ExtractPropTypes, PropType } from 'vue'; import { InputTextAlign, InputTextAlignMap, InputType, InputTypeMap, InputUpdateOn } from "./types"; -import { createPropsResolver } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '../../dynamic-resolver'; import inputGroupSchema from './schema/input-group.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; @@ -67,7 +67,7 @@ export const inputProps = { export type InputCommonProps = ExtractPropTypes; export type InputProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( +export const propsResolverGenerator = getPropsResolverGenerator( inputProps, inputGroupSchema, schemaMapper, diff --git a/packages/mobile-ui-vue/components/list-view/index.ts b/packages/mobile-ui-vue/components/list-view/index.ts index dc245320aec..f240ad43dd5 100644 --- a/packages/mobile-ui-vue/components/list-view/index.ts +++ b/packages/mobile-ui-vue/components/list-view/index.ts @@ -1,7 +1,7 @@ -import { withInstall } from '@components/common'; +import { RegisterContext, withInstall } from '@components/common'; import ListViewInstallless from './src/list-view.component'; import ListViewDesign from './src/designer/list-view.design.component'; -import { propsResolver } from './src/list-view.props'; +import { propsResolverGenerator } from './src/list-view.props'; const LIST_VIEW_REGISTER_NAME = 'list-view'; const ListView = withInstall(ListViewInstallless); @@ -10,19 +10,19 @@ export * from './src/list-view.props'; ListView.register = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext ) => { componentMap[LIST_VIEW_REGISTER_NAME] = ListView; - propsResolverMap[LIST_VIEW_REGISTER_NAME] = propsResolver; -}; + propsResolverMap[LIST_VIEW_REGISTER_NAME] = propsResolverGenerator(registerContext); +} ListView.registerDesigner = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record,registerContext: RegisterContext ) => { componentMap[LIST_VIEW_REGISTER_NAME] = ListViewDesign; - propsResolverMap[LIST_VIEW_REGISTER_NAME] = propsResolver; -}; + propsResolverMap[LIST_VIEW_REGISTER_NAME] = propsResolverGenerator(registerContext); +} export { ListView }; 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 229a5883e35..a976b558d7c 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 @@ -18,7 +18,7 @@ import { ExtractPropTypes, PropType } from 'vue'; import { ListProps } from '@components/list'; import { PullRefreshProps } from '@components/pull-refresh'; import { CheckboxProps } from '@components/checkbox/src/checkbox.props'; -import { createPropsResolver } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '../../dynamic-resolver'; import { schemaMapper } from './schema/schema-mapper'; import listViewSchema from './schema/list-view.schema.json'; import listViewPropertyConfig from './property-config/list-view.property-config.json'; @@ -107,7 +107,7 @@ export interface ListViewToolbarItem { export type ListViewProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( +export const propsResolverGenerator = getPropsResolverGenerator( listViewProps, listViewSchema, schemaMapper, diff --git a/packages/mobile-ui-vue/components/navbar/index.ts b/packages/mobile-ui-vue/components/navbar/index.ts index 9860ea71a68..9ae1fa8300e 100644 --- a/packages/mobile-ui-vue/components/navbar/index.ts +++ b/packages/mobile-ui-vue/components/navbar/index.ts @@ -1,20 +1,22 @@ -import { withInstall } from '@components/common'; -import { propsResolver } from './src/navbar.props'; +import { RegisterContext, withInstall } from '@components/common'; +import { propsResolverGenerator } from './src/navbar.props'; import NavbarInstallless from './src/navbar.component'; import NavbarDesign from './src/designer/nav.design.component'; -const NAVBAR_REGISTERED_NAME = 'navigation-bar'; +const NAVBAR_REGISTERED_NAME = 'navbar'; const Navbar = withInstall(NavbarInstallless); -Navbar.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { +Navbar.register = (componentMap: Record, propsResolverMap: Record, + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext) => { componentMap[NAVBAR_REGISTERED_NAME] = Navbar; - propsResolverMap[NAVBAR_REGISTERED_NAME] = propsResolver; + propsResolverMap[NAVBAR_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; -Navbar.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { +Navbar.registerDesigner = (componentMap: Record, propsResolverMap: Record, + configresolverMap: Record, registerContext: RegisterContext) => { componentMap[NAVBAR_REGISTERED_NAME] = NavbarDesign; - propsResolverMap[NAVBAR_REGISTERED_NAME] = propsResolver; + propsResolverMap[NAVBAR_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; export { Navbar }; export default Navbar; 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 bd3add9711b..33e9db98dfc 100644 --- a/packages/mobile-ui-vue/components/navbar/src/navbar.props.ts +++ b/packages/mobile-ui-vue/components/navbar/src/navbar.props.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { ExtractPropTypes } from 'vue'; -import { createPropsResolver } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '../../dynamic-resolver'; import navbarSchema from './schema/navbar.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; @@ -45,7 +45,7 @@ export const navbarProps = { } }; -export const propsResolver = createPropsResolver( +export const propsResolverGenerator = getPropsResolverGenerator( navbarProps, navbarSchema, schemaMapper, 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 index 4a06ab6f5e7..1edbadd507b 100644 --- a/packages/mobile-ui-vue/components/navbar/src/schema/navbar.schema.json +++ b/packages/mobile-ui-vue/components/navbar/src/schema/navbar.schema.json @@ -1,7 +1,7 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://farris-design.gitee.io/navbar.schema.json", - "title": "navigation-bar", + "title": "navbar", "description": "页面导航组件", "type": "object", "properties": { 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 7d141367928..7d4ff284dae 100644 --- a/packages/mobile-ui-vue/components/page-body-container/index.ts +++ b/packages/mobile-ui-vue/components/page-body-container/index.ts @@ -14,22 +14,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { withInstall } from '@components/common'; +import { RegisterContext, withInstall } from '@components/common'; import PageBodyContainerInstallless from './src/page-body-container.component'; import PageBodyContainerDesign from './src/designer/page-body-container.design.component'; -import { propsResolver } from './src/page-body-container.props'; +import { propsResolverGenerator } from './src/page-body-container.props'; const PAGE_BODY_CONTAINER_REGISTER_NAME = 'page-body-container'; const PageBodyContainer = withInstall(PageBodyContainerInstallless); -PageBodyContainer.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void => { +PageBodyContainer.register = (componentMap: Record, propsResolverMap: Record, + configresolverMap: Record,registerContext: RegisterContext): void => { componentMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = PageBodyContainer; - propsResolverMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = propsResolver; + propsResolverMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = propsResolverGenerator(registerContext); }; -PageBodyContainer.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record): void => { +PageBodyContainer.registerDesigner = (componentMap: Record, propsResolverMap: Record, + configresolverMap: Record,registerContext: RegisterContext): void => { componentMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = PageBodyContainerDesign; - propsResolverMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = propsResolver; + propsResolverMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = propsResolverGenerator(registerContext); }; export * from './src/page-body-container.props'; diff --git a/packages/mobile-ui-vue/components/page-body-container/src/page-body-container.props.ts b/packages/mobile-ui-vue/components/page-body-container/src/page-body-container.props.ts index 4a4089bf75c..6c98c831eb5 100644 --- a/packages/mobile-ui-vue/components/page-body-container/src/page-body-container.props.ts +++ b/packages/mobile-ui-vue/components/page-body-container/src/page-body-container.props.ts @@ -1,5 +1,5 @@ import { ExtractPropTypes } from 'vue'; -import { createPropsResolver } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '../../dynamic-resolver'; import { schemaMapper } from './schema/schema-mapper'; import pageBodyContainerSchema from './schema/page-body-container.schema.json'; import { schemaResolver } from './schema/schema-resolver'; @@ -12,7 +12,7 @@ export const pageBodyContainerProps = { export type PageBodyContainerProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( +export const propsResolverGenerator = getPropsResolverGenerator( pageBodyContainerProps, pageBodyContainerSchema, schemaMapper, diff --git a/packages/mobile-ui-vue/components/page-container/index.ts b/packages/mobile-ui-vue/components/page-container/index.ts index 4438af465e2..9fa20b8158b 100644 --- a/packages/mobile-ui-vue/components/page-container/index.ts +++ b/packages/mobile-ui-vue/components/page-container/index.ts @@ -14,26 +14,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { withInstall } from '@components/common'; +import { RegisterContext, withInstall } from '@components/common'; import PageContainerInstallless from './src/page-container.component'; import PageContainerDesign from './src/designer/page-container.design.component'; -import { propsResolver } from './src/page-container.props'; +import { propsResolverGenerator } from './src/page-container.props'; const PAGE_CONTAINER_REGISTERED_NAME = 'page-container'; const PageContainer = withInstall(PageContainerInstallless); PageContainer.register = ( - componentMap: Record, propsResolverMap: Record, configResolverMap: Record + componentMap: Record, propsResolverMap: Record, + configresolverMap: Record,registerContext: RegisterContext ): void => { componentMap[PAGE_CONTAINER_REGISTERED_NAME] = PageContainer; - propsResolverMap[PAGE_CONTAINER_REGISTERED_NAME] = propsResolver; + propsResolverMap[PAGE_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; PageContainer.registerDesigner = ( - componentMap: Record, propsResolverMap: Record, configResolverMap: Record + componentMap: Record, propsResolverMap: Record, + configresolverMap: Record,registerContext: RegisterContext ): void => { componentMap[PAGE_CONTAINER_REGISTERED_NAME] = PageContainerDesign; - propsResolverMap[PAGE_CONTAINER_REGISTERED_NAME] = propsResolver; + propsResolverMap[PAGE_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; export * from './src/page-container.props'; diff --git a/packages/mobile-ui-vue/components/page-container/src/page-container.props.ts b/packages/mobile-ui-vue/components/page-container/src/page-container.props.ts index c7a084830eb..fb3003a9af1 100644 --- a/packages/mobile-ui-vue/components/page-container/src/page-container.props.ts +++ b/packages/mobile-ui-vue/components/page-container/src/page-container.props.ts @@ -1,5 +1,5 @@ import { ExtractPropTypes } from 'vue'; -import { createPropsResolver } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '../../dynamic-resolver'; import { schemaMapper } from './schema/schema-mapper'; import pageContainerSchema from './schema/page-container.schema.json'; import { schemaResolver } from './schema/schema-resolver'; @@ -12,7 +12,7 @@ export const pageContainerProps = { export type PageContainerProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( +export const propsResolverGenerator = getPropsResolverGenerator( pageContainerProps, pageContainerSchema, schemaMapper, diff --git a/packages/mobile-ui-vue/components/page-container/src/page-container.scss b/packages/mobile-ui-vue/components/page-container/src/page-container.scss index cfc7bc5443e..36231eade9a 100644 --- a/packages/mobile-ui-vue/components/page-container/src/page-container.scss +++ b/packages/mobile-ui-vue/components/page-container/src/page-container.scss @@ -10,4 +10,17 @@ right: 0; bottom: 0; left: 0; +} + +.fm-page-container .drag-container { + display: inherit; + flex-direction: inherit; + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0%; + flex-wrap: inherit; + justify-content: inherit; + align-items: inherit; + width: 100%; + overflow: inherit } \ No newline at end of file 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 e8cec7710ae..4f092e91b30 100644 --- a/packages/mobile-ui-vue/components/page-footer-container/index.ts +++ b/packages/mobile-ui-vue/components/page-footer-container/index.ts @@ -14,28 +14,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { withInstall } from '@components/common'; +import { RegisterContext, withInstall } from '@components/common'; import PageFooterContainerInstallless from './src/page-footer-container.component'; import PageFooterContainerDesign from './src/designer/page-footer-container.design.component'; -import { propsResolver } from './src/page-footer-container.props'; +import { propsResolverGenerator } from './src/page-footer-container.props'; const COMPONENT_TYPE = 'page-footer-container'; const PageFooterContainer = withInstall(PageFooterContainerInstallless); PageFooterContainer.register = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record + configresolverMap: Record,registerContext: RegisterContext ): void => { componentMap[COMPONENT_TYPE] = PageFooterContainer; - propsResolverMap[COMPONENT_TYPE] = propsResolver; + propsResolverMap[COMPONENT_TYPE] = propsResolverGenerator(registerContext); }; PageFooterContainer.registerDesigner = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record + configresolverMap: Record,registerContext: RegisterContext ): void => { componentMap[COMPONENT_TYPE] = PageFooterContainerDesign; - propsResolverMap[COMPONENT_TYPE] = propsResolver; + propsResolverMap[COMPONENT_TYPE] = propsResolverGenerator(registerContext); }; export * from './src/page-footer-container.props'; diff --git a/packages/mobile-ui-vue/components/page-footer-container/src/page-footer-container.props.ts b/packages/mobile-ui-vue/components/page-footer-container/src/page-footer-container.props.ts index 79bc601420a..4b16652f2d6 100644 --- a/packages/mobile-ui-vue/components/page-footer-container/src/page-footer-container.props.ts +++ b/packages/mobile-ui-vue/components/page-footer-container/src/page-footer-container.props.ts @@ -1,5 +1,5 @@ import { ExtractPropTypes } from 'vue'; -import { createPropsResolver } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '../../dynamic-resolver'; import { schemaMapper } from './schema/schema-mapper'; import pageFooterContainerSchema from './schema/page-footer-container.schema.json'; import { schemaResolver } from './schema/schema-resolver'; @@ -12,7 +12,7 @@ export const pageFooterContainerProps = { export type PageFooterContainerProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( +export const propsResolverGenerator = getPropsResolverGenerator( pageFooterContainerProps, pageFooterContainerSchema, schemaMapper, 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 1a36319a7ec..aaa69ded1db 100644 --- a/packages/mobile-ui-vue/components/page-header-container/index.ts +++ b/packages/mobile-ui-vue/components/page-header-container/index.ts @@ -14,27 +14,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { withInstall } from '@components/common'; +import { RegisterContext, withInstall } from '@components/common'; import PageHeaderContainerInstallless from './src/page-header-container.component'; import PageHeaderContainerDesign from './src/designer/page-header-container.design.component'; -import { propsResolver } from './src/page-header-container.props'; +import { propsResolverGenerator } from './src/page-header-container.props'; const PAGE_HEADER_CONTAINER_REGISTERED_NAME = 'page-header-container'; const PageHeaderContainer = withInstall(PageHeaderContainerInstallless); PageHeaderContainer.register = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record + configresolverMap: Record,registerContext: RegisterContext ): void => { componentMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = PageHeaderContainer; - propsResolverMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = propsResolver; + propsResolverMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; PageHeaderContainer.registerDesigner = ( - componentMap: Record, propsResolverMap: Record, configResolverMap: Record + componentMap: Record, propsResolverMap: Record, + configresolverMap: Record,registerContext: RegisterContext ): void => { componentMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = PageHeaderContainerDesign; - propsResolverMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = propsResolver; + propsResolverMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; export * from './src/page-header-container.props'; diff --git a/packages/mobile-ui-vue/components/page-header-container/src/page-header-container.props.ts b/packages/mobile-ui-vue/components/page-header-container/src/page-header-container.props.ts index 15901f23a8d..8b7ab403b1d 100644 --- a/packages/mobile-ui-vue/components/page-header-container/src/page-header-container.props.ts +++ b/packages/mobile-ui-vue/components/page-header-container/src/page-header-container.props.ts @@ -1,5 +1,5 @@ import { ExtractPropTypes } from 'vue'; -import { createPropsResolver } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '../../dynamic-resolver'; import { schemaMapper } from './schema/schema-mapper'; import pageHeaderContainerSchema from './schema/page-header-container.schema.json'; import { schemaResolver } from './schema/schema-resolver'; @@ -12,7 +12,7 @@ export const pageHeaderContainerProps = { export type PageHeaderContainerProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( +export const propsResolverGenerator = getPropsResolverGenerator( pageHeaderContainerProps, pageHeaderContainerSchema, schemaMapper, diff --git a/packages/mobile-ui-vue/components/picker-input/index.ts b/packages/mobile-ui-vue/components/picker-input/index.ts index 02d38dfc325..899d6578d08 100644 --- a/packages/mobile-ui-vue/components/picker-input/index.ts +++ b/packages/mobile-ui-vue/components/picker-input/index.ts @@ -1,6 +1,6 @@ -import { withInstall } from '@components/common'; +import { RegisterContext, withInstall } from '@components/common'; import PickerInputInstallless from "./src/picker-input.component"; -import { propsResolver } from './src/picker-input.props'; +import { propsResolverGenerator } from './src/picker-input.props'; import EnumFieldInputDesign from './src/designer/enum-field-input.design.component'; export * from './src/picker-input.props'; @@ -11,13 +11,15 @@ const ENUM_FIELD_REGISTERED_NAME = 'enum-field'; const PickerInput = withInstall(PickerInputInstallless); -PickerInput.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { +PickerInput.register = (componentMap: Record, propsResolverMap: Record, + configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext) => { componentMap[ENUM_FIELD_REGISTERED_NAME] = PickerInput; - propsResolverMap[ENUM_FIELD_REGISTERED_NAME] = propsResolver; + propsResolverMap[ENUM_FIELD_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; -PickerInput.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record) => { +PickerInput.registerDesigner = (componentMap: Record, propsResolverMap: Record, + configresolverMap: Record,registerContext: RegisterContext) => { componentMap[ENUM_FIELD_REGISTERED_NAME] = EnumFieldInputDesign; - propsResolverMap[ENUM_FIELD_REGISTERED_NAME] = propsResolver; + propsResolverMap[ENUM_FIELD_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; 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..0dcaefd1389 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 @@ -1,7 +1,7 @@ import { ExtractPropTypes } from 'vue'; import { buttonEditProps } from '@/components/button-edit'; import { pickerProps } from '@/components/picker'; -import { createPropsResolver } from '@/components/dynamic-resolver'; +import { getPropsResolverGenerator } 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'; @@ -15,4 +15,4 @@ export const pickerInputProps = { export type PickerInputProps = ExtractPropTypes; -export const propsResolver = createPropsResolver(pickerInputProps, inputSchema, schemaMapper, schemaResolver); +export const propsResolverGenerator = getPropsResolverGenerator(pickerInputProps, inputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/radio-group/index.ts b/packages/mobile-ui-vue/components/radio-group/index.ts index 4c196194195..0d03a93a00c 100644 --- a/packages/mobile-ui-vue/components/radio-group/index.ts +++ b/packages/mobile-ui-vue/components/radio-group/index.ts @@ -1,6 +1,6 @@ -import { withInstall } from '@components/common'; +import { RegisterContext, withInstall } from '@components/common'; import RadioGroupInstallless from './src/radio-group.component'; -import { propsResolver } from './src/radio-group.props'; +import { propsResolverGenerator } from './src/radio-group.props'; import RadioGroupDesign from './src/designer/radio-group.design.component'; export * from './src/radio-group.props'; @@ -9,13 +9,15 @@ const RADIO_GROUP_REGISTERED_NAME = 'radio-group'; const RadioGroup = withInstall(RadioGroupInstallless); -RadioGroup.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { +RadioGroup.register = (componentMap: Record, propsResolverMap: Record, + configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext) => { componentMap[RADIO_GROUP_REGISTERED_NAME] = RadioGroup; - propsResolverMap[RADIO_GROUP_REGISTERED_NAME] = propsResolver; + propsResolverMap[RADIO_GROUP_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; -RadioGroup.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record) => { +RadioGroup.registerDesigner = (componentMap: Record, propsResolverMap: Record, + configresolverMap: Record,registerContext: RegisterContext) => { componentMap[RADIO_GROUP_REGISTERED_NAME] = RadioGroupDesign; - propsResolverMap[RADIO_GROUP_REGISTERED_NAME] = propsResolver; + propsResolverMap[RADIO_GROUP_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; diff --git a/packages/mobile-ui-vue/components/radio-group/src/radio-group.props.ts b/packages/mobile-ui-vue/components/radio-group/src/radio-group.props.ts index f246ce170f2..bd3ed6e0a75 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/radio-group.props.ts +++ b/packages/mobile-ui-vue/components/radio-group/src/radio-group.props.ts @@ -1,7 +1,7 @@ import { ExtractPropTypes, PropType } from 'vue'; import {CheckerShape, CheckerShapeMap } from '@components/checker'; import { CheckboxGroupContext, checkboxGroupProps } from '@components/checkbox-group'; -import { createPropsResolver } from '@/components/dynamic-resolver'; +import { getPropsResolverGenerator } from '@/components/dynamic-resolver'; import inputSchema from './schema/radio-group.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; @@ -24,4 +24,4 @@ type Merge = { export type RadioGroupContext = Merge void }>; -export const propsResolver = createPropsResolver(radioGroupProps, inputSchema, schemaMapper, schemaResolver); +export const propsResolverGenerator = getPropsResolverGenerator(radioGroupProps, inputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/register-designer.ts b/packages/mobile-ui-vue/components/register-designer.ts new file mode 100644 index 00000000000..2f21751e448 --- /dev/null +++ b/packages/mobile-ui-vue/components/register-designer.ts @@ -0,0 +1,31 @@ +import { RegisterContext } from "./common"; +import { propertyConfigSchemaMapForDesigner, schemaMapForDesigner, schemaResolverMapForDesigner } from "./dynamic-resolver"; +import { propertyEffectMapForDesigner } from "./dynamic-resolver/src/resolver/property-config/property-config-resolver-design"; + +const componentMap: Record = {}; +const componentPropsConverter: Record = {}; +const componentPropertyConfigConverter: Record = {}; + +let componentsRegistered = false; +/** + * 加载设计时组件 + */ +function registerDesignerComponents(components: any[]) { + if (componentsRegistered) { + return; + } + + componentsRegistered = true; + const registerContext:RegisterContext = { + schemaMap: schemaMapForDesigner, + propertyConfigSchemaMap: propertyConfigSchemaMapForDesigner, + propertyEffectMap: propertyEffectMapForDesigner, + schemaResolverMap: schemaResolverMapForDesigner + }; + + components.forEach(component => { + component.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter, registerContext); + }); +} + +export { registerDesignerComponents }; diff --git a/packages/mobile-ui-vue/components/switch/index.ts b/packages/mobile-ui-vue/components/switch/index.ts index bd7a3b611a2..fe512ef5502 100644 --- a/packages/mobile-ui-vue/components/switch/index.ts +++ b/packages/mobile-ui-vue/components/switch/index.ts @@ -1,7 +1,7 @@ -import { withInstall } from '@components/common'; +import { RegisterContext, withInstall } from '@components/common'; import SwitchInstallless from "./src/switch.component"; import SwitchDesign from './src/designer/switch.design.component'; -import { propsResolver } from './src/switch.props'; +import { propsResolverGenerator } from './src/switch.props'; export * from './src/switch.props'; @@ -12,18 +12,18 @@ const Switch = withInstall(SwitchInstallless); Switch.register = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext ) => { componentMap[SWITCH_REGISTERED_NAME] = Switch; - propsResolverMap[SWITCH_REGISTERED_NAME] = propsResolver; + propsResolverMap[SWITCH_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; Switch.registerDesigner = ( componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record + configresolverMap: Record,registerContext: RegisterContext ) => { componentMap[SWITCH_REGISTERED_NAME] = SwitchDesign; - propsResolverMap[SWITCH_REGISTERED_NAME] = propsResolver; + propsResolverMap[SWITCH_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; export { Switch }; diff --git a/packages/mobile-ui-vue/components/switch/src/switch.props.ts b/packages/mobile-ui-vue/components/switch/src/switch.props.ts index d208781ec45..f3f001985cd 100644 --- a/packages/mobile-ui-vue/components/switch/src/switch.props.ts +++ b/packages/mobile-ui-vue/components/switch/src/switch.props.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { createPropsResolver } from '@/components/dynamic-resolver'; +import { getPropsResolverGenerator } from '@/components/dynamic-resolver'; import { ExtractPropTypes } from 'vue'; import switchSchema from './schema/switch.schema.json'; import { schemaMapper } from './schema/schema-mapper'; @@ -41,7 +41,7 @@ export const switchProps = { export type SwitchProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( +export const propsResolverGenerator = getPropsResolverGenerator( switchProps, switchSchema, schemaMapper, diff --git a/packages/mobile-ui-vue/components/textarea/index.ts b/packages/mobile-ui-vue/components/textarea/index.ts index b41ca39b337..1075596d651 100644 --- a/packages/mobile-ui-vue/components/textarea/index.ts +++ b/packages/mobile-ui-vue/components/textarea/index.ts @@ -1,7 +1,7 @@ -import { withInstall } from '@components/common'; +import { RegisterContext, withInstall } from '@components/common'; import TextareaInstallless from './src/textarea.component'; import TextareaDesign from './src/designer/textarea.design.component'; -import { propsResolver } from './src/textarea.props'; +import { propsResolverGenerator } from './src/textarea.props'; export * from './src/textarea.props'; @@ -9,13 +9,15 @@ const TEXTAREA_REGISTERED_NAME = 'textarea'; const Textarea = withInstall(TextareaInstallless); -Textarea.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { +Textarea.register = (componentMap: Record, propsResolverMap: Record, + configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext) => { componentMap[TEXTAREA_REGISTERED_NAME] = Textarea; - propsResolverMap[TEXTAREA_REGISTERED_NAME] = propsResolver; + propsResolverMap[TEXTAREA_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; -Textarea.registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record) => { +Textarea.registerDesigner = (componentMap: Record, propsResolverMap: Record, + configresolverMap: Record,registerContext: RegisterContext) => { componentMap[TEXTAREA_REGISTERED_NAME] = TextareaDesign; - propsResolverMap[TEXTAREA_REGISTERED_NAME] = propsResolver; + propsResolverMap[TEXTAREA_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; 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..0e13b5750a5 100644 --- a/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts +++ b/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts @@ -1,6 +1,6 @@ import { ExtractPropTypes } from 'vue'; import { inputCommonProps } from '@/components/input-group'; -import { createPropsResolver } from '@/components/dynamic-resolver'; +import { getPropsResolverGenerator } from '@/components/dynamic-resolver'; import textareaSchema from './schema/input.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; @@ -23,4 +23,4 @@ export const textareaProps = { export type TextareaProps = ExtractPropTypes; -export const propsResolver = createPropsResolver(textareaProps, textareaSchema, schemaMapper, schemaResolver); +export const propsResolverGenerator = getPropsResolverGenerator(textareaProps, textareaSchema, schemaMapper, schemaResolver); diff --git a/packages/ui-vue/components/common/types.ts b/packages/ui-vue/components/common/types.ts index 147885f34ad..6db6011a56d 100644 --- a/packages/ui-vue/components/common/types.ts +++ b/packages/ui-vue/components/common/types.ts @@ -1,4 +1,5 @@ import { ComputedRef, Ref } from "vue"; +import { EffectFunction, SchemaResolverFunction } from "../dynamic-resolver"; export interface TextBoxProps { @@ -134,3 +135,10 @@ export type TimeAgoOptions = { export interface UseTimeAgoFormat { formatTo(date: TimeAgoDate, opts?: TimeAgoOptions): string } + +export interface RegisterContext { + schemaMap: Record; + schemaResolverMap: Record; + propertyConfigSchemaMap: Record; + propertyEffectMap: Record; +} \ No newline at end of file diff --git a/packages/ui-vue/components/designer-canvas/src/components/maps.ts b/packages/ui-vue/components/designer-canvas/src/components/maps.ts index 966dd0c7170..66f61bb31ce 100644 --- a/packages/ui-vue/components/designer-canvas/src/components/maps.ts +++ b/packages/ui-vue/components/designer-canvas/src/components/maps.ts @@ -56,6 +56,9 @@ import FTreeGrid from '@farris/ui-vue/components/tree-grid'; import FFieldset from '@farris/ui-vue/components/fieldset'; import FDrawer from '@farris/ui-vue/components/drawer'; import FHtmlTemplate from '@farris/ui-vue/components/html-template'; +import { RegisterContext } from '@farris/ui-vue/components/common'; +import { propertyConfigSchemaMapForDesigner, propertyEffectMapForDesigner } from '@farris/ui-vue/components/dynamic-resolver'; +import { schemaMapForDesigner, schemaResolverMapForDesigner } from '@farris/ui-vue/components/dynamic-resolver'; const componentMap: Record = {}; const componentPropsConverter: Record = {}; @@ -64,7 +67,7 @@ const componentPropertyConfigConverter: Record = {}; let hasLoaded = false; /** - * 加载设计时组件 + * 加载设计时组件,后续移除该方法,通过registerDesignerComponents注册组件 */ function loadDesignerRegister() { if (!hasLoaded) { @@ -131,4 +134,26 @@ function loadDesignerRegister() { } } -export { componentMap, componentPropsConverter, componentPropertyConfigConverter, loadDesignerRegister }; +/** + * 加载设计时组件 + */ +function registerDesignerComponents(components: any[]) { + if (hasLoaded) { + return; + } + + hasLoaded = true; + const registerContext:RegisterContext = { + schemaMap: schemaMapForDesigner, + propertyConfigSchemaMap: propertyConfigSchemaMapForDesigner, + propertyEffectMap: propertyEffectMapForDesigner, + schemaResolverMap: schemaResolverMapForDesigner + }; + + components.forEach(component => { + component.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter, registerContext); + }); +} + + +export { componentMap, componentPropsConverter, componentPropertyConfigConverter, loadDesignerRegister, registerDesignerComponents }; diff --git a/packages/ui-vue/components/designer-canvas/src/composition/class/designer-canvas.css b/packages/ui-vue/components/designer-canvas/src/composition/class/designer-canvas.css index 2beb6bb539f..23774c829d2 100644 --- a/packages/ui-vue/components/designer-canvas/src/composition/class/designer-canvas.css +++ b/packages/ui-vue/components/designer-canvas/src/composition/class/designer-canvas.css @@ -182,6 +182,14 @@ min-width: 900px; } +/* 移动画布样式 */ +.editorDiv .editorPanel.Mobile { + min-width: 414px; + width: 414px; + margin: 20px auto; + height: calc(100% - 40px); +} + /** 卡片区块 **/ .editorDiv .f-struct-like-card { display: block; diff --git a/packages/ui-vue/components/designer-canvas/src/composition/function/use-designer-component.ts b/packages/ui-vue/components/designer-canvas/src/composition/function/use-designer-component.ts index 63499e437ba..c3f65f3bafd 100644 --- a/packages/ui-vue/components/designer-canvas/src/composition/function/use-designer-component.ts +++ b/packages/ui-vue/components/designer-canvas/src/composition/function/use-designer-component.ts @@ -1,7 +1,7 @@ import { Ref, ref } from "vue"; import { DesignerHostService, DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../types"; import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from "../../types"; -import { getSchemaByType } from '../../../../dynamic-resolver/src/schema-resolver'; +import { getSchemaByTypeForDesigner } from '@farris/ui-vue/components/dynamic-resolver'; export function useDesignerComponent( elementRef: Ref, @@ -131,7 +131,7 @@ export function useDesignerComponent( */ function addNewChildComponentSchema(resolveContext: DraggingResolveContext, designerHostService: DesignerHostService) { const { componentType } = resolveContext; - let componentSchema = getSchemaByType(componentType, resolveContext, designerHostService) as ComponentSchema; + let componentSchema = getSchemaByTypeForDesigner(componentType, resolveContext, designerHostService) as ComponentSchema; if (designerRules && designerRules.onResolveNewComponentSchema) { componentSchema = designerRules.onResolveNewComponentSchema(resolveContext, componentSchema); } diff --git a/packages/ui-vue/components/designer-canvas/src/composition/function/use-designer-inner-component.ts b/packages/ui-vue/components/designer-canvas/src/composition/function/use-designer-inner-component.ts index 07336537dc9..c4985249537 100644 --- a/packages/ui-vue/components/designer-canvas/src/composition/function/use-designer-inner-component.ts +++ b/packages/ui-vue/components/designer-canvas/src/composition/function/use-designer-inner-component.ts @@ -1,7 +1,7 @@ import { inject, Ref, ref } from "vue"; import { DesignerHostService, DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../types"; import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from "../../types"; -import { getSchemaByType } from '../../../../dynamic-resolver/src/schema-resolver'; +import { getSchemaByTypeForDesigner } from '@farris/ui-vue/components/dynamic-resolver'; export function useDesignerInnerComponent( elementRef: Ref, @@ -123,7 +123,7 @@ export function useDesignerInnerComponent( function addNewChildComponentSchema(resolveContext: DraggingResolveContext) { const { componentType } = resolveContext; const designerHostServer = inject('designer-host-service') as DesignerHostService; - let componentSchema = getSchemaByType(componentType, resolveContext, designerHostServer) as ComponentSchema; + let componentSchema = getSchemaByTypeForDesigner(componentType, resolveContext, designerHostServer) as ComponentSchema; if (designerRules && designerRules.onResolveNewComponentSchema) { componentSchema = designerRules.onResolveNewComponentSchema(resolveContext, componentSchema); } diff --git a/packages/ui-vue/components/designer-canvas/src/composition/props/designer-canvas.props.ts b/packages/ui-vue/components/designer-canvas/src/composition/props/designer-canvas.props.ts index ab5965b8ccc..13d2a86ecb1 100644 --- a/packages/ui-vue/components/designer-canvas/src/composition/props/designer-canvas.props.ts +++ b/packages/ui-vue/components/designer-canvas/src/composition/props/designer-canvas.props.ts @@ -6,6 +6,9 @@ export const designerCanvasProps = { */ modelValue: { type: Object, default: {} }, componentId: { type: String, default: '' }, + components:{ type: Array }, + canvasMode:{ type: String, default: 'PC' }, + } as Record; export type DesignerCanvasPropsType = ExtractPropTypes; diff --git a/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx b/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx index f51372a3c5f..b57a64585f2 100644 --- a/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx +++ b/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx @@ -8,7 +8,7 @@ import { DesignerHostService, UseDragula } from './composition/types'; import FDesignerItem from './components/designer-item.component'; import './composition/class/designer-canvas.css'; import './composition/class/control.css'; -import { loadDesignerRegister } from './components/maps'; +import { loadDesignerRegister, registerDesignerComponents } from './components/maps'; import { F_MODAL_SERVICE_TOKEN } from '../../modal'; import { canvasKey, refreshCanvas } from './composition/update-cancas'; @@ -24,6 +24,8 @@ export default defineComponent({ const designerItemElementRef = ref(); const componentInstance = ref(); const componentId = ref(props.componentId); + const { canvasMode } = props; + let resizeObserver: ResizeObserver | null; let resizeObserverTimer; @@ -44,7 +46,13 @@ export default defineComponent({ const useDragulaComposition = useDragula(designerHostService); - loadDesignerRegister(); + // 后需统一采用registerDesignerComponents注册控件 + if (props.components) { + registerDesignerComponents(props.components); + } else { + loadDesignerRegister(); + } + provide('canvas-dragula', useDragulaComposition); provide('design-item-context', { designerItemElementRef, @@ -62,6 +70,24 @@ export default defineComponent({ return classObject; }); + const designerEditorPanelClass = computed(() => { + const classObject = { + 'editorPanel': true, + 'd-flex': true, + 'flex-fill': true, + 'flex-column': true, + [canvasMode]: true + } as Record; + return classObject; + }); + + + watch([() => props.modelValue, () => props.componentId], + ([newSchema, newComponentId]) => { + schema.value = newSchema; + componentId.value = newComponentId; + } + ) watch(canvasChanged, () => { setPositionOfButtonGroupInContainer(designerCanvasElementRef.value); @@ -120,7 +146,7 @@ export default defineComponent({ return () => { return (
    -
    +
    {schema.value && }
    diff --git a/packages/ui-vue/components/designer-outline/src/composition/use-data-view.ts b/packages/ui-vue/components/designer-outline/src/composition/use-data-view.ts index d9674219f62..205143ae5af 100644 --- a/packages/ui-vue/components/designer-outline/src/composition/use-data-view.ts +++ b/packages/ui-vue/components/designer-outline/src/composition/use-data-view.ts @@ -16,26 +16,26 @@ export function useDataView( const { getIcon, getTitle } = useOutlineNodeComposition; /** 处理子组件 */ - function handleChildComponent(componentsItem: any, findComponents: any, number: number, parentComponent: any) { + function handleChildComponent(componentsItem: any, findComponents: any, number: number, parentComponent: any, componentId: string) { const childComponentItem = props.data.module?.components.find((component: any) => component.id === componentsItem.component); if (childComponentItem) { - handleInputData([childComponentItem], findComponents, number, parentComponent, null); + handleInputData([childComponentItem], findComponents, number, parentComponent, componentId); } } /** 处理数据 */ - function handleInputData(components: any, findComponents: any, number: number, parentComponent: any, parentNode: any) { + function handleInputData(components: any, findComponents: any, number: number, parentComponent: any, componentId: string) { components.forEach((componentsItem: any) => { if (componentsItem.type === 'component-ref') { - handleChildComponent(componentsItem, findComponents, number, parentComponent); + handleChildComponent(componentsItem, findComponents, number, parentComponent, componentId); return; } const findComponentsItem = { originalId: componentsItem.id, layer: number, originalParent: parentComponent?.id, - parentNode: parentNode, + componentId: componentId, name: getTitle(componentsItem, parentComponent), type: componentsItem.type, controlIcon: getIcon(componentsItem), @@ -44,7 +44,7 @@ export function useDataView( findComponents.push(cloneDeep(findComponentsItem)); if (componentsItem.contents || componentsItem.buttons) { - handleInputData(componentsItem.contents || componentsItem.buttons, findComponents, number + 1, componentsItem, findComponentsItem); + handleInputData(componentsItem.contents || componentsItem.buttons, findComponents, number + 1, componentsItem, componentId); } }); return findComponents; @@ -110,7 +110,6 @@ export function useDataView( const appendInputDatas: any[] = []; inputDatas.forEach((inputData: any) => { inputData[0].originalParent = frameNode.originalId; - inputData[0].parentNode = frameNode; appendInputDatas.push(...inputData); }); @@ -132,7 +131,7 @@ export function useDataView( components.push(component); const number = 1; const findComponents: any = []; - const inputData = handleInputData(components, findComponents, number, null, null); + const inputData = handleInputData(components, findComponents, number, null, component.id); inputDatas.push(inputData); } }); diff --git a/packages/ui-vue/components/designer-toolbox/src/toolbox.component.tsx b/packages/ui-vue/components/designer-toolbox/src/toolbox.component.tsx index df043bb56a2..807fefdf6f3 100644 --- a/packages/ui-vue/components/designer-toolbox/src/toolbox.component.tsx +++ b/packages/ui-vue/components/designer-toolbox/src/toolbox.component.tsx @@ -2,7 +2,6 @@ import { defineComponent, ref, watch } from 'vue'; import { ToolboxPropsType, toolboxProps } from './toolbox.props'; import { ToolboxCategory, ToolboxItem } from './types'; -import toolboxItems from './toolbox.json'; import './toolbox.css'; export default defineComponent({ @@ -10,7 +9,7 @@ export default defineComponent({ props: toolboxProps, emits: [], setup(props: ToolboxPropsType) { - const controlCategoryList = ref(props.toolboxItems ? props.toolboxItems : toolboxItems); + const controlCategoryList = ref(props.toolboxItems); const dragularCompostion = ref(props.dragula); function onClickCardHeader(payload: MouseEvent, category: any) { diff --git a/packages/ui-vue/components/designer-toolbox/src/toolbox.props.ts b/packages/ui-vue/components/designer-toolbox/src/toolbox.props.ts index e7f2b92e07f..3ca6647825c 100644 --- a/packages/ui-vue/components/designer-toolbox/src/toolbox.props.ts +++ b/packages/ui-vue/components/designer-toolbox/src/toolbox.props.ts @@ -4,7 +4,7 @@ import { ToolboxCategory } from './types'; export const toolboxProps = { id: { type: String, default: '' }, dragula: { type: Object }, - toolboxItems: { type: Array } + toolboxItems: { type: Array, default: [] } }; export type ToolboxPropsType = ExtractPropTypes; diff --git a/packages/ui-vue/components/dynamic-form/src/designer/form-group.design.component.tsx b/packages/ui-vue/components/dynamic-form/src/designer/form-group.design.component.tsx index e793a606f28..f0354778366 100644 --- a/packages/ui-vue/components/dynamic-form/src/designer/form-group.design.component.tsx +++ b/packages/ui-vue/components/dynamic-form/src/designer/form-group.design.component.tsx @@ -4,7 +4,7 @@ import { DynamicFormGroupPropsType, dynamicFormGroupProps } from '../component/d import { DesignerItemContext } from '../../../designer-canvas/src/types'; import { useDesignerComponent } from '../../../designer-canvas/src/composition/function/use-designer-component'; import FDynamicFormGroupDesign from '../component/dynamic-form-group/dynamic-form-group.design.component'; -import { propertyConfigSchemaMap } from '../../../../components/dynamic-resolver/src/property-config-resolver'; +import { propertyConfigSchemaMapForDesigner } from '@farris/ui-vue/components/dynamic-resolver'; import { DesignerHostService } from '../../../../components/designer-canvas/src/composition/types'; import { useDesignerRulesForFormGroup } from './form-group-use-designer-rules'; @@ -23,7 +23,7 @@ export default defineComponent({ elementRef.value.componentInstance = componentInstance; componentInstance.value.getPropConfig = (...args) => { - let propertyConfigSchema = propertyConfigSchemaMap[props.editor.type]; + let propertyConfigSchema = propertyConfigSchemaMapForDesigner[props.editor.type]; if (propertyConfigSchema && Object.keys(propertyConfigSchema).length === 0 && elementRef.value?.editorRef && elementRef.value?.editorRef?.getPropConfig) { propertyConfigSchema = elementRef.value.editorRef.getPropConfig(...args, componentInstance.value); } diff --git a/packages/ui-vue/components/dynamic-form/src/designer/response-form-use-designer-rules.ts b/packages/ui-vue/components/dynamic-form/src/designer/response-form-use-designer-rules.ts index 0a6f2ab9dab..813778ed56f 100644 --- a/packages/ui-vue/components/dynamic-form/src/designer/response-form-use-designer-rules.ts +++ b/packages/ui-vue/components/dynamic-form/src/designer/response-form-use-designer-rules.ts @@ -1,7 +1,7 @@ import { DesignerHostService, DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../../../designer-canvas/src/composition/types"; import { useDragulaCommonRule } from "../../../designer-canvas/src/composition/rule/use-dragula-common-rule"; import { ComponentSchema, DesignerItemContext } from "../../../designer-canvas/src/types"; -import { getSchemaByType } from "../../../dynamic-resolver/src/schema-resolver"; +import { getSchemaByTypeForDesigner } from "@farris/ui-vue/components/dynamic-resolver"; import { UseTemplateDragAndDropRules } from "../../../designer-canvas/src/composition/rule/use-template-rule"; import { ResponseFormProperty } from "../property-config/response-form.property-config"; import { DgControl } from "../../../designer-canvas"; @@ -433,7 +433,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe const controlCreatorUtils = designerHostService?.controlCreatorUtils; formGroupElementSchema = controlCreatorUtils.setFormFieldProperty(resolveContext.bindingSourceContext?.entityFieldNode, componentSchema?.type); } else { - formGroupElementSchema = getSchemaByType('form-group') as ComponentSchema; + formGroupElementSchema = getSchemaByTypeForDesigner('form-group') as ComponentSchema; formGroupElementSchema.editor = componentSchema; formGroupElementSchema.label = label; } diff --git a/packages/ui-vue/components/dynamic-resolver/index.ts b/packages/ui-vue/components/dynamic-resolver/index.ts index 2500f1c640b..975ca9f8144 100644 --- a/packages/ui-vue/components/dynamic-resolver/index.ts +++ b/packages/ui-vue/components/dynamic-resolver/index.ts @@ -8,6 +8,9 @@ export * from './src/selection-item-resolver'; export * from './src/editor-resolver'; export * from './src/visible-prop-resolver'; export * from './src/event-handler-resolver'; -export * from './src/schema-resolver'; +export * from './src/resolver/schema/schema-resolver'; +export * from './src/resolver/schema/schema-resolver-design'; export * from './src/update-columns-resolver'; -export { propertyConfigSchemaMap } from './src/property-config-resolver'; +export { propertyConfigSchemaMap, propertyEffectMap } from './src/resolver/property-config/property-config-resolver'; +export { propertyConfigSchemaMapForDesigner, propertyEffectMapForDesigner } from './src/resolver/property-config/property-config-resolver-design'; + diff --git a/packages/ui-vue/components/dynamic-resolver/src/property-config-resolver.ts b/packages/ui-vue/components/dynamic-resolver/src/property-config-resolver.ts deleted file mode 100644 index e3d7db975b7..00000000000 --- a/packages/ui-vue/components/dynamic-resolver/src/property-config-resolver.ts +++ /dev/null @@ -1,246 +0,0 @@ -import { computed, ref } from "vue"; -import { EffectFunction, PropertyConverter, SchemaService } from './types'; -import { EditorConfig } from "../../dynamic-form"; -import { useObjectExpression } from './object-expression'; -import { ComponentSchema } from "../../designer-canvas/src/types"; -import { resolveSchemaWithDefaultValue } from "./schema-resolver"; -import appearanceConverter from './converter/appearance.converter'; -import buttonsConverter from "./converter/buttons.converter"; -import propertyEditorConverter from "./converter/property-editor.converter"; -import typeConverter from "./converter/type.converter"; -import changeEditorConverter from "./converter/change-editor.converter"; -import fieldSelectorConverter from "./converter/field-selector.converter"; -import paginationConverter from "./converter/pagination.converter"; -import rowNumberConverter from "./converter/row-number.converter"; -import gridSelectionConverter from "./converter/grid-selection.converter"; -import { ElementPropertyConfig, PropertyEntity } from "../../property-panel/src/composition/entity/property-entity"; -import itemsCountConverter from "./converter/items-count.converter"; -import formGroupLabelConverter from "./converter/form-group-label.converter"; - -const propertyConfigSchemaMap = {} as Record; -const propertyConverterMap = new Map([ - ['/converter/appearance.converter', appearanceConverter], - ['/converter/buttons.converter', buttonsConverter], - ['/converter/property-editor.converter', propertyEditorConverter], - ['/converter/items-count.converter', itemsCountConverter], - ['/converter/type.converter', typeConverter], - ['/converter/change-editor.converter', changeEditorConverter], - ['/converter/form-group-label.converter', formGroupLabelConverter], - ['/converter/field-selector.converter', fieldSelectorConverter], - ['/converter/pagination.converter', paginationConverter], - ['/converter/row-number.converter', rowNumberConverter], - ['/converter/grid-selection.converter', gridSelectionConverter] -]); -const propertyEffectMap = {} as Record; -const propertyEditorMap = new Map([ - ['string', { type: 'input-group', enableClear: false }], - ['boolean', { - "type": "combo-list", - "textField": "name", - "valueField": "value", - "idField": "value", - "enableClear": false, - "editable": false, - "maxHeight": 64, - "data": [ - { - "value": true, - "name": "是" - }, - { - "value": false, - "name": "否" - } - ] - }], - ['enum', { "type": "combo-list", "maxHeight": 128, "enableClear": false, "editable": false }], - ['array', { "type": "button-edit" }], - ['number', { "type": "number-spinner", "placeholder": "" }], - ['events-editor', { "type": "events-editor", hide: true }] -]); - -const useObjectExpressionComponstion = useObjectExpression(); - -function generateBooleanValue(pvalueSchema: Record, propertyConfigMap: Record) { - return () => useObjectExpressionComponstion.parseValueSchema(pvalueSchema, propertyConfigMap); -} - -function isVisible(propertySchemaKeys: string[], propertySchema: Record, propertyConfigMap: Record) - : boolean | (() => boolean) { - if (propertySchemaKeys.includes('visible') && propertySchema.visible !== undefined) { - return typeof propertySchema.visible === 'boolean' ? - () => Boolean(propertySchema.visible) : - propertySchema.visible === undefined ? true : generateBooleanValue(propertySchema.visible, propertyConfigMap); - } - return () => true; -} - -function isReadonly(propertySchemaKeys: string[], propertySchema: Record, propertyConfigMap: Record) { - if (propertySchemaKeys.includes('readonly') && propertySchema.readonly !== undefined) { - return typeof propertySchema.readonly === 'boolean' ? - () => Boolean(propertySchema.readonly) : - generateBooleanValue(propertySchema.readonly, propertyConfigMap); - } - return () => false; -} - -function tryGetPropertyConverter(propertySchema: Record, categoryConverter): PropertyConverter | null { - const $converter = propertySchema['$converter'] || categoryConverter; - if (typeof $converter === 'string') { - if ($converter && propertyConverterMap.has($converter)) { - return propertyConverterMap.get($converter) || null; - } - } - return $converter || null; -} - -/** - * - * @param propertiesInCategory - * 举例: - * visible: { - description: "运行时组件是否可见", - title: "是否可见", - type: "boolean" - } - 其中type属性 这个属性用来控制编辑器是哪一种,对应关系在propertyEditorMap中定义,boolean指定了下拉 - * @param propertyConfigMap - * @param editingSchema - * @param rawSchema - * @param schemaService - * @returns - */ -function getPropertyEntities( - propertiesInCategory: Record, - propertyConfigMap: Record, - editingSchema: ComponentSchema, - rawSchema: ComponentSchema, - schemaService: SchemaService, - componentId = '', - categoryConverter: any = '' -): PropertyEntity[] { - const propertyEntities = Object.keys(propertiesInCategory).map((propertyKey: string) => { - const updateCount = ref(1); - const propertyID = propertyKey; - const propertySchema = propertiesInCategory[propertyKey]; - const propertySchemaKeys = Object.keys(propertySchema); - const propertyName = propertySchema.title; - const propertyType = propertySchema.type; - const defaultEditor = propertyEditorMap.get(propertyType) || { type: 'input-group', enableClear: false }; - const editor = propertySchema.editor ? Object.assign({}, defaultEditor, propertySchema.editor) as EditorConfig : Object.assign({}, defaultEditor); - const visible = isVisible(propertySchemaKeys, propertySchema, propertyConfigMap); - const readonly = isReadonly(propertySchemaKeys, propertySchema, propertyConfigMap); - editor.readonly = editor.readonly === undefined ? readonly() : editor.readonly; - const cascadeConfig = propertySchema.type === 'cascade' ? getPropertyEntities(propertySchema.properties, propertyConfigMap, editingSchema, rawSchema, schemaService, componentId, categoryConverter) : []; - const hideCascadeTitle = true; - let converter = tryGetPropertyConverter(propertySchema, categoryConverter); - // const propertyValue = ref(converter ? converter.convertFrom(schema, propertyKey) : schema[propertyKey]); - const propertyValue = computed({ - get() { - if (updateCount.value) { - // class、style 统一处理 - if (['class', 'style'].find(id => id === propertyID) && !converter) { - converter = propertyConverterMap.get('/converter/appearance.converter') || null; - } - if (converter && converter.convertFrom) { - return converter.convertFrom(editingSchema, propertyKey, schemaService, componentId); - } - // 获取属性时,如果没有convertForm,并且通过在Schema上获取得值是空,那就获取defaultValue属性值或者是空 - const editingSchemaValue = editingSchema[propertyKey]; - return Object.prototype.hasOwnProperty.call(propertySchema, 'defaultValue') && (editingSchemaValue === undefined || typeof editingSchemaValue == 'string' && editingSchemaValue === '') ? propertySchema['defaultValue'] || '' : editingSchemaValue; - } - return null; - }, - set(newValue) { - updateCount.value += 1; - if (converter && converter.convertTo) { - converter.convertTo(rawSchema, propertyKey, newValue, schemaService, componentId); - converter.convertTo(editingSchema, propertyKey, newValue, schemaService, componentId); - } else { - rawSchema[propertyKey] = newValue; - editingSchema[propertyKey] = newValue; - } - } - }); - const { refreshPanelAfterChanged, description, isExpand } = propertySchema; - const propertyEntity = { propertyID, propertyName, propertyType, propertyValue, editor, visible, readonly, cascadeConfig, hideCascadeTitle, refreshPanelAfterChanged, description, isExpand }; - propertyConfigMap[propertyID] = propertyEntity; - return propertyEntity; - }); - return propertyEntities; -} - -function getPropertyConfigByType(schemaType: string, schemaService: SchemaService, schema = {} as ComponentSchema): ElementPropertyConfig[] { - const propertyConfigMap = {} as Record; - const propertyConfigSchema = propertyConfigSchemaMap[schemaType]; - if (propertyConfigSchema && propertyConfigSchema.categories) { - const propertyConfigs = Object.keys(propertyConfigSchema.categories).map((categoryId: string) => { - const propertyCategory = propertyConfigSchema.categories[categoryId]; - const categoryName = propertyCategory?.title; - const properties = getPropertyEntities(propertyCategory.properties || {}, propertyConfigMap, {} as ComponentSchema, schema, schemaService); - return { categoryId, categoryName, properties }; - }); - return propertyConfigs; - } - return []; -} - -function tryToResolveReference(categoryId: string, propertyCategory: Record, rawSchema: ComponentSchema, schemaService: SchemaService, componentId = '') { - const refSchemaPath = propertyCategory.$ref.schema; - const $converter = propertyCategory.$ref.converter; - const refSchema = rawSchema[refSchemaPath]; - - const schemaType = refSchema.type; - const editingSchema = resolveSchemaWithDefaultValue(refSchema) as ComponentSchema; - const propertyConfigMap = {} as Record; - const propertyConfigSchema = propertyConfigSchemaMap[schemaType]; - if (propertyConfigSchema && propertyConfigSchema.categories) { - const propertyCategory = propertyConfigSchema.categories[categoryId]; - const categoryName = propertyCategory?.title; - if ($converter) { - Object.keys(propertyCategory.properties).forEach((propertyKey: any) => { - propertyCategory.properties[propertyKey].$converter = $converter; - }); - } - const propertiesInCategory = propertyCategory?.properties || {}; - const properties = getPropertyEntities(propertiesInCategory, propertyConfigMap, editingSchema, refSchema, schemaService, componentId); - return { categoryId, categoryName, properties }; - - } - return { categoryId, categoryName: '', properties: [] }; -} - -// jumphere -function getPropertyConfigBySchema(rawSchema: ComponentSchema, schemaService: SchemaService, designerItem: any, componentId: string, propertyConfig?: Record): ElementPropertyConfig[] { - const schemaType = rawSchema.type; - const editingSchema = resolveSchemaWithDefaultValue(rawSchema) as ComponentSchema; - const propertyConfigMap = {} as Record; - - // 先从ConfigMap中取简单类属性,若找不到,则在控件实例中取复杂属性 - let propertyConfigSchema = propertyConfig || propertyConfigSchemaMap[schemaType]; - if (propertyConfigSchema && Object.keys(propertyConfigSchema).length === 0 && designerItem && designerItem.getPropConfig) { - propertyConfigSchema = designerItem.getPropConfig(componentId); - } - if (propertyConfigSchema && propertyConfigSchema.categories) { - const propertyConfigs = [] as Array; - Object.keys(propertyConfigSchema.categories).map((categoryId: string) => { - const propertyCategory = propertyConfigSchema.categories[categoryId]; - if (propertyCategory.$ref) { - propertyConfigs.push(tryToResolveReference(categoryId, propertyCategory, rawSchema, schemaService, componentId) as ElementPropertyConfig); - return; - } - const categoryName = propertyCategory?.title; - const tabId = propertyCategory?.tabId; - const tabName = propertyCategory?.tabName; - const hide = propertyCategory?.hide; - const hideTitle = propertyCategory?.hideTitle; - const properties = getPropertyEntities(propertyCategory.properties || {}, propertyConfigMap, editingSchema, rawSchema, schemaService, componentId, propertyCategory['$converter']); - const { setPropertyRelates } = propertyCategory; - propertyConfigs.push({ categoryId, categoryName, tabId, tabName, hide, properties, hideTitle, setPropertyRelates }); - }); - return propertyConfigs; - } - return []; -} - -export { getPropertyConfigBySchema, getPropertyConfigByType, propertyConfigSchemaMap, propertyConverterMap, propertyEffectMap }; diff --git a/packages/ui-vue/components/dynamic-resolver/src/props-resolver.ts b/packages/ui-vue/components/dynamic-resolver/src/props-resolver.ts index 8884abfc439..4149639d269 100644 --- a/packages/ui-vue/components/dynamic-resolver/src/props-resolver.ts +++ b/packages/ui-vue/components/dynamic-resolver/src/props-resolver.ts @@ -1,7 +1,9 @@ import { DesignerHostService } from './../../designer-canvas/src/composition/types'; -import { mappingSchemaToProps, resolveSchemaToProps, schemaMap, schemaResolverMap } from './schema-resolver'; +import { mappingSchemaToProps, resolveSchemaToProps, schemaMap, schemaResolverMap } from './resolver/schema/schema-resolver'; import { DynamicResolver, EffectFunction, MapperFunction, SchemaResolverFunction } from './types'; -import { propertyConfigSchemaMap, propertyEffectMap } from './property-config-resolver'; +import { propertyConfigSchemaMap, propertyEffectMap } from './resolver/property-config/property-config-resolver'; +import { schemaMapForDesigner, schemaResolverMapForDesigner } from './resolver/schema/schema-resolver-design'; +import { propertyConfigSchemaMapForDesigner as propertyConfigSchemaMapForDesigner, propertyEffectMapForDesigner } from './resolver/property-config/property-config-resolver-design'; export function createPropsResolver>( componentPropsObject: T, @@ -20,6 +22,12 @@ export function createPropsResolver>( schemaResolverMap[defaultSchema.title] = schemaResolver; propertyConfigSchemaMap[defaultSchema.title] = propertyConfig; propertyEffectMap[defaultSchema.title] = propertyEffect; + + schemaMapForDesigner[defaultSchema.title] = defaultSchema; + schemaResolverMapForDesigner[defaultSchema.title] = schemaResolver; + propertyConfigSchemaMapForDesigner[defaultSchema.title] = propertyConfig; + propertyEffectMapForDesigner[defaultSchema.title] = propertyEffect; + return (schemaValue: Record = {}, mergeDefaults: boolean = true) => { if (!mergeDefaults) { return mappingSchemaToProps(schemaValue, schemaMapper); diff --git a/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver-design.ts b/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver-design.ts new file mode 100644 index 00000000000..e4fba29a4a8 --- /dev/null +++ b/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver-design.ts @@ -0,0 +1,13 @@ +import { EffectFunction } from '../../types'; +import { usePropertyConfigResolver } from './use-property-config-resolver'; + +const propertyConfigSchemaMapForDesigner = {} as Record; +const propertyEffectMapForDesigner = {} as Record; + +const { getPropertyConfigBySchema, getPropertyConfigByType, propertyConverterMap } = + usePropertyConfigResolver(propertyConfigSchemaMapForDesigner, propertyEffectMapForDesigner); + +export { + getPropertyConfigBySchema as getPropertyConfigBySchemaForDesigner, getPropertyConfigByType as getPropertyConfigByTypeForDesigner, + propertyConfigSchemaMapForDesigner, propertyConverterMap as propertyConverterMapForDesigner, propertyEffectMapForDesigner +}; diff --git a/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver.ts b/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver.ts new file mode 100644 index 00000000000..199cbf45c5e --- /dev/null +++ b/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver.ts @@ -0,0 +1,10 @@ +import { EffectFunction} from '../../types'; +import { usePropertyConfigResolver } from './use-property-config-resolver'; + +const propertyConfigSchemaMap = {} as Record; +const propertyEffectMap = {} as Record; + +const { getPropertyConfigBySchema, getPropertyConfigByType, propertyConverterMap } = + usePropertyConfigResolver(propertyConfigSchemaMap, propertyEffectMap); + +export { getPropertyConfigBySchema, getPropertyConfigByType, propertyConfigSchemaMap, propertyConverterMap, propertyEffectMap }; diff --git a/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts b/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts new file mode 100644 index 00000000000..e96fe51d4aa --- /dev/null +++ b/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts @@ -0,0 +1,248 @@ +import { computed, ref } from "vue"; +import { EffectFunction, PropertyConverter, SchemaService } from '../../types'; +import { EditorConfig } from "../../../../dynamic-form"; +import { useObjectExpression } from '../../object-expression'; +import { ComponentSchema } from "../../../../designer-canvas/src/types"; +import { resolveSchemaWithDefaultValue } from "../schema/schema-resolver"; +import appearanceConverter from '../../converter/appearance.converter'; +import buttonsConverter from "../../converter/buttons.converter"; +import propertyEditorConverter from "../../converter/property-editor.converter"; +import typeConverter from "../../converter/type.converter"; +import changeEditorConverter from "../../converter/change-editor.converter"; +import fieldSelectorConverter from "../../converter/field-selector.converter"; +import paginationConverter from "../../converter/pagination.converter"; +import rowNumberConverter from "../../converter/row-number.converter"; +import gridSelectionConverter from "../../converter/grid-selection.converter"; +import { ElementPropertyConfig, PropertyEntity } from "../../../../property-panel/src/composition/entity/property-entity"; +import itemsCountConverter from "../../converter/items-count.converter"; +import formGroupLabelConverter from "../../converter/form-group-label.converter"; + +export function usePropertyConfigResolver(propertyConfigSchemaMap: Record, propertyEffectMap: Record) { + const propertyConverterMap = new Map([ + ['/converter/appearance.converter', appearanceConverter], + ['/converter/buttons.converter', buttonsConverter], + ['/converter/property-editor.converter', propertyEditorConverter], + ['/converter/items-count.converter', itemsCountConverter], + ['/converter/type.converter', typeConverter], + ['/converter/change-editor.converter', changeEditorConverter], + ['/converter/form-group-label.converter', formGroupLabelConverter], + ['/converter/field-selector.converter', fieldSelectorConverter], + ['/converter/pagination.converter', paginationConverter], + ['/converter/row-number.converter', rowNumberConverter], + ['/converter/grid-selection.converter', gridSelectionConverter] + ]); + const propertyEditorMap = new Map([ + ['string', { type: 'input-group', enableClear: false }], + ['boolean', { + "type": "combo-list", + "textField": "name", + "valueField": "value", + "idField": "value", + "enableClear": false, + "editable": false, + "maxHeight": 64, + "data": [ + { + "value": true, + "name": "是" + }, + { + "value": false, + "name": "否" + } + ] + }], + ['enum', { "type": "combo-list", "maxHeight": 128, "enableClear": false, "editable": false }], + ['array', { "type": "button-edit" }], + ['number', { "type": "number-spinner", "placeholder": "" }], + ['events-editor', { "type": "events-editor", hide: true }] + ]); + + const useObjectExpressionComponstion = useObjectExpression(); + + function generateBooleanValue(pvalueSchema: Record, propertyConfigMap: Record) { + return () => useObjectExpressionComponstion.parseValueSchema(pvalueSchema, propertyConfigMap); + } + + function isVisible(propertySchemaKeys: string[], propertySchema: Record, propertyConfigMap: Record) + : boolean | (() => boolean) { + if (propertySchemaKeys.includes('visible') && propertySchema.visible !== undefined) { + return typeof propertySchema.visible === 'boolean' ? + () => Boolean(propertySchema.visible) : + propertySchema.visible === undefined ? true : generateBooleanValue(propertySchema.visible, propertyConfigMap); + } + return () => true; + } + + function isReadonly(propertySchemaKeys: string[], propertySchema: Record, propertyConfigMap: Record) { + if (propertySchemaKeys.includes('readonly') && propertySchema.readonly !== undefined) { + return typeof propertySchema.readonly === 'boolean' ? + () => Boolean(propertySchema.readonly) : + generateBooleanValue(propertySchema.readonly, propertyConfigMap); + } + return () => false; + } + + function tryGetPropertyConverter(propertySchema: Record, categoryConverter): PropertyConverter | null { + const $converter = propertySchema['$converter'] || categoryConverter; + if (typeof $converter === 'string') { + if ($converter && propertyConverterMap.has($converter)) { + return propertyConverterMap.get($converter) || null; + } + } + return $converter || null; + } + + /** + * + * @param propertiesInCategory + * 举例: + * visible: { + description: "运行时组件是否可见", + title: "是否可见", + type: "boolean" + } + 其中type属性 这个属性用来控制编辑器是哪一种,对应关系在propertyEditorMap中定义,boolean指定了下拉 + * @param propertyConfigMap + * @param editingSchema + * @param rawSchema + * @param schemaService + * @returns + */ + function getPropertyEntities( + propertiesInCategory: Record, + propertyConfigMap: Record, + editingSchema: ComponentSchema, + rawSchema: ComponentSchema, + schemaService: SchemaService, + componentId = '', + categoryConverter: any = '' + ): PropertyEntity[] { + const propertyEntities = Object.keys(propertiesInCategory).map((propertyKey: string) => { + const updateCount = ref(1); + const propertyID = propertyKey; + const propertySchema = propertiesInCategory[propertyKey]; + const propertySchemaKeys = Object.keys(propertySchema); + const propertyName = propertySchema.title; + const propertyType = propertySchema.type; + const defaultEditor = propertyEditorMap.get(propertyType) || { type: 'input-group', enableClear: false }; + const editor = propertySchema.editor ? Object.assign({}, defaultEditor, propertySchema.editor) as EditorConfig : Object.assign({}, defaultEditor); + const visible = isVisible(propertySchemaKeys, propertySchema, propertyConfigMap); + const readonly = isReadonly(propertySchemaKeys, propertySchema, propertyConfigMap); + editor.readonly = editor.readonly === undefined ? readonly() : editor.readonly; + const cascadeConfig = propertySchema.type === 'cascade' ? getPropertyEntities(propertySchema.properties, propertyConfigMap, editingSchema, rawSchema, schemaService, componentId, categoryConverter) : []; + const hideCascadeTitle = true; + let converter = tryGetPropertyConverter(propertySchema, categoryConverter); + // const propertyValue = ref(converter ? converter.convertFrom(schema, propertyKey) : schema[propertyKey]); + const propertyValue = computed({ + get() { + if (updateCount.value) { + // class、style 统一处理 + if (['class', 'style'].find(id => id === propertyID) && !converter) { + converter = propertyConverterMap.get('/converter/appearance.converter') || null; + } + if (converter && converter.convertFrom) { + return converter.convertFrom(editingSchema, propertyKey, schemaService, componentId); + } + // 获取属性时,如果没有convertForm,并且通过在Schema上获取得值是空,那就获取defaultValue属性值或者是空 + const editingSchemaValue = editingSchema[propertyKey]; + return Object.prototype.hasOwnProperty.call(propertySchema, 'defaultValue') && (editingSchemaValue === undefined || typeof editingSchemaValue == 'string' && editingSchemaValue === '') ? propertySchema['defaultValue'] || '' : editingSchemaValue; + } + return null; + }, + set(newValue) { + updateCount.value += 1; + if (converter && converter.convertTo) { + converter.convertTo(rawSchema, propertyKey, newValue, schemaService, componentId); + converter.convertTo(editingSchema, propertyKey, newValue, schemaService, componentId); + } else { + rawSchema[propertyKey] = newValue; + editingSchema[propertyKey] = newValue; + } + } + }); + const { refreshPanelAfterChanged, description, isExpand } = propertySchema; + const propertyEntity = { propertyID, propertyName, propertyType, propertyValue, editor, visible, readonly, cascadeConfig, hideCascadeTitle, refreshPanelAfterChanged, description, isExpand }; + propertyConfigMap[propertyID] = propertyEntity; + return propertyEntity; + }); + return propertyEntities; + } + + function getPropertyConfigByType(schemaType: string, schemaService: SchemaService, schema = {} as ComponentSchema): ElementPropertyConfig[] { + const propertyConfigMap = {} as Record; + const propertyConfigSchema = propertyConfigSchemaMap[schemaType]; + if (propertyConfigSchema && propertyConfigSchema.categories) { + const propertyConfigs = Object.keys(propertyConfigSchema.categories).map((categoryId: string) => { + const propertyCategory = propertyConfigSchema.categories[categoryId]; + const categoryName = propertyCategory?.title; + const properties = getPropertyEntities(propertyCategory.properties || {}, propertyConfigMap, {} as ComponentSchema, schema, schemaService); + return { categoryId, categoryName, properties }; + }); + return propertyConfigs; + } + return []; + } + + function tryToResolveReference(categoryId: string, propertyCategory: Record, rawSchema: ComponentSchema, schemaService: SchemaService, componentId = '') { + const refSchemaPath = propertyCategory.$ref.schema; + const $converter = propertyCategory.$ref.converter; + const refSchema = rawSchema[refSchemaPath]; + + const schemaType = refSchema.type; + const editingSchema = resolveSchemaWithDefaultValue(refSchema) as ComponentSchema; + const propertyConfigMap = {} as Record; + const propertyConfigSchema = propertyConfigSchemaMap[schemaType]; + if (propertyConfigSchema && propertyConfigSchema.categories) { + const propertyCategory = propertyConfigSchema.categories[categoryId]; + const categoryName = propertyCategory?.title; + if ($converter) { + Object.keys(propertyCategory.properties).forEach((propertyKey: any) => { + propertyCategory.properties[propertyKey].$converter = $converter; + }); + } + const propertiesInCategory = propertyCategory?.properties || {}; + const properties = getPropertyEntities(propertiesInCategory, propertyConfigMap, editingSchema, refSchema, schemaService, componentId); + return { categoryId, categoryName, properties }; + + } + return { categoryId, categoryName: '', properties: [] }; + } + + function getPropertyConfigBySchema(rawSchema: ComponentSchema, schemaService: SchemaService, designerItem: any, componentId: string, propertyConfig?: Record): ElementPropertyConfig[] { + const schemaType = rawSchema.type; + const editingSchema = resolveSchemaWithDefaultValue(rawSchema) as ComponentSchema; + const propertyConfigMap = {} as Record; + + // 先从ConfigMap中取简单类属性,若找不到,则在控件实例中取复杂属性 + let propertyConfigSchema = propertyConfig || propertyConfigSchemaMap[schemaType]; + if (propertyConfigSchema && Object.keys(propertyConfigSchema).length === 0 && designerItem && designerItem.getPropConfig) { + propertyConfigSchema = designerItem.getPropConfig(componentId); + } + if (propertyConfigSchema && propertyConfigSchema.categories) { + const propertyConfigs = [] as Array; + Object.keys(propertyConfigSchema.categories).map((categoryId: string) => { + const propertyCategory = propertyConfigSchema.categories[categoryId]; + if (propertyCategory.$ref) { + propertyConfigs.push(tryToResolveReference(categoryId, propertyCategory, rawSchema, schemaService, componentId) as ElementPropertyConfig); + return; + } + const categoryName = propertyCategory?.title; + const tabId = propertyCategory?.tabId; + const tabName = propertyCategory?.tabName; + const hide = propertyCategory?.hide; + const hideTitle = propertyCategory?.hideTitle; + const properties = getPropertyEntities(propertyCategory.properties || {}, propertyConfigMap, editingSchema, rawSchema, schemaService, componentId, propertyCategory['$converter']); + const { setPropertyRelates } = propertyCategory; + propertyConfigs.push({ categoryId, categoryName, tabId, tabName, hide, properties, hideTitle, setPropertyRelates }); + }); + return propertyConfigs; + } + return []; + } + + return { + getPropertyConfigBySchema, getPropertyConfigByType, propertyConverterMap + }; +} + diff --git a/packages/ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver-design.ts b/packages/ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver-design.ts new file mode 100644 index 00000000000..d5fe3e93162 --- /dev/null +++ b/packages/ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver-design.ts @@ -0,0 +1,14 @@ +import { SchemaResolverFunction } from "../../types"; +import { useSchemaResolver } from "./use-schema-resolver"; + +const schemaMapForDesigner = {} as Record; +const schemaResolverMapForDesigner = {} as Record; + +const { getSchemaByType, resolveSchemaWithDefaultValue, resolveSchemaToProps, mappingSchemaToProps } = + useSchemaResolver(schemaMapForDesigner, schemaResolverMapForDesigner); + +export { + getSchemaByType as getSchemaByTypeForDesigner, resolveSchemaWithDefaultValue as resolveSchemaWithDefaultValueForDesigner, + resolveSchemaToProps as resolveSchemaToPropsForDesigner, schemaMapForDesigner, schemaResolverMapForDesigner, + mappingSchemaToProps as mappingSchemaToPropsForDesigner +}; diff --git a/packages/ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver.ts b/packages/ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver.ts new file mode 100644 index 00000000000..083e2015cd3 --- /dev/null +++ b/packages/ui-vue/components/dynamic-resolver/src/resolver/schema/schema-resolver.ts @@ -0,0 +1,10 @@ +import { SchemaResolverFunction } from "../../types"; +import { useSchemaResolver } from "./use-schema-resolver"; + +const schemaMap = {} as Record; +const schemaResolverMap = {} as Record; + +const { getSchemaByType, resolveSchemaWithDefaultValue, resolveSchemaToProps, mappingSchemaToProps } = + useSchemaResolver(schemaMap, schemaResolverMap); + +export { getSchemaByType, resolveSchemaWithDefaultValue, resolveSchemaToProps, schemaMap, schemaResolverMap, mappingSchemaToProps }; diff --git a/packages/ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts b/packages/ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts new file mode 100644 index 00000000000..f1654b900b5 --- /dev/null +++ b/packages/ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts @@ -0,0 +1,136 @@ +import { cloneDeep, isPlainObject } from "lodash-es"; +import { MapperFunction, SchemaResolverFunction } from "../../types"; +import { DesignerHostService } from "@farris/ui-vue/components/designer-canvas"; + +export function useSchemaResolver(schemaMap: Record, schemaResolverMap: Record) { + + function getSchemaValueByDefault(defaultSchema: Record): Record { + const { properties, title, ignore: ignoreList } = defaultSchema as Record; + const canIgnoreProperty = ignoreList && Array.isArray(ignoreList); + const resolvedSchema = Object.keys(properties).reduce((propsObject: Record, propKey: string) => { + if (!canIgnoreProperty || !ignoreList.find(item => item === propKey)) { + propsObject[propKey] = (properties[propKey].type === 'object' && !!properties[propKey].properties) ? + getSchemaValueByDefault(properties[propKey]) : cloneDeep(properties[propKey].default); + } + return propsObject; + }, {}); + if (title && (!canIgnoreProperty || !ignoreList.find(item => item === 'id'))) { + const typePrefix = title.toLowerCase().replace(/-/g, '_'); + resolvedSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; + } + return resolvedSchema; + } + + /** + * 获取控件元数据,只组装必填的字段 + */ + function getRequiredSchemaValueByDefault(defaultSchema: Record): Record { + const { properties, title, required: requiredProperty } = defaultSchema as Record; + if (requiredProperty && Array.isArray(requiredProperty)) { + const resolvedSchema = requiredProperty.reduce((propsObject: Record, propKey: string) => { + + propsObject[propKey] = (properties[propKey].type === 'object' && !!properties[propKey].properties) ? + getSchemaValueByDefault(properties[propKey]) : cloneDeep(properties[propKey].default); + + return propsObject; + }, {}); + if (title && requiredProperty.find(item => item === 'id')) { + const typePrefix = title.toLowerCase().replace(/-/g, '_'); + resolvedSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; + } + return resolvedSchema; + } + return { + type: title + }; + + } + + function getSchemaByType(componentType: string, resolveContext: Record = {}, designerHostService?: DesignerHostService) + : Record | null { + const defaultSchema = schemaMap[componentType]; + if (defaultSchema) { + let componentSchema = getRequiredSchemaValueByDefault(defaultSchema); + const schemaResolver = schemaResolverMap[componentType]; + componentSchema = schemaResolver ? schemaResolver({ getSchemaByType }, componentSchema, resolveContext, designerHostService) + : componentSchema; + return componentSchema; + } + return null; + } + + function resolveSchema(schemaValue: Record, defaultSchema: Record): Record { + + const resolvedSchema = getSchemaValueByDefault(defaultSchema); + + Object.keys(resolvedSchema).reduce((resolvedSchema: Record, propKey: string) => { + if (Object.prototype.hasOwnProperty.call(schemaValue, propKey)) { + // 解决属性是对象类型,默认值被冲掉的情况 + // 增加非判断,解决针对属性时对象,但是schemaValue=null或者undefined情况 + if (resolvedSchema[propKey] && isPlainObject(resolvedSchema[propKey]) && (isPlainObject(schemaValue[propKey] || !schemaValue[propKey]))) { + Object.assign(resolvedSchema[propKey], schemaValue[propKey] || {}); + } else { + resolvedSchema[propKey] = schemaValue[propKey]; + } + } + + return resolvedSchema; + }, resolvedSchema); + + return resolvedSchema; + }; + + function mappingSchemaToProps(resolvedSchema: Record, schemaMapper: Map) { + const props = Object.keys(resolvedSchema) + .filter((propKey: string) => resolvedSchema[propKey] != null) + .reduce((resolvedProps: Record, propKey: string) => { + if (schemaMapper.has(propKey)) { + const mapper = schemaMapper.get(propKey) as string | MapperFunction; + if (typeof mapper === 'string') { + resolvedProps[mapper] = resolvedSchema[propKey]; + } else { + const mapperResult = (mapper as MapperFunction)(propKey, resolvedSchema[propKey], resolvedSchema); + Object.assign(resolvedProps, mapperResult); + } + } else { + resolvedProps[propKey] = resolvedSchema[propKey]; + } + return resolvedProps; + }, {}); + return props; + } + + function resolveSchemaToProps( + schemaValue: Record, + defaultSchema: Record, + schemaMapper: Map = new Map() + ): Record { + const resolvedSchema = resolveSchema(schemaValue, defaultSchema); + const props = mappingSchemaToProps(resolvedSchema, schemaMapper); + return props; + } + + function resolveSchemaWithDefaultValue(schemaValue: Record): Record { + const componentType = schemaValue.type; + if (componentType) { + const defaultSchema = schemaMap[componentType]; + if (!defaultSchema) { + return schemaValue; + } + const resolvedSchema = resolveSchema(schemaValue, defaultSchema); + const editorType = schemaValue.editor?.type || ''; + /* 解决schemeValue结构如下图场景,在editor下,获取不到date-picker类型的默认值的问题 + * {type:'input-group',...,editor:{type:'date-picker',...}} + */ + if (editorType) { + const defaulEditorSchema = schemaMap[editorType]; + const resolvedEditorSchema = resolveSchema(schemaValue.editor, defaulEditorSchema); + resolvedSchema.editor = resolvedEditorSchema; + } + return resolvedSchema; + } + return schemaValue; + } + + return { getSchemaByType, resolveSchemaWithDefaultValue, resolveSchemaToProps, mappingSchemaToProps }; +} diff --git a/packages/ui-vue/components/dynamic-resolver/src/schema-resolver.ts b/packages/ui-vue/components/dynamic-resolver/src/schema-resolver.ts deleted file mode 100644 index d9adc5dfc35..00000000000 --- a/packages/ui-vue/components/dynamic-resolver/src/schema-resolver.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { cloneDeep, isPlainObject } from "lodash-es"; -import { DesignerHostService } from "../../designer-canvas/src/composition/types"; -import { MapperFunction, SchemaResolverFunction } from "./types"; - -const schemaMap = {} as Record; -const schemaResolverMap = {} as Record; - -function getSchemaValueByDefault(defaultSchema: Record): Record { - const { properties, title, ignore: ignoreList } = defaultSchema as Record; - const canIgnoreProperty = ignoreList && Array.isArray(ignoreList); - const resolvedSchema = Object.keys(properties).reduce((propsObject: Record, propKey: string) => { - if (!canIgnoreProperty || !ignoreList.find(item => item === propKey)) { - propsObject[propKey] = (properties[propKey].type === 'object' && !!properties[propKey].properties) ? - getSchemaValueByDefault(properties[propKey]) : cloneDeep(properties[propKey].default); - } - return propsObject; - }, {}); - if (title && (!canIgnoreProperty || !ignoreList.find(item => item === 'id'))) { - const typePrefix = title.toLowerCase().replace(/-/g, '_'); - resolvedSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; - } - return resolvedSchema; -} -/** - * 获取控件元数据,只组装必填的字段 - */ -function getRequiredSchemaValueByDefault(defaultSchema: Record): Record { - const { properties, title, required: requiredProperty } = defaultSchema as Record; - if (requiredProperty && Array.isArray(requiredProperty)) { - const resolvedSchema = requiredProperty.reduce((propsObject: Record, propKey: string) => { - - propsObject[propKey] = (properties[propKey].type === 'object' && !!properties[propKey].properties) ? - getSchemaValueByDefault(properties[propKey]) : cloneDeep(properties[propKey].default); - - return propsObject; - }, {}); - if (title && requiredProperty.find(item => item === 'id')) { - const typePrefix = title.toLowerCase().replace(/-/g, '_'); - resolvedSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; - } - return resolvedSchema; - } - return { - type: title - }; - -} -function getSchemaByType(componentType: string, resolveContext: Record = {}, designerHostService?: DesignerHostService) - : Record | null { - const defaultSchema = schemaMap[componentType]; - if (defaultSchema) { - let componentSchema = getRequiredSchemaValueByDefault(defaultSchema); - const schemaResolver = schemaResolverMap[componentType]; - componentSchema = schemaResolver ? schemaResolver({ getSchemaByType }, componentSchema, resolveContext, designerHostService) - : componentSchema; - return componentSchema; - } - return null; -} - -function resolveSchema(schemaValue: Record, defaultSchema: Record): Record { - - const resolvedSchema = getSchemaValueByDefault(defaultSchema); - - Object.keys(resolvedSchema).reduce((resolvedSchema: Record, propKey: string) => { - if (Object.prototype.hasOwnProperty.call(schemaValue, propKey)) { - // 解决属性是对象类型,默认值被冲掉的情况 - // 增加非判断,解决针对属性时对象,但是schemaValue=null或者undefined情况 - if (resolvedSchema[propKey] && isPlainObject(resolvedSchema[propKey]) && (isPlainObject(schemaValue[propKey] || !schemaValue[propKey]))) { - Object.assign(resolvedSchema[propKey], schemaValue[propKey] || {}); - } else { - resolvedSchema[propKey] = schemaValue[propKey]; - } - } - - return resolvedSchema; - }, resolvedSchema); - - return resolvedSchema; -}; - -function mappingSchemaToProps(resolvedSchema: Record, schemaMapper: Map) { - const props = Object.keys(resolvedSchema) - .filter((propKey: string) => resolvedSchema[propKey] != null) - .reduce((resolvedProps: Record, propKey: string) => { - if (schemaMapper.has(propKey)) { - const mapper = schemaMapper.get(propKey) as string | MapperFunction; - if (typeof mapper === 'string') { - resolvedProps[mapper] = resolvedSchema[propKey]; - } else { - const mapperResult = (mapper as MapperFunction)(propKey, resolvedSchema[propKey], resolvedSchema); - Object.assign(resolvedProps, mapperResult); - } - } else { - resolvedProps[propKey] = resolvedSchema[propKey]; - } - return resolvedProps; - }, {}); - return props; -} - -function resolveSchemaToProps( - schemaValue: Record, - defaultSchema: Record, - schemaMapper: Map = new Map() -): Record { - const resolvedSchema = resolveSchema(schemaValue, defaultSchema); - const props = mappingSchemaToProps(resolvedSchema, schemaMapper); - return props; -} - -function resolveSchemaWithDefaultValue(schemaValue: Record): Record { - const componentType = schemaValue.type; - if (componentType) { - const defaultSchema = schemaMap[componentType]; - if (!defaultSchema) { - return schemaValue; - } - const resolvedSchema = resolveSchema(schemaValue, defaultSchema); - const editorType = schemaValue.editor?.type || ''; - /* 解决schemeValue结构如下图场景,在editor下,获取不到date-picker类型的默认值的问题 - * {type:'input-group',...,editor:{type:'date-picker',...}} - */ - if (editorType) { - const defaulEditorSchema = schemaMap[editorType]; - const resolvedEditorSchema = resolveSchema(schemaValue.editor, defaulEditorSchema); - resolvedSchema.editor = resolvedEditorSchema; - } - return resolvedSchema; - } - return schemaValue; -} - -export { getSchemaByType, resolveSchemaWithDefaultValue, resolveSchemaToProps, schemaMap, schemaResolverMap, mappingSchemaToProps }; diff --git a/packages/ui-vue/components/property-panel/src/property-panel.component.tsx b/packages/ui-vue/components/property-panel/src/property-panel.component.tsx index 96fbe145210..a9ecb5916d0 100644 --- a/packages/ui-vue/components/property-panel/src/property-panel.component.tsx +++ b/packages/ui-vue/components/property-panel/src/property-panel.component.tsx @@ -17,7 +17,7 @@ */ import { defineComponent, SetupContext, ref, watch, onMounted, onBeforeMount, inject } from 'vue'; import { PropertyPanelProps, propertyPanelProps } from './composition/props/property-panel.props'; -import { getPropertyConfigBySchema } from '../../dynamic-resolver/src/property-config-resolver'; +import { getPropertyConfigBySchemaForDesigner } from '../../dynamic-resolver/src/resolver/property-config/property-config-resolver-design'; import { SchemaService } from '../../dynamic-resolver'; import FPropertyPanelItemList from '../src/component/property-panel-item-list.component'; @@ -288,7 +288,7 @@ export default defineComponent({ if (!props.schema || !props.schema.type) { propertyConfig.value = []; } else { - propertyConfig.value = getPropertyConfigBySchema(propertyData.value, schemaService as SchemaService, designerItem, componentId); + propertyConfig.value = getPropertyConfigBySchemaForDesigner(propertyData.value, schemaService as SchemaService, designerItem, componentId); } checkShowTabCategory(); onClearEvent(keyword.value); @@ -304,7 +304,7 @@ export default defineComponent({ if (!propertyData.value || newSchema) { propertyData.value = newSchema || props.schema; } - propertyConfig.value = getPropertyConfigBySchema(propertyData.value, schemaService as SchemaService, designerItem, componentId, newPropertyConfig); + propertyConfig.value = getPropertyConfigBySchemaForDesigner(propertyData.value, schemaService as SchemaService, designerItem, componentId, newPropertyConfig); checkShowTabCategory(); onClearEvent(keyword.value); refreshFlag && categoryReload.value++; @@ -349,7 +349,7 @@ export default defineComponent({ } } function onRefreshPanel() { - propertyConfig.value = getPropertyConfigBySchema(propertyData.value, schemaService as SchemaService, designerItem, componentId); + propertyConfig.value = getPropertyConfigBySchemaForDesigner(propertyData.value, schemaService as SchemaService, designerItem, componentId); checkShowTabCategory(); } /** 搜索框 */ diff --git a/packages/ui-vue/components/response-toolbar/src/designer/use-designer-item-rules.ts b/packages/ui-vue/components/response-toolbar/src/designer/use-designer-item-rules.ts index 5e6a255d90b..91ebcdcda47 100644 --- a/packages/ui-vue/components/response-toolbar/src/designer/use-designer-item-rules.ts +++ b/packages/ui-vue/components/response-toolbar/src/designer/use-designer-item-rules.ts @@ -3,7 +3,7 @@ import { DraggingResolveContext, UseDesignerRules } from "../../../designer-canv import { ComponentSchema, DesignerItemContext } from "../../../designer-canvas/src/types"; import { TabToolbarItemProperty } from "../../../tabs/src/property-config/tab-toolbar-item.property-config"; import { ResponseToolbarItemProperty } from "../property-config/response-toolbar-item.property-config"; -import { getSchemaByType } from '../../../dynamic-resolver/src/schema-resolver'; +import { getSchemaByTypeForDesigner } from '../../../dynamic-resolver/src/resolver/schema/schema-resolver-design'; import { ResponseToolbarItemActionHandler } from "../types/common"; // import { canvasChanged } from "@/components/designer-canvas/src/composition/designer-canvas-changed"; @@ -50,7 +50,7 @@ export function useDesignerItemRules(designerItemContext: DesignerItemContext, d */ function createResponseToolbarItemSchema() { const componentType = designerItemContext.schema.type || 'response-toolbar-item'; - const componentSchema = getSchemaByType(componentType) as ComponentSchema; + const componentSchema = getSchemaByTypeForDesigner(componentType) as ComponentSchema; const typePrefix = componentType.toLowerCase().replace('-', '_'); if (componentSchema && !componentSchema.id && componentSchema.type === componentType) { componentSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; diff --git a/packages/ui-vue/components/tabs/src/designer/tab-header.design.component.tsx b/packages/ui-vue/components/tabs/src/designer/tab-header.design.component.tsx index 3f52d26d38c..e8611718f02 100644 --- a/packages/ui-vue/components/tabs/src/designer/tab-header.design.component.tsx +++ b/packages/ui-vue/components/tabs/src/designer/tab-header.design.component.tsx @@ -4,7 +4,7 @@ import { TabPageContext, UseDesignTabs, UseNav, UseOnePage } from "../compositio import renderTabHeaderItem from './tab-header-item.design.component'; import { ComponentSchema, DesignerComponentInstance } from "../../../designer-canvas/src/types"; -import { getSchemaByType } from "../../../dynamic-resolver/src/schema-resolver"; +import { getSchemaByTypeForDesigner } from "../../../dynamic-resolver/src/resolver/schema/schema-resolver-design"; import { UseDesignerRules } from "../../../designer-canvas/src/composition/types"; export default function ( @@ -59,7 +59,7 @@ export default function ( event.stopPropagation(); event.preventDefault(); } - const tabPageSchema = getSchemaByType('tab-page') as ComponentSchema; + const tabPageSchema = getSchemaByTypeForDesigner('tab-page') as ComponentSchema; tabPageSchema.id = `tab_page_${Math.random().toString().slice(2, 6)}`; tabPageSchema.title = `标题`; tabPageSchema.toolbar = { buttons: [] }; diff --git a/packages/ui-vue/components/tabs/src/designer/tabs-use-design.ts b/packages/ui-vue/components/tabs/src/designer/tabs-use-design.ts index fa7a3f26112..c6c2f5e09d6 100644 --- a/packages/ui-vue/components/tabs/src/designer/tabs-use-design.ts +++ b/packages/ui-vue/components/tabs/src/designer/tabs-use-design.ts @@ -18,7 +18,7 @@ import { TabsProps } from '../tabs.props'; import { TabPageContext, UseDesignTabs } from '../composition/types'; import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from '../../../designer-canvas/src/types'; import { canvasChanged, setPositionForSelectedElement } from '../../../designer-canvas/src/composition/designer-canvas-changed'; -import { getSchemaByType } from '../../../dynamic-resolver/src/schema-resolver'; +import { getSchemaByTypeForDesigner } from '../../../dynamic-resolver/src/resolver/schema/schema-resolver-design'; import { DesignerHTMLElement } from '../../../designer-canvas/src/composition/types'; export function useDesignTabs( @@ -369,7 +369,7 @@ export function useDesignTabs( tabPage.toolbar = { buttons: [] }; } - const tabToolbarItemSchema = getSchemaByType('tab-toolbar-item') as ComponentSchema; + const tabToolbarItemSchema = getSchemaByTypeForDesigner('tab-toolbar-item') as ComponentSchema; tabToolbarItemSchema.id = `tab_toolbar_item_${Math.random().toString().slice(2, 6)}`; tabPage.toolbar.buttons.push(tabToolbarItemSchema); -- Gitee From 860e67837fdb8c7ec0afc8fc6da48b5158cb19fd Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Fri, 11 Apr 2025 09:17:17 +0800 Subject: [PATCH 210/287] =?UTF-8?q?chore:=20=E5=AE=8C=E5=96=84=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../list-view/src/designer/list-view.design.component.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mobile-ui-vue/components/list-view/src/designer/list-view.design.component.tsx b/packages/mobile-ui-vue/components/list-view/src/designer/list-view.design.component.tsx index 613a425325f..7a019a4beea 100644 --- a/packages/mobile-ui-vue/components/list-view/src/designer/list-view.design.component.tsx +++ b/packages/mobile-ui-vue/components/list-view/src/designer/list-view.design.component.tsx @@ -47,7 +47,7 @@ export default defineComponent({ finished={true} >
    -
    +
    -- Gitee From adb7f2b2c34bc168091a37f7baca6d4601940122 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Fri, 11 Apr 2025 09:37:35 +0800 Subject: [PATCH 211/287] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0MobileRender?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .ls-lint.yml | 4 ++-- eslint.config.mjs | 3 ++- packages/mobile-render/README.md | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 packages/mobile-render/README.md diff --git a/.ls-lint.yml b/.ls-lint.yml index 625af457582..1642ad5bdf3 100644 --- a/.ls-lint.yml +++ b/.ls-lint.yml @@ -144,6 +144,6 @@ ignore: # mobile-render - packages/mobile-render/dist - packages/mobile-render/node_modules - - packages/mobile-render/public - - packages/mobile-render/publish + - packages/mobile-render/public/** + - packages/mobile-render/publish/** - packages/mobile-render/scripts diff --git a/eslint.config.mjs b/eslint.config.mjs index 3512846a8e7..527dee74e58 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -27,7 +27,8 @@ export default [ "packages/f-theme-editor-project/*", "packages/mobile-ui-vue/docs/*", "packages/devkit/public/*", - "packages/mobile-command-services/public/*" + "packages/mobile-command-services/public/*", + "packages/mobile-render/publish/*" ] }, { diff --git a/packages/mobile-render/README.md b/packages/mobile-render/README.md new file mode 100644 index 00000000000..a456527acc6 --- /dev/null +++ b/packages/mobile-render/README.md @@ -0,0 +1,19 @@ +## 如何运行 + +### 开发模式运行 + +- 移动渲染引擎主要依赖devkit、bef、mobile-command-servies、mobile-ui四个包,均已经通过alias直接引用了源码。 +- 直接运行npm run dev,然后在浏览器里输入指定地址修改几个包的源码即可实时预览; +- 注意:样式文件暂时不支持直接修改,需要修改后拷贝到public/assets目录下; +- 注意:元数据的加载仅在表单的第一个页面访问时 + +```html +示例地址 +localhost:5173/#/MobileListCard04091455/list-page-component?metadataPath=/Jiwt/JiwtFarrisVueModule/MobileTest0409/bo-mobiletest0409-front/metadata/components/MobileListCard04091455.mfrm&projectPath=/Jiwt/JiwtFarrisVueModule/MobileTest0409/bo-mobiletest0409-front/metadata/components +``` + +### 发布模式运行 + +- 进入到mobile-render目录,运行时./scripts/publish.sh +- 将publish目录下的增量覆盖到安装盘内; +- 表单设计器点击运行,预览表单; \ No newline at end of file -- Gitee From 15290589868aeae492ecc5246e01b278b44a7725 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Fri, 11 Apr 2025 10:01:05 +0800 Subject: [PATCH 212/287] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=E5=86=B2?= =?UTF-8?q?=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/mobile-ui-vue/components/form-item/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mobile-ui-vue/components/form-item/index.ts b/packages/mobile-ui-vue/components/form-item/index.ts index 09379b3e0b9..f8258f39a4a 100644 --- a/packages/mobile-ui-vue/components/form-item/index.ts +++ b/packages/mobile-ui-vue/components/form-item/index.ts @@ -1,4 +1,4 @@ -import { withInstall } from '@farris/mobile-ui-vue/common'; +import { withInstall, RegisterContext } from '@farris/mobile-ui-vue/common'; import { propsResolverGenerator } from './src/form-item.props'; import FormItemInstallless from './src/form-item.component'; import FormItemDesign from './src/designer/form-item.design.component'; -- Gitee From 036f89a0c6054dc3520f8b1fb6b068cc8f2d8efc Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Fri, 11 Apr 2025 10:20:57 +0800 Subject: [PATCH 213/287] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=E5=86=B2?= =?UTF-8?q?=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/date-picker/src/date-picker.props.ts | 2 +- .../components/date-time-picker/src/date-time-picker.props.ts | 4 ++-- packages/mobile-ui-vue/components/number-input/index.ts | 2 +- .../components/number-input/src/number-input.props.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) 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 10e0a31b3a9..54ffec58aa0 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 @@ -19,4 +19,4 @@ export const datePickerProps = { export type DatePickerProps = ExtractPropTypes; -export const propsResolver = getPropsResolverGenerator(datePickerProps, datePickerSchema, schemaMapper, schemaResolver); +export const propsResolverGenerator = getPropsResolverGenerator(datePickerProps, datePickerSchema, schemaMapper, schemaResolver); 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 808cce0ebd1..0adc5379481 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,7 +1,7 @@ import { ExtractPropTypes } from 'vue'; import { buttonEditProps } from '@farris/mobile-ui-vue/button-edit'; import { dateTimePickerPanelProps } from './date-time-picker-panel.props'; -import { createPropsResolver } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '../../dynamic-resolver'; import { schemaResolver } from './schema/schema-resolver'; import { schemaMapper } from './schema/schema-mapper'; import dateTimePickerSchema from './schema/datetime-picker.schema.json' @@ -16,6 +16,6 @@ export const dateTimePickerProps = { export type DateTimePickerProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( +export const propsResolver = getPropsResolverGenerator( dateTimePickerProps, dateTimePickerSchema, schemaMapper, schemaResolver ); diff --git a/packages/mobile-ui-vue/components/number-input/index.ts b/packages/mobile-ui-vue/components/number-input/index.ts index 7b914dfea58..7f5900346d4 100644 --- a/packages/mobile-ui-vue/components/number-input/index.ts +++ b/packages/mobile-ui-vue/components/number-input/index.ts @@ -1,4 +1,4 @@ -import { withInstall } from '@components/common'; +import { withInstall } from '@farris/mobile-ui-vue/common'; import NumberInputInstallless from './src/number-input.component'; import { propsResolver } from './src/number-input.props'; 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 index 836ba36b0af..3dc6e215977 100644 --- 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 @@ -1,6 +1,6 @@ import { ExtractPropTypes } from 'vue'; import { inputCommonProps } from '@/components/input-group'; -import { createPropsResolver } from '@/components/dynamic-resolver'; +import { getPropsResolverGenerator } from '@/components/dynamic-resolver'; import numberInputSchema from './schema/number-input.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; @@ -15,4 +15,4 @@ export const numberInputProps = { export type NumberInputProps = ExtractPropTypes; -export const propsResolver = createPropsResolver(numberInputProps, numberInputSchema, schemaMapper, schemaResolver); +export const propsResolver = getPropsResolverGenerator(numberInputProps, numberInputSchema, schemaMapper, schemaResolver); -- Gitee From d21bb2032586a76fcd719260faa0a0a9e134156d Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Fri, 11 Apr 2025 16:01:48 +0800 Subject: [PATCH 214/287] =?UTF-8?q?chore:=20=E8=AE=BE=E8=AE=A1=E5=99=A8?= =?UTF-8?q?=E9=80=82=E9=85=8D=E7=A7=BB=E5=8A=A8=E7=AB=AF=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile-supported-controller.json | 267 ++++++++++++++---- .../src/components/designer.component.tsx | 22 +- .../designer/src/components/types/basic.ts | 1 + .../composition/use-type-resolver-design.ts | 2 +- .../composition/entity/schema-dom-mapping.ts | 6 +- .../components/register-designer.ts | 2 +- .../property-config-resolver-design.ts | 3 +- .../property-config-resolver.ts | 9 +- .../use-property-config-resolver.ts | 4 +- 9 files changed, 235 insertions(+), 81 deletions(-) diff --git a/packages/designer/src/components/composition/command/supported-controllers/mobile-supported-controller.json b/packages/designer/src/components/composition/command/supported-controllers/mobile-supported-controller.json index 264ee50e48c..070d89c4029 100644 --- a/packages/designer/src/components/composition/command/supported-controllers/mobile-supported-controller.json +++ b/packages/designer/src/components/composition/command/supported-controllers/mobile-supported-controller.json @@ -1,139 +1,282 @@ { + "9ef56595-7cb7-4bbe-8f64-c6efcb7b1f9d": [ + { + "id": "719edeb6-5471-43b0-8d0b-5f1fc519bc9a", + "code": "Create" + }, + { + "id": "e7c7e7da-31d7-42fa-8674-36c04f671065", + "code": "CreateByPath" + }, + { + "id": "8e048c96-42b2-48ba-9504-e99714615da0", + "code": "Append" + } + ], + "0a68799b-48c6-4c9f-b0d7-140683c62b58": [ + { + "id": "16350846-55b7-452a-b5c9-fe03901e604c", + "code": "LoadForList" + }, + { + "id": "54b9b45e-eef3-4d5e-9708-bb1026e614d6", + "code": "LoadForCard" + }, + { + "id": "9dd24b2f-4a17-46c7-98c5-5a4b89511365", + "code": "LoadAndAddForCard" + }, + { + "id": "384ba725-0a14-4c98-92ec-491a93b946d5", + "code": "LoadAndEditForCard" + }, + { + "id": "5f66ed0e-636b-447b-b476-5b6091b01d2d", + "code": "LoadAndViewForCard" + }, + { + "id": "3c597c5e-0f15-491b-8ce0-4f6f51b258a5", + "code": "LoadAndAddForChildCard" + }, + { + "id": "799df45f-d4b9-49bd-900f-19b6c2e3d4be", + "code": "LoadAndEditForChildCard" + }, + { + "id": "f33ae378-45fe-4001-bf14-165457074599", + "code": "LoadAndViewForChildCard" + } + ], + "4ed10691-451e-4dd2-821a-0d2421e7c334": [ + { + "id": "57d6b105-0820-4722-b716-e42e44edda1c", + "code": "View" + }, + { + "id": "e47ae3f9-7789-4512-99cf-9a27bcafcd14", + "code": "ViewByPath" + } + ], + "05592163-fd45-474e-b0ab-61d7dc02e5c0": [ + { + "id": "e8dbc136-29ac-439e-98a7-e4f3d07470da", + "code": "Cancel" + } + ], + "f863c66a-bf93-4d1f-9f99-bcd76009609d": [ + { + "id": "9a78d149-0110-42bf-87b2-6f0aedcb635f", + "code": "SaveForCard" + }, + { + "id": "7de99e9f-659b-4b08-ad0c-425eefa1a04c", + "code": "SaveForChildCard" + }, + { + "id": "1aa455dd-9ecf-48a1-8296-a4559d2fac58", + "code": "SaveAndGoBackForChildCard" + }, + { + "id": "767f2faa-da44-4efd-83ff-aa591b31fc83", + "code": "Save" + }, + { + "id": "34ba8742-942d-4ef6-b903-bcd92258264e", + "code": "SaveAndValidateDataForCard" + } + ], + "f458e095-a3c6-43e8-a95b-fc886f6f619e": [ + { + "id": "2f8f14a9-a472-4667-9bf6-70f99199b2e9", + "code": "Edit" + }, + { + "id": "78176c86-bff8-4fc0-aed2-d4ec310bb45a", + "code": "EditByPath" + } + ], + "dab6b7f1-f56f-490a-879c-3d74232cd3ba": [ + { + "id": "5cc3d0e2-6382-46ee-a006-37d328eb74f4", + "code": "RemoveById" + }, + { + "id": "0b976739-1b02-40f1-8bb9-86a5e919f2c5", + "code": "RemoveByIds" + }, + { + "id": "e191d6a9-f72e-4479-80a7-ee5299f4e13b", + "code": "RemoveByPathAndId" + } + ], + "eae5387b-042d-45bf-93fa-f2c8085e9e5d": [ + { + "id": "498556a6-543b-490a-a436-8df0d8b8a567", + "code": "Update" + } + ], "910661bd-963a-4287-aa32-441c95b8720f": [ { - "id": "973bb999-b8dc-0ff5-0ba1-5cd7b816eba9", + "id": "d6938e12-2a7f-4bde-9344-8a2a6b7ae858", "code": "Navigate" }, { - "id": "4dd30b6a-f0d7-0799-7c04-593e5b71fd7b", + "id": "c6232e45-b248-4bcb-9a08-783f5eb4b1b8", "code": "NavigateForRtc" }, { - "id": "9dca239c-9153-70f9-e522-5ba2c384aa4f", + "id": "24b9e3c9-70c7-4c3a-9eb2-f65a832daded", "code": "GoBack" }, { - "id": "632f46ae-620e-3bb7-a75e-c43473624c49", + "id": "83928701-0dfa-410f-925e-dfb29aa00f3d", "code": "GoBackAndCheck" }, { - "id": "34c9cb64-0ea0-f483-2d51-c36ff0ee6cb2", + "id": "9cc3ef53-70bb-42db-949e-22b4861234fd", "code": "GoBackForChildCard" }, { - "id": "9740b808-9900-f494-516c-08e89640f5af", + "id": "6f19252c-c89d-47a6-a504-334348b6147f", "code": "CloseWindow" }, { - "id": "66371216-60d9-f2c3-734e-6b56b6e71d27", + "id": "ecb7f16e-6c48-4a7e-bff1-f770b9628aa0", "code": "NavigateAndCheck" }, { - "id": "b0d557ac-1ee8-8afe-73ea-006c43bd10d1", + "id": "0a750ff9-73d4-431d-8dd6-6460f5ecfbbf", "code": "NavigateForChildCard" } ], - "cf5e568a-5243-4539-94ea-e195eb4d6736": [ + "91cc23fb-2ecf-418b-9700-99469eab2e84": [ { - "id": "e875be9f-07b8-b8ac-e20b-53e6b3e7894d", - "code": "LoadPage" + "id": "e0212f85-453e-45d4-b51d-6ee256ee0830", + "code": "SubmitApprove" }, { - "id": "98b8d9a5-dc18-77e8-7bdf-7ea191c6bc8d", - "code": "LoadPageForList" + "id": "49d48df4-8c11-4558-864b-77fe74ed1823", + "code": "SaveAndSubmit" }, { - "id": "dd80df23-0cd7-b11c-1fa5-df8a8847b81b", - "code": "LoadPageForCard" + "id": "7acb49f4-237c-4b31-92e2-2524a2338148", + "code": "CancelSubmit" }, { - "id": "54f3153f-e646-e185-b403-5467b9984a78", - "code": "LoadPageForChildCard" + "id": "05fe4f03-7a6f-4333-95f7-bb0e92c3f096", + "code": "SubmitWithBizDefKey" }, { - "id": "6441c6c5-4f8d-e53e-2db0-639b4c81e418", - "code": "LoadListPage" + "id": "4fef2208-d449-4a08-850e-00dca35b3b9a", + "code": "CancelSubmitWithDataId" }, { - "id": "53827e22-6f6f-e0f3-e4a2-9ca3e6b8f568", - "code": "LoadCardPage" - } - ], - - "0a68799b-48c6-4c9f-b0d7-140683c62b58": [ + "id": "0431d656-94bc-4d0f-8a93-80120b42015d", + "code": "BatchSubmitWithBizDefKey" + }, { - "id": "06351c11-ec4b-f7b0-d9b4-e8bca9202b86", - "code": "LoadForList" + "id": "f141b4cd-1b08-409a-9068-5e580d5e00e8", + "code": "BatchCancelSubmitWithDataId" }, { - "id": "cb7f4216-0eb4-26a0-80b5-a38448e393c1", - "code": "LoadForCard" + "id": "3a58325a-d079-43cc-9cd8-b2715863a08a", + "code": "ChildSubmit" }, { - "id": "67edc617-d63a-b4f5-cdc7-4adba1b6e48b", - "code": "LoadAndAddForCard" + "id": "21cfd511-b591-433d-9c4c-f1b51a0334e0", + "code": "ChildCancelSubmit" }, { - "id": "33e538a8-717d-00ad-4cb6-a575f4b151c7", - "code": "LoadAndEditForCard" + "id": "cc3592ec-34f3-425e-a990-6c912b7fe319", + "code": "ChildBatchSubmit" }, { - "id": "d868341e-5eff-2a65-ba96-8b4fe5b243d7", - "code": "LoadAndViewForCard" + "id": "f6f8e28c-3a6f-4864-99b6-ac8a102ee7ed", + "code": "ChildBatchCancelSubmit" + } + ], + "ad4b014c-ff01-4bb0-8b3a-cb5e7dd2f8ea": [ + { + "id": "042cabd8-dcd7-4be4-b4f2-f22478d8b1ed", + "code": "uploadAndUpdateRow" }, { - "id": "afc70350-24fc-9879-9505-689f57575ec2", - "code": "LoadAndAddForChildCard" + "id": "8102a66f-8ad9-4bdb-963b-356993b0ef6c", + "code": "uploadAndBatchAddRows" }, { - "id": "4a7b5ccb-f61a-ac4f-e308-c00f6b52860b", - "code": "LoadAndEditForChildCard" + "id": "ae5fcdcf-d39a-4d12-a1f6-501585f09a6e", + "code": "removeAttachmentRows" }, { - "id": "9272925f-38d0-d814-2161-605f75240169", - "code": "LoadAndViewForChildCard" + "id": "4f49ca99-e305-4a9a-9dd1-05cdf69dca66", + "code": "updateAttachmentField" + }, + { + "id": "b1f3e9e6-7d02-4ebf-a547-c15f7e3695c0", + "code": "clearAttachmentField" } ], - "dab6b7f1-f56f-490a-879c-3d74232cd3ba": [ + "82cebb17-9f81-40be-86c3-389c5912bde7": [ { - "id": "eca45728-53c9-ca70-14ca-ec8eb468ee44", - "code": "RemoveById" + "id": "d29640d0-76cb-4e5c-a367-145638867fdf", + "code": "ExecuteAction" + } + ], + "f8149a59-0133-49cb-8793-1eacbdc357bd": [ + { + "id": "314f9113-8260-4f1d-992c-880e93e3f5e6", + "code": "AddComment" }, { - "id": "6036c9c0-1ee6-ab06-e311-78f5becca6b4", - "code": "RemoveByIds" + "id": "eb2d9a60-90de-47bb-ba35-192c8c2be863", + "code": "QueryInitComments" }, { - "id": "a35467a1-4ca7-5655-cd2a-18ce42a3097a", - "code": "RemoveByPathAndId" + "id": "90fc416d-19f4-4dab-af02-62e8a01c4da3", + "code": "SetReplyUser" + }, + { + "id": "e0933b21-cd0f-4b63-9804-72fad70de02b", + "code": "registerBeforeGetData" } ], - "f863c66a-bf93-4d1f-9f99-bcd76009609d": [ + "2051ecc9-0c92-4d26-99b9-24361b2a2335": [ { - "id": "129fb301-123d-6011-755d-c1aad5bf1dd3", - "code": "SaveForCard" + "id": "7f7ca2d2-1f58-42f6-a248-8106a66dac11", + "code": "SetLookupCustomData" + } + ], + "cf5e568a-5243-4539-94ea-e195eb4d6736": [ + { + "id": "814be6a0-39f0-4586-95f0-aa541c1ed18f", + "code": "LoadPage" }, { - "id": "2ade863f-4b38-7d2b-ca9f-87f1e18d8692", - "code": "SaveForChildCard" + "id": "04aed309-5865-4e08-88ce-28dd4cca1d63", + "code": "LoadPageForList" }, { - "id": "f7ebeab7-0481-041a-2cc4-d524840c6468", - "code": "SaveAndGoBackForChildCard" + "id": "b6e237a9-250f-4c23-8078-eaf85e7d0f8b", + "code": "LoadPageForCard" }, { - "id": "7eab8d99-4698-c0d4-4d2b-08bf724ed439", - "code": "Save" + "id": "cf2af519-f67e-46f3-85d1-6ba50f1580f0", + "code": "LoadPageForChildCard" }, { - "id": "55eb3067-d220-56dd-41b3-2228db302ae0", - "code": "SaveAndValidateDataForCard" + "id": "ef4be6f5-44d1-4966-8715-32a539dd78be", + "code": "LoadListPage" + }, + { + "id": "891496db-22f9-4a51-874a-f726e162d1fd", + "code": "LoadCardPage" } ], - "05592163-fd45-474e-b0ab-61d7dc02e5c0": [ + "efab0177-e16d-4d1f-9567-0bd1f607e53a": [ { - "id": "d5b847bd-ceb3-1b27-ed7f-b6b1e38088cd", - "code": "Cancel" + "id": "cc312b7a-995e-485d-a668-8c8d58b1b938", + "code": "setFieldsTruncateConfig" } ] } \ No newline at end of file diff --git a/packages/designer/src/components/designer.component.tsx b/packages/designer/src/components/designer.component.tsx index ece9834bcb4..b92c011f818 100644 --- a/packages/designer/src/components/designer.component.tsx +++ b/packages/designer/src/components/designer.component.tsx @@ -19,7 +19,7 @@ import { useCommandBuilderService } from "./composition/command-builder.service" import useFormStateMachine from './composition/use-form-statemachine'; import { MetadataService } from "./composition/metadata.service"; -import { UseDesignerContext } from "./types/designer-context"; +import { DesignerMode, UseDesignerContext } from "./types/designer-context"; export default defineComponent({ name: 'FDesigner', @@ -118,17 +118,25 @@ export default defineComponent({ const loadingInstance = loadingService?.show({ message: '解析中,请稍候...' }); const metadataId = useFormSchemaComposition.getFormMetadataBasicInfo()?.id; const relativePath = useFormSchemaComposition.getFormMetadataBasicInfo()?.relativePath; + const formCode = useFormSchemaComposition.getFormMetadataBasicInfo()?.code; useFormMetadataComposition.publishFormMetadata().then((publishInfo) => { if (publishInfo.result) { loadingInstance.value.close(); - const previewUrl = `${window.location.origin}/platform/common/web/renderer/index.html#/preview?metadataPath=${metadataPath}&projectPath=${relativePath}&metadataId=${metadataId}`; + let previewUrl; + if (designerContext.designerMode === DesignerMode.Mobile) { + const component = useFormSchemaComposition.getComponents()[0]; + const uri = component?.route?.uri; + previewUrl = `${window.location.origin}/platform/common/web/mobile-renderer/index.html#/${formCode}/${uri}?metadataPath=${metadataPath}&projectPath=${relativePath}&metadataId=${metadataId}`; + } else { + previewUrl = `${window.location.origin}/platform/common/web/renderer/index.html#/preview?metadataPath=${metadataPath}&projectPath=${relativePath}&metadataId=${metadataId}`; + } const windowProxy = window.open(previewUrl); if (!windowProxy) { - messageBoxService.error('预览失败,请调整浏览器安全设置后重试!'); - } - } else { - loadingInstance.value.close(); - messageBoxService.error(publishInfo.error || '表单解析失败'); + messageBoxService.error('预览失败,请调整浏览器安全设置后重试!'); + } + } else { + loadingInstance.value.close(); + messageBoxService.error(publishInfo.error || '表单解析失败'); } }); diff --git a/packages/designer/src/components/types/basic.ts b/packages/designer/src/components/types/basic.ts index 9f1a095b93b..a3e36ce32c3 100644 --- a/packages/designer/src/components/types/basic.ts +++ b/packages/designer/src/components/types/basic.ts @@ -132,6 +132,7 @@ export interface FormComponent { code?: string; name?: string; + route?:any; } /** diff --git a/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver-design.ts b/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver-design.ts index 9777e1d6971..d18293e03dd 100644 --- a/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver-design.ts +++ b/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver-design.ts @@ -1,4 +1,4 @@ -import { componentMap, componentPropsConverter } from '../../../../components/designer-canvas/src/components/maps'; +import { componentMap,componentPropsConverter } from '@/components/register-designer'; import FInputGroupDesign from '../../../input-group/src/designer/input-group.design.component'; import { EditorType, EditorConfig } from "../types"; import { UseTypeResolver } from "./types"; diff --git a/packages/mobile-ui-vue/components/property-panel/src/composition/entity/schema-dom-mapping.ts b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/schema-dom-mapping.ts index fe8b7152564..3fd0215be1e 100644 --- a/packages/mobile-ui-vue/components/property-panel/src/composition/entity/schema-dom-mapping.ts +++ b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/schema-dom-mapping.ts @@ -13,7 +13,7 @@ export class SchemaDOMMapping { { key: DgControl['date-picker'].type, value: DgControl['date-picker'].name }, { key: DgControl['check-group'].type, value: DgControl['check-group'].name }, { key: DgControl['radio-group'].type, value: DgControl['radio-group'].name }, - { key: DgControl['combo-list'].type, value: DgControl['combo-list'].name }, + { key: DgControl['picker'].type, value: DgControl['picker'].name }, { key: DgControl['textarea'].type, value: DgControl['textarea'].name }, ], Text: [ @@ -43,12 +43,12 @@ export class SchemaDOMMapping { { key: DgControl['check-box'].type, value: DgControl['check-box'].name }, ], Enum: [ - { key: DgControl['combo-list'].type, value: DgControl['combo-list'].name }, + { key: DgControl['picker'].type, value: DgControl['picker'].name }, { key: DgControl['radio-group'].type, value: DgControl['radio-group'].name }, ], Object: [ { key: DgControl['lookup'].type, value: DgControl['lookup'].name }, - { key: DgControl['combo-list'].type, value: DgControl['combo-list'].name }, + { key: DgControl['picker'].type, value: DgControl['picker'].name }, { key: DgControl['radio-group'].type, value: DgControl['radio-group'].name }, ] }; diff --git a/packages/mobile-ui-vue/components/register-designer.ts b/packages/mobile-ui-vue/components/register-designer.ts index 2f21751e448..dbb9c1503ac 100644 --- a/packages/mobile-ui-vue/components/register-designer.ts +++ b/packages/mobile-ui-vue/components/register-designer.ts @@ -28,4 +28,4 @@ function registerDesignerComponents(components: any[]) { }); } -export { registerDesignerComponents }; +export { registerDesignerComponents, componentMap, componentPropsConverter }; diff --git a/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver-design.ts b/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver-design.ts index e4fba29a4a8..85449d9b22f 100644 --- a/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver-design.ts +++ b/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver-design.ts @@ -1,11 +1,12 @@ import { EffectFunction } from '../../types'; import { usePropertyConfigResolver } from './use-property-config-resolver'; +import { resolveSchemaWithDefaultValueForDesigner } from "../schema/schema-resolver-design"; const propertyConfigSchemaMapForDesigner = {} as Record; const propertyEffectMapForDesigner = {} as Record; const { getPropertyConfigBySchema, getPropertyConfigByType, propertyConverterMap } = - usePropertyConfigResolver(propertyConfigSchemaMapForDesigner, propertyEffectMapForDesigner); + usePropertyConfigResolver(propertyConfigSchemaMapForDesigner, propertyEffectMapForDesigner, resolveSchemaWithDefaultValueForDesigner); export { getPropertyConfigBySchema as getPropertyConfigBySchemaForDesigner, getPropertyConfigByType as getPropertyConfigByTypeForDesigner, diff --git a/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver.ts b/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver.ts index 199cbf45c5e..728806ffbf2 100644 --- a/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver.ts +++ b/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/property-config-resolver.ts @@ -1,10 +1,11 @@ -import { EffectFunction} from '../../types'; +import { EffectFunction } from '../../types'; import { usePropertyConfigResolver } from './use-property-config-resolver'; +import { resolveSchemaWithDefaultValue } from "../schema/schema-resolver"; const propertyConfigSchemaMap = {} as Record; const propertyEffectMap = {} as Record; -const { getPropertyConfigBySchema, getPropertyConfigByType, propertyConverterMap } = - usePropertyConfigResolver(propertyConfigSchemaMap, propertyEffectMap); - +const { getPropertyConfigBySchema, getPropertyConfigByType, propertyConverterMap } = + usePropertyConfigResolver(propertyConfigSchemaMap, propertyEffectMap, resolveSchemaWithDefaultValue); + export { getPropertyConfigBySchema, getPropertyConfigByType, propertyConfigSchemaMap, propertyConverterMap, propertyEffectMap }; diff --git a/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts b/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts index e96fe51d4aa..de6b785ee54 100644 --- a/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts +++ b/packages/ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts @@ -3,7 +3,6 @@ import { EffectFunction, PropertyConverter, SchemaService } from '../../types'; import { EditorConfig } from "../../../../dynamic-form"; import { useObjectExpression } from '../../object-expression'; import { ComponentSchema } from "../../../../designer-canvas/src/types"; -import { resolveSchemaWithDefaultValue } from "../schema/schema-resolver"; import appearanceConverter from '../../converter/appearance.converter'; import buttonsConverter from "../../converter/buttons.converter"; import propertyEditorConverter from "../../converter/property-editor.converter"; @@ -17,7 +16,8 @@ import { ElementPropertyConfig, PropertyEntity } from "../../../../property-pane import itemsCountConverter from "../../converter/items-count.converter"; import formGroupLabelConverter from "../../converter/form-group-label.converter"; -export function usePropertyConfigResolver(propertyConfigSchemaMap: Record, propertyEffectMap: Record) { +export function usePropertyConfigResolver(propertyConfigSchemaMap: Record, propertyEffectMap: Record, + resolveSchemaWithDefaultValue: (schemaValue: Record) => Record) { const propertyConverterMap = new Map([ ['/converter/appearance.converter', appearanceConverter], ['/converter/buttons.converter', buttonsConverter], -- Gitee From a8a31602bdfdd80eb0b82665d46ada38f05c9be0 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Fri, 11 Apr 2025 16:06:07 +0800 Subject: [PATCH 215/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E8=AE=BE=E8=AE=A1=E6=97=B6=E5=B1=9E=E6=80=A7=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../use-mobile-control-creator.ts | 2 +- .../control-property-changed.service.ts | 2 +- .../use-mobile-designer-context.ts | 6 +- .../components/button-group/index.ts | 11 +-- .../components/checkbox-group/index.ts | 14 +--- .../src/utils/src/with-register-designer.ts | 9 ++- .../common/src/utils/src/with-register.ts | 10 ++- .../components/date-time-picker/index.ts | 8 +- .../src/date-time-picker.props.ts | 2 +- .../designer/date-picker.design.component.tsx | 54 +++++++++++++ .../src/designer/use-designer-rules.ts | 15 ++++ .../src/property-config/date-format.ts | 79 +++++++++++++++++++ .../date-picker.property-config.ts | 44 +++++++++++ .../src/schema/datetime-picker.schema.json | 2 +- .../src/schema/schema-mapper.ts | 2 +- .../src/schema/schema-resolver.ts | 2 +- .../designer-canvas/src/components/maps.ts | 2 +- .../src/composition/dg-control.ts | 2 +- .../src/composition/function/drag-resolve.tsx | 4 +- .../dynamic-resolver/src/props-resolver.ts | 2 +- .../resolver/schema/use-schema-resolver.ts | 2 +- .../components/form-item/index.ts | 19 +---- .../mobile-ui-vue/components/form/index.ts | 21 +---- .../components/input-group/index.ts | 19 +---- .../components/number-input/index.ts | 11 ++- .../number-input.design.component.tsx | 30 +++++++ .../src/designer/use-designer-rules.ts | 15 ++++ .../src/number-input.component.tsx | 4 +- .../number-input/src/number-input.props.ts | 6 +- .../number-input.property-config.ts | 20 +++++ .../src/schema/number-input.schema.json | 4 +- .../number-input/src/schema/schema-mapper.ts | 2 +- .../src/schema/schema-resolver.ts | 2 +- .../picker/src/schema/picker.schema.json | 2 +- .../mobile-ui-vue/components/switch/index.ts | 19 +---- .../components/textarea/index.ts | 15 +--- .../designer/textarea.design.component.tsx | 1 + 37 files changed, 330 insertions(+), 134 deletions(-) create mode 100644 packages/mobile-ui-vue/components/date-time-picker/src/designer/date-picker.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/date-time-picker/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-format.ts create mode 100644 packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts create mode 100644 packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/number-input/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts diff --git a/packages/designer/src/components/composition/control-creator/use-mobile-control-creator.ts b/packages/designer/src/components/composition/control-creator/use-mobile-control-creator.ts index 18808919572..36c3e602434 100644 --- a/packages/designer/src/components/composition/control-creator/use-mobile-control-creator.ts +++ b/packages/designer/src/components/composition/control-creator/use-mobile-control-creator.ts @@ -1,4 +1,4 @@ -import { getSchemaByType } from "@farris/mobile-ui-vue/components"; +import { getSchemaByType } from "@farris/mobile-ui-vue"; import { FormBindingType, FormSchemaEntityField, FormSchemaEntityFieldTypeName, UseControlCreator } from "../../types"; import { FormMetadataConverter } from "../form-metadata-converter"; diff --git a/packages/designer/src/components/composition/control-property-changed.service.ts b/packages/designer/src/components/composition/control-property-changed.service.ts index b6dd93b59bc..f642a2cdfd2 100644 --- a/packages/designer/src/components/composition/control-property-changed.service.ts +++ b/packages/designer/src/components/composition/control-property-changed.service.ts @@ -1,4 +1,4 @@ -import { FormPropertyChangeObject, SchemaDOMMapping } from "@farris/ui-vue"; +import { FormPropertyChangeObject, SchemaDOMMapping } from "@farris/ui-vue/components"; import { get, set } from "lodash-es"; import { FormBindingType, FormVariableCategory, UseDesignViewModel, UseFormSchema, UseSchemaService } from "../types"; import { DesignViewModelField } from "../types/design-viewmodel"; diff --git a/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts b/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts index b69bd7a9667..e2a9532f04f 100644 --- a/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts +++ b/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts @@ -3,9 +3,9 @@ import ToolboxItems from '../../types/toolbox/mobile-toolbox.json'; import SupportedControllers from '../../composition/command/supported-controllers/mobile-supported-controller.json'; import { - Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, + Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, Picker, ContentContainer, FloatContainer, Navbar, ListView, Form, FormItem, InputGroup, Button, registerDesignerComponents -} from '@farris/mobile-ui-vue/components'; +} from '@farris/mobile-ui-vue'; import { useMobileControlCreator } from "../control-creator/use-mobile-control-creator"; import { FormComponent, UseFormSchema } from "../../../components/types"; import ControllCategories from '../schema-repository/controller/mobile-categories'; @@ -22,7 +22,7 @@ export function useMobileDesignerContext(): UseDesignerContext { const componentsToRegister: any[] = [ Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, ContentContainer, FloatContainer, - Navbar, ListView, + Navbar, ListView,Picker, Form, FormItem, InputGroup, Button ]; diff --git a/packages/mobile-ui-vue/components/button-group/index.ts b/packages/mobile-ui-vue/components/button-group/index.ts index 8bd0183d780..4bb2569a6cc 100644 --- a/packages/mobile-ui-vue/components/button-group/index.ts +++ b/packages/mobile-ui-vue/components/button-group/index.ts @@ -1,18 +1,13 @@ import { Plugin } from 'vue'; -import { withInstall, RegisterContext } from '@farris/mobile-ui-vue/common'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import ButtonGroupInstallless from './src/button-group.component'; import { propsResolverGenerator } 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, registerContext: RegisterContext -) => { - componentMap[BUTTON_GROUP_REGISTERED_NAME] = ButtonGroup; - propsResolverMap[BUTTON_GROUP_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; +withRegister(ButtonGroup, { name: BUTTON_GROUP_REGISTERED_NAME, propsResolverGenerator }); +// withRegisterDesigner(ButtonGroup, { name: BUTTON_GROUP_REGISTERED_NAME, propsResolverGenerator, designerComponent: InputGroupDesign }); export * from './src/button-group.props'; export { ButtonGroup }; diff --git a/packages/mobile-ui-vue/components/checkbox-group/index.ts b/packages/mobile-ui-vue/components/checkbox-group/index.ts index d78ed2d4ed3..d40dfb75597 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/index.ts +++ b/packages/mobile-ui-vue/components/checkbox-group/index.ts @@ -1,4 +1,4 @@ -import { withInstall, RegisterContext } from '@farris/mobile-ui-vue/common'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import CheckboxGroupInstallless from './src/checkbox-group.component'; import { propsResolverGenerator } from './src/checkbox-group.props'; import CheckBoxGroupDesign from './src/designer/checkbox-group.design.component'; @@ -11,16 +11,8 @@ const CHECH_GROUP_REGISTERED_NAME = 'check-group'; const CheckboxGroup = withInstall(CheckboxGroupInstallless); -CheckboxGroup.register = (componentMap: Record, propsResolverMap: Record, - configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext) => { - componentMap[CHECH_GROUP_REGISTERED_NAME] = CheckboxGroup; - propsResolverMap[CHECH_GROUP_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; -CheckboxGroup.registerDesigner = (componentMap: Record, propsResolverMap: Record, - configresolverMap: Record, registerContext: RegisterContext) => { - componentMap[CHECH_GROUP_REGISTERED_NAME] = CheckBoxGroupDesign; - propsResolverMap[CHECH_GROUP_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; +withRegister(CheckboxGroup, { name: CHECH_GROUP_REGISTERED_NAME, propsResolverGenerator }); +withRegisterDesigner(CheckboxGroup, { name: CHECH_GROUP_REGISTERED_NAME, propsResolverGenerator, designerComponent: CheckBoxGroupDesign }); export { CheckboxGroup }; export default CheckboxGroup; diff --git a/packages/mobile-ui-vue/components/common/src/utils/src/with-register-designer.ts b/packages/mobile-ui-vue/components/common/src/utils/src/with-register-designer.ts index 0058b59394f..eb801e50c1b 100644 --- a/packages/mobile-ui-vue/components/common/src/utils/src/with-register-designer.ts +++ b/packages/mobile-ui-vue/components/common/src/utils/src/with-register-designer.ts @@ -1,4 +1,4 @@ -import { RegisterContext } from '@/components/common/types'; +import { RegisterContext } from '@farris/mobile-ui-vue/common/types'; import type { App, Component } from 'vue'; export type WithRegisterDesigner = T & { @@ -8,7 +8,12 @@ export type WithRegisterDesigner = T & { export function withRegisterDesigner(component: T, options: { name: string, designerComponent: Component, propsResolverGenerator: (registerContext: RegisterContext) => (schemaValue?: Record) => Record }) { const { name, designerComponent, propsResolverGenerator } = options; - (component as Record).registerDesigner = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, registerContext: RegisterContext) => { + (component as Record).registerDesigner = ( + componentMap: Record, + propsResolverMap: Record, + configResolverMap: Record, + registerContext: RegisterContext + ) => { componentMap[name] = designerComponent; propsResolverMap[name] = propsResolverGenerator(registerContext); }; diff --git a/packages/mobile-ui-vue/components/common/src/utils/src/with-register.ts b/packages/mobile-ui-vue/components/common/src/utils/src/with-register.ts index c26681843d5..94a387f7ed8 100644 --- a/packages/mobile-ui-vue/components/common/src/utils/src/with-register.ts +++ b/packages/mobile-ui-vue/components/common/src/utils/src/with-register.ts @@ -1,4 +1,4 @@ -import { RegisterContext } from '@/components/common/types'; +import { RegisterContext } from '@farris/mobile-ui-vue/common/types'; import type { App, Component } from 'vue'; export type WithRegister = T & { @@ -8,7 +8,13 @@ export type WithRegister = T & { export function withRegister(component: T, options: { name: string, propsResolverGenerator: (registerContext: RegisterContext) => (schemaValue?: Record) => Record }) { const { name, propsResolverGenerator } = options; - (component as Record).register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record, registerContext: RegisterContext) => { + (component as Record).register = ( + componentMap: Record, + propsResolverMap: Record, + configResolverMap: Record, + resolverMap: Record, + registerContext: RegisterContext + ) => { componentMap[name] = component; propsResolverMap[name] = propsResolverGenerator(registerContext); }; 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 1c939f183cc..04222bedc9c 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/index.ts +++ b/packages/mobile-ui-vue/components/date-time-picker/index.ts @@ -1,7 +1,8 @@ -import { withInstall, withRegister } from '@farris/mobile-ui-vue/common'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import DateTimePickerInputInstallless from './src/date-time-picker.component'; import DateTimePickerPanelInstallless from './src/date-time-picker-panel.component'; -import { propsResolver } from './src/date-time-picker.props'; +import { propsResolverGenerator } from './src/date-time-picker.props'; +import DateTimePickerDesigner from './src/designer/date-picker.design.component'; export * from './src/date-time-picker-panel.props'; @@ -10,7 +11,8 @@ const DateTimePicker = withInstall(DateTimePickerInputInstallless); // 注册运行时及设计时 const DATETIME_PICKER_REGISTERED_NAME = 'datetime-picker'; -withRegister(DateTimePicker, { name: DATETIME_PICKER_REGISTERED_NAME, propsResolver }); +withRegister(DateTimePicker, { name: DATETIME_PICKER_REGISTERED_NAME, propsResolverGenerator }); +withRegisterDesigner(DateTimePicker, { name: DATETIME_PICKER_REGISTERED_NAME, propsResolverGenerator, designerComponent: DateTimePickerDesigner }); export { DateTimePicker, DateTimePickerPanel }; export default DateTimePicker; 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 0adc5379481..c2a66c2a278 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 @@ -16,6 +16,6 @@ export const dateTimePickerProps = { export type DateTimePickerProps = ExtractPropTypes; -export const propsResolver = getPropsResolverGenerator( +export const propsResolverGenerator = getPropsResolverGenerator( dateTimePickerProps, dateTimePickerSchema, schemaMapper, schemaResolver ); diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/designer/date-picker.design.component.tsx b/packages/mobile-ui-vue/components/date-time-picker/src/designer/date-picker.design.component.tsx new file mode 100644 index 00000000000..a7ec3ac9de6 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-time-picker/src/designer/date-picker.design.component.tsx @@ -0,0 +1,54 @@ + +/** + * 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, defineComponent, inject, onMounted, ref, SetupContext } from 'vue'; + +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/designer-canvas';; +import { useDesignerRules } from './use-designer-rules'; +import { dateTimePickerProps } from '../date-time-picker.props'; +import DateTimePicker from '../date-time-picker.component'; + +export default defineComponent({ + name: 'FmDatePickerDesign', + props: dateTimePickerProps, + emits: [], + setup(props, context: SetupContext) { + const elementRef = ref(); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerHostService = inject('designer-host-service'); + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext,designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + context.expose(componentInstance.value); + + const inputProps = computed(() => ({ + ...props, + editable: false, + readonly: true, + modelValue:null + })); + + return () => { + return ( + + ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/date-time-picker/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..6dafcd627e2 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-time-picker/src/designer/use-designer-rules.ts @@ -0,0 +1,15 @@ +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext, UseDesignerRules } from "@farris/mobile-ui-vue/designer-canvas"; +import { DateTimePickerProperty } from "../property-config/date-picker.property-config"; +export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { + + const schema = designItemContext.schema as ComponentSchema; + + // 构造属性配置方法 + function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { + const dateTimePickerProps = new DateTimePickerProperty(componentId, designerHostService); + return dateTimePickerProps.getPropertyConfig(schema, componentInstance); + } + + return { getPropsConfig } as UseDesignerRules; + +} diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-format.ts b/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-format.ts new file mode 100644 index 00000000000..7a962b1db6a --- /dev/null +++ b/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-format.ts @@ -0,0 +1,79 @@ +export function DATE_FORMATS() { + + let languageCode = 'zh-CHS'; + if (window && window.top && window.top.localStorage && window.top.localStorage.languageCode) { + ({ languageCode } = window.top.localStorage); + } + + const timeFormats = [ + { id: 'yyyy-MM-dd HH:mm:ss', name: 'yyyy-MM-dd HH:mm:ss' }, + { id: 'yyyy/MM/dd HH:mm:ss', name: 'yyyy/MM/dd HH:mm:ss' }, + { id: 'yyyyMMddHHmmss', name: 'yyyyMMddHHmmss' }, + { id: 'yyyy-MM-dd HH:mm', name: 'yyyy-MM-dd HH:mm' }, + { id: 'yyyy/MM/dd HH:mm', name: 'yyyy/MM/dd HH:mm' }, + { id: 'yyyyMMddHHmm', name: 'yyyyMMddHHmm' } + ]; + const yMdFormats = [ + { id: 'yyyy-MM-dd', name: 'yyyy-MM-dd' }, + { id: 'yyyy/MM/dd', name: 'yyyy/MM/dd' }, + { id: 'yyyyMMdd', name: 'yyyyMMdd' }, + { id: 'MM/dd/yyyy', name: 'MM/dd/yyyy' } + ]; + const yMFormats = [ + { id: 'yyyy-MM', name: 'yyyy-MM' }, + { id: 'yyyy/MM', name: 'yyyy/MM' }, + { id: 'yyyyMM', name: 'yyyyMM' } + ]; + + const mdFormats = [ + { id: 'MM/dd', name: 'MM/dd' }, + { id: 'MMdd', name: 'MMdd' }, + { id: 'MM-dd', name: 'MM-dd' } + ]; + + const yFormats = [ + { id: 'yyyy', name: 'yyyy' } + ]; + + // 区分语言 + if (languageCode === 'zh-CHS') { + timeFormats.push( + { id: 'yyyy年MM月dd日 HH时mm分ss秒', name: 'yyyy年MM月dd日 HH时mm分ss秒' }, + { id: 'yyyy年MM月dd日 HH时mm分', name: 'yyyy年MM月dd日 HH时mm分' } + ); + yMdFormats.push( + { id: 'yyyy年MM月dd日', name: 'yyyy年MM月dd日' } + ); + yMFormats.push( + { id: 'yyyy年MM月', name: 'yyyy年MM月' } + ); + mdFormats.push( + { id: 'MM月dd日', name: 'MM月dd日' } + ); + yFormats.push( + { id: 'yyyy年', name: 'yyyy年' } + ); + } + if (languageCode === 'zh-CHT') { + timeFormats.push( + { id: 'yyyy年MM月dd日 HH時mm分ss秒', name: 'yyyy年MM月dd日 HH時mm分ss秒' }, + { id: 'yyyy年MM月dd日 HH時mm分', name: 'yyyy年MM月dd日 HH時mm分' } + ); + yMdFormats.push( + { id: 'yyyy年MM月dd日', name: 'yyyy年MM月dd日' } + ); + yMFormats.push( + { id: 'yyyy年MM月', name: 'yyyy年MM月' } + ); + mdFormats.push( + { id: 'MM月dd日', name: 'MM月dd日' } + ); + yFormats.push( + { id: 'yyyy年', name: 'yyyy年' } + ); + } + + + return { timeFormats, yMFormats, yMdFormats, mdFormats, yFormats }; + +} diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts b/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts new file mode 100644 index 00000000000..7503bc65889 --- /dev/null +++ b/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts @@ -0,0 +1,44 @@ +import { InputBaseProperty } from "@farris/mobile-ui-vue/common/src/entity/input-base-property"; +import { DATE_FORMATS } from "./date-format"; + +export class DateTimePickerProperty extends InputBaseProperty { + + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + + getEditorProperties(propertyData: any) { + const displayFormatOptions = this.getDateFormatOptions(propertyData?.editor); + return this.getComponentConfig(propertyData, { type: "year-month-day" }, { + placeholder: { + description: "空值时,输入控件内的占位文本", + title: "提示文本", + type: "string" + }, + displayFormat: { + description: "", + title: "显示格式", + type: "enum", + editor: { + data: displayFormatOptions + } + } + }); + } + + private getDateFormatOptions(editorData: any) { + let formats: any[] = []; + const { timeFormats, yMdFormats, yMFormats, mdFormats, yFormats } = DATE_FORMATS(); + + formats = formats.concat(timeFormats); + + formats = formats.concat(yMdFormats); + formats = formats.concat(yMFormats); + formats = formats.concat(yFormats); + formats = formats.concat(mdFormats); + + return formats; + } + +} diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/schema/datetime-picker.schema.json b/packages/mobile-ui-vue/components/date-time-picker/src/schema/datetime-picker.schema.json index 75a07a3f608..73f07942ace 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/schema/datetime-picker.schema.json +++ b/packages/mobile-ui-vue/components/date-time-picker/src/schema/datetime-picker.schema.json @@ -12,7 +12,7 @@ "type": { "description": "控件类型", "type": "string", - "default": "textarea" + "default": "datetime-picker" }, "appearance": { "description": "外观", diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/date-time-picker/src/schema/schema-mapper.ts index 00a707c6fba..a14506b5dd6 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/date-time-picker/src/schema/schema-mapper.ts @@ -1,4 +1,4 @@ -import { MapperFunction, resolveAppearance } from '@/components/dynamic-resolver'; +import { MapperFunction, resolveAppearance } from '@farris/mobile-ui-vue/dynamic-resolver'; export const schemaMapper = new Map([ ['appearance', resolveAppearance], diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/date-time-picker/src/schema/schema-resolver.ts index 660e1e609e1..7c8af7fc63d 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/schema/schema-resolver.ts +++ b/packages/mobile-ui-vue/components/date-time-picker/src/schema/schema-resolver.ts @@ -1,4 +1,4 @@ -import { DynamicResolver } from "@/components/dynamic-resolver"; +import { DynamicResolver } from "@farris/mobile-ui-vue/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 6e244c258fc..329fd482b8e 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, DatePicker, FormItem, PageHeaderContainer, Picker, RadioGroup, Switch } from "@/components"; +import { CheckboxGroup, ContentContainer, DatePicker, FormItem, PageHeaderContainer, Picker, RadioGroup, Switch } from "@farris/mobile-ui-vue"; import Button from "@farris/mobile-ui-vue/button"; import Component from "@farris/mobile-ui-vue/component"; import FloatContainer from "@farris/mobile-ui-vue/float-container"; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts index 6e44a4bd847..92fbcf39ee5 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts @@ -43,6 +43,6 @@ export const DgControl = { 'navbar': { type: 'navbar', name: '导航栏', icon: 'NavBar' }, - 'enum-field': { type: 'enum-field', name: '选择器', icon: 'EnumField' }, + 'picker': { type: 'picker', name: '选择器', icon: 'EnumField' }, }; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/drag-resolve.tsx b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/drag-resolve.tsx index 491c53d94b1..05dbcb49147 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/drag-resolve.tsx +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/drag-resolve.tsx @@ -1,9 +1,9 @@ import { ModalFunctions } from "../../../../modal/src/composition/type"; import { ComponentBindingSourceContext, DesignerHostService, DesignerHTMLElement, DraggingResolveContext } from "../types"; -import { DesignViewModelField, FormVariable } from "../../../../common/entity/entity-schema"; +import { DesignViewModelField, FormVariable } from "../../../../common/src/entity/entity-schema"; import { merge } from "lodash-es"; import { DgControl } from "../dg-control"; -import { DesignerComponentInstance } from "@/components"; +import { DesignerComponentInstance } from "@farris/mobile-ui-vue"; export function dragResolveService(designerHostService: DesignerHostService) { /** 弹窗实例 */ diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts index 7334627b13f..ad0cbb6f00d 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts @@ -1,7 +1,7 @@ import { DesignerHostService } from './../../designer-canvas/src/composition/types'; import { resolveSchemaToProps } from './resolver/schema/schema-resolver'; import { DynamicResolver, EffectFunction, MapperFunction, SchemaResolverFunction } from './types'; -import { RegisterContext } from '@/components/common'; +import { RegisterContext } from '@farris/mobile-ui-vue/common'; /** * 注册schema和props diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts index 96fb6a51599..24e765c8fbe 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts @@ -1,6 +1,6 @@ import { cloneDeep, isPlainObject } from "lodash-es"; import { MapperFunction, SchemaResolverFunction } from "../../types"; -import { DesignerHostService } from "@components/designer-canvas"; +import { DesignerHostService } from "@farris/mobile-ui-vue/designer-canvas"; export function useSchemaResolver(schemaMap: Record, schemaResolverMap: Record) { diff --git a/packages/mobile-ui-vue/components/form-item/index.ts b/packages/mobile-ui-vue/components/form-item/index.ts index f8258f39a4a..3a7475c17ac 100644 --- a/packages/mobile-ui-vue/components/form-item/index.ts +++ b/packages/mobile-ui-vue/components/form-item/index.ts @@ -1,4 +1,4 @@ -import { withInstall, RegisterContext } from '@farris/mobile-ui-vue/common'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import { propsResolverGenerator } from './src/form-item.props'; import FormItemInstallless from './src/form-item.component'; import FormItemDesign from './src/designer/form-item.design.component'; @@ -7,21 +7,8 @@ const FORM_ITEM_REGISTERED_NAME = 'form-group'; const FormItem = withInstall(FormItemInstallless); -FormItem.register = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext -) => { - componentMap[FORM_ITEM_REGISTERED_NAME] = FormItem; - propsResolverMap[FORM_ITEM_REGISTERED_NAME] = propsResolverGenerator; -}; - -FormItem.registerDesigner = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext -) => { - componentMap[FORM_ITEM_REGISTERED_NAME] = FormItemDesign; - propsResolverMap[FORM_ITEM_REGISTERED_NAME] = propsResolverGenerator; -}; +withRegister(FormItem, { name: FORM_ITEM_REGISTERED_NAME, propsResolverGenerator }); +withRegisterDesigner(FormItem, { name: FORM_ITEM_REGISTERED_NAME, propsResolverGenerator, designerComponent: FormItemDesign }); export * from './src/form-item.props'; export { FormItem }; diff --git a/packages/mobile-ui-vue/components/form/index.ts b/packages/mobile-ui-vue/components/form/index.ts index e064f839aeb..b91f4f8ab50 100644 --- a/packages/mobile-ui-vue/components/form/index.ts +++ b/packages/mobile-ui-vue/components/form/index.ts @@ -15,30 +15,17 @@ * limitations under the License. */ import { Plugin } from 'vue'; -import { withInstall, RegisterContext } from '@farris/mobile-ui-vue/common'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import { propsResolverGenerator } from '@farris/mobile-ui-vue/form-item/src/form.props'; import FormInstallless from '@farris/mobile-ui-vue/form-item/src/form.component'; -import FormInstalllessDesign from '../form-item/src/designer/response-form.design.component'; +import FormDesign from '../form-item/src/designer/response-form.design.component'; const FORM_REGISTERED_NAME = 'form'; const Form = withInstall(FormInstallless); -Form.register = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext -) => { - componentMap[FORM_REGISTERED_NAME] = Form; - propsResolverMap[FORM_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; - -Form.registerDesigner = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext -) => { - componentMap[FORM_REGISTERED_NAME] = FormInstalllessDesign; - propsResolverMap[FORM_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; +withRegister(Form, { name: FORM_REGISTERED_NAME, propsResolverGenerator }); +withRegisterDesigner(Form, { name: FORM_REGISTERED_NAME, propsResolverGenerator, designerComponent: FormDesign }); export * from '@farris/mobile-ui-vue/form-item/src/form.props'; export { Form }; diff --git a/packages/mobile-ui-vue/components/input-group/index.ts b/packages/mobile-ui-vue/components/input-group/index.ts index 652e74c0a50..e7494d76fdb 100644 --- a/packages/mobile-ui-vue/components/input-group/index.ts +++ b/packages/mobile-ui-vue/components/input-group/index.ts @@ -1,4 +1,4 @@ -import { withInstall, RegisterContext } from '@farris/mobile-ui-vue/common'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import { propsResolverGenerator } from './src/input-group.props'; import InputGroupInstallless from './src/input-group.component'; import InputGroupDesign from './src/designer/input-group.design.component'; @@ -7,21 +7,8 @@ const INPUT_GROUP_REGISTERED_NAME = 'input-group'; const InputGroup = withInstall(InputGroupInstallless); -InputGroup.register = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext -) => { - componentMap[INPUT_GROUP_REGISTERED_NAME] = InputGroup; - propsResolverMap[INPUT_GROUP_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; - -InputGroup.registerDesigner = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext -) => { - componentMap[INPUT_GROUP_REGISTERED_NAME] = InputGroupDesign; - propsResolverMap[INPUT_GROUP_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; +withRegister(InputGroup, { name: INPUT_GROUP_REGISTERED_NAME, propsResolverGenerator }); +withRegisterDesigner(InputGroup, { name: INPUT_GROUP_REGISTERED_NAME, propsResolverGenerator, designerComponent: InputGroupDesign }); export * from './src/input-group.props'; export * from './src/types'; diff --git a/packages/mobile-ui-vue/components/number-input/index.ts b/packages/mobile-ui-vue/components/number-input/index.ts index 7f5900346d4..3f43cf190a4 100644 --- a/packages/mobile-ui-vue/components/number-input/index.ts +++ b/packages/mobile-ui-vue/components/number-input/index.ts @@ -1,6 +1,7 @@ -import { withInstall } from '@farris/mobile-ui-vue/common'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import NumberInputInstallless from './src/number-input.component'; -import { propsResolver } from './src/number-input.props'; +import { propsResolverGenerator } from './src/number-input.props'; +import NumberInputDesign from './src/designer/number-input.design.component'; export * from './src/number-input.props'; @@ -8,10 +9,8 @@ const NUMBER_INPUT_REGISTERED_NAME = 'number-input'; 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; -}; +withRegister(NumberInput, { name: NUMBER_INPUT_REGISTERED_NAME, propsResolverGenerator }); +withRegisterDesigner(NumberInput, { name: NUMBER_INPUT_REGISTERED_NAME, propsResolverGenerator, designerComponent: NumberInputDesign }); export { NumberInput }; export default NumberInput; diff --git a/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx b/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx new file mode 100644 index 00000000000..c9a170b7c4d --- /dev/null +++ b/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx @@ -0,0 +1,30 @@ +import { defineComponent, inject, onMounted, ref, SetupContext } from 'vue'; + +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/designer-canvas';; +import { useDesignerRules } from './use-designer-rules'; +import { numberInputProps } from '../number-input.props'; +import InputGroup from '../..'; + +export default defineComponent({ + name: 'FmNunberInputDesign', + props: numberInputProps, + emits: [], + setup(props, context: SetupContext) { + const elementRef = ref(); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerHostService = inject('designer-host-service'); + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + context.expose(componentInstance.value); + + + return () => ( + + ); + } +}); diff --git a/packages/mobile-ui-vue/components/number-input/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/number-input/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..12ebbbcebe3 --- /dev/null +++ b/packages/mobile-ui-vue/components/number-input/src/designer/use-designer-rules.ts @@ -0,0 +1,15 @@ +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext, UseDesignerRules } from "@farris/mobile-ui-vue/designer-canvas"; +import { NumberInputProperty } from "../property-config/number-input.property-config"; +export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { + + const schema = designItemContext.schema as ComponentSchema; + + // 构造属性配置方法 + function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { + const numberInputProps = new NumberInputProperty(componentId, designerHostService); + return numberInputProps.getPropertyConfig(schema, componentInstance); + } + + return { getPropsConfig } as UseDesignerRules; + +} 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 index 5b1f2b1b786..c17b190c06e 100644 --- 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 @@ -15,8 +15,8 @@ */ import { defineComponent, SetupContext } from 'vue'; -import { useBem } from '@/components/common'; -import InputGroup from "@/components/input-group"; +import { useBem } from '@farris/mobile-ui-vue/common'; +import InputGroup from "@farris/mobile-ui-vue/input-group"; import { NUMBER_INPUT_NAME, numberInputProps, NumberInputProps } from './number-input.props'; export default defineComponent({ 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 index 3dc6e215977..fb1e2812957 100644 --- 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 @@ -1,6 +1,6 @@ import { ExtractPropTypes } from 'vue'; -import { inputCommonProps } from '@/components/input-group'; -import { getPropsResolverGenerator } from '@/components/dynamic-resolver'; +import { inputCommonProps } from '@farris/mobile-ui-vue/input-group'; +import { getPropsResolverGenerator } from '@farris/mobile-ui-vue/dynamic-resolver'; import numberInputSchema from './schema/number-input.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; @@ -15,4 +15,4 @@ export const numberInputProps = { export type NumberInputProps = ExtractPropTypes; -export const propsResolver = getPropsResolverGenerator(numberInputProps, numberInputSchema, schemaMapper, schemaResolver); +export const propsResolverGenerator = getPropsResolverGenerator(numberInputProps, numberInputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts b/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts new file mode 100644 index 00000000000..6805fcedb92 --- /dev/null +++ b/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts @@ -0,0 +1,20 @@ +import { InputBaseProperty } from "@farris/mobile-ui-vue/common/src/entity/input-base-property"; + +export class NumberInputProperty extends InputBaseProperty { + + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + + getEditorProperties(propertyData: any) { + return this.getComponentConfig(propertyData, { type: "year-month-day" }, { + placeholder: { + description: "空值时,输入控件内的占位文本", + title: "提示文本", + type: "string" + }, + }); + } + +} diff --git a/packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json b/packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json index 5efd6ace2fe..77d8162dab9 100644 --- a/packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json +++ b/packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json @@ -10,9 +10,9 @@ "type": "string" }, "type": { - "description": "类型", + "description": "控件类型", "type": "string", - "default": "textarea" + "default": "number-input" }, "appearance": { "description": "外观", 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 index d1c21abde8b..42b3a02141c 100644 --- 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 @@ -1,4 +1,4 @@ -import { MapperFunction, resolveAppearance } from '@/components/dynamic-resolver'; +import { MapperFunction, resolveAppearance } from '@farris/mobile-ui-vue/dynamic-resolver'; export const schemaMapper = new Map([ ['appearance', resolveAppearance], 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 index 660e1e609e1..7c8af7fc63d 100644 --- 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 @@ -1,4 +1,4 @@ -import { DynamicResolver } from "@/components/dynamic-resolver"; +import { DynamicResolver } from "@farris/mobile-ui-vue/dynamic-resolver"; export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { return schema; diff --git a/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json b/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json index 697dadb0045..19a83d6350b 100644 --- a/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json +++ b/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json @@ -12,7 +12,7 @@ "type": { "description": "控件类型", "type": "string", - "default": "enum-field" + "default": "picker" }, "appearance": { "description": "外观", diff --git a/packages/mobile-ui-vue/components/switch/index.ts b/packages/mobile-ui-vue/components/switch/index.ts index 75b86b59c50..004a82cdfd6 100644 --- a/packages/mobile-ui-vue/components/switch/index.ts +++ b/packages/mobile-ui-vue/components/switch/index.ts @@ -1,4 +1,4 @@ -import { withInstall, RegisterContext } from '@farris/mobile-ui-vue/common'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import SwitchInstallless from "./src/switch.component"; import SwitchDesign from './src/designer/switch.design.component'; import { propsResolverGenerator } from './src/switch.props'; @@ -10,21 +10,8 @@ const SWITCH_REGISTERED_NAME = 'switch'; const Switch = withInstall(SwitchInstallless); -Switch.register = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext -) => { - componentMap[SWITCH_REGISTERED_NAME] = Switch; - propsResolverMap[SWITCH_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; - -Switch.registerDesigner = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext -) => { - componentMap[SWITCH_REGISTERED_NAME] = SwitchDesign; - propsResolverMap[SWITCH_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; +withRegister(Switch, { name: SWITCH_REGISTERED_NAME, propsResolverGenerator }); +withRegisterDesigner(Switch, { name: SWITCH_REGISTERED_NAME, propsResolverGenerator, designerComponent: SwitchDesign }); export { Switch }; export default Switch; diff --git a/packages/mobile-ui-vue/components/textarea/index.ts b/packages/mobile-ui-vue/components/textarea/index.ts index 07886bae83a..524590e7db1 100644 --- a/packages/mobile-ui-vue/components/textarea/index.ts +++ b/packages/mobile-ui-vue/components/textarea/index.ts @@ -1,4 +1,4 @@ -import { withInstall, RegisterContext } from '@farris/mobile-ui-vue/common'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import TextareaInstallless from './src/textarea.component'; import TextareaDesign from './src/designer/textarea.design.component'; import { propsResolverGenerator } from './src/textarea.props'; @@ -9,17 +9,8 @@ const TEXTAREA_REGISTERED_NAME = 'textarea'; const Textarea = withInstall(TextareaInstallless); -Textarea.register = (componentMap: Record, propsResolverMap: Record, - configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext) => { - componentMap[TEXTAREA_REGISTERED_NAME] = Textarea; - propsResolverMap[TEXTAREA_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; -Textarea.registerDesigner = (componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext) => { - componentMap[TEXTAREA_REGISTERED_NAME] = TextareaDesign; - propsResolverMap[TEXTAREA_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; - +withRegister(Textarea, { name: TEXTAREA_REGISTERED_NAME, propsResolverGenerator }); +withRegisterDesigner(Textarea, { name: TEXTAREA_REGISTERED_NAME, propsResolverGenerator, designerComponent: TextareaDesign }); export { Textarea }; export default Textarea; diff --git a/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx b/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx index 7e60fbef2e6..e125d0ec7ca 100644 --- a/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx +++ b/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx @@ -37,6 +37,7 @@ export default defineComponent({ const inputGroupProps = computed(() => ({ ...props, + type:"textarea", editable: false, modelValue:null })); -- Gitee From aea4ad100b9d14b378db5c1a552e42669ad42a76 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Fri, 11 Apr 2025 16:09:08 +0800 Subject: [PATCH 216/287] =?UTF-8?q?chore:=20=E8=AE=BE=E8=AE=A1=E5=99=A8?= =?UTF-8?q?=E9=80=82=E9=85=8D=E7=A7=BB=E5=8A=A8=E7=AB=AF=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/designer-canvas/src/composition/dg-control.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts index 6e44a4bd847..92fbcf39ee5 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts @@ -43,6 +43,6 @@ export const DgControl = { 'navbar': { type: 'navbar', name: '导航栏', icon: 'NavBar' }, - 'enum-field': { type: 'enum-field', name: '选择器', icon: 'EnumField' }, + 'picker': { type: 'picker', name: '选择器', icon: 'EnumField' }, }; -- Gitee From 3096cade7daca1e08ba4b579674ec310c3dff7c8 Mon Sep 17 00:00:00 2001 From: LuPing Zou <“zouluping@inspur.com”> Date: Fri, 11 Apr 2025 11:44:13 +0800 Subject: [PATCH 217/287] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dpr=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile-ui-vue/components/card/src/card.props.ts | 4 ++-- .../components/content-container/index.ts | 2 +- .../components/date-time-picker/index.ts | 2 +- .../date-time-picker/src/date-time-picker.props.ts | 4 ++-- .../components/float-container/index.ts | 2 +- packages/mobile-ui-vue/components/navbar/index.ts | 6 ++++-- .../mobile-ui-vue/components/number-input/index.ts | 9 ++++++--- .../number-input/src/number-input.props.ts | 4 ++-- .../components/page-body-container/index.ts | 6 ++++-- .../mobile-ui-vue/components/page-container/index.ts | 8 ++++---- .../components/page-footer-container/index.ts | 2 +- .../components/page-header-container/index.ts | 2 +- packages/mobile-ui-vue/components/register.ts | 12 +++++++++++- packages/mobile-ui-vue/farris.config.mjs | 7 +++---- 14 files changed, 43 insertions(+), 27 deletions(-) diff --git a/packages/mobile-ui-vue/components/card/src/card.props.ts b/packages/mobile-ui-vue/components/card/src/card.props.ts index 76b4b1ef63b..22306fa6b4b 100644 --- a/packages/mobile-ui-vue/components/card/src/card.props.ts +++ b/packages/mobile-ui-vue/components/card/src/card.props.ts @@ -1,5 +1,5 @@ import { ExtractPropTypes } from 'vue'; -import { createPropsResolver } from '@components/dynamic-resolver'; +import { getPropsResolverGenerator } from '@components/dynamic-resolver'; import { ButtonItem } from '@components/button-group'; import cardSchema from './schema/card.schema.json'; import { schemaMapper } from './schema/schema-mapper'; @@ -22,7 +22,7 @@ export const cardProps = { toolbarItems: { type: Array, default: [] }, }; -export const propsResolver = createPropsResolver( +export const propsResolver = getPropsResolverGenerator( cardProps, cardSchema, schemaMapper, diff --git a/packages/mobile-ui-vue/components/content-container/index.ts b/packages/mobile-ui-vue/components/content-container/index.ts index d6c256518cf..744717a9c7b 100644 --- a/packages/mobile-ui-vue/components/content-container/index.ts +++ b/packages/mobile-ui-vue/components/content-container/index.ts @@ -12,7 +12,7 @@ FContentContainer.install = (app: App) => { FContentContainer.register = ( componentMap: Record, propsResolverMap: Record, - configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext ) => { componentMap[CONTENT_CONTAINER_REGISTERED_NAME] = FContentContainer; propsResolverMap[CONTENT_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); 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 8857ca520d6..f8a83a6a232 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/index.ts +++ b/packages/mobile-ui-vue/components/date-time-picker/index.ts @@ -10,7 +10,7 @@ const DateTimePicker = withInstall(DateTimePickerInputInstallless); // 注册运行时及设计时 const DATETIME_PICKER_REGISTERED_NAME = 'datetime-picker'; -withRegister(DateTimePicker, { name: DATETIME_PICKER_REGISTERED_NAME, propsResolver }); +withRegister(DateTimePicker, { name: DATETIME_PICKER_REGISTERED_NAME, propsResolverGenerator: propsResolver }); export { DateTimePicker, DateTimePickerPanel }; export default DateTimePicker; 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 2806cdb6847..59d05184fd7 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,7 +1,7 @@ import { ExtractPropTypes } from 'vue'; import { buttonEditProps } from '@/components/button-edit'; import { dateTimePickerPanelProps } from './date-time-picker-panel.props'; -import { createPropsResolver } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '../../dynamic-resolver'; import { schemaResolver } from './schema/schema-resolver'; import { schemaMapper } from './schema/schema-mapper'; import dateTimePickerSchema from './schema/datetime-picker.schema.json' @@ -15,6 +15,6 @@ export const dateTimePickerProps = { export type DateTimePickerProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( +export const propsResolver = getPropsResolverGenerator( dateTimePickerProps, dateTimePickerSchema, schemaMapper, schemaResolver ); diff --git a/packages/mobile-ui-vue/components/float-container/index.ts b/packages/mobile-ui-vue/components/float-container/index.ts index e11c0591c1d..002ce51ba65 100644 --- a/packages/mobile-ui-vue/components/float-container/index.ts +++ b/packages/mobile-ui-vue/components/float-container/index.ts @@ -10,7 +10,7 @@ const FloatContainer = withInstall(FloatContainerInstallless); FloatContainer.register = ( componentMap: Record, propsResolverMap: Record, - configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext ) => { componentMap[FLOAT_CONTAINER_REGISTERED_NAME] = FloatContainer; propsResolverMap[FLOAT_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); diff --git a/packages/mobile-ui-vue/components/navbar/index.ts b/packages/mobile-ui-vue/components/navbar/index.ts index 8220d80abc4..5d10977d1a6 100644 --- a/packages/mobile-ui-vue/components/navbar/index.ts +++ b/packages/mobile-ui-vue/components/navbar/index.ts @@ -7,8 +7,10 @@ const NAVBAR_REGISTERED_NAME = 'navbar'; const Navbar = withInstall(NavbarInstallless); -Navbar.register = (componentMap: Record, propsResolverMap: Record, - configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext) => { +Navbar.register = ( + componentMap: Record, propsResolverMap: Record, + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext +) => { componentMap[NAVBAR_REGISTERED_NAME] = Navbar; propsResolverMap[NAVBAR_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; diff --git a/packages/mobile-ui-vue/components/number-input/index.ts b/packages/mobile-ui-vue/components/number-input/index.ts index 7b914dfea58..83dbf08be13 100644 --- a/packages/mobile-ui-vue/components/number-input/index.ts +++ b/packages/mobile-ui-vue/components/number-input/index.ts @@ -1,4 +1,4 @@ -import { withInstall } from '@components/common'; +import { RegisterContext, withInstall } from '@components/common'; import NumberInputInstallless from './src/number-input.component'; import { propsResolver } from './src/number-input.props'; @@ -8,9 +8,12 @@ const NUMBER_INPUT_REGISTERED_NAME = 'number-input'; const NumberInput = withInstall(NumberInputInstallless); -NumberInput.register = (componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record) => { +NumberInput.register = ( + componentMap: Record, propsResolverMap: Record, + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext +) => { componentMap[NUMBER_INPUT_REGISTERED_NAME] = NumberInput; - propsResolverMap[NUMBER_INPUT_REGISTERED_NAME] = propsResolver; + propsResolverMap[NUMBER_INPUT_REGISTERED_NAME] = propsResolver(registerContext); }; export { NumberInput }; 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 index 836ba36b0af..3dc6e215977 100644 --- 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 @@ -1,6 +1,6 @@ import { ExtractPropTypes } from 'vue'; import { inputCommonProps } from '@/components/input-group'; -import { createPropsResolver } from '@/components/dynamic-resolver'; +import { getPropsResolverGenerator } from '@/components/dynamic-resolver'; import numberInputSchema from './schema/number-input.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; @@ -15,4 +15,4 @@ export const numberInputProps = { export type NumberInputProps = ExtractPropTypes; -export const propsResolver = createPropsResolver(numberInputProps, numberInputSchema, schemaMapper, schemaResolver); +export const propsResolver = getPropsResolverGenerator(numberInputProps, numberInputSchema, schemaMapper, schemaResolver); 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 7d4ff284dae..180a62c6251 100644 --- a/packages/mobile-ui-vue/components/page-body-container/index.ts +++ b/packages/mobile-ui-vue/components/page-body-container/index.ts @@ -22,8 +22,10 @@ import { propsResolverGenerator } from './src/page-body-container.props'; const PAGE_BODY_CONTAINER_REGISTER_NAME = 'page-body-container'; const PageBodyContainer = withInstall(PageBodyContainerInstallless); -PageBodyContainer.register = (componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext): void => { +PageBodyContainer.register = ( + componentMap: Record, propsResolverMap: Record, + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext +): void => { componentMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = PageBodyContainer; propsResolverMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = propsResolverGenerator(registerContext); }; diff --git a/packages/mobile-ui-vue/components/page-container/index.ts b/packages/mobile-ui-vue/components/page-container/index.ts index 9fa20b8158b..fabc705e175 100644 --- a/packages/mobile-ui-vue/components/page-container/index.ts +++ b/packages/mobile-ui-vue/components/page-container/index.ts @@ -23,16 +23,16 @@ const PAGE_CONTAINER_REGISTERED_NAME = 'page-container'; const PageContainer = withInstall(PageContainerInstallless); PageContainer.register = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext + componentMap: Record, propsResolverMap: Record, + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext ): void => { componentMap[PAGE_CONTAINER_REGISTERED_NAME] = PageContainer; propsResolverMap[PAGE_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; PageContainer.registerDesigner = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext + componentMap: Record, propsResolverMap: Record, + configresolverMap: Record, registerContext: RegisterContext ): void => { componentMap[PAGE_CONTAINER_REGISTERED_NAME] = PageContainerDesign; propsResolverMap[PAGE_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); 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 4f092e91b30..3d106562ad4 100644 --- a/packages/mobile-ui-vue/components/page-footer-container/index.ts +++ b/packages/mobile-ui-vue/components/page-footer-container/index.ts @@ -24,7 +24,7 @@ const COMPONENT_TYPE = 'page-footer-container'; const PageFooterContainer = withInstall(PageFooterContainerInstallless); PageFooterContainer.register = ( componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext ): void => { componentMap[COMPONENT_TYPE] = PageFooterContainer; propsResolverMap[COMPONENT_TYPE] = propsResolverGenerator(registerContext); 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 aaa69ded1db..bfcdff47f04 100644 --- a/packages/mobile-ui-vue/components/page-header-container/index.ts +++ b/packages/mobile-ui-vue/components/page-header-container/index.ts @@ -24,7 +24,7 @@ const PAGE_HEADER_CONTAINER_REGISTERED_NAME = 'page-header-container'; const PageHeaderContainer = withInstall(PageHeaderContainerInstallless); PageHeaderContainer.register = ( componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext ): void => { componentMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = PageHeaderContainer; propsResolverMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); diff --git a/packages/mobile-ui-vue/components/register.ts b/packages/mobile-ui-vue/components/register.ts index 02f0fe96957..1a7db76c2a8 100644 --- a/packages/mobile-ui-vue/components/register.ts +++ b/packages/mobile-ui-vue/components/register.ts @@ -21,6 +21,10 @@ import DatePicker from './date-picker'; import DateTimePicker from './date-time-picker'; import Picker from './picker'; +import { propertyConfigSchemaMap, schemaMap, schemaResolverMap } from "./dynamic-resolver"; +import { propertyEffectMap } from "./dynamic-resolver/src/resolver/property-config/property-config-resolver"; +import { RegisterContext } from "./common"; + const componentMap: Record = {}; const propsConverterMap: Record = {}; const propConfigsConverterMap: Record = {}; @@ -43,8 +47,14 @@ function registerComponents() { Navbar, Button, ButtonGroup, Listview, Form, FormItem, InputGroup, Textarea, NumberInput, Switch, DatePicker, DateTimePicker, Picker ]; + const registerContext: RegisterContext = { + schemaMap, + propertyConfigSchemaMap, + propertyEffectMap, + schemaResolverMap, + }; componentsToRegister.forEach((componentToRegister) => { - componentToRegister.register(componentMap, propsConverterMap, propConfigsConverterMap, resolverMap); + componentToRegister.register(componentMap, propsConverterMap, propConfigsConverterMap, resolverMap, registerContext); }); } diff --git a/packages/mobile-ui-vue/farris.config.mjs b/packages/mobile-ui-vue/farris.config.mjs index 7c008eaa28b..92d8a6bd1ec 100644 --- a/packages/mobile-ui-vue/farris.config.mjs +++ b/packages/mobile-ui-vue/farris.config.mjs @@ -2,8 +2,7 @@ import { fileURLToPath, URL } from 'node:url'; const { BUILD_TYPE } = process.env; const outDir = BUILD_TYPE === 'app' ? "dist" : 'package'; -const externals = [BUILD_TYPE === 'components' ? "@components" : '']; -const externalDependencies = BUILD_TYPE !== 'app'; +const externals = BUILD_TYPE === 'components' ? ["@components", "vue"] : ["vue"]; export default { lib: { @@ -30,8 +29,8 @@ export default { } } }, - externalDependencies, - minify: true, + externalDependencies: false, + minify: false, target: 'es2015', alias: [ { find: '@', replacement: fileURLToPath(new URL('./', import.meta.url)) }, -- Gitee From 82649558ce84e72afc918ce7c9dfdb604da985c3 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Fri, 11 Apr 2025 17:12:53 +0800 Subject: [PATCH 218/287] =?UTF-8?q?chore:=20=E8=AE=BE=E8=AE=A1=E5=99=A8?= =?UTF-8?q?=E9=80=82=E9=85=8D=E7=A7=BB=E5=8A=A8=E7=AB=AF=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile-supported-controller.json | 124 +++++++++--------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/packages/designer/src/components/composition/command/supported-controllers/mobile-supported-controller.json b/packages/designer/src/components/composition/command/supported-controllers/mobile-supported-controller.json index 070d89c4029..e1c6d867ea6 100644 --- a/packages/designer/src/components/composition/command/supported-controllers/mobile-supported-controller.json +++ b/packages/designer/src/components/composition/command/supported-controllers/mobile-supported-controller.json @@ -1,281 +1,281 @@ { "9ef56595-7cb7-4bbe-8f64-c6efcb7b1f9d": [ { - "id": "719edeb6-5471-43b0-8d0b-5f1fc519bc9a", + "id": "faa47af6-1354-5139-2849-2f676b4e0c19", "code": "Create" }, { - "id": "e7c7e7da-31d7-42fa-8674-36c04f671065", + "id": "2df293ac-eab4-065c-38be-16d1427281e3", "code": "CreateByPath" }, { - "id": "8e048c96-42b2-48ba-9504-e99714615da0", + "id": "77ab0b98-2cc1-dcbc-6e21-16552efeea88", "code": "Append" } ], "0a68799b-48c6-4c9f-b0d7-140683c62b58": [ { - "id": "16350846-55b7-452a-b5c9-fe03901e604c", + "id": "06351c11-ec4b-f7b0-d9b4-e8bca9202b86", "code": "LoadForList" }, { - "id": "54b9b45e-eef3-4d5e-9708-bb1026e614d6", + "id": "cb7f4216-0eb4-26a0-80b5-a38448e393c1", "code": "LoadForCard" }, { - "id": "9dd24b2f-4a17-46c7-98c5-5a4b89511365", + "id": "67edc617-d63a-b4f5-cdc7-4adba1b6e48b", "code": "LoadAndAddForCard" }, { - "id": "384ba725-0a14-4c98-92ec-491a93b946d5", + "id": "33e538a8-717d-00ad-4cb6-a575f4b151c7", "code": "LoadAndEditForCard" }, { - "id": "5f66ed0e-636b-447b-b476-5b6091b01d2d", + "id": "d868341e-5eff-2a65-ba96-8b4fe5b243d7", "code": "LoadAndViewForCard" }, { - "id": "3c597c5e-0f15-491b-8ce0-4f6f51b258a5", + "id": "afc70350-24fc-9879-9505-689f57575ec2", "code": "LoadAndAddForChildCard" }, { - "id": "799df45f-d4b9-49bd-900f-19b6c2e3d4be", + "id": "4a7b5ccb-f61a-ac4f-e308-c00f6b52860b", "code": "LoadAndEditForChildCard" }, { - "id": "f33ae378-45fe-4001-bf14-165457074599", + "id": "9272925f-38d0-d814-2161-605f75240169", "code": "LoadAndViewForChildCard" } ], "4ed10691-451e-4dd2-821a-0d2421e7c334": [ { - "id": "57d6b105-0820-4722-b716-e42e44edda1c", + "id": "ff453ad8-cd6a-2f01-4e94-d0d382f6f429", "code": "View" }, { - "id": "e47ae3f9-7789-4512-99cf-9a27bcafcd14", + "id": "1a6adc1d-bd2e-b8c3-1e01-c4c6e0803659", "code": "ViewByPath" } ], "05592163-fd45-474e-b0ab-61d7dc02e5c0": [ { - "id": "e8dbc136-29ac-439e-98a7-e4f3d07470da", + "id": "d5b847bd-ceb3-1b27-ed7f-b6b1e38088cd", "code": "Cancel" } ], "f863c66a-bf93-4d1f-9f99-bcd76009609d": [ { - "id": "9a78d149-0110-42bf-87b2-6f0aedcb635f", + "id": "129fb301-123d-6011-755d-c1aad5bf1dd3", "code": "SaveForCard" }, { - "id": "7de99e9f-659b-4b08-ad0c-425eefa1a04c", + "id": "2ade863f-4b38-7d2b-ca9f-87f1e18d8692", "code": "SaveForChildCard" }, { - "id": "1aa455dd-9ecf-48a1-8296-a4559d2fac58", + "id": "f7ebeab7-0481-041a-2cc4-d524840c6468", "code": "SaveAndGoBackForChildCard" }, { - "id": "767f2faa-da44-4efd-83ff-aa591b31fc83", + "id": "7eab8d99-4698-c0d4-4d2b-08bf724ed439", "code": "Save" }, { - "id": "34ba8742-942d-4ef6-b903-bcd92258264e", + "id": "55eb3067-d220-56dd-41b3-2228db302ae0", "code": "SaveAndValidateDataForCard" } ], "f458e095-a3c6-43e8-a95b-fc886f6f619e": [ { - "id": "2f8f14a9-a472-4667-9bf6-70f99199b2e9", + "id": "b0dfb230-7548-c4c7-66db-370cf5e98ee8", "code": "Edit" }, { - "id": "78176c86-bff8-4fc0-aed2-d4ec310bb45a", + "id": "aaf37f29-c5a4-5571-473c-1e8a252d0782", "code": "EditByPath" } ], "dab6b7f1-f56f-490a-879c-3d74232cd3ba": [ { - "id": "5cc3d0e2-6382-46ee-a006-37d328eb74f4", + "id": "eca45728-53c9-ca70-14ca-ec8eb468ee44", "code": "RemoveById" }, { - "id": "0b976739-1b02-40f1-8bb9-86a5e919f2c5", + "id": "6036c9c0-1ee6-ab06-e311-78f5becca6b4", "code": "RemoveByIds" }, { - "id": "e191d6a9-f72e-4479-80a7-ee5299f4e13b", + "id": "a35467a1-4ca7-5655-cd2a-18ce42a3097a", "code": "RemoveByPathAndId" } ], "eae5387b-042d-45bf-93fa-f2c8085e9e5d": [ { - "id": "498556a6-543b-490a-a436-8df0d8b8a567", + "id": "f7bd5f2f-abc8-9fd4-35df-a9199b47a434", "code": "Update" } ], "910661bd-963a-4287-aa32-441c95b8720f": [ { - "id": "d6938e12-2a7f-4bde-9344-8a2a6b7ae858", + "id": "973bb999-b8dc-0ff5-0ba1-5cd7b816eba9", "code": "Navigate" }, { - "id": "c6232e45-b248-4bcb-9a08-783f5eb4b1b8", + "id": "4dd30b6a-f0d7-0799-7c04-593e5b71fd7b", "code": "NavigateForRtc" }, { - "id": "24b9e3c9-70c7-4c3a-9eb2-f65a832daded", + "id": "9dca239c-9153-70f9-e522-5ba2c384aa4f", "code": "GoBack" }, { - "id": "83928701-0dfa-410f-925e-dfb29aa00f3d", + "id": "632f46ae-620e-3bb7-a75e-c43473624c49", "code": "GoBackAndCheck" }, { - "id": "9cc3ef53-70bb-42db-949e-22b4861234fd", + "id": "34c9cb64-0ea0-f483-2d51-c36ff0ee6cb2", "code": "GoBackForChildCard" }, { - "id": "6f19252c-c89d-47a6-a504-334348b6147f", + "id": "9740b808-9900-f494-516c-08e89640f5af", "code": "CloseWindow" }, { - "id": "ecb7f16e-6c48-4a7e-bff1-f770b9628aa0", + "id": "66371216-60d9-f2c3-734e-6b56b6e71d27", "code": "NavigateAndCheck" }, { - "id": "0a750ff9-73d4-431d-8dd6-6460f5ecfbbf", + "id": "b0d557ac-1ee8-8afe-73ea-006c43bd10d1", "code": "NavigateForChildCard" } ], "91cc23fb-2ecf-418b-9700-99469eab2e84": [ { - "id": "e0212f85-453e-45d4-b51d-6ee256ee0830", + "id": "0fcae913-ce17-a5ba-2d4a-99de7e92a4b4", "code": "SubmitApprove" }, { - "id": "49d48df4-8c11-4558-864b-77fe74ed1823", + "id": "f1229a4f-ecfc-5eda-e870-e50a5fc69a96", "code": "SaveAndSubmit" }, { - "id": "7acb49f4-237c-4b31-92e2-2524a2338148", + "id": "d59bbde0-d2a6-9e6b-0aa7-7a9a47472e48", "code": "CancelSubmit" }, { - "id": "05fe4f03-7a6f-4333-95f7-bb0e92c3f096", + "id": "1eda006d-5b2d-e3ff-21a7-061eba33ac30", "code": "SubmitWithBizDefKey" }, { - "id": "4fef2208-d449-4a08-850e-00dca35b3b9a", + "id": "fd018acf-f6d0-2ef2-335f-a39c955f2c67", "code": "CancelSubmitWithDataId" }, { - "id": "0431d656-94bc-4d0f-8a93-80120b42015d", + "id": "809b783b-38d3-e70a-64f4-95bc80955cc2", "code": "BatchSubmitWithBizDefKey" }, { - "id": "f141b4cd-1b08-409a-9068-5e580d5e00e8", + "id": "2daf7893-a636-dd79-a26e-80fdd6a19b7c", "code": "BatchCancelSubmitWithDataId" }, { - "id": "3a58325a-d079-43cc-9cd8-b2715863a08a", + "id": "171df093-e755-59f1-319b-bd51cfb8a38f", "code": "ChildSubmit" }, { - "id": "21cfd511-b591-433d-9c4c-f1b51a0334e0", + "id": "175197fd-6064-697c-d6ee-d90e9fe6ecc7", "code": "ChildCancelSubmit" }, { - "id": "cc3592ec-34f3-425e-a990-6c912b7fe319", + "id": "3abbaf6f-2644-2e2e-2bd6-2d04809ec594", "code": "ChildBatchSubmit" }, { - "id": "f6f8e28c-3a6f-4864-99b6-ac8a102ee7ed", + "id": "50283e79-e71b-8429-98db-1fe2d919eb0c", "code": "ChildBatchCancelSubmit" } ], "ad4b014c-ff01-4bb0-8b3a-cb5e7dd2f8ea": [ { - "id": "042cabd8-dcd7-4be4-b4f2-f22478d8b1ed", + "id": "f1925f3d-e442-2010-f441-cb7c6d5c0e49", "code": "uploadAndUpdateRow" }, { - "id": "8102a66f-8ad9-4bdb-963b-356993b0ef6c", + "id": "cd84830a-e9aa-ccbf-7417-dac561df7828", "code": "uploadAndBatchAddRows" }, { - "id": "ae5fcdcf-d39a-4d12-a1f6-501585f09a6e", + "id": "32d549ab-9f9c-1427-7aaf-f3e9c50de517", "code": "removeAttachmentRows" }, { - "id": "4f49ca99-e305-4a9a-9dd1-05cdf69dca66", + "id": "23ca8283-05ba-448e-809b-427ef90ffdc2", "code": "updateAttachmentField" }, { - "id": "b1f3e9e6-7d02-4ebf-a547-c15f7e3695c0", + "id": "8c0c6bc3-1a4b-4f17-95e4-91a7b14f617c", "code": "clearAttachmentField" } ], "82cebb17-9f81-40be-86c3-389c5912bde7": [ { - "id": "d29640d0-76cb-4e5c-a367-145638867fdf", + "id": "4d2d6302-6891-f7c2-116a-f29f059d1dd4", "code": "ExecuteAction" } ], "f8149a59-0133-49cb-8793-1eacbdc357bd": [ { - "id": "314f9113-8260-4f1d-992c-880e93e3f5e6", + "id": "e8938f1c-0e85-4a65-bf9f-f3e7a8e719b5", "code": "AddComment" }, { - "id": "eb2d9a60-90de-47bb-ba35-192c8c2be863", + "id": "141eabe0-0792-6b62-18df-e51d1b4629fc", "code": "QueryInitComments" }, { - "id": "90fc416d-19f4-4dab-af02-62e8a01c4da3", + "id": "37030d87-8eb1-cccd-c895-638b2b8bfca4", "code": "SetReplyUser" }, { - "id": "e0933b21-cd0f-4b63-9804-72fad70de02b", + "id": "d2ba691d-8121-166d-52d3-dbc365624313", "code": "registerBeforeGetData" } ], "2051ecc9-0c92-4d26-99b9-24361b2a2335": [ { - "id": "7f7ca2d2-1f58-42f6-a248-8106a66dac11", + "id": "d2124707-ecf8-b5df-5f71-acd81f981929", "code": "SetLookupCustomData" } ], "cf5e568a-5243-4539-94ea-e195eb4d6736": [ { - "id": "814be6a0-39f0-4586-95f0-aa541c1ed18f", + "id": "e875be9f-07b8-b8ac-e20b-53e6b3e7894d", "code": "LoadPage" }, { - "id": "04aed309-5865-4e08-88ce-28dd4cca1d63", + "id": "98b8d9a5-dc18-77e8-7bdf-7ea191c6bc8d", "code": "LoadPageForList" }, { - "id": "b6e237a9-250f-4c23-8078-eaf85e7d0f8b", + "id": "dd80df23-0cd7-b11c-1fa5-df8a8847b81b", "code": "LoadPageForCard" }, { - "id": "cf2af519-f67e-46f3-85d1-6ba50f1580f0", + "id": "54f3153f-e646-e185-b403-5467b9984a78", "code": "LoadPageForChildCard" }, { - "id": "ef4be6f5-44d1-4966-8715-32a539dd78be", + "id": "6441c6c5-4f8d-e53e-2db0-639b4c81e418", "code": "LoadListPage" }, { - "id": "891496db-22f9-4a51-874a-f726e162d1fd", + "id": "53827e22-6f6f-e0f3-e4a2-9ca3e6b8f568", "code": "LoadCardPage" } ], "efab0177-e16d-4d1f-9567-0bd1f607e53a": [ { - "id": "cc312b7a-995e-485d-a668-8c8d58b1b938", + "id": "63af6df0-163c-8e0e-1ed4-a9766f4921ae", "code": "setFieldsTruncateConfig" } ] -- Gitee From 94c7f27962cbd042c3d69d143ecb19c4507d404e Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Sat, 12 Apr 2025 14:14:03 +0800 Subject: [PATCH 219/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E8=BE=93=E5=85=A5=E7=BB=84=E4=BB=B6=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E6=97=B6=E8=A1=A5=E5=85=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../use-mobile-designer-context.ts | 8 +- .../checkbox-group.property-config.ts | 106 ++++++------ .../src/schema/checkbox-group.schema.json | 10 ++ .../components/common/src/utils/src/date.ts | 8 +- .../src/date-picker-panel.props.ts | 2 +- .../date-picker.property-config.ts | 102 +++++++----- .../src/schema/date-picker.schema.json | 7 +- .../src/composition/use-date-state.ts | 2 +- .../src/date-time-picker-panel.props.ts | 2 +- .../designer/date-picker.design.component.tsx | 29 +--- .../date-picker.property-config.ts | 101 +++++++----- .../src/composition/dg-control.ts | 8 +- .../composition/use-type-resolver-design.ts | 2 +- .../src/schema/form-item.schema.json | 2 - .../src/composition/use-textarea.ts | 2 +- .../input-group/src/input-group.component.tsx | 6 +- .../input-group/src/input-group.props.ts | 4 +- .../converter/input.converter.ts | 86 ++++++++++ .../input-group.property-config.ts | 110 ++++++++++--- .../src/schema/input-group.schema.json | 4 +- .../number-input.design.component.tsx | 2 +- .../number-input.property-config.ts | 20 ++- .../src/schema/number-input.schema.json | 5 +- .../picker/src/schema/picker.schema.json | 4 +- .../composition/entity/schema-dom-mapping.ts | 16 +- .../radio-group.property-config.ts | 99 +++++++----- .../src/schema/radio-group.schema.json | 151 +++++++++--------- .../property-config/switch.property-config.ts | 101 ++++++------ .../switch/src/switch.component.tsx | 17 +- .../components/switch/src/switch.props.ts | 10 +- .../textarea.property-config.ts | 16 +- .../textarea/src/schema/textarea.schema.json | 4 +- .../textarea/src/textarea.component.tsx | 3 +- .../components/textarea/src/textarea.props.ts | 2 +- .../mobile-ui-vue/demos/date-picker/type.vue | 2 +- .../demos/date-time-picker/type.vue | 2 +- packages/mobile-ui-vue/demos/switch/size.vue | 9 +- packages/mobile-ui-vue/tsconfig.json | 3 - 38 files changed, 656 insertions(+), 411 deletions(-) create mode 100644 packages/mobile-ui-vue/components/input-group/src/property-config/converter/input.converter.ts diff --git a/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts b/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts index e2a9532f04f..e3da548d7ae 100644 --- a/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts +++ b/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts @@ -3,8 +3,8 @@ import ToolboxItems from '../../types/toolbox/mobile-toolbox.json'; import SupportedControllers from '../../composition/command/supported-controllers/mobile-supported-controller.json'; import { - Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, Picker, - ContentContainer, FloatContainer, Navbar, ListView, Form, FormItem, InputGroup, Button, registerDesignerComponents + Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, Picker, NumberInput, Textarea, DatePicker, DateTimePicker, + ContentContainer, FloatContainer, Navbar, ListView, Form, FormItem, InputGroup, Button, registerDesignerComponents, Switch, CheckboxGroup, RadioGroup, } from '@farris/mobile-ui-vue'; import { useMobileControlCreator } from "../control-creator/use-mobile-control-creator"; import { FormComponent, UseFormSchema } from "../../../components/types"; @@ -21,8 +21,8 @@ export function useMobileDesignerContext(): UseDesignerContext { /** 要注册的UI组件 */ const componentsToRegister: any[] = [ Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, - ContentContainer, FloatContainer, - Navbar, ListView,Picker, + ContentContainer, FloatContainer,Textarea,DatePicker,DateTimePicker, + Navbar, ListView,Picker,NumberInput,Switch,CheckboxGroup,RadioGroup, Form, FormItem, InputGroup, Button ]; diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts b/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts index 66fef5807b8..8d632abab80 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts +++ b/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts @@ -1,53 +1,63 @@ -import { InputBaseProperty } from "@farris/mobile-ui-vue/common/src/entity/input-base-property"; +import { InputBaseProperty } from '@farris/mobile-ui-vue/common/src/entity/input-base-property'; export class CheckBoxGroupProperty extends InputBaseProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } - constructor(componentId: string, designerHostService: any) { - super(componentId, designerHostService); - } - - - getEditorProperties(propertyData: any) { - const self = this; - const editorProperties = self.getComponentConfig(propertyData, { type: "radio-group" }, { - direction: { - description: "", - title: "排列方向", - type: "enum", - editor: { - data: [{ "id": "horizontal", "name": "横向" }, - { "id": "vertical", "name": "纵向" }] - } - }, - data: { - description: "", - title: "数据", - type: "array", - $converter: "/converter/enum-data.converter", - ...self.getItemCollectionEditor(propertyData, propertyData.editor.valueField, propertyData.editor.textField), - // 这个属性,标记当属性变更得时候触发重新更新属性 - refreshPanelAfterChanged: true, - } - }); - editorProperties['setPropertyRelates'] = function (changeObject, newPropertyData, parameters) { - if (!changeObject) { - return; + getEditorProperties(propertyData: any) { + const self = this; + const editorProperties = self.getComponentConfig( + propertyData, + {}, + { + placeholder: { + visible: false + }, + disabled: { + visible: false + }, + data: { + description: '', + title: '数据', + type: 'array', + $converter: '/converter/enum-data.converter', + ...self.getItemCollectionEditor( + propertyData, + propertyData.editor.valueField, + propertyData.editor.textField + ), + // 这个属性,标记当属性变更得时候触发重新更新属性 + refreshPanelAfterChanged: true + }, + textField: { + description: '', + title: '文本字段', + type: 'string', + readonly: true + }, + valueField: { + description: '', + title: '值字段', + type: 'string', + readonly: true + } + }, + (changeObject, parameters) => { + if (!changeObject) { + return; + } + switch (changeObject.propertyID) { + case 'data': { + // 此类型默认可以编辑数据,要同步更新格式化 + if (propertyData.formatter) { + propertyData.formatter.data = [...changeObject.propertyValue]; } - switch (changeObject.propertyID) { - case 'data': { - if (parameters) { - propertyData.editor.valueField = parameters.valueField; - propertyData.editor.textField = parameters.nameField; - } - // 此类型默认可以编辑数据,要同步更新格式化 - if (propertyData.formatter) { - propertyData.formatter.data = [...changeObject.propertyValue]; - } - break; - } - } - }; - return editorProperties; - } - + break; + } + } + } + ); + return editorProperties; + } } diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/schema/checkbox-group.schema.json b/packages/mobile-ui-vue/components/checkbox-group/src/schema/checkbox-group.schema.json index 7cbd3c17fe8..0a7a1f7c964 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/src/schema/checkbox-group.schema.json +++ b/packages/mobile-ui-vue/components/checkbox-group/src/schema/checkbox-group.schema.json @@ -64,6 +64,16 @@ "description": "", "type": "string", "default": "horizontal" + }, + "textField": { + "description": "", + "type": "string", + "default": "name" + }, + "valueField": { + "description": "", + "type": "string", + "default": "value" } }, "required": [ diff --git a/packages/mobile-ui-vue/components/common/src/utils/src/date.ts b/packages/mobile-ui-vue/components/common/src/utils/src/date.ts index 12d69995035..14fbaec4b97 100644 --- a/packages/mobile-ui-vue/components/common/src/utils/src/date.ts +++ b/packages/mobile-ui-vue/components/common/src/utils/src/date.ts @@ -63,9 +63,9 @@ export const parseTime = (value: string) => { export const formatDate = (value: Date, format: string) => { const { year, month, day, hours, minutes, seconds } = getDateRecord(value); return format - .replace('YYYY', String(year)) + .replace('yyyy', String(year)) .replace('MM', String(month).padStart(2, '0')) - .replace('DD', String(day).padStart(2, '0')) + .replace('dd', String(day).padStart(2, '0')) .replace('HH', String(hours).padStart(2, '0')) .replace('mm', String(minutes).padStart(2, '0')) .replace('ss', String(seconds).padStart(2, '0')); @@ -88,9 +88,9 @@ export const parseDate = (value: string, format: string) => { .split('-') .map((item) => Number(item)); - const year = dateValueParts[formatMap.YYYY]; + const year = dateValueParts[formatMap.yyyy]; const month = dateValueParts[formatMap.MM] ? dateValueParts[formatMap.MM] - 1 : 0; - const day = dateValueParts[formatMap.DD] || 1; + const day = dateValueParts[formatMap.dd] || 1; const { hours, minutes, seconds } = getTimeRecord(timeValue); diff --git a/packages/mobile-ui-vue/components/date-picker/src/date-picker-panel.props.ts b/packages/mobile-ui-vue/components/date-picker/src/date-picker-panel.props.ts index 96358661511..2d4219a4fed 100644 --- a/packages/mobile-ui-vue/components/date-picker/src/date-picker-panel.props.ts +++ b/packages/mobile-ui-vue/components/date-picker/src/date-picker-panel.props.ts @@ -12,7 +12,7 @@ export const datePickerPanelProps = { modelValueType: { type: String as PropType, default: '' }, - format: { type: String, default: 'YYYY-MM-DD' }, + format: { type: String, default: 'yyyy-MM-dd' }, maxDate: { type: Date, default: undefined }, diff --git a/packages/mobile-ui-vue/components/date-picker/src/property-config/date-picker.property-config.ts b/packages/mobile-ui-vue/components/date-picker/src/property-config/date-picker.property-config.ts index dedd50001ec..205e01d02ba 100644 --- a/packages/mobile-ui-vue/components/date-picker/src/property-config/date-picker.property-config.ts +++ b/packages/mobile-ui-vue/components/date-picker/src/property-config/date-picker.property-config.ts @@ -1,44 +1,72 @@ -import { InputBaseProperty } from "@farris/mobile-ui-vue/common/src/entity/input-base-property"; -import { DATE_FORMATS } from "./date-format"; +import { InputBaseProperty } from '@farris/mobile-ui-vue/common/src/entity/input-base-property'; +import { DATE_FORMATS } from './date-format'; export class DatePickerProperty extends InputBaseProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } - constructor(componentId: string, designerHostService: any) { - super(componentId, designerHostService); - } + getEditorProperties(propertyData: any) { + const displayFormatOptions = this.getDateFormatOptions(propertyData?.editor); + return this.getComponentConfig( + propertyData, + {}, + { + title: { + description: '', + title: '标题', + type: 'string', + }, + valueFormat: { + description: '', + title: '日期格式', + type: 'enum', + editor: { + data: displayFormatOptions + } + }, + maxDate: { + description: '', + title: '最大日期', + type: 'string', + editor: { + type: 'date-picker', + displayFormat: propertyData?.editor?.valueFormat || 'yyyy-MM-dd', + valueFormat: propertyData?.editor?.valueFormat || 'yyyy-MM-dd', + minDate: propertyData?.editor?.minDate || '1900-01-01', + maxDate: '9999-12-31', + showTime: false + }, + refreshPanelAfterChanged: true + }, + minDate: { + description: '', + title: '最小日期', + type: 'string', + editor: { + type: 'date-picker', + displayFormat: propertyData?.editor?.valueFormat || 'yyyy-MM-dd', + valueFormat: propertyData?.editor?.valueFormat || 'yyyy-MM-dd', + minDate: '1900-01-01', + maxDate: propertyData?.editor?.maxDate || '9999-12-31', + showTime: false + }, + refreshPanelAfterChanged: true + } + } + ); + } + private getDateFormatOptions(editorData: any) { + let formats: any[] = []; + const { timeFormats, yMdFormats, yMFormats, mdFormats, yFormats } = DATE_FORMATS(); - getEditorProperties(propertyData: any) { - const displayFormatOptions = this.getDateFormatOptions(propertyData?.editor); - return this.getComponentConfig(propertyData, { type: "year-month-day" }, { - placeholder: { - description: "空值时,输入控件内的占位文本", - title: "提示文本", - type: "string" - }, - displayFormat: { - description: "", - title: "显示格式", - type: "enum", - editor: { - data: displayFormatOptions - } - } - }); - } - - private getDateFormatOptions(editorData: any) { - let formats: any[] = []; - const { timeFormats, yMdFormats, yMFormats, mdFormats, yFormats } = DATE_FORMATS(); - - formats = formats.concat(timeFormats); - - formats = formats.concat(yMdFormats); - formats = formats.concat(yMFormats); - formats = formats.concat(yFormats); - formats = formats.concat(mdFormats); - - return formats; - } + formats = formats.concat(yMdFormats); + // formats = formats.concat(timeFormats); + // formats = formats.concat(yMFormats); + // formats = formats.concat(yFormats); + // formats = formats.concat(mdFormats); + return formats; + } } diff --git a/packages/mobile-ui-vue/components/date-picker/src/schema/date-picker.schema.json b/packages/mobile-ui-vue/components/date-picker/src/schema/date-picker.schema.json index e9c26da2110..6bbe0de09fc 100644 --- a/packages/mobile-ui-vue/components/date-picker/src/schema/date-picker.schema.json +++ b/packages/mobile-ui-vue/components/date-picker/src/schema/date-picker.schema.json @@ -12,7 +12,7 @@ "type": { "description": "控件类型", "type": "string", - "default": "textarea" + "default": "date-picker" }, "appearance": { "description": "外观", @@ -82,7 +82,8 @@ ], "ignore": [ "id", - "type", - "appearance" + "appearance", + "binding", + "visible" ] } \ No newline at end of file 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/src/composition/use-date-state.ts index 0603beeaf3e..947eb271410 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/src/composition/use-date-state.ts @@ -7,7 +7,7 @@ export const useDateState = (props: DateTimePickerPanelProps) => { return (props.type.split(" ")[0] as DatePickerType) || DatePickerType.Date; }); const dateFormat = computed(() => { - return props.format.split(" ")[0] || 'YYYY-MM-DD'; + return props.format.split(" ")[0] || 'yyyy-MM-dd'; }); const dateValue = ref(); diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker-panel.props.ts b/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker-panel.props.ts index 7b1d850a313..764f4c16036 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker-panel.props.ts +++ b/packages/mobile-ui-vue/components/date-time-picker/src/date-time-picker-panel.props.ts @@ -13,7 +13,7 @@ export const dateTimePickerPanelProps = { modelValueType: { type: String as PropType, default: '' }, - format: { type: String, default: 'YYYY-MM-DD HH:mm:ss' }, + format: { type: String, default: 'yyyy-MM-dd HH:mm:ss' }, maxDate: { type: Date, default: undefined }, diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/designer/date-picker.design.component.tsx b/packages/mobile-ui-vue/components/date-time-picker/src/designer/date-picker.design.component.tsx index a7ec3ac9de6..76e3afe3176 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/designer/date-picker.design.component.tsx +++ b/packages/mobile-ui-vue/components/date-time-picker/src/designer/date-picker.design.component.tsx @@ -1,31 +1,14 @@ - -/** - * 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, defineComponent, inject, onMounted, ref, SetupContext } from 'vue'; +import { computed, defineComponent, inject, onMounted, ref } from 'vue'; import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/designer-canvas';; import { useDesignerRules } from './use-designer-rules'; -import { dateTimePickerProps } from '../date-time-picker.props'; -import DateTimePicker from '../date-time-picker.component'; +import { ButtonEdit, buttonEditProps} from '@farris/mobile-ui-vue/button-edit'; export default defineComponent({ name: 'FmDatePickerDesign', - props: dateTimePickerProps, + props: buttonEditProps, emits: [], - setup(props, context: SetupContext) { + setup(props, context) { const elementRef = ref(); const designItemContext = inject('design-item-context') as DesignerItemContext; const designerHostService = inject('designer-host-service'); @@ -42,12 +25,12 @@ export default defineComponent({ ...props, editable: false, readonly: true, - modelValue:null + modelValue: '' })); return () => { return ( - + ); }; } diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts b/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts index 7503bc65889..990e7b8e3c4 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts +++ b/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts @@ -1,44 +1,73 @@ -import { InputBaseProperty } from "@farris/mobile-ui-vue/common/src/entity/input-base-property"; -import { DATE_FORMATS } from "./date-format"; +import { InputBaseProperty } from '@farris/mobile-ui-vue/common/src/entity/input-base-property'; +import { DATE_FORMATS } from './date-format'; export class DateTimePickerProperty extends InputBaseProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } - constructor(componentId: string, designerHostService: any) { - super(componentId, designerHostService); - } + getEditorProperties(propertyData: any) { + const displayFormatOptions = this.getDateFormatOptions(propertyData?.editor); + return this.getComponentConfig( + propertyData, + {}, + { + title: { + description: '', + title: '标题', + type: 'string', + }, + valueFormat: { + description: '', + title: '日期格式', + type: 'enum', + editor: { + data: displayFormatOptions + } + }, + maxDate: { + description: '', + title: '最大日期', + type: 'string', + editor: { + type: 'date-picker', + displayFormat: propertyData?.editor?.valueFormat || 'yyyy-MM-dd HH:mm:ss', + valueFormat: propertyData?.editor?.valueFormat || 'yyyy-MM-dd HH:mm:ss', + minDate: propertyData?.editor?.minDate || '1900-01-01', + maxDate: '9999-12-31', + showTime: true + }, + refreshPanelAfterChanged: true + }, + minDate: { + description: '', + title: '最小日期', + type: 'string', + editor: { + type: 'date-picker', + displayFormat: propertyData?.editor?.valueFormat || 'yyyy-MM-dd HH:mm:ss', + valueFormat: propertyData?.editor?.valueFormat || 'yyyy-MM-dd HH:mm:ss', + minDate: '1900-01-01', + maxDate: propertyData?.editor?.maxDate || '9999-12-31', + showTime: true + }, + refreshPanelAfterChanged: true + } + } + ); + } + private getDateFormatOptions(editorData: any) { + let formats: any[] = []; + const { timeFormats, yMdFormats, yMFormats, mdFormats, yFormats } = DATE_FORMATS(); - getEditorProperties(propertyData: any) { - const displayFormatOptions = this.getDateFormatOptions(propertyData?.editor); - return this.getComponentConfig(propertyData, { type: "year-month-day" }, { - placeholder: { - description: "空值时,输入控件内的占位文本", - title: "提示文本", - type: "string" - }, - displayFormat: { - description: "", - title: "显示格式", - type: "enum", - editor: { - data: displayFormatOptions - } - } - }); - } + formats = formats.concat(timeFormats); - private getDateFormatOptions(editorData: any) { - let formats: any[] = []; - const { timeFormats, yMdFormats, yMFormats, mdFormats, yFormats } = DATE_FORMATS(); - - formats = formats.concat(timeFormats); - - formats = formats.concat(yMdFormats); - formats = formats.concat(yMFormats); - formats = formats.concat(yFormats); - formats = formats.concat(mdFormats); - - return formats; - } + // formats = formats.concat(yMdFormats); + // formats = formats.concat(yMFormats); + // formats = formats.concat(yFormats); + // formats = formats.concat(mdFormats); + return formats; + } } diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts index 92fbcf39ee5..e230774a9f9 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts @@ -25,18 +25,20 @@ export const DgControl = { 'lookup': { type: 'lookup', name: '帮助', icon: 'LookupEdit' }, - 'number-spinner': { type: 'number-spinner', name: '数值', icon: 'NumericBox' }, + 'number-input': { type: 'number-input', name: '数值', icon: 'NumericBox' }, 'date-picker': { type: 'date-picker', name: '日期', icon: 'DateBox' }, + 'datetime-picker': { type: 'datetime-picker', name: '日期时间', icon: 'DateBox' }, + 'switch': { type: 'switch', name: '开关', icon: 'SwitchField' }, 'radio-group': { type: 'radio-group', name: '单选组', icon: 'RadioGroup' }, + 'check-group': { type: 'check-group', name: '多选组', icon: 'CheckGroup' }, + 'check-box': { type: 'check-box', name: '复选框', icon: 'CheckBox' }, - 'check-group': { type: 'check-group', name: '复选框组', icon: 'CheckGroup' }, - 'combo-list': { type: 'combo-list', name: '下拉列表', icon: 'EnumField' }, 'form': { type: 'form', name: '卡片面板', icon: 'Form' }, diff --git a/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver-design.ts b/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver-design.ts index d18293e03dd..ae5bdac3857 100644 --- a/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver-design.ts +++ b/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver-design.ts @@ -1,4 +1,4 @@ -import { componentMap,componentPropsConverter } from '@/components/register-designer'; +import { componentMap,componentPropsConverter } from '@farris/mobile-ui-vue/register-designer'; import FInputGroupDesign from '../../../input-group/src/designer/input-group.design.component'; import { EditorType, EditorConfig } from "../types"; import { UseTypeResolver } from "./types"; 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 57c71e28033..82f34c27ccf 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 @@ -62,7 +62,5 @@ "editor" ], "ignore": [ - "id", - "type" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/input-group/src/composition/use-textarea.ts b/packages/mobile-ui-vue/components/input-group/src/composition/use-textarea.ts index d05a3eeee0e..62f5441e55d 100644 --- a/packages/mobile-ui-vue/components/input-group/src/composition/use-textarea.ts +++ b/packages/mobile-ui-vue/components/input-group/src/composition/use-textarea.ts @@ -27,7 +27,7 @@ export function useTextarea(props: InputProps, inputRef: Ref { const input = unref(inputRef); - if (!(props.type === InputTypeMap.textarea && props.autoSize) || !input) { + if (!(props.type === InputTypeMap.textarea && props.autoHeight) || !input) { return; } 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 ad57970043b..06291c23313 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 @@ -55,7 +55,7 @@ export default defineComponent({ placeholder: placeholder.value, disabled: props.disabled, readonly: props.readonly || !props.editable, - maxlength: props.maxlength, + maxLength: props.maxLength, onChange: stopPropagation, }; }); @@ -109,9 +109,9 @@ export default defineComponent({ const renderWordLimit = () => props.showWordLimit && - props.maxlength && ( + props.maxLength && (
    - {String(innerValue.value).length}/{props.maxlength} + {String(innerValue.value).length}/{props.maxLength}
    ); 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 8090d466384..13a26c3e1d6 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,7 @@ 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: '' }, }; @@ -50,7 +50,7 @@ const inputNumberProps = { }; const inputTextAreaProps = { - autoSize: { type: Boolean, default: undefined }, + autoHeight: { type: Boolean, default: undefined }, rows: { type: Number, default: undefined }, diff --git a/packages/mobile-ui-vue/components/input-group/src/property-config/converter/input.converter.ts b/packages/mobile-ui-vue/components/input-group/src/property-config/converter/input.converter.ts new file mode 100644 index 00000000000..2e66e4b8e92 --- /dev/null +++ b/packages/mobile-ui-vue/components/input-group/src/property-config/converter/input.converter.ts @@ -0,0 +1,86 @@ +import { ComponentSchema } from "../../../../designer-canvas/src/types"; +import { PropertyConverter, SchemaService } from "../../../../dynamic-resolver/src/types"; + +const inputFormatValidationTypes = [ + { key: 'none', value: '无'}, + { key: 'cellNumber', value: '手机号' }, + { key: 'tel', value: '座机号/传真号' }, + { key: 'telOrCell', value: '手机号/座机号/传真号' }, + { key: 'postCode', value: '邮编' }, + { key: 'email', value: '电子邮箱' }, + { key: 'idCode', value: '身份证号' }, + { key: 'carCode', value: '车牌号' }, + { key: 'subjectCode', value: '10位数字会计科目代码' }, + { key: 'custom', value: '自定义' }, +]; + +function getInputExByInputType(inputTypeKey: string): string { + switch (inputTypeKey) { + case 'none': { + return ''; + } + case 'cellNumber': { + return '^1[0-9]{10}$'; + } + case 'tel': { + return '^(0[0-9]{2,3}\\-)?([2-9][0-9]{6,7})+(\\-[0-9]{1,4})?$'; + } + case 'telOrCell': { + return '^(0[0-9]{2,3}\\-)?([2-9][0-9]{6,7})+(\\-[0-9]{1,4})?$|^1[0-9]{10}$'; + } + case 'postCode': { + return '^[1-9]\\d{5}(?!\\d)$'; + } + case 'workCode': { + return '^\\d{8}$'; + } + case 'email': { + return '^[A-Za-z\\d]+([-_.][A-Za-z\\d]+)*@([A-Za-z\\d]+[-.])+[A-Za-z]{2,5}$'; + } + case 'idCode': { + return '^[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)$'; + } + case 'carCode': { + return '[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}'; + } + case 'carCodeNew': { + return '[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF])|([DF][A-HJ-NP-Z0-9][0-9]{4}))'; + } + case 'subjectCode': { + return '^\\d{10}$'; + } + } + return ''; +} + +function getMessage(propertyValue) { + return "请输入正确的" + inputFormatValidationTypes.find(type => type.key === propertyValue)?.value; +} +const typeConverter = { + convertTo: (schema: ComponentSchema, propertyKey: string, propertyValue: any, schemaService: SchemaService) => { + if (!schema.editor.formatValidation) { + schema.editor.formatValidation={type:'none'}; + } + schema.editor.formatValidation.type = propertyValue; + schema.editor.formatValidation.expression = getInputExByInputType(propertyValue); + schema.editor.formatValidation.message = getMessage(propertyValue); + + }, + convertFrom: (schema: ComponentSchema, propertyKey: string, schemaService: SchemaService) => { + return schema.editor.formatValidation ? schema.editor.formatValidation[propertyKey] : schema.editor[propertyKey]; + } +} as PropertyConverter; + +const commonConverter = { + convertTo: (schema: ComponentSchema, propertyKey: string, propertyValue: any, schemaService: SchemaService) => { + if (!schema.editor.formatValidation) { + schema.editor.formatValidation={type:'none'}; + } + schema.editor.formatValidation[propertyKey] = propertyValue; + }, + convertFrom: (schema: ComponentSchema, propertyKey: string, schemaService: SchemaService) => { + return schema.editor.formatValidation ? schema.editor.formatValidation[propertyKey] : schema.editor[propertyKey]; + } +} as PropertyConverter; + +export { typeConverter, commonConverter, inputFormatValidationTypes }; diff --git a/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts b/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts index a24b07e870c..33eb86d5708 100644 --- a/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts +++ b/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts @@ -1,34 +1,92 @@ -import { InputBaseProperty } from "@farris/mobile-ui-vue/common/src/entity/input-base-property"; +import { InputBaseProperty } from '@farris/mobile-ui-vue/common/src/entity/input-base-property'; +import { DesignerComponentInstance } from '@farris/mobile-ui-vue/designer-canvas'; +import { + typeConverter, + commonConverter, + inputFormatValidationTypes +} from './converter/input.converter'; export class InputGroupProperty extends InputBaseProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } - constructor(componentId: string, designerHostService: any) { - super(componentId, designerHostService); - } + public getPropertyConfig(propertyData: any, componentInstance: DesignerComponentInstance) { + super.getPropertyConfig(propertyData, componentInstance); + // 输入格式校验 + this.propertyConfig.categories['formatValidation'] = this.getFormatValidation(propertyData); + return this.propertyConfig; + } + + getEditorProperties(propertyData: any) { + const self = this; + const editorProperties = self.getComponentConfig( + propertyData, + {}, + { + maxLength: { + description: '文本字数最大长度', + title: '最大长度', + type: 'number', + editor: { + nullable: true, + min: 0, + useThousands: false + } + } + }, + (changeObject) => { + if (!changeObject) { + return; + } + } + ); - - getEditorProperties(propertyData: any) { - const self = this; - const editorProperties = self.getComponentConfig(propertyData, { type: "radio-group" }, { - placeholder: { - description: "空值时,输入控件内的占位文本", - title: "提示文本", - type: "string" - } - }); - editorProperties['setPropertyRelates'] = function (changeObject) { - if (!changeObject) { - return; - } - switch (changeObject.propertyID) { - case 'data': { + return editorProperties; + } - break; - } - } - }; - return editorProperties; + public getFormatValidation(propertyData) { + const formatValidationSchema: any = { + title: '输入格式校验', + description: 'formatValidation', + properties: { + type: { + title: '输入类型', + type: 'enum', + description: '输入类型', + editor: { + type: 'combo-list', + textField: 'value', + valueField: 'key', + idField: 'key', + editable: false, + data: inputFormatValidationTypes + }, + refreshPanelAfterChanged: true, + $converter: typeConverter + } + } + }; + if ( + propertyData.editor.formatValidation?.type && + propertyData.editor.formatValidation?.type !== 'none' + ) { + formatValidationSchema.properties.message = { + title: '输入错误提示', + type: 'string', + description: '输入错误提示', + $converter: commonConverter + }; } + if (propertyData.editor.formatValidation?.type === 'custom') { + formatValidationSchema.properties.expression = { + title: '匹配正则', + type: 'string', + description: '匹配正则', - + $converter: commonConverter + }; + } + return formatValidationSchema; + } } 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 a166044de2d..658e623f094 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 @@ -70,6 +70,8 @@ ], "ignore": [ "id", - "appearance" + "appearance", + "binding", + "visible" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx b/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx index c9a170b7c4d..e030ff53571 100644 --- a/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx +++ b/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx @@ -24,7 +24,7 @@ export default defineComponent({ return () => ( - + ); } }); diff --git a/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts b/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts index 6805fcedb92..63918fbc45a 100644 --- a/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts +++ b/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts @@ -8,11 +8,21 @@ export class NumberInputProperty extends InputBaseProperty { getEditorProperties(propertyData: any) { - return this.getComponentConfig(propertyData, { type: "year-month-day" }, { - placeholder: { - description: "空值时,输入控件内的占位文本", - title: "提示文本", - type: "string" + return this.getComponentConfig(propertyData, {}, { + precision: { + description: "", + title: "精度", + type: "number" + }, + max: { + description: "", + title: "最大值", + type: "number" + }, + min: { + description: "", + title: "最小值", + type: "number" }, }); } diff --git a/packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json b/packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json index 77d8162dab9..867a2b29ae9 100644 --- a/packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json +++ b/packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json @@ -78,7 +78,8 @@ ], "ignore": [ "id", - "type", - "appearance" + "appearance", + "binding", + "visible" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json b/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json index 19a83d6350b..1e7f0100e7d 100644 --- a/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json +++ b/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json @@ -84,8 +84,8 @@ ], "ignore": [ "id", - "type", "appearance", - "binding" + "binding", + "visible" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/property-panel/src/composition/entity/schema-dom-mapping.ts b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/schema-dom-mapping.ts index 3fd0215be1e..066d549361d 100644 --- a/packages/mobile-ui-vue/components/property-panel/src/composition/entity/schema-dom-mapping.ts +++ b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/schema-dom-mapping.ts @@ -9,34 +9,36 @@ export class SchemaDOMMapping { static fieldControlTypeMapping = { String: [ { key: DgControl['input-group'].type, value: DgControl['input-group'].name }, + { key: DgControl['textarea'].type, value: DgControl['textarea'].name }, { key: DgControl['lookup'].type, value: DgControl['lookup'].name }, { key: DgControl['date-picker'].type, value: DgControl['date-picker'].name }, - { key: DgControl['check-group'].type, value: DgControl['check-group'].name }, + { key: DgControl['datetime-picker'].type, value: DgControl['datetime-picker'].name }, { key: DgControl['radio-group'].type, value: DgControl['radio-group'].name }, + { key: DgControl['check-group'].type, value: DgControl['check-group'].name }, { key: DgControl['picker'].type, value: DgControl['picker'].name }, - { key: DgControl['textarea'].type, value: DgControl['textarea'].name }, ], Text: [ { key: DgControl['textarea'].type, value: DgControl['textarea'].name }, { key: DgControl['lookup'].type, value: DgControl['lookup'].name } ], Decimal: [ - { key: DgControl['number-spinner'].type, value: DgControl['number-spinner'].name } + { key: DgControl['number-input'].type, value: DgControl['number-input'].name } ], Integer: [ - { key: DgControl['number-spinner'].type, value: DgControl['number-spinner'].name } + { key: DgControl['number-input'].type, value: DgControl['number-input'].name } ], Number: [ - { key: DgControl['number-spinner'].type, value: DgControl['number-spinner'].name } + { key: DgControl['number-input'].type, value: DgControl['number-input'].name } ], BigNumber: [ - { key: DgControl['number-spinner'].type, value: DgControl['number-spinner'].name } + { key: DgControl['number-input'].type, value: DgControl['number-input'].name } ], Date: [ { key: DgControl['date-picker'].type, value: DgControl['date-picker'].name } ], DateTime: [ - { key: DgControl['date-picker'].type, value: DgControl['date-picker'].name } + { key: DgControl['date-picker'].type, value: DgControl['date-picker'].name }, + { key: DgControl['datetime-picker'].type, value: DgControl['datetime-picker'].name } ], Boolean: [ { key: DgControl['switch'].type, value: DgControl['switch'].name }, diff --git a/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts b/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts index 8a8d0155482..9b69160f235 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts +++ b/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts @@ -1,48 +1,59 @@ -import { InputBaseProperty } from "@farris/mobile-ui-vue/common/src/entity/input-base-property"; +import { InputBaseProperty } from '@farris/mobile-ui-vue/common/src/entity/input-base-property'; export class RadioGroupProperty extends InputBaseProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } - constructor(componentId: string, designerHostService: any) { - super(componentId, designerHostService); - } - - - getEditorProperties(propertyData: any) { - const self = this; - const editorProperties = self.getComponentConfig(propertyData, { type: "radio-group" }, { - direction: { - description: "", - title: "排列方向", - type: "enum", - editor: { - type: "combo-list", - textField: "value", - valueField: "key", - data: [{ "key": "horizontal", "value": "横向" }, { "key": "vertical", "value": "纵向" }] - } - }, - data: { - description: "", - title: "数据", - type: "array", - $converter: "/converter/enum-data.converter", - ...self.getItemCollectionEditor(propertyData, propertyData.editor.valueField, propertyData.editor.textField), - // 这个属性,标记当属性变更得时候触发重新更新属性 - refreshPanelAfterChanged: true, - } - }); - editorProperties['setPropertyRelates'] = function (changeObject) { - if (!changeObject) { - return; - } - switch (changeObject.propertyID) { - case 'data': { - - break; - } - } - }; - return editorProperties; - } - + getEditorProperties(propertyData: any) { + const self = this; + const editorProperties = self.getComponentConfig( + propertyData, + {}, + { + placeholder: { + visible: false + }, + disabled: { + visible: false + }, + data: { + description: '', + title: '数据', + type: 'array', + $converter: '/converter/enum-data.converter', + ...self.getItemCollectionEditor( + propertyData, + propertyData.editor.valueField, + propertyData.editor.textField + ), + // 这个属性,标记当属性变更得时候触发重新更新属性 + refreshPanelAfterChanged: true + }, + textField: { + description: '', + title: '文本字段', + type: 'string', + readonly: true + }, + valueField: { + description: '', + title: '值字段', + type: 'string', + readonly: true + } + } + ); + editorProperties['setPropertyRelates'] = function (changeObject) { + if (!changeObject) { + return; + } + switch (changeObject.propertyID) { + case 'data': { + break; + } + } + }; + return editorProperties; + } } diff --git a/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json b/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json index 316b66fc68f..7fad6675bf4 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json +++ b/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json @@ -1,78 +1,81 @@ { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://farris-design.gitee.io/radio-group.schema.json", - "title": "radio-group", - "description": "A Farris Input Component", - "type": "object", - "properties": { - "id": { - "description": "The unique identifier for a Input Group", - "type": "string" - }, - "type": { - "description": "The type string of Input Group component", - "type": "string", - "default": "radio-group" - }, - "appearance": { - "description": "", - "type": "object", - "properties": { - "class": { - "type": "string" - }, - "style": { - "type": "string" - } - }, - "default": {} - }, - "binding": { - "description": "", - "type": "object", - "default": {} - }, - "readonly": { - "type": "string", - "default": false - }, - "title": { - "description": "", - "type": "string", - "default": "" - }, - "label": { - "description": "", - "type": "string", - "default": "" - }, - "lableWidth": { - "description": "", - "type": "number" - }, - "visible": { - "description": "", - "type": "boolean", - "default": true - }, - "data": { - "description": "", - "type": "array", - "default": [] + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/radio-group.schema.json", + "title": "radio-group", + "description": "A Farris Input Component", + "type": "object", + "properties": { + "id": { + "description": "The unique identifier for a Input Group", + "type": "string" + }, + "type": { + "description": "The type string of Input Group component", + "type": "string", + "default": "radio-group" + }, + "appearance": { + "description": "", + "type": "object", + "properties": { + "class": { + "type": "string" }, - "direction": { - "description": "", - "type": "string", - "default": "horizontal" + "style": { + "type": "string" } + }, + "default": {} + }, + "binding": { + "description": "", + "type": "object", + "default": {} + }, + "readonly": { + "type": "string", + "default": false + }, + "title": { + "description": "", + "type": "string", + "default": "" + }, + "label": { + "description": "", + "type": "string", + "default": "" + }, + "lableWidth": { + "description": "", + "type": "number" + }, + "visible": { + "description": "", + "type": "boolean", + "default": true + }, + "data": { + "description": "", + "type": "array", + "default": [] + }, + "direction": { + "description": "", + "type": "string", + "default": "horizontal" + }, + "textField": { + "description": "", + "type": "string", + "default": "name" }, - "required": [ - "type" - ], - "ignore": [ - "id", - "appearance", - "binding", - "visible" - ] -} \ No newline at end of file + "valueField": { + "description": "", + "type": "string", + "default": "value" + } + }, + "required": ["type"], + "ignore": ["id", "appearance", "binding", "visible"] +} diff --git a/packages/mobile-ui-vue/components/switch/src/property-config/switch.property-config.ts b/packages/mobile-ui-vue/components/switch/src/property-config/switch.property-config.ts index 7ae587e475a..ed4cd54c1f8 100644 --- a/packages/mobile-ui-vue/components/switch/src/property-config/switch.property-config.ts +++ b/packages/mobile-ui-vue/components/switch/src/property-config/switch.property-config.ts @@ -1,55 +1,56 @@ -import { InputBaseProperty } from "@farris/mobile-ui-vue/common/src/entity/input-base-property"; +import { InputBaseProperty } from '@farris/mobile-ui-vue/common/src/entity/input-base-property'; export class SwitchProperty extends InputBaseProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } - constructor(componentId: string, designerHostService: any) { - super(componentId, designerHostService); - } + getEditorProperties(propertyData: any) { + const self = this; + const editorProperties = self.getComponentConfig( + propertyData, + {}, + { + disabled: { + visible: false + }, + placeholder: { + visible: false + }, + // onColor: { + // description: '', + // title: '打开时背景色', + // type: 'string' + // }, + // offColor: { + // description: '', + // title: '关闭时背景色', + // type: 'string' + // }, + size: { + description: '', + title: '尺寸', + type: 'enum', + editor: { + data: [ + { + id: 'small', + name: '小号' + }, + { + id: 'medium', + name: '中号' + }, + { + id: 'large', + name: '大号' + } + ] + } + } + } + ); - - getEditorProperties(propertyData: any) { - const self = this; - const editorProperties = self.getComponentConfig(propertyData, { type: "switch" }, { - onBackground: { - description: "", - title: "打开时背景色", - type: "string" - }, - offBackground: { - description: "", - title: "关闭时背景色", - type: "string" - }, - size: { - description: "", - title: "尺寸", - type: "number" - }, - // size:{ - // description: "", - // title: "尺寸", - // type: "enum", - // editor:{ - // data: [ - // { - // id: "small", - // name: "小号" - // }, - // { - // id: "medium", - // name: "中号" - // }, - // { - // id: "large", - // name: "大号" - // } - // ] - // } - // } - }); - - return editorProperties; - } - - + return editorProperties; + } } diff --git a/packages/mobile-ui-vue/components/switch/src/switch.component.tsx b/packages/mobile-ui-vue/components/switch/src/switch.component.tsx index 31f6ca847d1..5035a7c20f6 100644 --- a/packages/mobile-ui-vue/components/switch/src/switch.component.tsx +++ b/packages/mobile-ui-vue/components/switch/src/switch.component.tsx @@ -32,6 +32,15 @@ export default defineComponent({ return props.modelValue === props.activeValue; }); + const sizeMap = { + small: 16, + medium: 22, + large: 28 + }; + const SwitchSize = computed(()=>{ + return sizeMap[props.size]; + }); + const onClick = (event: MouseEvent) => { emit('click', event); @@ -45,7 +54,7 @@ export default defineComponent({ }; const renderLoading = () => { - return ; + return ; }; const switchClass = computed(() => ({ @@ -57,7 +66,7 @@ export default defineComponent({ })); const switchSize = computed(() => { - const height = props.size + 2; + const height = SwitchSize.value + 2; const width = height * 1.66; return { height, @@ -79,8 +88,8 @@ export default defineComponent({ const { height, width } = switchSize.value; const translateX = checked.value ? width - height : 0; return { - width: addUnit(props.size), - height: addUnit(props.size), + width: addUnit(SwitchSize.value), + height: addUnit(SwitchSize.value), transform: `translateX(${addUnit(translateX)})` }; }); diff --git a/packages/mobile-ui-vue/components/switch/src/switch.props.ts b/packages/mobile-ui-vue/components/switch/src/switch.props.ts index 576a1e0c1a2..5bd636f7241 100644 --- a/packages/mobile-ui-vue/components/switch/src/switch.props.ts +++ b/packages/mobile-ui-vue/components/switch/src/switch.props.ts @@ -14,11 +14,17 @@ * limitations under the License. */ import { getPropsResolverGenerator } from '@farris/mobile-ui-vue/dynamic-resolver'; -import { ExtractPropTypes } from 'vue'; +import { ExtractPropTypes, PropType } from 'vue'; import switchSchema from './schema/switch.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; +export enum SwitchSize { + small = 'small', + medium = 'medium', + large = 'large' +} + export const switchProps = { modelValue: { type: Boolean, default: false }, @@ -28,7 +34,7 @@ export const switchProps = { loading: { type: Boolean, default: false }, - size: { type: Number, default: 22 }, + size: { type: String as PropType, default: SwitchSize.medium }, activeColor: { type: String, default: '' }, diff --git a/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts b/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts index 1f4820171a9..b43218b55be 100644 --- a/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts +++ b/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts @@ -8,11 +8,6 @@ export class TextareaProperty extends InputBaseProperty { getEditorProperties(propertyData: any) { return this.getComponentConfig(propertyData, { type: "textarea" }, { - placeholder: { - description: "空值时,输入控件内的占位文本", - title: "提示文本", - type: "string" - }, rows: { description: "", title: "文本区域可见的行数", @@ -28,10 +23,15 @@ export class TextareaProperty extends InputBaseProperty { type: "boolean" }, maxLength: { - description: "", - title: "文本最大长度", + description: "文本最大长度", + title: "最大长度", type: "number" - } + }, + autoHeight: { + description: "", + title: "自动高度", + type: "boolean" + }, }); } 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 index 44635921d58..3217fa61013 100644 --- a/packages/mobile-ui-vue/components/textarea/src/schema/textarea.schema.json +++ b/packages/mobile-ui-vue/components/textarea/src/schema/textarea.schema.json @@ -83,6 +83,8 @@ ], "ignore": [ "id", - "appearance" + "appearance", + "binding", + "visible" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/textarea/src/textarea.component.tsx b/packages/mobile-ui-vue/components/textarea/src/textarea.component.tsx index dc0def2f57b..c456de710e2 100644 --- a/packages/mobile-ui-vue/components/textarea/src/textarea.component.tsx +++ b/packages/mobile-ui-vue/components/textarea/src/textarea.component.tsx @@ -23,7 +23,6 @@ export default defineComponent({ name: TEXTAREA_NAME, props: textareaProps, setup(props: TextareaProps, context) { - const { bem } = useBem(TEXTAREA_NAME); const { emit } = context; const handleValueChange = (value: string | number) => { @@ -31,7 +30,7 @@ export default defineComponent({ }; return () => ( - + ); } }); 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 4b4045b5573..4eb0aa16e86 100644 --- a/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts +++ b/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts @@ -10,7 +10,7 @@ export const TEXTAREA_NAME = 'FmTextarea'; export const textareaProps = { ...inputCommonProps, - autoSize: { type: Boolean, default: undefined }, + autoHeight: { type: Boolean, default: undefined }, rows: { type: Number, default: undefined }, diff --git a/packages/mobile-ui-vue/demos/date-picker/type.vue b/packages/mobile-ui-vue/demos/date-picker/type.vue index f2a95012193..ea3bd2cf5a9 100644 --- a/packages/mobile-ui-vue/demos/date-picker/type.vue +++ b/packages/mobile-ui-vue/demos/date-picker/type.vue @@ -1,5 +1,5 @@ diff --git a/packages/mobile-ui-vue/demos/button/base.vue b/packages/mobile-ui-vue/demos/button/base.vue index 336dddcddfb..6caa6bce949 100644 --- a/packages/mobile-ui-vue/demos/button/base.vue +++ b/packages/mobile-ui-vue/demos/button/base.vue @@ -5,9 +5,5 @@ 成功按钮 警告按钮 危险按钮 - 信息按钮 - - - diff --git a/packages/mobile-ui-vue/demos/button/block.vue b/packages/mobile-ui-vue/demos/button/block.vue index ac1b62ab749..b8cadd0af89 100644 --- a/packages/mobile-ui-vue/demos/button/block.vue +++ b/packages/mobile-ui-vue/demos/button/block.vue @@ -1,7 +1,3 @@ - - - - diff --git a/packages/mobile-ui-vue/demos/button/color.vue b/packages/mobile-ui-vue/demos/button/color.vue index 954659decfa..18d1ed76361 100644 --- a/packages/mobile-ui-vue/demos/button/color.vue +++ b/packages/mobile-ui-vue/demos/button/color.vue @@ -3,7 +3,3 @@ 单色按钮 渐变色按钮 - - - - diff --git a/packages/mobile-ui-vue/demos/button/disabled.vue b/packages/mobile-ui-vue/demos/button/disabled.vue index 6e242fa688c..6313e98fe33 100644 --- a/packages/mobile-ui-vue/demos/button/disabled.vue +++ b/packages/mobile-ui-vue/demos/button/disabled.vue @@ -2,7 +2,3 @@ 禁用状态 禁用状态 - - - - diff --git a/packages/mobile-ui-vue/demos/button/icon.vue b/packages/mobile-ui-vue/demos/button/icon.vue index 2f94fe14bc3..a8c161cde41 100644 --- a/packages/mobile-ui-vue/demos/button/icon.vue +++ b/packages/mobile-ui-vue/demos/button/icon.vue @@ -2,7 +2,3 @@ 按钮 - - - - diff --git a/packages/mobile-ui-vue/demos/button/loading.vue b/packages/mobile-ui-vue/demos/button/loading.vue index 1659578b827..eb010eb779f 100644 --- a/packages/mobile-ui-vue/demos/button/loading.vue +++ b/packages/mobile-ui-vue/demos/button/loading.vue @@ -3,7 +3,3 @@ - - - - diff --git a/packages/mobile-ui-vue/demos/button/plain.vue b/packages/mobile-ui-vue/demos/button/plain.vue index 200028ea59b..9a82b77133e 100644 --- a/packages/mobile-ui-vue/demos/button/plain.vue +++ b/packages/mobile-ui-vue/demos/button/plain.vue @@ -3,7 +3,3 @@ 线框按钮 线框按钮 - - - - diff --git a/packages/mobile-ui-vue/demos/button/round.vue b/packages/mobile-ui-vue/demos/button/round.vue index c7d8c18833e..558edd35c7f 100644 --- a/packages/mobile-ui-vue/demos/button/round.vue +++ b/packages/mobile-ui-vue/demos/button/round.vue @@ -3,6 +3,3 @@ 圆角按钮 - - - diff --git a/packages/mobile-ui-vue/demos/button/size.vue b/packages/mobile-ui-vue/demos/button/size.vue index b023d231a91..3ef91c05259 100644 --- a/packages/mobile-ui-vue/demos/button/size.vue +++ b/packages/mobile-ui-vue/demos/button/size.vue @@ -1,11 +1,6 @@ - - - - -- Gitee From 1d57c078761258c8ace6d289f58cf8c3142e2642 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Mon, 14 Apr 2025 10:10:46 +0800 Subject: [PATCH 225/287] =?UTF-8?q?chore:=20=E8=A7=A3=E5=86=B3=E5=86=B2?= =?UTF-8?q?=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/date-time-picker/src/date-time-picker.props.ts | 4 ++-- .../components/number-input/src/number-input.props.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) 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 2806cdb6847..59d05184fd7 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,7 +1,7 @@ import { ExtractPropTypes } from 'vue'; import { buttonEditProps } from '@/components/button-edit'; import { dateTimePickerPanelProps } from './date-time-picker-panel.props'; -import { createPropsResolver } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '../../dynamic-resolver'; import { schemaResolver } from './schema/schema-resolver'; import { schemaMapper } from './schema/schema-mapper'; import dateTimePickerSchema from './schema/datetime-picker.schema.json' @@ -15,6 +15,6 @@ export const dateTimePickerProps = { export type DateTimePickerProps = ExtractPropTypes; -export const propsResolver = createPropsResolver( +export const propsResolver = getPropsResolverGenerator( dateTimePickerProps, dateTimePickerSchema, schemaMapper, schemaResolver ); 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 index 836ba36b0af..3dc6e215977 100644 --- 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 @@ -1,6 +1,6 @@ import { ExtractPropTypes } from 'vue'; import { inputCommonProps } from '@/components/input-group'; -import { createPropsResolver } from '@/components/dynamic-resolver'; +import { getPropsResolverGenerator } from '@/components/dynamic-resolver'; import numberInputSchema from './schema/number-input.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; @@ -15,4 +15,4 @@ export const numberInputProps = { export type NumberInputProps = ExtractPropTypes; -export const propsResolver = createPropsResolver(numberInputProps, numberInputSchema, schemaMapper, schemaResolver); +export const propsResolver = getPropsResolverGenerator(numberInputProps, numberInputSchema, schemaMapper, schemaResolver); -- Gitee From 992298c2dd6a7808e3a395becb4b468612d99d7e Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Mon, 14 Apr 2025 10:35:50 +0800 Subject: [PATCH 226/287] Merge branch 'v1.6.0' into v1.6.0-designer-adapt-mobile-new --- .../src/schema/date-picker.schema.json | 5 +- .../src/schema/datetime-picker.schema.json | 2 +- .../src/schema/form-item.schema.json | 2 + .../src/schema/input-group.schema.json | 4 +- .../navbar/src/schema/navbar.schema.json | 6 +- .../src/schema/number-input.schema.json | 9 +- .../picker/src/schema/picker.schema.json | 4 +- .../textarea/src/schema/textarea.schema.json | 4 +- .../textarea/src/textarea.component.tsx | 7 +- pnpm-lock.yaml | 145 +++++++++++++++--- 10 files changed, 145 insertions(+), 43 deletions(-) diff --git a/packages/mobile-ui-vue/components/date-picker/src/schema/date-picker.schema.json b/packages/mobile-ui-vue/components/date-picker/src/schema/date-picker.schema.json index 6bbe0de09fc..0174321e036 100644 --- a/packages/mobile-ui-vue/components/date-picker/src/schema/date-picker.schema.json +++ b/packages/mobile-ui-vue/components/date-picker/src/schema/date-picker.schema.json @@ -82,8 +82,7 @@ ], "ignore": [ "id", - "appearance", - "binding", - "visible" + "type", + "appearance" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/schema/datetime-picker.schema.json b/packages/mobile-ui-vue/components/date-time-picker/src/schema/datetime-picker.schema.json index 73f07942ace..75a07a3f608 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/schema/datetime-picker.schema.json +++ b/packages/mobile-ui-vue/components/date-time-picker/src/schema/datetime-picker.schema.json @@ -12,7 +12,7 @@ "type": { "description": "控件类型", "type": "string", - "default": "datetime-picker" + "default": "textarea" }, "appearance": { "description": "外观", 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 82f34c27ccf..57c71e28033 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 @@ -62,5 +62,7 @@ "editor" ], "ignore": [ + "id", + "type" ] } \ No newline at end of file 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 658e623f094..a166044de2d 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 @@ -70,8 +70,6 @@ ], "ignore": [ "id", - "appearance", - "binding", - "visible" + "appearance" ] } \ No newline at end of file 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 index 1d7fac2629e..fef1b8208a8 100644 --- a/packages/mobile-ui-vue/components/navbar/src/schema/navbar.schema.json +++ b/packages/mobile-ui-vue/components/navbar/src/schema/navbar.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://farris-design.gitee.io/navbar.schema.json", "title": "navbar", - "description": "页面导航组件", + "description": "导航栏", "type": "object", "properties": { "id": { @@ -12,7 +12,7 @@ "type": { "description": "组件类型", "type": "string", - "default": "button-group" + "default": "navbar" }, "appearance": { "description": "外观", @@ -54,8 +54,6 @@ "type" ], "ignore": [ - "id", - "type", "appearance" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json b/packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json index 867a2b29ae9..5efd6ace2fe 100644 --- a/packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json +++ b/packages/mobile-ui-vue/components/number-input/src/schema/number-input.schema.json @@ -10,9 +10,9 @@ "type": "string" }, "type": { - "description": "控件类型", + "description": "类型", "type": "string", - "default": "number-input" + "default": "textarea" }, "appearance": { "description": "外观", @@ -78,8 +78,7 @@ ], "ignore": [ "id", - "appearance", - "binding", - "visible" + "type", + "appearance" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json b/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json index 1e7f0100e7d..19a83d6350b 100644 --- a/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json +++ b/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json @@ -84,8 +84,8 @@ ], "ignore": [ "id", + "type", "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 index 3217fa61013..44635921d58 100644 --- a/packages/mobile-ui-vue/components/textarea/src/schema/textarea.schema.json +++ b/packages/mobile-ui-vue/components/textarea/src/schema/textarea.schema.json @@ -83,8 +83,6 @@ ], "ignore": [ "id", - "appearance", - "binding", - "visible" + "appearance" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/textarea/src/textarea.component.tsx b/packages/mobile-ui-vue/components/textarea/src/textarea.component.tsx index c456de710e2..79de19a9062 100644 --- a/packages/mobile-ui-vue/components/textarea/src/textarea.component.tsx +++ b/packages/mobile-ui-vue/components/textarea/src/textarea.component.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { defineComponent } from 'vue'; +import { defineComponent, SetupContext } from 'vue'; import { useBem } from '@farris/mobile-ui-vue/common'; import InputGroup from "@farris/mobile-ui-vue/input-group"; import { TEXTAREA_NAME, textareaProps, TextareaProps } from './textarea.props'; @@ -22,7 +22,8 @@ import { TEXTAREA_NAME, textareaProps, TextareaProps } from './textarea.props'; export default defineComponent({ name: TEXTAREA_NAME, props: textareaProps, - setup(props: TextareaProps, context) { + setup(props: TextareaProps, context: SetupContext) { + const { bem } = useBem(TEXTAREA_NAME); const { emit } = context; const handleValueChange = (value: string | number) => { @@ -30,7 +31,7 @@ export default defineComponent({ }; return () => ( - + ); } }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cc9ef9559ce..7667ee58df0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -668,7 +668,7 @@ importers: 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(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)) + 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)) vite-svg-loader: specifier: ^5.1.0 version: 5.1.0(vue@3.5.12(typescript@5.6.3)) @@ -901,7 +901,7 @@ importers: 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(jsdom@20.0.3)(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 @@ -1079,7 +1079,7 @@ importers: 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(jsdom@20.0.3)(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 @@ -1309,7 +1309,7 @@ importers: 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(jsdom@20.0.3)(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 @@ -1530,7 +1530,7 @@ importers: 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(jsdom@20.0.3)(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 @@ -1684,16 +1684,16 @@ importers: 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)) + 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(jsdom@20.0.3)(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) @@ -1944,7 +1944,7 @@ importers: 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(jsdom@20.0.3)(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 @@ -2198,7 +2198,7 @@ importers: version: 0.8.0 vite-plugin-md: specifier: ^0.21.5 - version: 0.21.5(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)) + 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)) vite-svg-loader: specifier: ^5.1.0 version: 5.1.0(vue@3.5.12(typescript@5.6.3)) @@ -15286,19 +15286,46 @@ snapshots: - terser - vite - '@yankeeinlondon/builder-api@1.4.1(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@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@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: '@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@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-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' - '@vitest/browser' - '@vitest/ui' - encoding + - happy-dom - jsdom - less - lightningcss @@ -15307,6 +15334,60 @@ snapshots: - sugarss - supports-color - terser + - vite + + '@yankeeinlondon/builder-api@1.4.1(happy-dom@8.9.0)(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@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@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' + - '@vitest/browser' + - '@vitest/ui' + - encoding + - jsdom + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + '@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 + 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)) + transitivePeerDependencies: + - '@edge-runtime/vm' + - '@vitest/browser' + - '@vitest/ui' + - encoding + - jsdom + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + '@yankeeinlondon/gray-matter@6.2.1': + dependencies: + inferred-types: 0.37.6 + js-yaml: 4.1.0 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 '@yankeeinlondon/gray-matter@6.2.1(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)': dependencies: @@ -23243,13 +23324,15 @@ snapshots: - terser - vite - vite-plugin-md@0.20.6(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0): + 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(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@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) gray-matter: 4.0.3 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' @@ -23289,7 +23372,8 @@ snapshots: vite-plugin-md@0.21.5(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(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) + '@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)) + '@yankeeinlondon/builder-api': 1.4.1(happy-dom@8.9.0)(jsdom@20.0.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 @@ -23310,15 +23394,15 @@ snapshots: - supports-color - terser - vite-plugin-md@0.22.5(@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-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@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) - '@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)) + '@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(happy-dom@8.9.0)(jsdom@20.0.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: 4.5.5(@types/node@18.19.57)(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' - '@vitest/browser' @@ -23334,6 +23418,29 @@ 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)): + 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(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) + '@yankeeinlondon/gray-matter': 6.2.1 + '@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 + - jsdom + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + vite-svg-loader@4.0.0: dependencies: '@vue/compiler-sfc': 3.5.12 -- Gitee From 0339da39f1ab768e3f34d27cadd4e8a372d93856 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Mon, 14 Apr 2025 11:28:36 +0800 Subject: [PATCH 227/287] =?UTF-8?q?chore:=20=E5=90=88=E5=B9=B61.6=E6=9C=80?= =?UTF-8?q?=E6=96=B0=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../checkbox-group.property-config.ts | 2 +- .../mobile-ui-vue/components/common/index.ts | 3 +- .../use-designer-component.ts | 6 +- .../{entity => properties}/base-property.ts | 0 .../src/{entity => properties}/dg-control.ts | 0 .../expression-property.ts | 0 .../src/{entity => properties}/index.ts | 6 +- .../input-base-property.ts | 2 +- .../schema-dom-mapping.ts | 0 .../use-property-editor.ts | 0 ...omponent-type.ts => designer-component.ts} | 2 +- ...designer-rule-type.ts => designer-rule.ts} | 4 +- .../common/src/types/entity-schema-type.ts | 274 ------------------ .../src/{entity => types}/entity-schema.ts | 0 .../components/common/src/types/index.ts | 9 +- ...erty-entity-type.ts => property-config.ts} | 0 .../common/{ => src/types}/types.ts | 2 +- .../common/src/utils/src/with-register.ts | 2 +- .../date-picker.property-config.ts | 2 +- .../date-picker.property-config.ts | 2 +- .../src/converter/appearance.converter.ts | 2 +- .../src/converter/buttons.converter.ts | 2 +- .../src/converter/change-editor.converter.ts | 2 +- .../src/converter/enum-data.converter.ts | 2 +- .../src/converter/grid-selection.converter.ts | 2 +- .../src/converter/items-count.converter.ts | 2 +- .../src/converter/pagination.converter.ts | 2 +- .../converter/property-editor.converter.ts | 2 +- .../src/converter/row-number.converter.ts | 2 +- .../src/converter/type.converter.ts | 4 +- .../src/property-config-resolver.ts | 4 +- .../use-property-config-resolver.ts | 3 +- .../src/float-container.component.tsx | 2 +- .../src/schema/form-item.schema.json | 2 - .../input-group.property-config.ts | 3 +- .../list-view/src/list-view.props.ts | 4 +- .../list-view.property-config.json | 143 --------- .../number-input.property-config.ts | 2 +- .../enum-field-input.property-config.ts | 2 +- .../radio-group.property-config.ts | 2 +- .../property-config/switch.property-config.ts | 2 +- .../textarea.property-config.ts | 2 +- 42 files changed, 43 insertions(+), 466 deletions(-) rename packages/mobile-ui-vue/components/common/src/{entity => properties}/base-property.ts (100%) rename packages/mobile-ui-vue/components/common/src/{entity => properties}/dg-control.ts (100%) rename packages/mobile-ui-vue/components/common/src/{entity => properties}/expression-property.ts (100%) rename packages/mobile-ui-vue/components/common/src/{entity => properties}/index.ts (42%) rename packages/mobile-ui-vue/components/common/src/{entity => properties}/input-base-property.ts (99%) rename packages/mobile-ui-vue/components/common/src/{entity => properties}/schema-dom-mapping.ts (100%) rename packages/mobile-ui-vue/components/common/src/{entity => properties}/use-property-editor.ts (100%) rename packages/mobile-ui-vue/components/common/src/types/{designer-component-type.ts => designer-component.ts} (98%) rename packages/mobile-ui-vue/components/common/src/types/{designer-rule-type.ts => designer-rule.ts} (97%) delete mode 100644 packages/mobile-ui-vue/components/common/src/types/entity-schema-type.ts rename packages/mobile-ui-vue/components/common/src/{entity => types}/entity-schema.ts (100%) rename packages/mobile-ui-vue/components/common/src/types/{property-entity-type.ts => property-config.ts} (100%) rename packages/mobile-ui-vue/components/common/{ => src/types}/types.ts (97%) delete mode 100644 packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.json diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts b/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts index 8d632abab80..1ec557f202c 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts +++ b/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts @@ -1,4 +1,4 @@ -import { InputBaseProperty } from '@farris/mobile-ui-vue/common/src/entity/input-base-property'; +import { InputBaseProperty } from '@farris/mobile-ui-vue/common'; export class CheckBoxGroupProperty extends InputBaseProperty { constructor(componentId: string, designerHostService: any) { diff --git a/packages/mobile-ui-vue/components/common/index.ts b/packages/mobile-ui-vue/components/common/index.ts index dc440060b8d..463f7bfd49f 100644 --- a/packages/mobile-ui-vue/components/common/index.ts +++ b/packages/mobile-ui-vue/components/common/index.ts @@ -1,5 +1,4 @@ export * from './src/compositions'; export * from './src/utils'; -export * from './types'; -export * from './src/entity/index'; export * from './src/types'; +export * from './src/properties'; diff --git a/packages/mobile-ui-vue/components/common/src/compositions/use-designer-component/use-designer-component.ts b/packages/mobile-ui-vue/components/common/src/compositions/use-designer-component/use-designer-component.ts index 1e08b16a652..0c31d5f8fd8 100644 --- a/packages/mobile-ui-vue/components/common/src/compositions/use-designer-component/use-designer-component.ts +++ b/packages/mobile-ui-vue/components/common/src/compositions/use-designer-component/use-designer-component.ts @@ -1,7 +1,7 @@ import { Ref, ref } from "vue"; -import { DesignerHostService, DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../../types/designer-rule-type"; -import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from "../../types/designer-component-type"; -import { getSchemaByTypeForDesigner } from '@farris/mobile-ui-vue/dynamic-resolver'; +import { DesignerHostService, DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../../types/designer-rule"; +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from "../../types/designer-component"; +import { getSchemaByTypeForDesigner } from '@farris/mobile-ui-vue/dynamic-resolver/src/resolver/schema/schema-resolver-design'; export function useDesignerComponent( elementRef: Ref, diff --git a/packages/mobile-ui-vue/components/common/src/entity/base-property.ts b/packages/mobile-ui-vue/components/common/src/properties/base-property.ts similarity index 100% rename from packages/mobile-ui-vue/components/common/src/entity/base-property.ts rename to packages/mobile-ui-vue/components/common/src/properties/base-property.ts diff --git a/packages/mobile-ui-vue/components/common/src/entity/dg-control.ts b/packages/mobile-ui-vue/components/common/src/properties/dg-control.ts similarity index 100% rename from packages/mobile-ui-vue/components/common/src/entity/dg-control.ts rename to packages/mobile-ui-vue/components/common/src/properties/dg-control.ts diff --git a/packages/mobile-ui-vue/components/common/src/entity/expression-property.ts b/packages/mobile-ui-vue/components/common/src/properties/expression-property.ts similarity index 100% rename from packages/mobile-ui-vue/components/common/src/entity/expression-property.ts rename to packages/mobile-ui-vue/components/common/src/properties/expression-property.ts diff --git a/packages/mobile-ui-vue/components/common/src/entity/index.ts b/packages/mobile-ui-vue/components/common/src/properties/index.ts similarity index 42% rename from packages/mobile-ui-vue/components/common/src/entity/index.ts rename to packages/mobile-ui-vue/components/common/src/properties/index.ts index 15871b7eafe..45e1b856918 100644 --- a/packages/mobile-ui-vue/components/common/src/entity/index.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/index.ts @@ -1,4 +1,4 @@ - -export { BaseControlProperty } from './base-property'; export * from './dg-control'; -export { SchemaDOMMapping } from './schema-dom-mapping'; \ No newline at end of file +export { SchemaDOMMapping } from './schema-dom-mapping'; +export { BaseControlProperty } from './base-property'; +export { InputBaseProperty } from './input-base-property'; \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts b/packages/mobile-ui-vue/components/common/src/properties/input-base-property.ts similarity index 99% rename from packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts rename to packages/mobile-ui-vue/components/common/src/properties/input-base-property.ts index b40059b650e..58894cf7b1a 100644 --- a/packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/input-base-property.ts @@ -4,7 +4,7 @@ import { SchemaDOMMapping } from './schema-dom-mapping'; // import { canvasChanged } from '../../../../common/src/composition/common-changed'; import { ExpressionProperty } from "./expression-property"; -import { FormSchemaEntityField$Type, FormSchemaEntityFieldType$Type, FormVariable } from "../types/entity-schema-type"; +import { FormSchemaEntityField$Type, FormSchemaEntityFieldType$Type, FormVariable } from "../types/entity-schema"; import { DesignerComponentInstance, FormBindingType, FormPropertyChangeObject } from "../types"; import { DgControl } from "./dg-control"; diff --git a/packages/mobile-ui-vue/components/common/src/entity/schema-dom-mapping.ts b/packages/mobile-ui-vue/components/common/src/properties/schema-dom-mapping.ts similarity index 100% rename from packages/mobile-ui-vue/components/common/src/entity/schema-dom-mapping.ts rename to packages/mobile-ui-vue/components/common/src/properties/schema-dom-mapping.ts diff --git a/packages/mobile-ui-vue/components/common/src/entity/use-property-editor.ts b/packages/mobile-ui-vue/components/common/src/properties/use-property-editor.ts similarity index 100% rename from packages/mobile-ui-vue/components/common/src/entity/use-property-editor.ts rename to packages/mobile-ui-vue/components/common/src/properties/use-property-editor.ts diff --git a/packages/mobile-ui-vue/components/common/src/types/designer-component-type.ts b/packages/mobile-ui-vue/components/common/src/types/designer-component.ts similarity index 98% rename from packages/mobile-ui-vue/components/common/src/types/designer-component-type.ts rename to packages/mobile-ui-vue/components/common/src/types/designer-component.ts index 727b972b6e8..6ca1bb9c26e 100644 --- a/packages/mobile-ui-vue/components/common/src/types/designer-component-type.ts +++ b/packages/mobile-ui-vue/components/common/src/types/designer-component.ts @@ -1,6 +1,6 @@ /* eslint-disable no-use-before-define */ import { Ref, SetupContext } from "vue"; -import { DesignerHostService, DesignerHTMLElement, DraggingResolveContext } from "./designer-rule-type"; +import { DesignerHostService, DesignerHTMLElement, DraggingResolveContext } from "./designer-rule"; export interface ComponentSchema { diff --git a/packages/mobile-ui-vue/components/common/src/types/designer-rule-type.ts b/packages/mobile-ui-vue/components/common/src/types/designer-rule.ts similarity index 97% rename from packages/mobile-ui-vue/components/common/src/types/designer-rule-type.ts rename to packages/mobile-ui-vue/components/common/src/types/designer-rule.ts index 4c0be7bf7bd..ed261cb18f6 100644 --- a/packages/mobile-ui-vue/components/common/src/types/designer-rule-type.ts +++ b/packages/mobile-ui-vue/components/common/src/types/designer-rule.ts @@ -1,6 +1,6 @@ import { Ref } from "vue"; -import { ComponentSchema, DesignerComponentButton, DesignerComponentInstance } from "./designer-component-type"; -import { DesignFormVariable, DesignViewModelField, FormSchemaEntity, FormSchemaEntityField } from "./entity-schema-type"; +import { ComponentSchema, DesignerComponentButton, DesignerComponentInstance } from "./designer-component"; +import { DesignFormVariable, DesignViewModelField, FormSchemaEntity, FormSchemaEntityField } from "./entity-schema"; export interface DesignerHTMLElement extends HTMLElement { /** 记录各子元素对应的控件schema json的集合,用于container类dom节点 */ diff --git a/packages/mobile-ui-vue/components/common/src/types/entity-schema-type.ts b/packages/mobile-ui-vue/components/common/src/types/entity-schema-type.ts deleted file mode 100644 index 30e62037ec6..00000000000 --- a/packages/mobile-ui-vue/components/common/src/types/entity-schema-type.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/src/entity/entity-schema.ts b/packages/mobile-ui-vue/components/common/src/types/entity-schema.ts similarity index 100% rename from packages/mobile-ui-vue/components/common/src/entity/entity-schema.ts rename to packages/mobile-ui-vue/components/common/src/types/entity-schema.ts diff --git a/packages/mobile-ui-vue/components/common/src/types/index.ts b/packages/mobile-ui-vue/components/common/src/types/index.ts index abf4d572af8..195bea74cd3 100644 --- a/packages/mobile-ui-vue/components/common/src/types/index.ts +++ b/packages/mobile-ui-vue/components/common/src/types/index.ts @@ -1,4 +1,5 @@ -export * from './designer-component-type'; -export * from './designer-rule-type'; -export * from './entity-schema-type'; -export * from './property-entity-type'; +export * from './types'; +export * from './designer-component'; +export * from './designer-rule'; +export * from './entity-schema'; +export * from './property-config'; diff --git a/packages/mobile-ui-vue/components/common/src/types/property-entity-type.ts b/packages/mobile-ui-vue/components/common/src/types/property-config.ts similarity index 100% rename from packages/mobile-ui-vue/components/common/src/types/property-entity-type.ts rename to packages/mobile-ui-vue/components/common/src/types/property-config.ts diff --git a/packages/mobile-ui-vue/components/common/types.ts b/packages/mobile-ui-vue/components/common/src/types/types.ts similarity index 97% rename from packages/mobile-ui-vue/components/common/types.ts rename to packages/mobile-ui-vue/components/common/src/types/types.ts index 351245ac179..47a5ed1fc2b 100644 --- a/packages/mobile-ui-vue/components/common/types.ts +++ b/packages/mobile-ui-vue/components/common/src/types/types.ts @@ -1,5 +1,5 @@ import { ComputedRef, Ref } from "vue"; -import { EffectFunction, SchemaResolverFunction } from "../dynamic-resolver"; +import { EffectFunction, SchemaResolverFunction } from "@farris/mobile-ui-vue/dynamic-resolver/src/types"; export interface TextBoxProps { diff --git a/packages/mobile-ui-vue/components/common/src/utils/src/with-register.ts b/packages/mobile-ui-vue/components/common/src/utils/src/with-register.ts index 94a387f7ed8..15608d737bd 100644 --- a/packages/mobile-ui-vue/components/common/src/utils/src/with-register.ts +++ b/packages/mobile-ui-vue/components/common/src/utils/src/with-register.ts @@ -1,4 +1,4 @@ -import { RegisterContext } from '@farris/mobile-ui-vue/common/types'; +import { RegisterContext } from '@farris/mobile-ui-vue/common'; import type { App, Component } from 'vue'; export type WithRegister = T & { diff --git a/packages/mobile-ui-vue/components/date-picker/src/property-config/date-picker.property-config.ts b/packages/mobile-ui-vue/components/date-picker/src/property-config/date-picker.property-config.ts index 205e01d02ba..1ea66076a51 100644 --- a/packages/mobile-ui-vue/components/date-picker/src/property-config/date-picker.property-config.ts +++ b/packages/mobile-ui-vue/components/date-picker/src/property-config/date-picker.property-config.ts @@ -1,4 +1,4 @@ -import { InputBaseProperty } from '@farris/mobile-ui-vue/common/src/entity/input-base-property'; +import { InputBaseProperty } from '@farris/mobile-ui-vue/common'; import { DATE_FORMATS } from './date-format'; export class DatePickerProperty extends InputBaseProperty { diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts b/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts index 990e7b8e3c4..5fd91541b73 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts +++ b/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts @@ -1,4 +1,4 @@ -import { InputBaseProperty } from '@farris/mobile-ui-vue/common/src/entity/input-base-property'; +import { InputBaseProperty } from '@farris/mobile-ui-vue/common'; import { DATE_FORMATS } from './date-format'; export class DateTimePickerProperty extends InputBaseProperty { diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/appearance.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/appearance.converter.ts index 7f1e0bdd4a8..b197eb6c32c 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/appearance.converter.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/appearance.converter.ts @@ -1,4 +1,4 @@ -import { ComponentSchema } from "../../../common/src/types/designer-component-type"; +import { ComponentSchema } from "@farris/mobile-ui-vue/common"; import { PropertyConverter, SchemaService } from "../types"; export default { diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/buttons.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/buttons.converter.ts index 1f987974221..1eb5a9f3b6d 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/buttons.converter.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/buttons.converter.ts @@ -1,4 +1,4 @@ -import { ComponentSchema } from "../../../common/src/types/designer-component-type"; +import { ComponentSchema } from "@farris/mobile-ui-vue/common"; import { PropertyConverter, SchemaService } from "../types"; export default { diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/change-editor.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/change-editor.converter.ts index cb065b0d51d..72f511cefe1 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/change-editor.converter.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/change-editor.converter.ts @@ -1,4 +1,4 @@ -import { ComponentSchema } from "../../../common/src/types/designer-component-type"; +import { ComponentSchema } from "@farris/mobile-ui-vue/common"; import { PropertyConverter, SchemaService } from "../types"; export default { diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/enum-data.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/enum-data.converter.ts index 8d22c5d8e33..aec811359a7 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/enum-data.converter.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/enum-data.converter.ts @@ -1,4 +1,4 @@ -import { ComponentSchema } from "../../../common/src/types/designer-component-type"; +import { ComponentSchema } from "@farris/mobile-ui-vue/common"; import { PropertyConverter, SchemaService } from "../types"; export default { convertTo: (schema: ComponentSchema, propertyKey: string, propertyValue: any, schemaService: SchemaService) => { diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/grid-selection.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/grid-selection.converter.ts index 4bcbeceda61..7c5e0797417 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/grid-selection.converter.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/grid-selection.converter.ts @@ -1,4 +1,4 @@ -import { ComponentSchema } from "../../../common/src/types/designer-component-type"; +import { ComponentSchema } from "@farris/mobile-ui-vue/common"; import { PropertyConverter, SchemaService } from "../types"; export default { convertTo: (schema: ComponentSchema, propertyKey: string, propertyValue: any, schemaService: SchemaService) => { diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/items-count.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/items-count.converter.ts index c483cb290e3..b23f948d25d 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/items-count.converter.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/items-count.converter.ts @@ -1,4 +1,4 @@ -import { ComponentSchema } from "../../../common/src/types/designer-component-type"; +import { ComponentSchema } from "@farris/mobile-ui-vue/common"; import { PropertyConverter, SchemaService } from "../types"; export default { diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/pagination.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/pagination.converter.ts index 6c2686f3d08..6cdde30711a 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/pagination.converter.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/pagination.converter.ts @@ -1,4 +1,4 @@ -import { ComponentSchema } from "../../../common/src/types/designer-component-type"; +import { ComponentSchema } from "@farris/mobile-ui-vue/common"; import { PropertyConverter, SchemaService } from "../types"; /** * NG版,此处pagination类型是布尔 diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/property-editor.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/property-editor.converter.ts index 0a2aabe7bb6..4c724568e9f 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/property-editor.converter.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/property-editor.converter.ts @@ -1,4 +1,4 @@ -import { ComponentSchema } from "../../../common/src/types/designer-component-type"; +import { ComponentSchema } from "@farris/mobile-ui-vue/common"; import { PropertyConverter, SchemaService } from "../types"; export default { diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/row-number.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/row-number.converter.ts index 0e098698c7b..94a4e5c8711 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/row-number.converter.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/row-number.converter.ts @@ -1,4 +1,4 @@ -import { ComponentSchema } from "../../../common/src/types/designer-component-type"; +import { ComponentSchema } from "@farris/mobile-ui-vue/common"; import { PropertyConverter, SchemaService } from "../types"; export default { convertTo: (schema: ComponentSchema, propertyKey: string, propertyValue: any, schemaService: SchemaService) => { diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/type.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/type.converter.ts index f52b21a421d..805dabf1907 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/type.converter.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/type.converter.ts @@ -1,5 +1,5 @@ -import { ComponentSchema } from "../../../common/src/types/designer-component-type"; -import { DgControl } from "../../../common/src/entity/dg-control"; +import { ComponentSchema } from "@farris/mobile-ui-vue/common"; +import { DgControl } from "../../../common/src/properties/dg-control"; import { PropertyConverter, SchemaService } from "../types"; export default { diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/property-config-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/property-config-resolver.ts index d1b360441bf..ccf969fd64a 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/property-config-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/property-config-resolver.ts @@ -1,8 +1,8 @@ import { computed, ref } from "vue"; import { EffectFunction, PropertyConverter, SchemaService } from './types'; -import { EditorConfig, resolveSchemaWithDefaultValue } from "@farris/mobile-ui-vue/dynamic-resolver"; +import { resolveSchemaWithDefaultValue } from "@farris/mobile-ui-vue/dynamic-resolver"; import { useObjectExpression } from './object-expression'; -import { ComponentSchema } from "../../common/src/types/designer-component-type"; +import { ComponentSchema, EditorConfig } from "@farris/mobile-ui-vue/common"; import appearanceConverter from './converter/appearance.converter'; import buttonsConverter from "./converter/buttons.converter"; import propertyEditorConverter from "./converter/property-editor.converter"; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts index 8147e8265e6..c2ca508936d 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/property-config/use-property-config-resolver.ts @@ -1,7 +1,7 @@ import { computed, ref } from "vue"; import { EffectFunction, PropertyConverter, SchemaService } from '../../types'; import { useObjectExpression } from '../../object-expression'; -import { ComponentSchema } from "../../../../common/src/types/designer-component-type"; +import { ComponentSchema,EditorConfig } from "@farris/mobile-ui-vue/common"; import { resolveSchemaWithDefaultValue } from "../schema/schema-resolver"; import appearanceConverter from '../../converter/appearance.converter'; import buttonsConverter from "../../converter/buttons.converter"; @@ -15,7 +15,6 @@ import gridSelectionConverter from "../../converter/grid-selection.converter"; import { ElementPropertyConfig, PropertyEntity } from "@farris/mobile-ui-vue/common"; import itemsCountConverter from "../../converter/items-count.converter"; import formGroupLabelConverter from "../../converter/form-group-label.converter"; -import { EditorConfig } from "../type-resolver/types"; export function usePropertyConfigResolver(propertyConfigSchemaMap: Record, propertyEffectMap: Record) { const propertyConverterMap = new Map([ 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 index c2718fcdc86..159f9933d50 100644 --- 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 @@ -1,5 +1,5 @@ import { SetupContext, defineComponent, computed } from 'vue'; -import { useBem } from '@farris/mobile-ui-vue/common/index'; +import { useBem } from '@farris/mobile-ui-vue/common'; import { FLOAT_CONTAINER_NAME, floatContainerProps, FloatContainerProps } from './float-container.props'; export default defineComponent({ 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 57c71e28033..82f34c27ccf 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 @@ -62,7 +62,5 @@ "editor" ], "ignore": [ - "id", - "type" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts b/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts index f2eb13665c0..7cfd630ed80 100644 --- a/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts +++ b/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts @@ -1,5 +1,4 @@ -import { InputBaseProperty } from '@farris/mobile-ui-vue/common/src/entity/input-base-property'; -import { DesignerComponentInstance } from '@farris/mobile-ui-vue/common'; +import { DesignerComponentInstance, InputBaseProperty } from '@farris/mobile-ui-vue/common'; import { typeConverter, commonConverter, 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 2bdf5bff01b..26512af3ede 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 @@ -21,7 +21,6 @@ import { CheckboxProps } from '@farris/mobile-ui-vue/checkbox/src/checkbox.props import { getPropsResolverGenerator } from '../../dynamic-resolver'; import { schemaMapper } from './schema/schema-mapper'; import listViewSchema from './schema/list-view.schema.json'; -import listViewPropertyConfig from './property-config/list-view.property-config.json'; import { schemaResolver } from './schema/schema-resolver'; export const LIST_VIEW_NAME = 'fm-list-view'; @@ -111,6 +110,5 @@ export const propsResolverGenerator = getPropsResolverGenerator( listViewProps, listViewSchema, schemaMapper, - schemaResolver, - listViewPropertyConfig, + schemaResolver ); diff --git a/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.json b/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.json deleted file mode 100644 index 75c9494bb38..00000000000 --- a/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.json +++ /dev/null @@ -1,143 +0,0 @@ -{ - "title": "list-view", - "description": "A Farris Component", - "type": "object", - "categories": { - "basic": { - "description": "Basic Infomation", - "title": "基本信息", - "properties": { - "id": { - "description": "组件标识", - "title": "标识", - "type": "string", - "readonly": true - }, - "type": { - "description": "组件类型", - "title": "控件类型", - "type": "string" - } - } - }, - "behavior": { - "description": "", - "title": "行为", - "properties": { - "visible": { - "description": "运行时组件是否可见", - "type": "boolean", - "title": "是否可见", - "editor": { - "type": "combo-list", - "data": [ - { - "value": true, - "name": "是" - }, - { - "value": false, - "name": "否" - } - ] - } - }, - "enablePullRefresh": { - "description": "是否启用下拉刷新列表数据", - "type": "boolean", - "title": "是否启用下拉刷新", - "editor": { - "type": "combo-list", - "data": [ - { - "value": true, - "name": "是" - }, - { - "value": false, - "name": "否" - } - ] - } - }, - "enableMultiSelect": { - "description": "是否启用多选功能,启用后长按列表条目进入多选状态", - "type": "boolean", - "title": "是否启用多选功能", - "editor": { - "type": "combo-list", - "data": [ - { - "value": true, - "name": "是" - }, - { - "value": false, - "name": "否" - } - ] - } - }, - "multiSelect": { - "description": "是否默认处于多选状态", - "type": "boolean", - "title": "是否默认处于多选状态", - "editor": { - "type": "combo-list", - "data": [ - { - "value": true, - "name": "是" - }, - { - "value": false, - "name": "否" - } - ] - } - }, - "fill": { - "description": "是否填充页面下方剩余区域", - "type": "boolean", - "title": "是否填充", - "editor": { - "type": "combo-list", - "data": [ - { - "value": true, - "name": "是" - }, - { - "value": false, - "name": "否" - } - ] - } - }, - "split": { - "description": "是否在列表条目之间显示分隔线", - "type": "boolean", - "title": "是否显示分隔线", - "editor": { - "type": "combo-list", - "data": [ - { - "value": true, - "name": "是" - }, - { - "value": false, - "name": "否" - } - ] - } - }, - "emptyMessage": { - "description": "列表数据为空时显示的占位文本", - "title": "空数据提示文本", - "type": "string" - } - } - } - } -} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts b/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts index 63918fbc45a..45e3182b0f9 100644 --- a/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts +++ b/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts @@ -1,4 +1,4 @@ -import { InputBaseProperty } from "@farris/mobile-ui-vue/common/src/entity/input-base-property"; +import { InputBaseProperty } from "@farris/mobile-ui-vue/common"; export class NumberInputProperty extends InputBaseProperty { diff --git a/packages/mobile-ui-vue/components/picker/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 index 44d93c7ca04..3e7ddf5ebf3 100644 --- a/packages/mobile-ui-vue/components/picker/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 @@ -1,4 +1,4 @@ -import { InputBaseProperty } from "@farris/mobile-ui-vue/common/src/entity/input-base-property"; +import { InputBaseProperty } from "@farris/mobile-ui-vue/common"; export class EnumFieldInputProperty extends InputBaseProperty { diff --git a/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts b/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts index 9b69160f235..066c73425c9 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts +++ b/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts @@ -1,4 +1,4 @@ -import { InputBaseProperty } from '@farris/mobile-ui-vue/common/src/entity/input-base-property'; +import { InputBaseProperty } from '@farris/mobile-ui-vue/common'; export class RadioGroupProperty extends InputBaseProperty { constructor(componentId: string, designerHostService: any) { diff --git a/packages/mobile-ui-vue/components/switch/src/property-config/switch.property-config.ts b/packages/mobile-ui-vue/components/switch/src/property-config/switch.property-config.ts index ed4cd54c1f8..8e3ee681a1d 100644 --- a/packages/mobile-ui-vue/components/switch/src/property-config/switch.property-config.ts +++ b/packages/mobile-ui-vue/components/switch/src/property-config/switch.property-config.ts @@ -1,4 +1,4 @@ -import { InputBaseProperty } from '@farris/mobile-ui-vue/common/src/entity/input-base-property'; +import { InputBaseProperty } from '@farris/mobile-ui-vue/common'; export class SwitchProperty extends InputBaseProperty { constructor(componentId: string, designerHostService: any) { diff --git a/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts b/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts index b43218b55be..481dff85bde 100644 --- a/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts +++ b/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts @@ -1,4 +1,4 @@ -import { InputBaseProperty } from "@farris/mobile-ui-vue/common/src/entity/input-base-property"; +import { InputBaseProperty } from "@farris/mobile-ui-vue/common"; export class TextareaProperty extends InputBaseProperty { -- Gitee From ea07647b04590cf2a8e2302ed9fc288d21913095 Mon Sep 17 00:00:00 2001 From: LuPing Zou <“zouluping@inspur.com”> Date: Sat, 12 Apr 2025 11:51:05 +0800 Subject: [PATCH 228/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E7=AB=AFC?= =?UTF-8?q?ontentContainer=E6=8E=A7=E4=BB=B6=E8=AE=BE=E8=AE=A1=E6=97=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../types/toolbox/mobile-toolbox.json | 7 - .../mobile-ui-vue/components/card/index.ts | 2 +- .../components/card/src/card.component.tsx | 4 +- .../components/card/src/card.props.ts | 4 +- .../src/properties/container-base-property.ts | 297 ++++++++++++++++++ .../components/common/src/properties/index.ts | 3 +- .../components/content-container/index.ts | 31 +- .../src/content-container.component.tsx | 71 ++++- .../src/content-container.props.ts | 35 ++- .../content-container.design.component.tsx | 33 +- .../src/designer/use-designer-rules.ts | 17 +- .../content-container.property-config.ts | 106 ++++++- .../src/schema/content-container.schema.json | 38 ++- .../components/list-view-item.component.tsx | 2 +- .../navbar/src/navbar.component.tsx | 8 +- .../components/navbar/src/navbar.props.ts | 2 +- .../src/designer/use-designer-rules.ts | 6 +- .../page-body-container.property-config.ts | 6 +- .../src/designer/use-designer-rules.ts | 12 +- .../page-container.property-config.ts | 6 +- .../src/designer/use-designer-rules.ts | 7 +- .../page-footer-container.property-config.ts | 8 +- .../schema/page-footer-container.schema.json | 2 +- .../src/designer/use-designer-rules.ts | 10 +- .../page-header-container.property-config.ts | 8 +- .../schema/page-header-container.schema.json | 5 + .../swipe-cell/src/composition/type.ts | 2 +- packages/mobile-ui-vue/farris.config.mjs | 4 +- 28 files changed, 622 insertions(+), 114 deletions(-) create mode 100644 packages/mobile-ui-vue/components/common/src/properties/container-base-property.ts diff --git a/packages/designer/src/components/types/toolbox/mobile-toolbox.json b/packages/designer/src/components/types/toolbox/mobile-toolbox.json index e160cd632e8..fdc942bfbc1 100644 --- a/packages/designer/src/components/types/toolbox/mobile-toolbox.json +++ b/packages/designer/src/components/types/toolbox/mobile-toolbox.json @@ -105,13 +105,6 @@ "category": "container", "icon": "content-container" }, - { - "id": "PageBodyContainer", - "type": "page-body-container", - "name": "页面主体容器", - "category": "container", - "icon": "content-container" - }, { "id": "PageFooterContainer", "type": "page-footer-container", diff --git a/packages/mobile-ui-vue/components/card/index.ts b/packages/mobile-ui-vue/components/card/index.ts index 65abf564a6c..92b7b6fd0cd 100644 --- a/packages/mobile-ui-vue/components/card/index.ts +++ b/packages/mobile-ui-vue/components/card/index.ts @@ -1,5 +1,5 @@ import { Plugin } from 'vue'; -import { withInstall } from '@components/common'; +import { withInstall } from '@farris/mobile-ui-vue/common'; import CardInstallless from './src/card.component'; import { propsResolver } from './src/card.props'; diff --git a/packages/mobile-ui-vue/components/card/src/card.component.tsx b/packages/mobile-ui-vue/components/card/src/card.component.tsx index 6639d7b7e7d..e03ab80aa91 100644 --- a/packages/mobile-ui-vue/components/card/src/card.component.tsx +++ b/packages/mobile-ui-vue/components/card/src/card.component.tsx @@ -1,6 +1,6 @@ import { defineComponent, computed } from 'vue'; -import { useBem } from '@components/common'; -import { ButtonGroup } from '@components/button-group'; +import { useBem } from '@farris/mobile-ui-vue/common'; +import { ButtonGroup } from '@farris/mobile-ui-vue/button-group'; import { CARD_NAME, cardProps, CardProps } from './card.props'; export default defineComponent({ diff --git a/packages/mobile-ui-vue/components/card/src/card.props.ts b/packages/mobile-ui-vue/components/card/src/card.props.ts index 22306fa6b4b..62957ef6da7 100644 --- a/packages/mobile-ui-vue/components/card/src/card.props.ts +++ b/packages/mobile-ui-vue/components/card/src/card.props.ts @@ -1,6 +1,6 @@ import { ExtractPropTypes } from 'vue'; -import { getPropsResolverGenerator } from '@components/dynamic-resolver'; -import { ButtonItem } from '@components/button-group'; +import { getPropsResolverGenerator } from '@farris/mobile-ui-vue/dynamic-resolver'; +import { ButtonItem } from '@farris/mobile-ui-vue/button-group'; import cardSchema from './schema/card.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; diff --git a/packages/mobile-ui-vue/components/common/src/properties/container-base-property.ts b/packages/mobile-ui-vue/components/common/src/properties/container-base-property.ts new file mode 100644 index 00000000000..3f511f440e8 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/src/properties/container-base-property.ts @@ -0,0 +1,297 @@ +import { BaseControlProperty } from "./base-property"; + +export class ContainerBaseProperty extends BaseControlProperty { + + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + protected getAppearanceConfig(propertyData: any = null): any { + return { + title: "外观", + description: "Appearance", + properties: this.getAppearanceProperties(["style"], propertyData), + }; + } + + protected getAppearanceProperties( + propertyNames: string[] = ["style"], + propertyData?: any, + ) { + const propertyName2PropertyGetter = { + style: this.getStyleProperties, + size: this.getSizeProperties, + padding: this.getPaddingProperties, + margin: this.getMarginProperties, + borderRadius: this.getBorderRadiusProperties, + position: this.getPositionProperties, + }; + const properties: any[] = []; + propertyNames.forEach((propertyName) => { + const propertyGetter = propertyName2PropertyGetter[propertyName]; + if (propertyGetter) { + properties.push(propertyGetter(propertyData)); + } + }); + return Object.assign({}, ...properties); + } + + private getStyleProperties(propertyData?: any) { + return { + class: { + title: "class样式", + type: "string", + description: "组件的CSS样式", + $converter: "/converter/appearance.converter" + }, + style: { + title: "style样式", + type: "string", + description: "组件的样式", + $converter: "/converter/appearance.converter" + }, + }; + } + + private getSizeProperties(propertyData?: any) { + return { + size: { + title: "尺寸", + type: "cascade", + description: "组件的尺寸", + isExpand: true, + properties: { + width: { + title: "宽度(px)", + type: "number", + description: "组件的宽度", + editor: { + min: 0, + decimals: 0, + nullable: true, + }, + }, + height: { + title: "高度(px)", + type: "number", + description: "组件的高度", + editor: { + min: 0, + decimals: 0, + nullable: true, + }, + } + } + }, + }; + } + + private getPaddingProperties(propertyData?: any) { + return { + padding: { + title: "内边距", + type: "cascade", + description: "组件的内边距", + isExpand: true, + properties: { + top: { + title: "上侧(px)", + type: "number", + description: "组件的上侧内边距", + editor: { + min: 0, + decimals: 0, + nullable: true, + }, + }, + right: { + title: "右侧(px)", + type: "number", + description: "组件的右侧内边距", + editor: { + min: 0, + decimals: 0, + nullable: true, + }, + }, + bottom: { + title: "下侧(px)", + type: "number", + description: "组件的下侧内边距", + editor: { + min: 0, + decimals: 0, + nullable: true, + }, + }, + left: { + title: "左侧(px)", + type: "number", + description: "组件的左侧内边距", + editor: { + min: 0, + decimals: 0, + nullable: true, + }, + }, + } + }, + }; + } + + private getMarginProperties(propertyData?: any) { + return { + margin: { + title: "外边距", + type: "cascade", + description: "组件的外边距", + isExpand: true, + properties: { + top: { + title: "上侧(px)", + type: "number", + description: "组件的上侧外边距", + editor: { + min: 0, + decimals: 0, + nullable: true, + }, + }, + right: { + title: "右侧(px)", + type: "number", + description: "组件的右侧外边距", + editor: { + min: 0, + decimals: 0, + nullable: true, + }, + }, + bottom: { + title: "下侧(px)", + type: "number", + description: "组件的下侧外边距", + editor: { + min: 0, + decimals: 0, + nullable: true, + }, + }, + left: { + title: "左侧(px)", + type: "number", + description: "组件的左侧外边距", + editor: { + min: 0, + decimals: 0, + nullable: true, + }, + }, + } + }, + }; + } + + private getBorderRadiusProperties(propertyData?: any) { + return { + borderRadius: { + title: "圆角", + type: "cascade", + description: "组件的圆角", + isExpand: true, + properties: { + topLeft: { + title: "左上角(px)", + type: "number", + description: "组件的左上圆角大小", + editor: { + min: 0, + decimals: 0, + nullable: true, + }, + }, + topRight: { + title: "右上角(px)", + type: "number", + description: "组件的右上圆角大小", + editor: { + min: 0, + decimals: 0, + nullable: true, + }, + }, + bottomRight: { + title: "右下角(px)", + type: "number", + description: "组件的右下圆角大小", + editor: { + min: 0, + decimals: 0, + nullable: true, + }, + }, + bottomLeft: { + title: "左下角(px)", + type: "number", + description: "组件的左下圆角大小", + editor: { + min: 0, + decimals: 0, + nullable: true, + }, + }, + } + }, + }; + } + + private getPositionProperties(propertyData?: any) { + return { + position: { + title: "位置", + type: "cascade", + description: "组件的位置", + isExpand: true, + properties: { + top: { + title: "上侧偏移(px)", + type: "number", + description: "组件相对于最近的非 static 定位祖先元素的上侧偏移", + editor: { + decimals: 0, + nullable: true, + }, + }, + right: { + title: "右侧偏移(px)", + type: "number", + description: "组件相对于最近的非 static 定位祖先元素的右侧偏移", + editor: { + decimals: 0, + nullable: true, + }, + }, + bottom: { + title: "下侧偏移(px)", + type: "number", + description: "组件相对于最近的非 static 定位祖先元素的下侧偏移", + editor: { + decimals: 0, + nullable: true, + }, + }, + left: { + title: "左侧偏移(px)", + type: "number", + description: "组件相对于最近的非 static 定位祖先元素的左侧偏移", + editor: { + decimals: 0, + nullable: true, + }, + }, + } + }, + }; + } + +} diff --git a/packages/mobile-ui-vue/components/common/src/properties/index.ts b/packages/mobile-ui-vue/components/common/src/properties/index.ts index 45e1b856918..cb90eb3e719 100644 --- a/packages/mobile-ui-vue/components/common/src/properties/index.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/index.ts @@ -1,4 +1,5 @@ export * from './dg-control'; export { SchemaDOMMapping } from './schema-dom-mapping'; export { BaseControlProperty } from './base-property'; -export { InputBaseProperty } from './input-base-property'; \ No newline at end of file +export { InputBaseProperty } from './input-base-property'; +export { ContainerBaseProperty } from './container-base-property'; diff --git a/packages/mobile-ui-vue/components/content-container/index.ts b/packages/mobile-ui-vue/components/content-container/index.ts index 744717a9c7b..06a7fa82d10 100644 --- a/packages/mobile-ui-vue/components/content-container/index.ts +++ b/packages/mobile-ui-vue/components/content-container/index.ts @@ -1,32 +1,15 @@ -import { App, Plugin } from 'vue'; -import FContentContainer from './src/content-container.component'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; +import ContentContainerInstallless from './src/content-container.component'; import { propsResolverGenerator } from './src/content-container.props'; import ContentContainerDesign from './src/designer/content-container.design.component'; -import { RegisterContext } from '../common'; 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, registerContext: RegisterContext -) => { - componentMap[CONTENT_CONTAINER_REGISTERED_NAME] = FContentContainer; - propsResolverMap[CONTENT_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; - -FContentContainer.registerDesigner = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext -) => { - componentMap[CONTENT_CONTAINER_REGISTERED_NAME] = ContentContainerDesign; - propsResolverMap[CONTENT_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; +const ContentContainer = withInstall(ContentContainerInstallless); +withRegister(ContentContainer, { name: CONTENT_CONTAINER_REGISTERED_NAME, propsResolverGenerator }); +withRegisterDesigner(ContentContainer, { name: CONTENT_CONTAINER_REGISTERED_NAME, propsResolverGenerator, designerComponent: ContentContainerDesign }); export * from './src/content-container.props'; -export { FContentContainer }; -export default FContentContainer as typeof FContentContainer & Plugin; +export { ContentContainer }; +export default ContentContainer; 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 index b1376f278cd..1d8bf1f326b 100644 --- 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 @@ -1,4 +1,4 @@ -import { SetupContext, defineComponent, computed } from 'vue'; +import { defineComponent, computed, ref, CSSProperties } from 'vue'; import { CONTENT_CONTAINER_NAME, ContentContainerProps, contentContainerProps } from './content-container.props'; import { useBem } from '../../common/index'; @@ -6,20 +6,77 @@ export default defineComponent({ name: CONTENT_CONTAINER_NAME, props: contentContainerProps, emits: [], - setup(props: ContentContainerProps, context: SetupContext) { + setup(props: ContentContainerProps, context) { const { bem } = useBem(CONTENT_CONTAINER_NAME); + const elementRef = ref(); + + function isValidDirection(value: string): boolean { + return ["top", "right", "bottom", "left"].includes(value); + } + + const containerPaddingStyle = computed(() => { + const paddingStyle = {}; + Object.keys(props.padding || {}).filter((direction) => { + return isValidDirection(direction); + }).forEach((direction) => { + if (typeof props.padding[direction] === 'number') { + paddingStyle[`padding-${direction}`] = `${props.padding[direction]}px`; + } + }); + return paddingStyle; + }); + + const containerMarginStyle = computed(() => { + const marginStyle = {}; + Object.keys(props.margin || {}).filter((direction) => { + return isValidDirection(direction); + }).forEach((direction) => { + if (typeof props.margin[direction] === 'number') { + marginStyle[`margin-${direction}`] = `${props.margin[direction]}px`; + } + }); + return marginStyle; + }); + + const containerSizeStyle = computed(() => ({ + width: typeof props.size?.width === 'number' ? `${props.size.width}px` : undefined, + height: typeof props.size?.height === 'number' ? `${props.size.height}px` : undefined, + })); + + const containerStyle = computed(() => { + return { + ...containerPaddingStyle.value, + ...containerMarginStyle.value, + ...containerSizeStyle.value, + }; + }); + + const containerFlexClass = computed(() => { + if (props.display !== 'flex') { + return {}; + } + return { + [`flex-${props.flexBox?.direction}`]: !!props.flexBox?.direction, + [`flex-wrap`]: props.flexBox?.wrap, + [`flex-nowrap`]: !props.flexBox?.wrap, + [`justify-content-${props.flexBox?.justifyContent}`]: !!props.flexBox?.justifyContent, + [`align-items-${props.flexBox?.alignItems}`]: !!props.flexBox?.alignItems, + }; + }); const containerClass = computed(() => ({ [bem()]: true, - [props.customClass || '']: true, + [`d-flex`]: props.display === 'flex', + ...containerFlexClass.value, })); - const customStyle = computed(() => { - return props.customStyle; - }); + context.expose({ elementRef }); 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 index 213f331a3db..823e195a8ed 100644 --- 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 @@ -1,4 +1,4 @@ -import { ExtractPropTypes } from 'vue'; +import { ExtractPropTypes, PropType } from 'vue'; import { getPropsResolverGenerator } from '../../dynamic-resolver'; import contentContainerSchema from './schema/content-container.schema.json'; import { schemaMapper } from './schema/schema-mapper'; @@ -6,9 +6,42 @@ import { schemaResolver } from './schema/schema-resolver'; export const CONTENT_CONTAINER_NAME = 'fm-content-container'; +export interface ContainerPadding { + top?: number; + right?: number; + bottom?: number; + left?: number; +} + +export interface ContainerMargin { + top?: number; + right?: number; + bottom?: number; + left?: number; +} + +export interface ContainerSize { + width?: number; + height?: number; +} + +export type ContainerDisplay = "flex" | "block"; + +export interface ContainerFlexBox { + direction?: "row" | "column"; + wrap?: boolean; + justifyContent?: "start" | "center" | "end" | "between" | "around"; + alignItems?: "start" | "center" | "end"; +} + export const contentContainerProps = { customClass: { type: String, default: '' }, customStyle: { type: String, default: '' }, + padding: { type: Object as PropType, default: {} }, + margin: { type: Object as PropType, default: {} }, + size: { type: Object as PropType, default: {} }, + display: { type: String as PropType, default: "flex" }, + flexBox: { type: Object as PropType, default: {} }, }; export type ContentContainerProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/content-container/src/designer/content-container.design.component.tsx b/packages/mobile-ui-vue/components/content-container/src/designer/content-container.design.component.tsx index 5e2ccbc4115..edc18151625 100644 --- a/packages/mobile-ui-vue/components/content-container/src/designer/content-container.design.component.tsx +++ b/packages/mobile-ui-vue/components/content-container/src/designer/content-container.design.component.tsx @@ -1,37 +1,44 @@ -import { SetupContext, computed, defineComponent, inject, onMounted, ref } from 'vue'; +import { computed, defineComponent, inject, onMounted, ref } from 'vue'; import { ContentContainerProps, contentContainerProps } from '../content-container.props'; import { useDesignerRulesForContentContainer } from './use-designer-rules'; -import { getCustomClass } from '@farris/mobile-ui-vue/common'; -import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common';; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common'; +import { ContentContainer } from '@farris/mobile-ui-vue/content-container'; export default defineComponent({ name: 'FContentContainerDesign', props: contentContainerProps, emits: [], setup(props: ContentContainerProps, context) { - const elementRef = ref(); + const contentContainerRef = ref(); + const elementRef = computed(() => { + return contentContainerRef.value?.elementRef; + }); + const designerHostService = inject('designer-host-service'); const designItemContext = inject('design-item-context') as DesignerItemContext; const designerRulesComposition = useDesignerRulesForContentContainer(designItemContext, designerHostService); const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); - const containerClass = computed(() => { - const classObject = { - 'drag-container': true - } as Record; - return getCustomClass(classObject, props?.customClass); - }); onMounted(() => { elementRef.value.componentInstance = componentInstance; }); - context.expose(componentInstance.value); + const designProps = computed(() => ({ + ...props, + display: 'block', + })); + return () => { return ( -
    + {context.slots.default && context.slots.default()} -
    + ); }; } diff --git a/packages/mobile-ui-vue/components/content-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/content-container/src/designer/use-designer-rules.ts index b78cbfcc46b..6871ed7a654 100644 --- a/packages/mobile-ui-vue/components/content-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/content-container/src/designer/use-designer-rules.ts @@ -1,38 +1,29 @@ -import { ComponentSchema, DesignerItemContext } from "@farris/mobile-ui-vue/common"; +import { DesignerItemContext } from "@farris/mobile-ui-vue/common"; import { ContentContainerProperty } from "../property-config/content-container.property-config"; import { DesignerHostService, DraggingResolveContext, UseDesignerRules } from "@farris/mobile-ui-vue/common"; export function useDesignerRulesForContentContainer(designItemContext: DesignerItemContext, designerHostService?: DesignerHostService): UseDesignerRules { - const schema = designItemContext.schema as ComponentSchema; - /** - * 判断是否可以接收拖拽新增的子级控件 - */ function canAccepts(draggingContext: DraggingResolveContext): boolean { return true; } function getStyles() { - const component = schema; - if (component.componentType) { - return 'display:inherit;flex-direction:inherit;margin-bottom:10px'; - } return ''; } function checkCanMoveComponent() { return true; } + function checkCanDeleteComponent() { return true; } function hideNestedPaddingInDesginerView() { - return false; + return true; } - /** - * 获取属性配置 - */ + function getPropsConfig(componentId: string) { const componentProp = new ContentContainerProperty(componentId, designerHostService); const { schema } = designItemContext; diff --git a/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts b/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts index e7d94c41f1e..304893a8e58 100644 --- a/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts +++ b/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts @@ -1,15 +1,117 @@ -import { BaseControlProperty } from "@farris/mobile-ui-vue/common"; +import { ContainerBaseProperty } from "@farris/mobile-ui-vue/common"; + +export class ContentContainerProperty extends ContainerBaseProperty { -export class ContentContainerProperty extends BaseControlProperty { constructor(componentId: string, designerHostService: any) { super(componentId, designerHostService); } + public getPropertyConfig(propertyData: any) { // 基本信息 this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); // 外观 this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + // 布局 + this.propertyConfig.categories['layout'] = this.getLayoutConfig(propertyData); + // 行为 + this.propertyConfig.categories['behavior'] = this.getBehaviorConfig(propertyData); return this.propertyConfig; } + + protected getAppearanceConfig(propertyData: any) { + return { + title: "外观", + description: "Appearance", + properties: this.getAppearanceProperties(["style", "size", "padding", "margin"], propertyData), + }; + } + + protected getLayoutConfig(propertyData: any) { + return { + title: "布局", + description: "Layout", + properties: { + display: { + title: "布局方式", + type: "select", + description: "运行时组件布局方式", + refreshPanelAfterChanged: true, + editor: { + type: 'combo-list', + textField: 'text', + valueField: 'value', + editable: false, + data: [ + { value: 'flex', text: '弹性布局' }, + { value: 'block', text: '流式布局' }, + ], + }, + }, + flexBox: { + title: "弹性布局", + type: "cascade", + visible: propertyData.display === "flex", + isExpand: true, + properties: { + direction: { + title: "布局方向", + type: "select", + description: "运行时组件弹性布局方向", + editor: { + type: 'combo-list', + textField: 'text', + valueField: 'value', + editable: false, + data: [ + { value: 'row', text: '水平' }, + { value: 'column', text: '竖直' }, + ], + }, + }, + wrap: { + title: "是否允许换行", + type: "boolean", + description: "运行时组件内部子元素是否允许换行显示", + }, + justifyContent: { + title: "水平对齐方式", + type: "select", + description: "运行时组件布局方式", + editor: { + type: 'combo-list', + textField: 'text', + valueField: 'value', + editable: false, + data: [ + { value: "start", text: "起始位置" }, + { value: "center", text: "居中" }, + { value: "end", text: "末尾位置" }, + { value: "between", text: "均匀排列(贴合边框)" }, + { value: "around", text: "均匀排列" }, + ], + }, + }, + alignItems: { + title: "竖直对齐方式", + type: "select", + description: "运行时组件内部子元素纵轴对齐方式", + editor: { + type: 'combo-list', + textField: 'text', + valueField: 'value', + editable: false, + data: [ + { value: "start", text: "起始位置" }, + { value: "center", text: "居中" }, + { value: "end", text: "末尾位置" }, + ], + }, + }, + }, + }, + }, + }; + } + } 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 index a082e40914e..752caf4dcb2 100644 --- 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 @@ -14,6 +14,11 @@ "type": "string", "default": "content-container" }, + "contents": { + "description": "子组件集合", + "type": "array", + "default": [] + }, "appearance": { "description": "外观", "type": "object", @@ -27,10 +32,35 @@ }, "default": {} }, - "contents": { - "description": "子组件集合", - "type": "array", - "default": [] + "padding": { + "description": "内边距", + "type": "object", + "default": {} + }, + "margin": { + "description": "外边距", + "type": "object", + "default": {} + }, + "size": { + "description": "尺寸", + "type": "object", + "default": {} + }, + "display": { + "description": "布局方式", + "type": "string", + "default": "flex" + }, + "flexBox": { + "description": "弹性布局", + "type": "object", + "default": {} + }, + "visible": { + "description": "是否可见", + "type": "boolean", + "default": true } }, "required": [ diff --git a/packages/mobile-ui-vue/components/list-view/src/components/list-view-item.component.tsx b/packages/mobile-ui-vue/components/list-view/src/components/list-view-item.component.tsx index 82b57d3f2a2..a32b0543e63 100644 --- a/packages/mobile-ui-vue/components/list-view/src/components/list-view-item.component.tsx +++ b/packages/mobile-ui-vue/components/list-view/src/components/list-view-item.component.tsx @@ -1,5 +1,5 @@ import { computed, SetupContext, toRefs } from "vue"; -import { SwipeCell } from '@components/swipe-cell'; +import { SwipeCell } from '@farris/mobile-ui-vue/swipe-cell'; import { LIST_VIEW_NAME, ListViewProps } from '../list-view.props'; import { UseData, UseSelection } from '../composition/types'; import { useBem } from '@farris/mobile-ui-vue/common'; 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 04c1d32cfcb..529f01fcae9 100644 --- a/packages/mobile-ui-vue/components/navbar/src/navbar.component.tsx +++ b/packages/mobile-ui-vue/components/navbar/src/navbar.component.tsx @@ -14,10 +14,10 @@ * limitations under the License. */ import { defineComponent, computed, ref } from 'vue'; -import { useBem } from '@components/common'; -import { Icon } from '@components/icon'; -import { Popover } from '@components/popover'; -import { ButtonItem } from '@components/button-group'; +import { useBem } from '@farris/mobile-ui-vue/common'; +import { Icon } from '@farris/mobile-ui-vue/icon'; +import { Popover } from '@farris/mobile-ui-vue/popover'; +import { ButtonItem } from '@farris/mobile-ui-vue/button-group'; import { NAVBAR_NAME, NavbarProps, navbarProps } from './navbar.props'; export default defineComponent({ 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 30313ca93e2..d4983176a38 100644 --- a/packages/mobile-ui-vue/components/navbar/src/navbar.props.ts +++ b/packages/mobile-ui-vue/components/navbar/src/navbar.props.ts @@ -15,7 +15,7 @@ */ import { ExtractPropTypes } from 'vue'; import { getPropsResolverGenerator } from '../../dynamic-resolver'; -import { ButtonItem } from '@components/button-group'; +import { ButtonItem } from '@farris/mobile-ui-vue/button-group'; import navbarSchema from './schema/navbar.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; diff --git a/packages/mobile-ui-vue/components/page-body-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/page-body-container/src/designer/use-designer-rules.ts index 509cfa3d619..9f065533d83 100644 --- a/packages/mobile-ui-vue/components/page-body-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/page-body-container/src/designer/use-designer-rules.ts @@ -31,10 +31,10 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe function checkCanMoveComponent() { - return true; + return !isInFixedContextRules; } function checkCanDeleteComponent() { - return true; + return !isInFixedContextRules; } function hideNestedPaddingInDesginerView() { @@ -52,7 +52,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe const componentProp = new PageBodyContainerProperty(componentId, designerHostService); const { schema } = designItemContext; return componentProp.getPropertyConfig(schema); - } + } return { diff --git a/packages/mobile-ui-vue/components/page-body-container/src/property-config/page-body-container.property-config.ts b/packages/mobile-ui-vue/components/page-body-container/src/property-config/page-body-container.property-config.ts index 3ffa3e43166..4c1c7876ce2 100644 --- a/packages/mobile-ui-vue/components/page-body-container/src/property-config/page-body-container.property-config.ts +++ b/packages/mobile-ui-vue/components/page-body-container/src/property-config/page-body-container.property-config.ts @@ -1,9 +1,11 @@ -import { BaseControlProperty } from "@farris/mobile-ui-vue/common"; +import { ContainerBaseProperty } from "@farris/mobile-ui-vue/common"; + +export class PageBodyContainerProperty extends ContainerBaseProperty { -export class PageBodyContainerProperty extends BaseControlProperty { constructor(componentId: string, designerHostService: any) { super(componentId, designerHostService); } + public getPropertyConfig(propertyData: any) { // 基本信息 this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); diff --git a/packages/mobile-ui-vue/components/page-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/page-container/src/designer/use-designer-rules.ts index a7220a9cb34..c4c351beae7 100644 --- a/packages/mobile-ui-vue/components/page-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/page-container/src/designer/use-designer-rules.ts @@ -42,10 +42,10 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe return true; } - function checkCanMoveComponent() { - return true; + return !isInFixedContextRules; } + function checkCanDeleteComponent() { return !isInFixedContextRules; } @@ -55,15 +55,14 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe } function getStyles(): string { - // return 'border-radius: 12px'; - return ' '; + return ''; } function getDesignerClass(): string { return PAGE_CONTAINER_NAME; } - + /** * 获取属性配置 */ @@ -71,8 +70,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe const componentProp = new PageContainerProperty(componentId, designerHostService); const { schema } = designItemContext; return componentProp.getPropertyConfig(schema); - } - + } return { canAccepts, diff --git a/packages/mobile-ui-vue/components/page-container/src/property-config/page-container.property-config.ts b/packages/mobile-ui-vue/components/page-container/src/property-config/page-container.property-config.ts index d36a043afa0..50bce32f8b4 100644 --- a/packages/mobile-ui-vue/components/page-container/src/property-config/page-container.property-config.ts +++ b/packages/mobile-ui-vue/components/page-container/src/property-config/page-container.property-config.ts @@ -1,9 +1,11 @@ -import { BaseControlProperty } from "@farris/mobile-ui-vue/common"; +import { ContainerBaseProperty } from "@farris/mobile-ui-vue/common"; + +export class PageContainerProperty extends ContainerBaseProperty { -export class PageContainerProperty extends BaseControlProperty { constructor(componentId: string, designerHostService: any) { super(componentId, designerHostService); } + public getPropertyConfig(propertyData: any) { // 基本信息 this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); diff --git a/packages/mobile-ui-vue/components/page-footer-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/page-footer-container/src/designer/use-designer-rules.ts index 00e12a993f2..1f356be804a 100644 --- a/packages/mobile-ui-vue/components/page-footer-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/page-footer-container/src/designer/use-designer-rules.ts @@ -26,10 +26,10 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe return true; } - function checkCanMoveComponent() { - return true; + return false; } + function checkCanDeleteComponent() { return true; } @@ -49,9 +49,8 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe const componentProp = new PageFooterContainerProperty(componentId, designerHostService); const { schema } = designItemContext; return componentProp.getPropertyConfig(schema); - } + } - return { canAccepts, triggerBelongedComponentToMoveWhenMoved, diff --git a/packages/mobile-ui-vue/components/page-footer-container/src/property-config/page-footer-container.property-config.ts b/packages/mobile-ui-vue/components/page-footer-container/src/property-config/page-footer-container.property-config.ts index 47fe8ee5999..0eab391033f 100644 --- a/packages/mobile-ui-vue/components/page-footer-container/src/property-config/page-footer-container.property-config.ts +++ b/packages/mobile-ui-vue/components/page-footer-container/src/property-config/page-footer-container.property-config.ts @@ -1,14 +1,18 @@ -import { BaseControlProperty } from "@farris/mobile-ui-vue/common"; +import { ContainerBaseProperty } from "@farris/mobile-ui-vue/common"; + +export class PageFooterContainerProperty extends ContainerBaseProperty { -export class PageFooterContainerProperty extends BaseControlProperty { constructor(componentId: string, designerHostService: any) { super(componentId, designerHostService); } + public getPropertyConfig(propertyData: any) { // 基本信息 this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); // 外观 this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + // 行为 + this.propertyConfig.categories['behavior'] = this.getBehaviorConfig(propertyData); return this.propertyConfig; } diff --git a/packages/mobile-ui-vue/components/page-footer-container/src/schema/page-footer-container.schema.json b/packages/mobile-ui-vue/components/page-footer-container/src/schema/page-footer-container.schema.json index c337e3b0856..e471aa1250e 100644 --- a/packages/mobile-ui-vue/components/page-footer-container/src/schema/page-footer-container.schema.json +++ b/packages/mobile-ui-vue/components/page-footer-container/src/schema/page-footer-container.schema.json @@ -46,7 +46,7 @@ "default": null }, "visible": { - "description": "", + "description": "是否可见", "type": "boolean", "default": true } diff --git a/packages/mobile-ui-vue/components/page-header-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/page-header-container/src/designer/use-designer-rules.ts index a2279ec5615..a77016a4d92 100644 --- a/packages/mobile-ui-vue/components/page-header-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/page-header-container/src/designer/use-designer-rules.ts @@ -1,6 +1,6 @@ import { ref } from "vue"; import { PAGE_HEADER_CONTAINER_NAME } from '../page-header-container.props'; -import { ComponentSchema, DesignerItemContext, UseDesignerRules } from "@farris/mobile-ui-vue/common"; +import { DesignerItemContext, UseDesignerRules } from "@farris/mobile-ui-vue/common"; import { DraggingResolveContext } from "@farris/mobile-ui-vue/common"; import { PageHeaderContainerProperty } from "../property-config/page-header-container.property-config"; @@ -38,8 +38,9 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe } function checkCanMoveComponent() { - return true; + return false; } + function checkCanDeleteComponent() { return true; } @@ -51,7 +52,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe function getDesignerClass(): string { return PAGE_HEADER_CONTAINER_NAME; } - + /** * 获取属性配置 */ @@ -59,8 +60,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe const componentProp = new PageHeaderContainerProperty(componentId, designerHostService); const { schema } = designItemContext; return componentProp.getPropertyConfig(schema); - } - + } return { canAccepts, diff --git a/packages/mobile-ui-vue/components/page-header-container/src/property-config/page-header-container.property-config.ts b/packages/mobile-ui-vue/components/page-header-container/src/property-config/page-header-container.property-config.ts index a292e7834f4..fa2d3e105f7 100644 --- a/packages/mobile-ui-vue/components/page-header-container/src/property-config/page-header-container.property-config.ts +++ b/packages/mobile-ui-vue/components/page-header-container/src/property-config/page-header-container.property-config.ts @@ -1,14 +1,18 @@ -import { BaseControlProperty } from "@farris/mobile-ui-vue/common"; +import { ContainerBaseProperty } from "@farris/mobile-ui-vue/common"; + +export class PageHeaderContainerProperty extends ContainerBaseProperty { -export class PageHeaderContainerProperty extends BaseControlProperty { constructor(componentId: string, designerHostService: any) { super(componentId, designerHostService); } + public getPropertyConfig(propertyData: any) { // 基本信息 this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); // 外观 this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + // 行为 + this.propertyConfig.categories['behavior'] = this.getBehaviorConfig(propertyData); return this.propertyConfig; } 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 e5066b03bab..800cfa89b3a 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,6 +31,11 @@ "description": "", "type": "array", "default": [] + }, + "visible": { + "description": "", + "type": "boolean", + "default": true } }, "required": [ diff --git a/packages/mobile-ui-vue/components/swipe-cell/src/composition/type.ts b/packages/mobile-ui-vue/components/swipe-cell/src/composition/type.ts index f94d637b5f6..5e4815b1b2c 100644 --- a/packages/mobile-ui-vue/components/swipe-cell/src/composition/type.ts +++ b/packages/mobile-ui-vue/components/swipe-cell/src/composition/type.ts @@ -1,4 +1,4 @@ -import { ButtonItem } from '@components/button-group'; +import { ButtonItem } from '@farris/mobile-ui-vue/button-group'; export type SwipeCellButton = Pick< ButtonItem, diff --git a/packages/mobile-ui-vue/farris.config.mjs b/packages/mobile-ui-vue/farris.config.mjs index ea0d910c16f..7974edc8634 100644 --- a/packages/mobile-ui-vue/farris.config.mjs +++ b/packages/mobile-ui-vue/farris.config.mjs @@ -2,7 +2,7 @@ import { fileURLToPath, URL } from 'node:url'; const { BUILD_TYPE } = process.env; const outDir = BUILD_TYPE === 'app' ? "dist" : 'package'; -const externals = [BUILD_TYPE === 'components' ? "@farris/mobile-ui-vue" : '']; +const externals = BUILD_TYPE === 'components' ? ["@farris/mobile-ui-vue", "vue"] : ["vue"]; const externalDependencies = BUILD_TYPE !== 'app'; export default { @@ -30,7 +30,7 @@ export default { } } }, - externalDependencies, + externalDependencies: false, minify: false, target: 'es2015', alias: [ -- Gitee From dcd8fa198b7b07f0c3c2cc28bb2187f270959d2c Mon Sep 17 00:00:00 2001 From: LuPing Zou <“zouluping@inspur.com”> Date: Sat, 12 Apr 2025 11:51:05 +0800 Subject: [PATCH 229/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E7=AB=AFC?= =?UTF-8?q?omponent=E6=8E=A7=E4=BB=B6=E8=AE=BE=E8=AE=A1=E6=97=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81name=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/designer/use-designer-rules.ts | 8 +++-- .../component.property-config.ts | 33 +++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/packages/mobile-ui-vue/components/component/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/component/src/designer/use-designer-rules.ts index 02050723a6f..e0d0aef98ea 100644 --- a/packages/mobile-ui-vue/components/component/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/component/src/designer/use-designer-rules.ts @@ -18,13 +18,12 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe return true; } - function hideNestedPaddingInDesginerView() { return false; } function getStyles(): string { - return ' '; + return ''; } /** @@ -74,8 +73,8 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe parentComponentInstance['parent']['updateToolbarItems'](); } } - } + /** * 组件删除后事件:移除viewmodel和component */ @@ -91,6 +90,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe formSchemaUtils.deleteComponent(schema.id); } } + /** * 组件删除后事件:移除表达式、界面规则、受控规则等全局配置 */ @@ -111,6 +111,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe } }); } + /** * 组件删除后事件 */ @@ -119,5 +120,6 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe removeGlobalConfigs(); removeViewModelComponent(); } + return { canAccepts, checkCanDeleteComponent, checkCanMoveComponent, hideNestedPaddingInDesginerView, getStyles, getPropsConfig, onRemoveComponent }; } diff --git a/packages/mobile-ui-vue/components/component/src/property-config/component.property-config.ts b/packages/mobile-ui-vue/components/component/src/property-config/component.property-config.ts index 43b773f68a1..8186280ca0d 100644 --- a/packages/mobile-ui-vue/components/component/src/property-config/component.property-config.ts +++ b/packages/mobile-ui-vue/components/component/src/property-config/component.property-config.ts @@ -2,9 +2,11 @@ import { BaseControlProperty } from "@farris/mobile-ui-vue/common"; export class ComponentProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { super(componentId, designerHostService); } + public getPropertyConfig(propertyData: any) { // 基本信息 this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); @@ -12,8 +14,30 @@ export class ComponentProperty extends BaseControlProperty { this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); // 事件 this.getEventPropConfig(propertyData); + return this.propertyConfig; } + + protected getAppearanceConfig(propertyData: any) { + const viewModel = this.formSchemaUtils.getViewModelById(this.viewModelId); + propertyData.name = viewModel?.name ?? null; + return super.getAppearanceConfig(propertyData, { + name: { + title: "组件名称", + type: "string", + description: "组件名称", + defaultValue: propertyData.name, + }, + }, (changeObject) => { + switch (changeObject.propertyID) { + case 'name': { + this.syncChangesToViewModel({ name: changeObject.propertyValue }); + break; + } + } + }); + } + private getEventPropConfig(propertyData: any) { const events = [ { @@ -60,4 +84,13 @@ export class ComponentProperty extends BaseControlProperty { } }; } + + /** 将变更的属性值同步到视图模型中 */ + private syncChangesToViewModel(changeObject: any) { + const viewModel = this.formSchemaUtils.getViewModelById(this.viewModelId); + if (!viewModel) { + return; + } + Object.assign(viewModel, changeObject); + } } -- Gitee From 1a02c211ed185a114039f5a2ce143ac888b5835d Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Mon, 14 Apr 2025 19:53:24 +0800 Subject: [PATCH 230/287] =?UTF-8?q?chore:=20=E5=90=88=E5=B9=B6=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E8=AE=BE=E8=AE=A1=E5=99=A8=E6=9C=80=E6=96=B0=E5=88=86?= =?UTF-8?q?=E6=94=AF=EF=BC=8C=E8=A7=A3=E5=86=B3=E6=89=93=E5=8C=85=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/composition/control-property-changed.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/designer/src/components/composition/control-property-changed.service.ts b/packages/designer/src/components/composition/control-property-changed.service.ts index b6dd93b59bc..f642a2cdfd2 100644 --- a/packages/designer/src/components/composition/control-property-changed.service.ts +++ b/packages/designer/src/components/composition/control-property-changed.service.ts @@ -1,4 +1,4 @@ -import { FormPropertyChangeObject, SchemaDOMMapping } from "@farris/ui-vue"; +import { FormPropertyChangeObject, SchemaDOMMapping } from "@farris/ui-vue/components"; import { get, set } from "lodash-es"; import { FormBindingType, FormVariableCategory, UseDesignViewModel, UseFormSchema, UseSchemaService } from "../types"; import { DesignViewModelField } from "../types/design-viewmodel"; -- Gitee From 46645661194e03b671a5c29df0b143b74de75a1c Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Tue, 15 Apr 2025 08:31:51 +0800 Subject: [PATCH 231/287] =?UTF-8?q?fix:=20MobileRenderer=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E6=A8=A1=E5=BC=8F=E4=B8=8B=E7=9A=84ui?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=88=AB=E5=90=8D=EF=BC=8C=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E6=89=BE=E4=B8=8D=E5=88=B0=E7=BB=84=E4=BB=B6=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/mobile-render/vite.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mobile-render/vite.config.ts b/packages/mobile-render/vite.config.ts index 4c68bb48c60..a90bdf444de 100644 --- a/packages/mobile-render/vite.config.ts +++ b/packages/mobile-render/vite.config.ts @@ -41,7 +41,7 @@ export default defineConfig({ '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-ui-vue": path.resolve(__dirname, "../mobile-ui-vue/components"), "@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"), -- Gitee From 4733b5cf425693c067e3db3e47813e0c43ef640f Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Tue, 15 Apr 2025 08:47:57 +0800 Subject: [PATCH 232/287] =?UTF-8?q?fix:=20=E7=A7=BB=E5=8A=A8button?= =?UTF-8?q?=E5=BC=95=E7=94=A8=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=84=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile-ui-vue/components/button/index.ts | 19 +++---------------- .../components/button/src/button.props.ts | 2 +- .../src/designer/button.design.component.tsx | 4 ++-- .../button/src/designer/use-designer-rules.ts | 4 ++-- .../button/src/schema/schema-mapper.ts | 2 +- .../button/src/schema/schema-resolver.ts | 2 +- 6 files changed, 10 insertions(+), 23 deletions(-) diff --git a/packages/mobile-ui-vue/components/button/index.ts b/packages/mobile-ui-vue/components/button/index.ts index f0dcd4d389a..15c9d8e848b 100644 --- a/packages/mobile-ui-vue/components/button/index.ts +++ b/packages/mobile-ui-vue/components/button/index.ts @@ -1,5 +1,5 @@ import { Plugin } from 'vue'; -import { withInstall, RegisterContext } from '@farris/mobile-ui-vue/common'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import ButtonInstallless from './src/button.component'; import { propsResolverGenerator } from './src/button.props'; import ButtonDesign from './src/designer/button.design.component'; @@ -7,22 +7,9 @@ import ButtonDesign from './src/designer/button.design.component'; const BUTTON_REGISTERED_NAME = 'button'; const Button = withInstall(ButtonInstallless); -Button.register = ( - componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record, registerContext: RegisterContext -) => { - componentMap[BUTTON_REGISTERED_NAME] = Button; - propsResolverMap[BUTTON_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; - -Button.registerDesigner = ( - componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, registerContext: RegisterContext -) => { - componentMap[BUTTON_REGISTERED_NAME] = ButtonDesign; - propsResolverMap[BUTTON_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; +withRegister(Button, { name: BUTTON_REGISTERED_NAME, propsResolverGenerator }); +withRegisterDesigner(Button, { name: BUTTON_REGISTERED_NAME, propsResolverGenerator, designerComponent: ButtonDesign }); export { 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 17b318d930f..25a3ebf90ef 100644 --- a/packages/mobile-ui-vue/components/button/src/button.props.ts +++ b/packages/mobile-ui-vue/components/button/src/button.props.ts @@ -1,5 +1,5 @@ import { ExtractPropTypes, PropType } from 'vue'; -import { getPropsResolverGenerator } from '../../dynamic-resolver'; +import { getPropsResolverGenerator } from '@farris/mobile-ui-vue/dynamic-resolver'; import buttonSchema from './schema/button.schema.json'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; diff --git a/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx b/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx index 6291f4b49ae..740e2c79009 100644 --- a/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx +++ b/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx @@ -15,9 +15,9 @@ * limitations under the License. */ import { computed, defineComponent, inject, onMounted, ref, SetupContext } from 'vue'; -import { ButtonProps, buttonProps } from '../button.props'; -import Button from '../..'; import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common';; +import { ButtonProps, buttonProps } from '../button.props'; +import Button from '../button.component'; import { useDesignerRules } from './use-designer-rules'; export default defineComponent({ diff --git a/packages/mobile-ui-vue/components/button/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/button/src/designer/use-designer-rules.ts index 897b4d86afd..da2a3b6fd2b 100644 --- a/packages/mobile-ui-vue/components/button/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/button/src/designer/use-designer-rules.ts @@ -1,7 +1,7 @@ import { ref } from "vue"; -import { ButtonProperty } from "../property-config/button.property-config"; -import { DesignerHostService, DesignerItemContext, UseDesignerRules } from "@farris/mobile-ui-vue/common"; import { DraggingResolveContext } from "@farris/mobile-ui-vue/common"; +import { DesignerHostService, DesignerItemContext, UseDesignerRules } from "@farris/mobile-ui-vue/common"; +import { ButtonProperty } from "../property-config/button.property-config"; export function useDesignerRules(designItemContext: DesignerItemContext, designerHostService?: DesignerHostService): UseDesignerRules { 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 index eca9607abe4..adc95460db6 100644 --- a/packages/mobile-ui-vue/components/button/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/button/src/schema/schema-mapper.ts @@ -1,4 +1,4 @@ -import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; +import { resolveAppearance, MapperFunction } from '@farris/mobile-ui-vue/dynamic-resolver'; function createTemplatePropResolver(name: string): MapperFunction { return (key: string, content: string) => { 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 index c1bf8da88a0..329b35ae2e0 100644 --- a/packages/mobile-ui-vue/components/button/src/schema/schema-resolver.ts +++ b/packages/mobile-ui-vue/components/button/src/schema/schema-resolver.ts @@ -1,4 +1,4 @@ -import { DynamicResolver } from "../../../dynamic-resolver"; +import { DynamicResolver } from "@farris/mobile-ui-vue/dynamic-resolver"; export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { return schema; -- Gitee From a685e6efdfe5f469df37a471ab43bc5ce82e2f8f Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Tue, 15 Apr 2025 09:24:39 +0800 Subject: [PATCH 233/287] =?UTF-8?q?chore:=20=E8=B0=83=E6=95=B4=E7=BB=84?= =?UTF-8?q?=E4=BB=B6register=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/form-designer/form-designer.component.tsx | 3 +++ packages/designer/tsconfig.json | 4 +++- .../button/src/designer/button.design.component.tsx | 2 +- .../components/common/src/properties/base-property.ts | 3 +-- .../src/resolver/type-resolver/use-type-resolver-design.ts | 4 ++-- .../src/resolver/type-resolver/use-type-resolver.ts | 3 ++- .../src/designer/response-form-use-designer-rules.ts | 4 ++-- .../mobile-ui-vue/components/page-body-container/index.ts | 2 +- packages/mobile-ui-vue/components/page-container/index.ts | 2 +- .../mobile-ui-vue/components/page-footer-container/index.ts | 2 +- .../mobile-ui-vue/components/page-header-container/index.ts | 2 +- packages/mobile-ui-vue/components/register-designer.ts | 6 +++--- .../src/composition/designer-canvas-changed.ts | 3 +++ .../designer-canvas/src/designer-canvas.component.tsx | 4 ++-- 14 files changed, 26 insertions(+), 18 deletions(-) diff --git a/packages/designer/src/components/components/form-designer/form-designer.component.tsx b/packages/designer/src/components/components/form-designer/form-designer.component.tsx index 339ec344900..5c41dced2d6 100644 --- a/packages/designer/src/components/components/form-designer/form-designer.component.tsx +++ b/packages/designer/src/components/components/form-designer/form-designer.component.tsx @@ -73,6 +73,9 @@ export default defineComponent({ if (changeObject.needRefreshEntityTree && entityTreeRef.value && entityTreeRef.value.refreshEntityTree) { entityTreeRef.value.refreshEntityTree(); } + if (changeObject.needChangeCanvas && canvasRef.value.changeCanvas) { + canvasRef.value.changeCanvas(); + } const afterPropeControlPropertyChanged = afterPropeControlPropertyChangedService(useFormSchema, designViewModelUtils, schemaUtil); afterPropeControlPropertyChanged.afterPropertyChanged(event); diff --git a/packages/designer/tsconfig.json b/packages/designer/tsconfig.json index 0b7f4ecc103..54db16283f1 100644 --- a/packages/designer/tsconfig.json +++ b/packages/designer/tsconfig.json @@ -19,7 +19,9 @@ "forceConsistentCasingInFileNames": true, "types": ["vitest/globals", "@types/jest"], "baseUrl": "./", - "paths": {} + "paths": { + "@farris/mobile-ui-vue": ["../mobile-ui-vue/components"] + } }, "include": ["components/**/*", "src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "designer/**/*"], "references": [{ "path": "./tsconfig.node.json" }] diff --git a/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx b/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx index 72d42c45033..49dc95cc6e4 100644 --- a/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx +++ b/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx @@ -17,7 +17,7 @@ import { computed, defineComponent, inject, onMounted, ref, SetupContext } from 'vue'; import { ButtonProps, buttonProps } from '../button.props'; import Button from '../..'; -import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common';; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common'; import { useDesignerRules } from './use-designer-rules'; export default defineComponent({ diff --git a/packages/mobile-ui-vue/components/common/src/properties/base-property.ts b/packages/mobile-ui-vue/components/common/src/properties/base-property.ts index f1dd8fb1477..5dea5049f08 100644 --- a/packages/mobile-ui-vue/components/common/src/properties/base-property.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/base-property.ts @@ -1,6 +1,5 @@ import { cloneDeep } from "lodash-es"; // import { refreshCanvas } from "../../../../common/src/composition/update-cancas"; -// import { canvasChanged } from "../../../../common/src/composition/common-changed"; import { ExpressionProperty } from "./expression-property"; import { usePropertyEditor } from "./use-property-editor"; import { DgControl } from "./dg-control"; @@ -125,7 +124,7 @@ export class BaseControlProperty { } switch (changeObject && changeObject.propertyID) { case 'class': case 'style': { - // canvasChanged.value++; + changeObject.needChangeCanvas = true; break; } } diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/type-resolver/use-type-resolver-design.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/type-resolver/use-type-resolver-design.ts index d29ea4e8b2a..b8d7996447d 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/type-resolver/use-type-resolver-design.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/type-resolver/use-type-resolver-design.ts @@ -1,4 +1,4 @@ -import { componentMapForDisngner,componentPropsConverterForDesigner } from '@farris/mobile-ui-vue/register-designer'; +import { componentMapForDesigner,componentPropsConverterForDesigner } from '@farris/mobile-ui-vue/register-designer'; import FInputGroupDesign from '../../../../input-group/src/designer/input-group.design.component'; import { UseTypeResolver } from "./types"; import { EditorConfig, EditorType } from '@farris/mobile-ui-vue/common'; @@ -12,7 +12,7 @@ export function useTypeResolverDesign(): UseTypeResolver { } function resolveEditorType(type: EditorType) { - return componentMapForDisngner[type] || FInputGroupDesign; + return componentMapForDesigner[type] || FInputGroupDesign; } function getChangeFunctionName(type: EditorType) { diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/type-resolver/use-type-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/type-resolver/use-type-resolver.ts index 4c24af16a5c..dc0fb311dd8 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/type-resolver/use-type-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/type-resolver/use-type-resolver.ts @@ -1,7 +1,8 @@ import FInputGroup from '../../../../input-group/src/input-group.component'; -import { EditorConfig, EditorType, UseTypeResolver } from "./types"; +import { UseTypeResolver } from "./types"; import { componentMap, propsConverterMap, registerComponents } from '../../../../register'; +import { EditorConfig, EditorType } from '@farris/mobile-ui-vue/common'; export function useTypeResolver(): UseTypeResolver { diff --git a/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts b/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts index 0d3fcd6504b..f0180528884 100644 --- a/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/form-item/src/designer/response-form-use-designer-rules.ts @@ -58,14 +58,14 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe // 控件若有绑定信息,则根据绑定信息创建控件 if (resolveContext.bindingSourceContext?.entityFieldNode) { const controlCreatorUtils = designerHostService?.controlCreatorUtils; - formGroupElementSchema = controlCreatorUtils.setFormFieldProperty(resolveContext.bindingSourceContext?.entityFieldNode, componentSchema.type); + formGroupElementSchema = controlCreatorUtils.setFormFieldProperty(resolveContext.bindingSourceContext?.entityFieldNode, componentSchema?.type); } else { formGroupElementSchema = getSchemaByTypeForDesigner('form-group') as ComponentSchema; formGroupElementSchema.editor = componentSchema; formGroupElementSchema.label = label; } - syncFieldToViewModel(resolveContext, componentSchema.type); + syncFieldToViewModel(resolveContext, componentSchema?.type); return formGroupElementSchema; } 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 25200201a9d..40d7e8e998a 100644 --- a/packages/mobile-ui-vue/components/page-body-container/index.ts +++ b/packages/mobile-ui-vue/components/page-body-container/index.ts @@ -23,7 +23,7 @@ const PAGE_BODY_CONTAINER_REGISTER_NAME = 'page-body-container'; const PageBodyContainer = withInstall(PageBodyContainerInstallless); PageBodyContainer.register = (componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext): void => { + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext): void => { componentMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = PageBodyContainer; propsResolverMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = propsResolverGenerator(registerContext); }; diff --git a/packages/mobile-ui-vue/components/page-container/index.ts b/packages/mobile-ui-vue/components/page-container/index.ts index 18325b70fe9..0737451b819 100644 --- a/packages/mobile-ui-vue/components/page-container/index.ts +++ b/packages/mobile-ui-vue/components/page-container/index.ts @@ -24,7 +24,7 @@ const PAGE_CONTAINER_REGISTERED_NAME = 'page-container'; const PageContainer = withInstall(PageContainerInstallless); PageContainer.register = ( componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext ): void => { componentMap[PAGE_CONTAINER_REGISTERED_NAME] = PageContainer; propsResolverMap[PAGE_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); 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 bceff3dd66d..2ad2032a673 100644 --- a/packages/mobile-ui-vue/components/page-footer-container/index.ts +++ b/packages/mobile-ui-vue/components/page-footer-container/index.ts @@ -24,7 +24,7 @@ const COMPONENT_TYPE = 'page-footer-container'; const PageFooterContainer = withInstall(PageFooterContainerInstallless); PageFooterContainer.register = ( componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext ): void => { componentMap[COMPONENT_TYPE] = PageFooterContainer; propsResolverMap[COMPONENT_TYPE] = propsResolverGenerator(registerContext); 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 d1bbc9022c7..37dd643a726 100644 --- a/packages/mobile-ui-vue/components/page-header-container/index.ts +++ b/packages/mobile-ui-vue/components/page-header-container/index.ts @@ -24,7 +24,7 @@ const PAGE_HEADER_CONTAINER_REGISTERED_NAME = 'page-header-container'; const PageHeaderContainer = withInstall(PageHeaderContainerInstallless); PageHeaderContainer.register = ( componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext ): void => { componentMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = PageHeaderContainer; propsResolverMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); diff --git a/packages/mobile-ui-vue/components/register-designer.ts b/packages/mobile-ui-vue/components/register-designer.ts index 69cb383b457..abf235bbdc6 100644 --- a/packages/mobile-ui-vue/components/register-designer.ts +++ b/packages/mobile-ui-vue/components/register-designer.ts @@ -2,7 +2,7 @@ import { RegisterContext } from "./common"; import { propertyConfigSchemaMapForDesigner, schemaMapForDesigner, schemaResolverMapForDesigner } from "./dynamic-resolver"; import { propertyEffectMapForDesigner } from "./dynamic-resolver/src/resolver/property-config/property-config-resolver-design"; -const componentMapForDisngner: Record = {}; +const componentMapForDesigner: Record = {}; const componentPropsConverterForDesigner: Record = {}; const componentPropertyConfigConverterForDesigner: Record = {}; @@ -24,8 +24,8 @@ function registerDesignerComponents(components: any[]) { }; components.forEach(component => { - component.registerDesigner && component.registerDesigner(componentMapForDisngner, componentPropsConverterForDesigner, componentPropertyConfigConverterForDesigner, registerContext); + component.registerDesigner && component.registerDesigner(componentMapForDesigner, componentPropsConverterForDesigner, componentPropertyConfigConverterForDesigner, registerContext); }); } -export { registerDesignerComponents, componentMapForDisngner, componentPropsConverterForDesigner }; +export { registerDesignerComponents, componentMapForDesigner, componentPropsConverterForDesigner }; diff --git a/packages/ui-vue/components/designer-canvas/src/composition/designer-canvas-changed.ts b/packages/ui-vue/components/designer-canvas/src/composition/designer-canvas-changed.ts index 87a3003a94f..867da936d1b 100644 --- a/packages/ui-vue/components/designer-canvas/src/composition/designer-canvas-changed.ts +++ b/packages/ui-vue/components/designer-canvas/src/composition/designer-canvas-changed.ts @@ -4,6 +4,9 @@ import { ref } from "vue"; /** 用于响应画布发生变更 */ export const canvasChanged = ref(0); +export function changeCanvas() { + canvasChanged.value++; +} /** * 判断DOM 是否在可视区域内 * @param el 元素 diff --git a/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx b/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx index b57a64585f2..9fd44536619 100644 --- a/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx +++ b/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx @@ -1,7 +1,7 @@ import { computed, defineComponent, inject, onMounted, onUnmounted, provide, ref, watch } from 'vue'; import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from './types'; -import { canvasChanged, setPositionOfButtonGroupInContainer } from './composition/designer-canvas-changed'; +import { canvasChanged, changeCanvas, setPositionOfButtonGroupInContainer } from './composition/designer-canvas-changed'; import { designerCanvasProps, DesignerCanvasPropsType } from './composition/props/designer-canvas.props'; import { useDragula } from './composition/function/use-dragula'; import { DesignerHostService, UseDragula } from './composition/types'; @@ -142,7 +142,7 @@ export default defineComponent({ resizeObserver = null; } }); - context.expose({ refreshCanvas }); + context.expose({ refreshCanvas, changeCanvas }); return () => { return (
    -- Gitee From bf16582b96f343e0dc23f340ed5394bb42530906 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Tue, 15 Apr 2025 10:37:08 +0800 Subject: [PATCH 234/287] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=BA=93=E6=B3=A8=E5=86=8C=E6=9C=BA=E5=88=B6=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E5=90=8E=EF=BC=8C=E9=A1=B5=E9=9D=A2=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile-ui-vue/components/button/index.ts | 5 +-- .../components/page-body-container/index.ts | 8 ++-- .../components/page-container/index.ts | 4 +- .../components/page-footer-container/index.ts | 4 +- .../components/page-header-container/index.ts | 4 +- packages/mobile-ui-vue/components/register.ts | 42 +++++++++++-------- 6 files changed, 38 insertions(+), 29 deletions(-) diff --git a/packages/mobile-ui-vue/components/button/index.ts b/packages/mobile-ui-vue/components/button/index.ts index f0dcd4d389a..824d65b7836 100644 --- a/packages/mobile-ui-vue/components/button/index.ts +++ b/packages/mobile-ui-vue/components/button/index.ts @@ -8,8 +8,8 @@ const BUTTON_REGISTERED_NAME = 'button'; const Button = withInstall(ButtonInstallless); Button.register = ( - componentMap: Record, propsResolverMap: Record, - configResolverMap: Record, resolverMap: Record, registerContext: RegisterContext + componentMap: Record, propsResolverMap: Record, configResolverMap: Record, + resolverMap: Record, registerContext: RegisterContext ) => { componentMap[BUTTON_REGISTERED_NAME] = Button; propsResolverMap[BUTTON_REGISTERED_NAME] = propsResolverGenerator(registerContext); @@ -23,6 +23,5 @@ Button.registerDesigner = ( propsResolverMap[BUTTON_REGISTERED_NAME] = propsResolverGenerator(registerContext); }; - export { Button }; export default Button as typeof Button & Plugin; 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 25200201a9d..fa1a45449b6 100644 --- a/packages/mobile-ui-vue/components/page-body-container/index.ts +++ b/packages/mobile-ui-vue/components/page-body-container/index.ts @@ -22,14 +22,16 @@ import { propsResolverGenerator } from './src/page-body-container.props'; const PAGE_BODY_CONTAINER_REGISTER_NAME = 'page-body-container'; const PageBodyContainer = withInstall(PageBodyContainerInstallless); -PageBodyContainer.register = (componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext): void => { +PageBodyContainer.register = ( + componentMap: Record, propsResolverMap: Record, configresolverMap: Record, + resolverMap: Record, registerContext: RegisterContext +): void => { componentMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = PageBodyContainer; propsResolverMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = propsResolverGenerator(registerContext); }; PageBodyContainer.registerDesigner = (componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext): void => { + configresolverMap: Record, registerContext: RegisterContext): void => { componentMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = PageBodyContainerDesign; propsResolverMap[PAGE_BODY_CONTAINER_REGISTER_NAME] = propsResolverGenerator(registerContext); }; diff --git a/packages/mobile-ui-vue/components/page-container/index.ts b/packages/mobile-ui-vue/components/page-container/index.ts index 18325b70fe9..5486a811191 100644 --- a/packages/mobile-ui-vue/components/page-container/index.ts +++ b/packages/mobile-ui-vue/components/page-container/index.ts @@ -23,8 +23,8 @@ const PAGE_CONTAINER_REGISTERED_NAME = 'page-container'; const PageContainer = withInstall(PageContainerInstallless); PageContainer.register = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext + componentMap: Record, propsResolverMap: Record, + configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext ): void => { componentMap[PAGE_CONTAINER_REGISTERED_NAME] = PageContainer; propsResolverMap[PAGE_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); 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 bceff3dd66d..9974e06a5cf 100644 --- a/packages/mobile-ui-vue/components/page-footer-container/index.ts +++ b/packages/mobile-ui-vue/components/page-footer-container/index.ts @@ -23,8 +23,8 @@ const COMPONENT_TYPE = 'page-footer-container'; const PageFooterContainer = withInstall(PageFooterContainerInstallless); PageFooterContainer.register = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext + componentMap: Record, propsResolverMap: Record, configresolverMap: Record, + resolverMap: Record, registerContext: RegisterContext ): void => { componentMap[COMPONENT_TYPE] = PageFooterContainer; propsResolverMap[COMPONENT_TYPE] = propsResolverGenerator(registerContext); 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 d1bbc9022c7..95cc9a89fde 100644 --- a/packages/mobile-ui-vue/components/page-header-container/index.ts +++ b/packages/mobile-ui-vue/components/page-header-container/index.ts @@ -23,8 +23,8 @@ const PAGE_HEADER_CONTAINER_REGISTERED_NAME = 'page-header-container'; const PageHeaderContainer = withInstall(PageHeaderContainerInstallless); PageHeaderContainer.register = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext + componentMap: Record, propsResolverMap: Record, configresolverMap: Record, + resolverMap: Record, registerContext: RegisterContext ): void => { componentMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = PageHeaderContainer; propsResolverMap[PAGE_HEADER_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); diff --git a/packages/mobile-ui-vue/components/register.ts b/packages/mobile-ui-vue/components/register.ts index 02f0fe96957..c3ee8994d30 100644 --- a/packages/mobile-ui-vue/components/register.ts +++ b/packages/mobile-ui-vue/components/register.ts @@ -1,26 +1,28 @@ +import { RegisterContext } from "./common"; +import { propertyConfigSchemaMap, schemaMap, schemaResolverMap } from "./dynamic-resolver"; +import { propertyEffectMap } from "./dynamic-resolver/src/resolver/property-config/property-config-resolver"; + +import Button from './button'; +import ButtonGroup from './button-group'; +import InputGroup from './input-group'; +import NumberInput from './number-input'; +import Textarea from './textarea'; +import Navbar from './navbar'; +import Switch from './switch'; +import Form from './form'; +import FormItem from './form-item'; +import { Picker } from './picker'; +import { DatePicker } from './date-picker'; +import { DateTimePicker } from "./date-time-picker"; import PageContainer from './page-container'; -import PageHeaderContainer from './page-header-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 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'; -import Textarea from './textarea'; -import NumberInput from './number-input'; -import Switch from './switch'; -import DatePicker from './date-picker'; -import DateTimePicker from './date-time-picker'; -import Picker from './picker'; - const componentMap: Record = {}; const propsConverterMap: Record = {}; const propConfigsConverterMap: Record = {}; @@ -36,15 +38,21 @@ function registerComponents() { return; } componentsRegistered = true; + const registerContext: RegisterContext = { + schemaMap: schemaMap, + propertyConfigSchemaMap: propertyConfigSchemaMap, + propertyEffectMap: propertyEffectMap, + schemaResolverMap: schemaResolverMap + }; const componentsToRegister = [ Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, ContentContainer, FloatContainer, - Navbar, Button, ButtonGroup, Listview, + Button, ButtonGroup, Navbar, Listview, Form, FormItem, InputGroup, Textarea, NumberInput, Switch, DatePicker, DateTimePicker, Picker ]; componentsToRegister.forEach((componentToRegister) => { - componentToRegister.register(componentMap, propsConverterMap, propConfigsConverterMap, resolverMap); + componentToRegister.register(componentMap, propsConverterMap, propConfigsConverterMap, resolverMap, registerContext); }); } -- Gitee From 450309bb3f7274f6a34f0bbd0604f1608507ec66 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Tue, 15 Apr 2025 16:14:21 +0800 Subject: [PATCH 235/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E7=BB=84=E4=BB=B6=E8=AE=BE=E8=AE=A1=E6=97=B6=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=8F=8A=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/src/properties/index.ts | 2 +- .../src/properties/input-base-property.ts | 56 ++++---- .../components/common/src/types/types.ts | 2 +- .../components/common/src/utils/src/common.ts | 11 ++ .../designer/date-picker.design.component.tsx | 82 +++++------ .../src/date-time-picker.props.ts | 2 +- .../designer/date-picker.design.component.tsx | 63 +++++---- .../dynamic-resolver/src/props-resolver.ts | 2 +- .../src/resolver/type-resolver/types.ts | 2 +- .../designer/form-item.design.component.tsx | 133 ++++++------------ .../response-form.design.component.tsx | 86 +++++------ .../form-item/src/form-item.component.tsx | 2 +- .../form-item/src/form-item.props.ts | 4 +- .../response-form.property-config.ts | 52 +++++-- .../src/schema/form-item.schema.json | 3 +- .../form-item/src/schema/form.schema.json | 9 ++ .../components/input-group/index.ts | 3 + .../designer/input-group.design.component.tsx | 78 ++++++---- .../src/designer/input-group.design.props.ts | 7 + .../number-input.design.component.tsx | 58 +++++--- .../number-input/src/number-input.props.ts | 4 +- .../number-input.property-config.ts | 6 +- .../mobile-ui-vue/components/picker/index.ts | 4 +- .../enum-field-input.design.component.tsx | 75 ---------- .../src/designer/picker.design.component.tsx | 62 ++++++++ .../picker/src/designer/use-designer-rules.ts | 8 +- .../enum-field-input.property-config.ts | 47 ------- .../property-config/picker.property-config.ts | 51 +++++++ .../src/designer/switch.design.component.tsx | 82 +++++------ .../switch/src/designer/use-designer-rules.ts | 4 +- .../designer/textarea.design.component.tsx | 86 ++++++----- .../textarea.property-config.ts | 76 +++++----- .../components/textarea/src/textarea.props.ts | 4 +- 33 files changed, 594 insertions(+), 572 deletions(-) create mode 100644 packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.props.ts delete mode 100644 packages/mobile-ui-vue/components/picker/src/designer/enum-field-input.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/picker/src/designer/picker.design.component.tsx delete mode 100644 packages/mobile-ui-vue/components/picker/src/property-config/enum-field-input.property-config.ts create mode 100644 packages/mobile-ui-vue/components/picker/src/property-config/picker.property-config.ts diff --git a/packages/mobile-ui-vue/components/common/src/properties/index.ts b/packages/mobile-ui-vue/components/common/src/properties/index.ts index 45e1b856918..d95bdeae6a1 100644 --- a/packages/mobile-ui-vue/components/common/src/properties/index.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/index.ts @@ -1,4 +1,4 @@ export * from './dg-control'; export { SchemaDOMMapping } from './schema-dom-mapping'; export { BaseControlProperty } from './base-property'; -export { InputBaseProperty } from './input-base-property'; \ No newline at end of file +export { InputBaseProperty } from './input-base-property'; diff --git a/packages/mobile-ui-vue/components/common/src/properties/input-base-property.ts b/packages/mobile-ui-vue/components/common/src/properties/input-base-property.ts index 58894cf7b1a..c563a8c9562 100644 --- a/packages/mobile-ui-vue/components/common/src/properties/input-base-property.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/input-base-property.ts @@ -1,8 +1,6 @@ import { BaseControlProperty } from "./base-property"; import { SchemaDOMMapping } from './schema-dom-mapping'; -// import { canvasChanged } from '../../../../common/src/composition/common-changed'; - import { ExpressionProperty } from "./expression-property"; import { FormSchemaEntityField$Type, FormSchemaEntityFieldType$Type, FormVariable } from "../types/entity-schema"; import { DesignerComponentInstance, FormBindingType, FormPropertyChangeObject } from "../types"; @@ -12,6 +10,9 @@ export class InputBaseProperty extends BaseControlProperty { /** 控件绑定的变量 */ public bindingVarible?: FormVariable; + public labelAlignVisible = true; + public labelAlignReadonly = false; + constructor(componentId: string, designerHostService: any) { super(componentId, designerHostService); } @@ -32,13 +33,7 @@ export class InputBaseProperty extends BaseControlProperty { // this.propertyConfig.categories['eventsEditor'] = this.getEventPropertyConfig(propertyData); return this.propertyConfig; } - public getGridFieldEdtiorPropConfig(propertyData: any, componentInstance: DesignerComponentInstance | null) { - this.propertyConfig.categories = {}; - this.getCommonPropertyConfig(propertyData, componentInstance); - // 事件 暂不支持 - // this.propertyConfig.categories['eventsEditor'] = this.getEventPropertyConfig(propertyData, 'gridFieldEditor'); - return this.propertyConfig.categories; - } + public getBasicProperties(propertyData, componentInstance): any { const self = this; this.setDesignViewModelField(propertyData); @@ -68,11 +63,6 @@ export class InputBaseProperty extends BaseControlProperty { readonly: !canChangeControlType }, }, - label: { - title: "标签", - type: "string", - $converter: '/converter/form-group-label.converter' - }, binding: { description: "绑定的表单字段", title: "绑定", @@ -89,6 +79,29 @@ export class InputBaseProperty extends BaseControlProperty { textField: 'bindingField' }, refreshPanelAfterChanged: true + }, + label: { + title: "标签", + type: "string", + $converter: '/converter/form-group-label.converter' + }, + labelAlign: { + title: "标签排列方式", + type: "string", + $converter: '/converter/form-group-label.converter', + visible: this.labelAlignVisible, + editor: { + type: 'combo-list', + data: [{id: 'left', name: '左侧'},{id: 'top', name: '上侧'}], + readonly: this.labelAlignReadonly + }, + refreshPanelAfterChanged: true + }, + labelWidth: { + title: "标签宽度", + type: "string", + $converter: '/converter/form-group-label.converter', + visible: propertyData.labelAlign !== 'top' } }, setPropertyRelates(changeObject, prop, paramters: any) { @@ -264,7 +277,7 @@ export class InputBaseProperty extends BaseControlProperty { }); // 解决undefined下默认值问题 if (Object.prototype.hasOwnProperty.call(oldControl, 'visible')) { - Object.assign(newControl, { visible: oldControl.visible }) + Object.assign(newControl, { visible: oldControl.visible }); } if (oldControl.editor) { ['readonly', 'required', 'placeholder'].map((item) => { @@ -377,19 +390,6 @@ export class InputBaseProperty extends BaseControlProperty { } - - /** - * 校验宽度样式值是否一致 - */ - private checkIsUniqueColumn(columnsInScreen: number[]) { - const keySet = new Set(columnsInScreen); - const exclusiveKeys = Array.from(keySet); - - if (exclusiveKeys.length === 1) { - return true; - } - return false; - } /** * 枚举项编辑器 * @param propertyData diff --git a/packages/mobile-ui-vue/components/common/src/types/types.ts b/packages/mobile-ui-vue/components/common/src/types/types.ts index 47a5ed1fc2b..b0c10ec0675 100644 --- a/packages/mobile-ui-vue/components/common/src/types/types.ts +++ b/packages/mobile-ui-vue/components/common/src/types/types.ts @@ -136,4 +136,4 @@ export interface RegisterContext { schemaResolverMap: Record; propertyConfigSchemaMap: Record; propertyEffectMap: Record; -} \ No newline at end of file +} 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 1010e19020f..d258ec7627a 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 @@ -86,3 +86,14 @@ export const setValue = (obj: Record, field: string, val: any) => { obj[field] = val; } }; +export function extractProperties( + obj: T, + props: K[] +): Pick { + return props.reduce((result, prop) => { + if (prop in obj) { + result[prop] = obj[prop]; + } + return result; + }, {} as Pick); +} diff --git a/packages/mobile-ui-vue/components/date-picker/src/designer/date-picker.design.component.tsx b/packages/mobile-ui-vue/components/date-picker/src/designer/date-picker.design.component.tsx index f3f77598216..6bf49f080e9 100644 --- a/packages/mobile-ui-vue/components/date-picker/src/designer/date-picker.design.component.tsx +++ b/packages/mobile-ui-vue/components/date-picker/src/designer/date-picker.design.component.tsx @@ -1,54 +1,42 @@ - -/** - * 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, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; - -import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common';; +import { computed, defineComponent, inject, onMounted, ref } from 'vue'; +import { + DesignerHostService, + DesignerItemContext, + extractProperties, + useDesignerComponent +} from '@farris/mobile-ui-vue/common'; +import InputGroup from '@farris/mobile-ui-vue/input-group'; import { useDesignerRules } from './use-designer-rules'; -import { datePickerProps, DatePickerProps } from '../date-picker.props'; -import DatePickerInput from '../..'; +import { datePickerProps } from '../date-picker.props'; export default defineComponent({ - name: 'FmDatePickerInputDesign', - props: datePickerProps, - emits: [], - setup(props: DatePickerProps, context: SetupContext) { - const elementRef = ref(); - const designItemContext = inject('design-item-context') as DesignerItemContext; - const designerHostService = inject('designer-host-service'); - const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); - const componentInstance = useDesignerComponent(elementRef, designItemContext,designerRulesComposition); + name: 'FmDatePickerInputDesign', + inheritAttrs: false, + props: extractProperties(datePickerProps, ['placeholder']), + setup(props, context) { + const elementRef = ref(); + const designItemContext = inject( + 'design-item-context' + ) as DesignerItemContext; + const designerHostService = inject('designer-host-service'); + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent( + elementRef, + designItemContext, + designerRulesComposition + ); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); - onMounted(() => { - elementRef.value.componentInstance = componentInstance; - }); + context.expose(componentInstance.value); - context.expose(componentInstance.value); + const inputProps = computed(() => ({ + ...props, + editable: false + })); - const inputProps = computed(() => ({ - ...props, - editable: false, - readonly: true, - modelValue:null - })); - - return () => { - return ( - - ); - }; - } + 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 c2a66c2a278..283d4a1f02b 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 @@ -4,7 +4,7 @@ import { dateTimePickerPanelProps } from './date-time-picker-panel.props'; import { getPropsResolverGenerator } from '../../dynamic-resolver'; import { schemaResolver } from './schema/schema-resolver'; import { schemaMapper } from './schema/schema-mapper'; -import dateTimePickerSchema from './schema/datetime-picker.schema.json' +import dateTimePickerSchema from './schema/datetime-picker.schema.json'; export const DATA_TIME_PICKER_NAME = 'FmDateTimePicker'; diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/designer/date-picker.design.component.tsx b/packages/mobile-ui-vue/components/date-time-picker/src/designer/date-picker.design.component.tsx index feaea41cd8b..1915144983b 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/designer/date-picker.design.component.tsx +++ b/packages/mobile-ui-vue/components/date-time-picker/src/designer/date-picker.design.component.tsx @@ -1,37 +1,42 @@ import { computed, defineComponent, inject, onMounted, ref } from 'vue'; - -import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common'; +import { + DesignerHostService, + DesignerItemContext, + extractProperties, + useDesignerComponent +} from '@farris/mobile-ui-vue/common'; +import InputGroup from '@farris/mobile-ui-vue/input-group'; import { useDesignerRules } from './use-designer-rules'; -import { ButtonEdit, buttonEditProps} from '@farris/mobile-ui-vue/button-edit'; +import { dateTimePickerProps } from '../date-time-picker.props'; export default defineComponent({ - name: 'FmDatePickerDesign', - props: buttonEditProps, - emits: [], - setup(props, context) { - const elementRef = ref(); - const designItemContext = inject('design-item-context') as DesignerItemContext; - const designerHostService = inject('designer-host-service'); - const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); - const componentInstance = useDesignerComponent(elementRef, designItemContext,designerRulesComposition); + name: 'FmDatePickerDesign', + inheritAttrs: false, + props: extractProperties(dateTimePickerProps, ['placeholder']), + setup(props, context) { + const elementRef = ref(); + const designItemContext = inject( + 'design-item-context' + ) as DesignerItemContext; + const designerHostService = inject('designer-host-service'); + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent( + elementRef, + designItemContext, + designerRulesComposition + ); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); - onMounted(() => { - elementRef.value.componentInstance = componentInstance; - }); + context.expose(componentInstance.value); - context.expose(componentInstance.value); + const inputProps = computed(() => ({ + ...props, + editable: false + })); - const inputProps = computed(() => ({ - ...props, - editable: false, - readonly: true, - modelValue: '' - })); - - return () => { - return ( - - ); - }; - } + return () => ; + } }); diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts index 1bfce6447bd..7610eb7c00f 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts @@ -44,6 +44,6 @@ export function getPropsResolverGenerator>( return propsObject; }, {}); return Object.assign(defaultProps, resolvedPropsValue); - } + }; }; } diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/type-resolver/types.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/type-resolver/types.ts index e849360777a..1ad88afe1e0 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/type-resolver/types.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/type-resolver/types.ts @@ -10,4 +10,4 @@ export interface UseTypeResolver { getChangeFunctionName(type: string): any; getClearFunctionName(type: string): any; -} \ No newline at end of file +}; diff --git a/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx b/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx index c4af84c0f3d..6164f934fb1 100644 --- a/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx +++ b/packages/mobile-ui-vue/components/form-item/src/designer/form-item.design.component.tsx @@ -1,38 +1,20 @@ -/** - * 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, defineComponent, inject, onMounted, ref, SetupContext, watch } from 'vue'; -import { useBem } from '@farris/mobile-ui-vue/common'; -import FmCell from '@farris/mobile-ui-vue/cell'; -import { FORM_ITEM_NAME, FormItemProps, formItemProps } from '../form-item.props'; -import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common';; -import { propertyConfigSchemaMapForDesigner } from '@farris/mobile-ui-vue/dynamic-resolver'; +import { computed, defineComponent, inject, onMounted, PropType, ref } from 'vue'; +import { DesignerHostService, DesignerItemContext, extractProperties, useDesignerComponent } from '@farris/mobile-ui-vue/common';; +import { propertyConfigSchemaMapForDesigner, useTypeResolverDesign } from '@farris/mobile-ui-vue/dynamic-resolver'; import { useDesignerRulesForFormItem } from './form-item-use-designer-rules'; -import { useTypeResolverDesign } from '@farris/mobile-ui-vue/dynamic-resolver'; +import { formItemProps } from '../form-item.props'; +import FormItem from '../form-item.component'; export default defineComponent({ name: 'FmFormItemDesign', - props: formItemProps, + inheritAttrs: false, + props: { + ...extractProperties(formItemProps, ['label', 'labelAlign', 'labelWidth']), + editor: { type: Object as PropType, default: ()=>({}) } + }, + setup(props, context) { + const { slots } = context; - setup(props: FormItemProps, context: SetupContext) { - const { slots, expose } = context; - - const labelAlign = ref(props.labelAlign); - const shouldShowRequired = ref(props.required); - const { bem } = useBem(FORM_ITEM_NAME); - const editor = ref(props.editor); const { resolveEditorProps, resolveEditorType } = useTypeResolverDesign(); const elementRef = ref(); @@ -43,53 +25,6 @@ export default defineComponent({ const designerRulesComposition = useDesignerRulesForFormItem(designItemContext, designerHostService); const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); - - const renderLabel = () => { - if (slots.label) { - return [slots.label()]; - } - return ; - }; - - const contentClass = computed(() => { - let contentAlign = props.contentAlign || 'right'; - if (labelAlign.value === 'top') { - contentAlign = 'left'; - } - return { - [bem('content')]: true, - [bem('content', contentAlign)]: true - }; - }); - const renderContent = () => { - const renderConditionEditor = computed(() => { - const editorType = editor.value.type || 'input-group'; - const Component = resolveEditorType(editorType); - const editorProps = resolveEditorProps(editorType, editor.value); - return () => ; - }); - - - return
    {renderConditionEditor.value()}
    ; - }; - - - const formItemClass = computed(() => { - const direction = labelAlign.value === 'top' ? 'vertical' : 'horizontal'; - return { - [bem()]: true, - [bem('', direction)]: true - }; - }); - - const labelClass = computed(() => { - const labelClasses = [bem('label'), bem('label', labelAlign.value)]; - if (shouldShowRequired.value === true) { - labelClasses.push(bem('label', 'required')); - } - return labelClasses.join(' '); - }); - onMounted(() => { elementRef.value.componentInstance = componentInstance; @@ -103,26 +38,38 @@ export default defineComponent({ }; }); - context.expose(componentInstance.value); - return () => { - const innerSlots = { - title: renderLabel, - default: renderContent, - leftIcon: slots.leftIcon, - rightIcon: slots.rightIcon, - extra: slots.extra - }; + const editorProps = computed(()=>{ + const editorType = props.editor.type || 'input-group'; + return resolveEditorProps(editorType, props.editor); + }); + + const renderConditionEditor = () => { + const editorType = props.editor.type || 'input-group'; + const Component = resolveEditorType(editorType); + return ; + }; - return ( - - - ); + const innerSlots = { + ...slots, + default: renderConditionEditor, }; + const formItemProps = computed(()=>{ + return { + ...props, + required: editorProps.value.required + }; + }); + + return () => ( + + + ); + } }); diff --git a/packages/mobile-ui-vue/components/form-item/src/designer/response-form.design.component.tsx b/packages/mobile-ui-vue/components/form-item/src/designer/response-form.design.component.tsx index eec6f5d64de..fdfcaacb932 100644 --- a/packages/mobile-ui-vue/components/form-item/src/designer/response-form.design.component.tsx +++ b/packages/mobile-ui-vue/components/form-item/src/designer/response-form.design.component.tsx @@ -1,46 +1,50 @@ import { computed, defineComponent, inject, onMounted, ref } from 'vue'; +import { + DesignerHostService, + DesignerItemContext, + extractProperties, + useDesignerComponent +} from '@farris/mobile-ui-vue/common'; import { useDesignerRules } from './response-form-use-designer-rules'; -import { FormProps, formProps } from '../form.props'; -import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common';; +import { formProps } from '../form.props'; +import Form from '../form.component'; export default defineComponent({ - name: 'FResponseFormDesign', - props: formProps, - emits: [], - setup(props: FormProps, context) { - const elementRef = ref(); - const designItemContext = inject('design-item-context') as DesignerItemContext; - const designerHostService = inject('designer-host-service'); - const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); - const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); - - onMounted(() => { - elementRef.value.componentInstance = componentInstance; - }); - - context.expose(componentInstance.value); - - const responseFormClass = computed(() => { - const customClassArray = []; - const classObject = { - 'drag-container': true - } as Record; - customClassArray.reduce((result: Record, classString: string) => { - result[classString] = true; - return result; - }, classObject); - return classObject; - }); - - - return () => { - return ( - -
    - {context.slots.default && context.slots.default()} -
    - - ); - }; - } + name: 'FResponseFormDesign', + inheritAttrs: false, + props: extractProperties(formProps, ['labelAlign', 'labelWidth']), + setup(props, context) { + const elementRef = ref(); + const designItemContext = inject( + 'design-item-context' + ) as DesignerItemContext; + const designerHostService = inject('designer-host-service'); + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent( + elementRef, + designItemContext, + designerRulesComposition + ); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + context.expose(componentInstance.value); + + const formProps = computed(() => { + return { + ...props + }; + }); + + return () => ( +
    + ); + } }); diff --git a/packages/mobile-ui-vue/components/form-item/src/form-item.component.tsx b/packages/mobile-ui-vue/components/form-item/src/form-item.component.tsx index 4dfb55249a2..1627034d57f 100644 --- a/packages/mobile-ui-vue/components/form-item/src/form-item.component.tsx +++ b/packages/mobile-ui-vue/components/form-item/src/form-item.component.tsx @@ -67,7 +67,7 @@ export default defineComponent({ }; }); const renderContent = () => { - return
    {slots.default()}
    ; + return
    {slots.default && slots.default()}
    ; }; const errorMessageClass = computed(() => { 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 7c8c29a4f9a..42952726e03 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 @@ -35,9 +35,7 @@ export const formItemProps = { showErrorMessage: { type: Boolean, default: undefined }, /** 错误信息位置 */ - errorMessageAlign: { type: String as PropType, deafult: undefined }, - - editor: { type: Object as PropType, default: {} }, + errorMessageAlign: { type: String as PropType, deafult: undefined } }; diff --git a/packages/mobile-ui-vue/components/form-item/src/property-config/response-form.property-config.ts b/packages/mobile-ui-vue/components/form-item/src/property-config/response-form.property-config.ts index 7b4fee85c2d..191cb96397e 100644 --- a/packages/mobile-ui-vue/components/form-item/src/property-config/response-form.property-config.ts +++ b/packages/mobile-ui-vue/components/form-item/src/property-config/response-form.property-config.ts @@ -1,16 +1,44 @@ -import { DesignerComponentInstance } from "@farris/mobile-ui-vue/common"; -import { BaseControlProperty } from "@farris/mobile-ui-vue/common"; +import { DesignerComponentInstance } from '@farris/mobile-ui-vue/common'; +import { BaseControlProperty } from '@farris/mobile-ui-vue/common'; export class ResponseFormProperty extends BaseControlProperty { - constructor(componentId: string, designerHostService: any) { - super(componentId, designerHostService); - } - public getPropertyConfig(propertyData: any, componentInstance: DesignerComponentInstance) { - // 基本信息 - this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); - // 外观 - this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + public getPropertyConfig(propertyData: any, componentInstance: DesignerComponentInstance) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); - return this.propertyConfig; - } + this.propertyConfig.categories['label'] = this.getLabelProperties(propertyData); + + return this.propertyConfig; + } + + getLabelProperties(propertyData: any) { + return { + description: '标签配置', + title: '标签', + properties: { + labelAlign: { + title: '标签排列方式', + type: 'string', + editor: { + type: 'combo-list', + data: [ + { id: 'left', name: '左侧' }, + { id: 'top', name: '上侧' } + ] + }, + refreshPanelAfterChanged: true + }, + labelWidth: { + title: "标签宽度", + type: "string", + visible: propertyData.labelAlign !== 'top' + } + } + }; + } } 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 82f34c27ccf..bc07415d539 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 @@ -43,7 +43,8 @@ }, "labelAlign": { "description": "标签排列方式", - "type": "string" + "type": "string", + "default": "left" }, "editor": { "description": "编辑器", 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 index 1052a2fc034..c1f7489be07 100644 --- 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 @@ -27,6 +27,15 @@ }, "default": {} }, + "labelWidth": { + "description": "标签宽度", + "type": "number" + }, + "labelAlign": { + "description": "标签排列方式", + "type": "string", + "default": "left" + }, "contents": { "description": "", "type": "array", diff --git a/packages/mobile-ui-vue/components/input-group/index.ts b/packages/mobile-ui-vue/components/input-group/index.ts index e7494d76fdb..a9c8bff602c 100644 --- a/packages/mobile-ui-vue/components/input-group/index.ts +++ b/packages/mobile-ui-vue/components/input-group/index.ts @@ -12,5 +12,8 @@ withRegisterDesigner(InputGroup, { name: INPUT_GROUP_REGISTERED_NAME, propsResol export * from './src/input-group.props'; export * from './src/types'; + +export * from './src/designer/input-group.design.props'; + export { InputGroup }; export default InputGroup; diff --git a/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx b/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx index c61c695f5f8..ebdf2badda9 100644 --- a/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx +++ b/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx @@ -1,4 +1,3 @@ - /** * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. * @@ -14,41 +13,58 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { computed, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; -import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common';; +import { computed, defineComponent, inject, onMounted, ref, SetupContext } from 'vue'; +import { + DesignerHostService, + DesignerItemContext, + extractProperties, + useDesignerComponent +} from '@farris/mobile-ui-vue/common'; import { useInputGroupDesignerRules } from './use-designer-rules'; import { InputProps, inputProps } from '../input-group.props'; -import { InputGroup } from '@farris/mobile-ui-vue'; - +import InputGroup from '../input-group.component'; +import { inputDesignProps } from './input-group.design.props'; export default defineComponent({ - name: 'FmInputGroupDesign', - props: inputProps, - emits: [] as (string[] & ThisType) | undefined, - setup(props: InputProps, context: SetupContext) { - const elementRef = ref(); - const designerHostService = inject('designer-host-service'); - const designItemContext = inject('design-item-context') as DesignerItemContext; - const designerRulesComposition = useInputGroupDesignerRules(designItemContext, designerHostService); - const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); - - onMounted(() => { - elementRef.value.componentInstance = componentInstance; - }); + name: 'FmInputGroupDesign', + inheritAttrs: false, + props: extractProperties(inputProps, ['placeholder']), + setup(props, context) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject( + 'design-item-context' + ) as DesignerItemContext; + const designerRulesComposition = useInputGroupDesignerRules( + designItemContext, + designerHostService + ); + const componentInstance = useDesignerComponent( + elementRef, + designItemContext, + designerRulesComposition + ); - const inputGroupProps = { - editable: false, - }; + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); - context.expose(componentInstance.value); + context.expose(componentInstance.value); + + const inputProps = computed(()=>{ + return { + ...props, + editable: false + }; + }); - return () => { - return ( - - ); - }; - } + return () => { + return ( + + ); + }; + } }); diff --git a/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.props.ts b/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.props.ts new file mode 100644 index 00000000000..b4dbda59adf --- /dev/null +++ b/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.props.ts @@ -0,0 +1,7 @@ +import { inputProps } from "../input-group.props"; + +export const inputDesignProps = { + placeholder: inputProps.placeholder, + rows: inputProps.rows, + showWordLimit: inputProps.showWordLimit +}; diff --git a/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx b/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx index d3d3f51dbbe..bb0e15f4c5e 100644 --- a/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx +++ b/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx @@ -1,30 +1,46 @@ -import { defineComponent, inject, onMounted, ref, SetupContext } from 'vue'; - -import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common';; +import { computed, defineComponent, inject, onMounted, ref } from 'vue'; +import { + DesignerHostService, + DesignerItemContext, + extractProperties, + useDesignerComponent +} from '@farris/mobile-ui-vue/common'; import { useDesignerRules } from './use-designer-rules'; +import InputGroup from '../number-input.component'; import { numberInputProps } from '../number-input.props'; -import InputGroup from '../..'; export default defineComponent({ - name: 'FmNunberInputDesign', - props: numberInputProps, - emits: [], - setup(props, context: SetupContext) { - const elementRef = ref(); - const designItemContext = inject('design-item-context') as DesignerItemContext; - const designerHostService = inject('designer-host-service'); - const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); - const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + name: 'FmNunberInputDesign', + inheritAttrs: false, + props: extractProperties(numberInputProps, ['placeholder', 'enableNull']), + setup(props, context) { + const elementRef = ref(); + const designItemContext = inject( + 'design-item-context' + ) as DesignerItemContext; + const designerHostService = inject('designer-host-service'); + const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent( + elementRef, + designItemContext, + designerRulesComposition + ); - onMounted(() => { - elementRef.value.componentInstance = componentInstance; - }); + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); - context.expose(componentInstance.value); + context.expose(componentInstance.value); + const inputProps = computed(()=>{ + return { + ...props, + type: 'number', + editable: false, + enableNull: true + }; + }); - return () => ( - - ); - } + 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 index fb1e2812957..b07dd2f0f18 100644 --- 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 @@ -11,8 +11,8 @@ export const numberInputProps = { ...inputCommonProps, enableNull: { type: Boolean, default: undefined }, precision: { type: Number, default: 2 } -} as Record; +}; export type NumberInputProps = ExtractPropTypes; -export const propsResolverGenerator = getPropsResolverGenerator(numberInputProps, numberInputSchema, schemaMapper, schemaResolver); +export const propsResolverGenerator = getPropsResolverGenerator(numberInputProps, numberInputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts b/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts index 45e3182b0f9..6dc50cb6fdd 100644 --- a/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts +++ b/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts @@ -17,12 +17,14 @@ export class NumberInputProperty extends InputBaseProperty { max: { description: "", title: "最大值", - type: "number" + type: "number", + visible: false }, min: { description: "", title: "最小值", - type: "number" + type: "number", + visible: false }, }); } diff --git a/packages/mobile-ui-vue/components/picker/index.ts b/packages/mobile-ui-vue/components/picker/index.ts index ee28dbf6b83..8f007d133f4 100644 --- a/packages/mobile-ui-vue/components/picker/index.ts +++ b/packages/mobile-ui-vue/components/picker/index.ts @@ -2,7 +2,7 @@ import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile- import PickerPanelInstallless from "./src/picker-panel.component"; import PickerInstallless from "./src/picker.component"; import { propsResolverGenerator } from './src/picker.props'; -import EnumFieldInputDesign from './src/designer/enum-field-input.design.component'; +import PickerDesign from './src/designer/picker.design.component'; export * from './src/picker-panel.props'; export * from './src/types'; @@ -20,7 +20,7 @@ const Picker = withInstall(PickerInstallless); // 注册运行时及设计时 withRegister(Picker, { name: PICKER_REGISTERED_NAME, propsResolverGenerator }); -withRegisterDesigner(Picker, { name: PICKER_REGISTERED_NAME, propsResolverGenerator, designerComponent: EnumFieldInputDesign }); +withRegisterDesigner(Picker, { name: PICKER_REGISTERED_NAME, propsResolverGenerator, designerComponent: PickerDesign }); export { Picker, PickerPanel }; export default Picker; diff --git a/packages/mobile-ui-vue/components/picker/src/designer/enum-field-input.design.component.tsx b/packages/mobile-ui-vue/components/picker/src/designer/enum-field-input.design.component.tsx deleted file mode 100644 index 407757aae8c..00000000000 --- a/packages/mobile-ui-vue/components/picker/src/designer/enum-field-input.design.component.tsx +++ /dev/null @@ -1,75 +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, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; -import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common'; -import { pickerProps } from '../picker.props'; -import Picker from '../picker.component'; -import { useEnumFieldDesignerRules } from './use-designer-rules';; - -export default defineComponent({ - name: 'FmEnumFieldInputDesign', - props: pickerProps, - emits: [] as (string[] & ThisType) | undefined, - setup(props, context: SetupContext) { - const elementRef = ref(); - const designerHostService = inject('designer-host-service'); - const designItemContext = inject('design-item-context') as DesignerItemContext; - const designerRulesComposition = useEnumFieldDesignerRules(designItemContext, designerHostService); - const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); - - onMounted(() => { - elementRef.value.componentInstance = componentInstance; - }); - - /** - * 解决在设计时,数据为空数组,界面不显示内容的问题 - */ - const realEnumData = computed(() => { - if (!props.columns || props.columns.length === 0) { - const result = [] as any; - [ - { value: 'example1', name: '示例一' }, - { value: 'example2', name: '示例二' } - ].map(item => { - const tempData = {}; - tempData[props.valueField] = item['value']; - tempData[props.textField] = item['name']; - result.push(tempData); - }); - return result; - } - return props.columns; - }); - - const inputGroupProps = computed(() => ({ - ...props, - editable: false, - readonly: true, - modelValue:null, - columns:realEnumData.value, - type:null - })); - - context.expose(componentInstance.value); - - return () => { - return ( - - ); - }; - } -}); diff --git a/packages/mobile-ui-vue/components/picker/src/designer/picker.design.component.tsx b/packages/mobile-ui-vue/components/picker/src/designer/picker.design.component.tsx new file mode 100644 index 00000000000..8f16c721e37 --- /dev/null +++ b/packages/mobile-ui-vue/components/picker/src/designer/picker.design.component.tsx @@ -0,0 +1,62 @@ +import { computed, defineComponent, inject, onMounted, ref } from 'vue'; +import { + DesignerHostService, + DesignerItemContext, + extractProperties, + useDesignerComponent +} from '@farris/mobile-ui-vue/common'; +import { pickerProps } from '../picker.props'; +import { usePickerDesignerRules } from './use-designer-rules'; +import InputGroup from '@farris/mobile-ui-vue/input-group'; + +export default defineComponent({ + name: 'FmPickerDesign', + inheritAttrs: false, + props: extractProperties(pickerProps, ['placeholder', 'columns', 'valueField', 'textField']), + setup(props, context) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject( + 'design-item-context' + ) as DesignerItemContext; + const designerRulesComposition = usePickerDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent( + elementRef, + designItemContext, + designerRulesComposition + ); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + /** + * 解决在设计时,数据为空数组,界面不显示内容的问题 + */ + const realEnumData = computed(() => { + if (!props.columns || props.columns.length === 0) { + const result = [] as any; + [ + { value: 'example1', name: '示例一' }, + { value: 'example2', name: '示例二' } + ].map((item) => { + const tempData = {}; + tempData[props.valueField] = item['value']; + tempData[props.textField] = item['name']; + result.push(tempData); + }); + return result; + } + return props.columns; + }); + + context.expose(componentInstance.value); + + const inputProps = computed(() => ({ + ...props, + editable: false + })); + + return () => ; + } +}); diff --git a/packages/mobile-ui-vue/components/picker/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/picker/src/designer/use-designer-rules.ts index 039b784430e..d889f74f73e 100644 --- a/packages/mobile-ui-vue/components/picker/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/picker/src/designer/use-designer-rules.ts @@ -1,13 +1,13 @@ import { ComponentSchema, DesignerComponentInstance, DesignerItemContext, UseDesignerRules } from "@farris/mobile-ui-vue/common"; -import { EnumFieldInputProperty } from "../property-config/enum-field-input.property-config"; -export function useEnumFieldDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { +import { PickerInputProperty } from "../property-config/picker.property-config"; +export function usePickerDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { const schema = designItemContext.schema as ComponentSchema; // 构造属性配置方法 function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { - const radioGroupProps = new EnumFieldInputProperty(componentId, designerHostService); - return radioGroupProps.getPropertyConfig(schema, componentInstance); + const radioGroupProps = new PickerInputProperty(componentId, designerHostService); + return radioGroupProps.getPropertyConfig(schema, componentInstance); } return { getPropsConfig } as UseDesignerRules; diff --git a/packages/mobile-ui-vue/components/picker/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 deleted file mode 100644 index 3e7ddf5ebf3..00000000000 --- a/packages/mobile-ui-vue/components/picker/src/property-config/enum-field-input.property-config.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { InputBaseProperty } from "@farris/mobile-ui-vue/common"; - -export class EnumFieldInputProperty extends InputBaseProperty { - - constructor(componentId: string, designerHostService: any) { - super(componentId, designerHostService); - } - - - getEditorProperties(propertyData: any) { - const self = this; - const editorProperties = self.getComponentConfig(propertyData, { type: "radio-group" }, { - editable: { - description: "", - title: "允许编辑", - type: "boolean" - }, - enableClear: { - description: "", - title: "启用清空", - type: "boolean" - }, - data: { - description: "", - title: "数据", - type: "array", - $converter: "/converter/enum-data.converter", - ...self.getItemCollectionEditor(propertyData, propertyData.editor.valueField, propertyData.editor.textField), - // 这个属性,标记当属性变更得时候触发重新更新属性 - refreshPanelAfterChanged: true, - } - }); - editorProperties['setPropertyRelates'] = function (changeObject) { - if (!changeObject) { - return; - } - switch (changeObject.propertyID) { - case 'data': { - - break; - } - } - }; - return editorProperties; - } - -} diff --git a/packages/mobile-ui-vue/components/picker/src/property-config/picker.property-config.ts b/packages/mobile-ui-vue/components/picker/src/property-config/picker.property-config.ts new file mode 100644 index 00000000000..5ab366074a6 --- /dev/null +++ b/packages/mobile-ui-vue/components/picker/src/property-config/picker.property-config.ts @@ -0,0 +1,51 @@ +import { InputBaseProperty } from '@farris/mobile-ui-vue/common'; + +export class PickerInputProperty extends InputBaseProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + getEditorProperties(propertyData: any) { + const self = this; + const editorProperties = self.getComponentConfig( + propertyData, + { type: 'radio-group' }, + { + editable: { + description: '', + title: '允许编辑', + type: 'boolean' + }, + enableClear: { + description: '', + title: '启用清空', + type: 'boolean' + }, + data: { + description: '', + title: '数据', + type: 'array', + $converter: '/converter/enum-data.converter', + ...self.getItemCollectionEditor( + propertyData, + propertyData.editor.valueField, + propertyData.editor.textField + ), + // 这个属性,标记当属性变更得时候触发重新更新属性 + refreshPanelAfterChanged: true + } + } + ); + editorProperties['setPropertyRelates'] = function (changeObject) { + if (!changeObject) { + return; + } + switch (changeObject.propertyID) { + case 'data': { + break; + } + } + }; + return editorProperties; + } +} diff --git a/packages/mobile-ui-vue/components/switch/src/designer/switch.design.component.tsx b/packages/mobile-ui-vue/components/switch/src/designer/switch.design.component.tsx index 602ae671bfd..a56bdc8759e 100644 --- a/packages/mobile-ui-vue/components/switch/src/designer/switch.design.component.tsx +++ b/packages/mobile-ui-vue/components/switch/src/designer/switch.design.component.tsx @@ -1,51 +1,47 @@ - -/** - * 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, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; -import { Switch, SwitchProps, switchProps } from '../..'; -import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common';; +import { computed, defineComponent, inject, onMounted, ref } from 'vue'; +import { Switch, switchProps } from '../..'; +import { + DesignerHostService, + DesignerItemContext, + extractProperties, + useDesignerComponent +} from '@farris/mobile-ui-vue/common'; import { useInputGroupDesignerRules } from './use-designer-rules'; export default defineComponent({ - name: 'FmSwitchDesign', - props: switchProps, - emits: [] as (string[] & ThisType) | undefined, - setup(props: SwitchProps, context: SetupContext) { - const elementRef = ref(); - const designerHostService = inject('designer-host-service'); - const designItemContext = inject('design-item-context') as DesignerItemContext; - const designerRulesComposition = useInputGroupDesignerRules(designItemContext, designerHostService); - const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + name: 'FmSwitchDesign', + inheritAttrs: false, + props: extractProperties(switchProps, ['activeColor', 'inactiveColor']), + setup(props, context) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject( + 'design-item-context' + ) as DesignerItemContext; + const designerRulesComposition = useInputGroupDesignerRules( + designItemContext, + designerHostService + ); + const componentInstance = useDesignerComponent( + elementRef, + designItemContext, + designerRulesComposition + ); - onMounted(() => { - elementRef.value.componentInstance = componentInstance; - }); + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); - const inputGroupProps = computed(() => ({ - ...props, - editable: false, - modelValue:null - })); + const inputGroupProps = computed(() => ({ + ...props, + editable: false, + modelValue: null + })); - context.expose(componentInstance.value); + context.expose(componentInstance.value); - return () => { - return ( - - ); - }; - } + return () => { + return ; + }; + } }); diff --git a/packages/mobile-ui-vue/components/switch/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/switch/src/designer/use-designer-rules.ts index 71636e20fa3..f73c931ad4a 100644 --- a/packages/mobile-ui-vue/components/switch/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/switch/src/designer/use-designer-rules.ts @@ -6,8 +6,8 @@ export function useInputGroupDesignerRules(designItemContext: DesignerItemContex // 构造属性配置方法 function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { - const inputGroupProps = new SwitchProperty(componentId, designerHostService); - return inputGroupProps.getPropertyConfig(schema, componentInstance); + const inputGroupProps = new SwitchProperty(componentId, designerHostService); + return inputGroupProps.getPropertyConfig(schema, componentInstance); } return { getPropsConfig } as UseDesignerRules; diff --git a/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx b/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx index ebdd1187f9e..bf4acc310bd 100644 --- a/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx +++ b/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx @@ -1,54 +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 { computed, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; -import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common'; -import { TEXTAREA_NAME, textareaProps, TextareaProps } from '../textarea.props'; +import { computed, defineComponent, inject, onMounted, ref } from 'vue'; +import { + DesignerHostService, + DesignerItemContext, + extractProperties, + useDesignerComponent +} from '@farris/mobile-ui-vue/common'; import { useTextareaDesignerRules } from './use-designer-rules'; -import Textarea from '../..'; - +import { textareaProps } from '../textarea.props'; +import Textarea from '../textarea.component'; export default defineComponent({ - name: 'FmTextareaDesign', - props: textareaProps, - emits: [] as (string[] & ThisType) | undefined, - setup(props: TextareaProps, context: SetupContext) { - const elementRef = ref(); - const designerHostService = inject('designer-host-service'); - const designItemContext = inject('design-item-context') as DesignerItemContext; - const designerRulesComposition = useTextareaDesignerRules(designItemContext, designerHostService); - const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + name: 'FmTextareaDesign', + inheritAttrs: false, + props: extractProperties(textareaProps, ['placeholder', 'rows', 'showWordLimit']), + setup(props, context) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject( + 'design-item-context' + ) as DesignerItemContext; + const designerRulesComposition = useTextareaDesignerRules( + designItemContext, + designerHostService + ); + const componentInstance = useDesignerComponent( + elementRef, + designItemContext, + designerRulesComposition + ); - onMounted(() => { - elementRef.value.componentInstance = componentInstance; - }); + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); - const inputGroupProps = computed(() => ({ - ...props, - type:"textarea", - editable: false, - modelValue:null - })); + const inputProps = computed(() => ({ + ...props, + type: 'textarea', + editable: false, + })); - context.expose(componentInstance.value); + context.expose(componentInstance.value); - return () => { - return ( - - ); - }; - } + return () => { + return ; + }; + } }); diff --git a/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts b/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts index 481dff85bde..b501e4ba78f 100644 --- a/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts +++ b/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts @@ -1,39 +1,45 @@ -import { InputBaseProperty } from "@farris/mobile-ui-vue/common"; +import { InputBaseProperty } from '@farris/mobile-ui-vue/common'; export class TextareaProperty extends InputBaseProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + this.labelAlignReadonly = true; + } + getBasicProperties(propertyData, componentInstance){ + propertyData.labelAlign = 'top'; - constructor(componentId: string, designerHostService: any) { - super(componentId, designerHostService); - } - - getEditorProperties(propertyData: any) { - return this.getComponentConfig(propertyData, { type: "textarea" }, { - rows: { - description: "", - title: "文本区域可见的行数", - type: "number", - editor: { - min: 0, - nullable:true - } - }, - showCount: { - description: "", - title: "展示输入文本数量", - type: "boolean" - }, - maxLength: { - description: "文本最大长度", - title: "最大长度", - type: "number" - }, - autoHeight: { - description: "", - title: "自动高度", - type: "boolean" - }, - }); - } - - + return super.getBasicProperties(propertyData, componentInstance); + } + getEditorProperties(propertyData: any) { + return this.getComponentConfig( + propertyData, + { type: 'textarea' }, + { + rows: { + description: '', + title: '文本区域可见的行数', + type: 'number', + editor: { + min: 0, + nullable: true + } + }, + showCount: { + description: '', + title: '展示输入文本数量', + type: 'boolean' + }, + maxLength: { + description: '文本最大长度', + title: '最大长度', + type: 'number' + }, + autoHeight: { + description: '', + title: '自动高度', + type: 'boolean' + } + } + ); + } } 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 4eb0aa16e86..c2e86cc6b97 100644 --- a/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts +++ b/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts @@ -19,8 +19,8 @@ export const textareaProps = { minHeight: { type: Number, default: undefined }, showWordLimit: { type: Boolean, default: undefined } -} as Record; +}; export type TextareaProps = ExtractPropTypes; -export const propsResolverGenerator = getPropsResolverGenerator(textareaProps, textareaSchema, schemaMapper, schemaResolver); +export const propsResolverGenerator = getPropsResolverGenerator(textareaProps, textareaSchema, schemaMapper, schemaResolver); -- Gitee From 7aace1d034fd240b6ea0a188ec13cd13f9951e66 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Tue, 15 Apr 2025 16:24:49 +0800 Subject: [PATCH 236/287] =?UTF-8?q?feature:=20MobileRender=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E9=80=9A=E7=94=A8=E7=9A=84=E6=95=B0=E7=BB=84=E5=92=8C?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E5=B1=9E=E6=80=A7=E7=9A=84=E9=80=92=E5=BD=92?= =?UTF-8?q?=E7=BB=91=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/assets/farris-mobile-ui-vue.css | 2 +- .../form/normalizers/component-normalizer.ts | 4 + .../page-config/bindings/binding-util.ts | 103 +++++++++++++-- .../services/page-config/bindings/types.ts | 9 ++ .../page-config/page-config-binder.ts | 118 ++++++++++-------- packages/mobile-render/src/utils/type-util.ts | 9 +- 6 files changed, 186 insertions(+), 59 deletions(-) create mode 100644 packages/mobile-render/src/services/page-config/bindings/types.ts diff --git a/packages/mobile-render/public/assets/farris-mobile-ui-vue.css b/packages/mobile-render/public/assets/farris-mobile-ui-vue.css index f0a165ea7eb..f5b06f98f6e 100644 --- a/packages/mobile-render/public/assets/farris-mobile-ui-vue.css +++ b/packages/mobile-render/public/assets/farris-mobile-ui-vue.css @@ -1 +1 @@ -@charset "UTF-8";:root{--fm-black: #000;--fm-white: #fff;--fm-gray-1: #f2f3f5;--fm-gray-2: #eee;--fm-gray-3: #ddd;--fm-gray-4: #ccc;--fm-gray-5: #999;--fm-gray-6: #666;--fm-gray-7: #333;--fm-red: #F24645;--fm-red-light: #f9e8e8;--fm-blue: #3A90FF;--fm-blue-2: #65a7ff;--fm-blue-light: #ecf2fe;--fm-green: #5CC171;--fm-green-2: #5AC1C3;--fm-green-light: #e9f5ed;--fm-orange: #FF9800;--fm-orange-2: #FA6400;--fm-orange-3: #FFB400;--fm-orange-light: #faf0e1;--fm-primary-color: var(--fm-blue);--fm-success-color: var(--fm-green);--fm-danger-color: var(--fm-red);--fm-warning-color: var(--fm-orange);--fm-submit-color: var(--fm-green-2);--fm-primary-color-light: var(--fm-blue-light);--fm-success-color-light: var(--fm-green-light);--fm-danger-color-light: var(--fm-red-light);--fm-warning-color-light: var(--fm-orange-light);--fm-text-color: var(--fm-gray-7);--fm-text-color-light: var(--fm-gray-5);--fm-active-color: var(--fm-gray-1);--fm-disabled-color: var(--fm-gray-4);--fm-readonly-color: var(--fm-gray-6);--fm-active-opacity: .7;--fm-readonly-opacity: .6;--fm-disabled-opacity: .5;--fm-background: var(--fm-gray-1);--fm-background-white: var(--fm-white);--fm-box-shadow-color: var(--fm-gray-1);--fm-padding-base: 4px;--fm-padding-xs: 8px;--fm-padding-sm: 12px;--fm-padding-md: 16px;--fm-padding-lg: 24px;--fm-padding-xl: 32px;--fm-padding-horizontal-xs: 0 var(--fm-padding-xs);--fm-padding-horizontal-sm: 0 var(--fm-padding-sm);--fm-padding-horizontal-md: 0 var(--fm-padding-md);--fm-padding-horizontal-lg: 0 var(--fm-padding-lg);--fm-margin-base: 4px;--fm-margin-xs: 8px;--fm-margin-sm: 12px;--fm-margin-md: 16px;--fm-margin-lg: 24px;--fm-margin-xl: 32px;--fm-margin-horizontal-xs: 0 var(--fm-margin-xs);--fm-margin-horizontal-sm: 0 var(--fm-margin-sm);--fm-margin-horizontal-md: 0 var(--fm-margin-md);--fm-margin-horizontal-lg: 0 var(--fm-margin-lg);--fm-font-bold-light: 500;--fm-font-bold: 600;--fm-font-size: 16px;--fm-line-height: 1.2;--fm-font-size-xs: 10px;--fm-font-size-sm: 12px;--fm-font-size-md: 14px;--fm-font-size-lg: 16px;--fm-gradient-blue: linear-gradient(-45deg,var(--fm-blue-2) 0%, var(--fm-blue) 100%);--fm-gradient-orange: linear-gradient(-45deg,var(--fm-orange) 0%, var(--fm-orange-2) 100%);--fm-base-font: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Segoe UI, Arial, Roboto, "PingFang SC", "miui", "Hiragino Sans GB", "Microsoft Yahei", sans-serif;--fm-price-font: avenir-heavy, "PingFang SC", helvetica neue, arial, sans-serif;--fm-duration-base: .3s;--fm-duration-fast: .2s;--fm-ease-out: ease-out;--fm-ease-in: ease-in;--fm-noborder: none;--fm-radius-sm: 2px;--fm-radius-md: 4px;--fm-radius-lg: 8px;--fm-radius-max: 999px;--fm-zindex-1: 9;--fm-zindex-2: 10;--fm-zindex-3: 99;--fm-zindex-4: 100;--fm-zindex-5: 999;--fm-zindex-6: 1000}*,*:before,*:after{box-sizing:border-box}body,h1,h2,h3,h4,p,figure,blockquote,dl,dd{margin:0}ul[role=list],ol[role=list]{list-style:none}html:focus-within{scroll-behavior:smooth}body{min-height:100vh;text-rendering:optimizeSpeed;line-height:1.5;font-family:-apple-system,Noto Sans,Helvetica Neue,Helvetica,Nimbus Sans L,Arial,Liberation Sans,PingFang SC,Hiragino Sans GB,Noto Sans CJK SC,Source Han Sans SC,Source Han Sans CN,Microsoft YaHei,Wenquanyi Micro Hei,WenQuanYi Zen Hei,ST Heiti,SimHei,WenQuanYi Zen Hei Sharp,sans-serif}a:not([class]){text-decoration-skip-ink:auto}img,picture{max-width:100%;display:block}input,button,textarea,select{font:inherit}@font-face{font-family:farrisMobile;font-style:normal;font-weight:400;src:url(data:font/ttf;base64,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AADmFAAAACUAAOYVAADmFQAAACYAAOYWAADmFgAAACcAAOYXAADmFwAAACgAAOYYAADmGAAAACkAAOYZAADmGQAAAHYAAOYaAADmGgAAAHUAAOYbAADmGwAAAHQAAOYcAADmHAAAAHMAAOYdAADmHQAAACoAAOYeAADmHgAAACsAAOYfAADmHwAAAHAAAOYgAADmIAAAAHEAAOYhAADmIQAAAHIAAOYiAADmIgAAAG8AAOYjAADmIwAAACwAAOYkAADmJAAAAGUAAOYlAADmJQAAAGYAAOYmAADmJgAAAGcAAOYnAADmJwAAAGgAAOYoAADmKAAAAGkAAOYpAADmKQAAAGoAAOYqAADmKgAAAGsAAOYrAADmKwAAAGwAAOYsAADmLAAAAG0AAOYtAADmLQAAAG4AAOYuAADmLgAAAGMAAOYvAADmLwAAAGQAAOYwAADmMAAAAGIAAOYyAADmMgAAADQAAOYzAADmMwAAAC0AAOY0AADmNAAAAC4AAOY2AADmNgAAAC8AAOY3AADmNwAAADAAAOY5AADmOQAAADEAAOY6AADmOgAAADIAAOZVAADmVQAAADUAAOZWAADmVgAAADoAAOZXAADmVwAAADcAAOZYAADmWAAAADgAAOZZAADmWQAAAD0AAOZaAADmWgAAAF4AAOZbAADmWwAAAF8AAOZcAADmXAAAAGAAAOZdAADmXQAAAGEAAOZeAADmXgAAADYAAOZfAADmXwAAADsAAOZgAADmYAAAADwAAOZhAADmYQAAADkAAOZiAADmYgAAAD4AAOZjAADmYwAAAD8AAOZkAADmZAAAAEAAAOZlAADmZQAAAEEAAOZmAADmZgAAAEIAAOZnAADmZwAAAEMAAOZoAADmaAAAAEQAAOZpAADmaQAAAEUAAOZqAADmagAAAEYAAOZrAADmawAAAEcAAOZsAADmbAAAAEgAAOZtAADmbQAAAEkAAOZuAADmbgAAAEoAAOZvAADmbwAAAEsAAOZwAADmcAAAAEwAAOZxAADmcQAAAE0AAOZyAADmcgAAAE4AAOZzAADmcwAAAE8AAOZ0AADmdAAAAFAAAOZ1AADmdQAAAFEAAOZ2AADmdgAAAFIAAOZ3AADmdwAAAFMAAOZ4AADmeAAAAFQAAOZ5AADmeQAAAFUAAOZ6AADmegAAAFYAAOZ7AADmewAAAFcAAOZ8AADmfAAAAFgAAOZ9AADmfQAAAFkAAOZ+AADmfgAAACgAAOZ/AADmfwAAAFoAAOaAAADmgAAAAFsAAOaBAADmgQAAAFwAAOaCAADmggAAAF0AAOaDAADmgwAAABoAAOaEAADmhAAAABsAAOaFAADmhQAAABgAAOaGAADmhgAAABkAAOaHAADmhwAAAA4AAOaIAADmiAAAAA8AAOaJAADmiQAAAAoAAOaKAADmigAAAAsAAOaLAADmiwAAAAwAAOaMAADmjAAAAA0AAOaNAADmjQAAAAkAAOaOAADmjgAAAAgAAOaPAADmjwAAABAAAOaQAADmkAAAABEAAOaRAADmkQAAABIAAOaSAADmkgAAABMAAOaTAADmkwAAABQAAOaUAADmlAAAABUAAOaVAADmlQAAABYAAOaWAADmlgAAABcAAOaXAADmlwAAAAcAAOaYAADmmAAAAAUAAOaZAADmmQAAAAYAAOaaAADmmgAAAAQAAOabAADmmwAAAAMAAOacAADmnAAAAAIAAOadAADmnQAAAAEAAOanAADmpwAAAIAAAOaoAADmqAAAAIEAAOapAADmqQAAAIIAAOaqAADmqgAAAIMAAOarAADmqwAAAIQAAOasAADmrAAAAIUAAOatAADmrQAAAIYAAOauAADmrgAAAIcAAOavAADmrwAAAIgAAOawAADmsAAAAIkAAOaxAADmsQAAAIoAAOayAADmsgAAAIsAAOazAADmswAAAIwAAOa0AADmtAAAAI0AAOa1AADmtQAAAI4AAOa2AADmtgAAAI8AAOa3AADmtwAAAHcAAOa4AADmuAAAAHgAAOa5AADmuQAAAHkAAOa6AADmugAAAHoAAOa7AADmuwAAAHsAAOa8AADmvAAAAHwAAOa9AADmvQAAAH0AAOa+AADmvgAAAH4AAOa/AADmvwAAAH8AAAAAADoApgEgAWYB4AMWA6QEAgSKBWYGLAceB7oIQgiQCNwJAAlACcwKGgqICtAL6AxwDLgOUA/YEBoQnhD0EVQRyBIEEjgSuhOMFEQU/hWSFhAWqheWGGwY8hmYGlIa+hv2HFIdFB6AHvofaB+MH+YgaiCOILIg4iEmIUohZCG2IfAiYiLmI1YjxCQaJF4kdCTuJPwlliXWJhAm3icAJ4Yn9ihAKMIo1ikkKV4p7CpCKoIqpCsQKx4roCv2LCgsti1SLpQu+DAuMUYxkDHmMpgy4jOSNBg0ljU6NXw2RjZoNsA3CDdoN9g4UjjUOUI5hjnKOi46jjs8O+o8RjywPWg9kj2sPrQ+0j8GP5hADkCmQXZB7kJ8QtZDPkOmRF5EmES0RTRFlEX0Rn5G6kcER1pHrEhYSNpJTEluScZKBkq8Sz5LckuGS8BMBkxgTMBNHk1eTXZNjk3iTjBOek6OTsZO6k9eT7pQMlEIUXJRrlLOU5pUOlTEVXRV5gADAAAAAAPBAwAACwAXACMAACUyFhQGIyEiJjQ2MwEyFhQGIyEiJjQ2MwEyFhQGIyEiJjQ2MwOQFBwcFPzgFBwcFAMgFBwcFPzgFBwcFAMgFBwcFPzgFBwcFIAcKBwcKBwBQBwoHBwoHAFAHCgcHCgcAAAAAAQAAP+AA+EDgAAXACgAOQBFAAABMhYUBisBAw4BByMhIiYvAQMjIiY0NjMFDgEHFRMXHgE+ATc1AzUuATMmBg8BAxUeAjY3NRM1LgEDMhYUBiMhIiY0NjMDrxUcHBVaKQM4KAn+gCg9BgEpWxQcHBQBKRAXAg0BAhkgFwINAxn+EBkDAQ0CFyAZAw4CFw0UHR0U/uwUHR0UAt4cKB39aCg5BDQoCQKYHSgc1AEVEAf+hwUQFQEWEAYBeQYQFAEVDwf+hwUQFwEUEAYBeQYQFgF3HCkcHCkcAAT///9/BAADgQAYAC0AOQBOAAAFIicuAScmNDc+ATc2MhceARcWFAcOAQcGJzI3Njc2NCcmJyYiBwYHBhQXFhcWAyIGFBYzITI2NCYjBTc+AS4CBg8BBhQfAR4BPgImJwIAaF9cjicoKCeOXF/QX1yOJygoJ45cX2h5Z2Q7PT07ZGfyZ2Q7PT07ZGcwDRISDQGPDRISDf5fkQYEBQ0REAWjCAijBRARDQUEBoAoJ45cX9BfXI4nKCgnjlxf0F9cjicoRD07ZGfyZ2Q7PT07ZGfyZ2Q7PQHbEhoSEhoSH6QGERALAwYGuQgYCLkGBgMLEBEGAAAGAAD/gAQAA4AACAARABoAIwAkADAAAAEjIgYdATM1MyUzMhYdASM1IwEjIiY9ATMVMwUzMjY9ASMVIwEzITIVMRQjISI1MTQBQP0cJ03zAYD9HCdN8/6A/RwnTfMBgP0cJ03z/UBAA4BAQPyAQAOAJxz9800nHP3z/E0nHP3zTScc/fMB80BAQEAAAAYAAP/fA+ADQAAPAEsATwBTAFcAWwAAATIWHQEUBisBIiY9ATQ2MwMiJj0BNDY7ATIWHQEUBisBFSEVMzIWHQEUBisBIiY9ATQ2OwE1IRUzMhYdARQGKwEiJj0BNDY7ATUhNRMjFTMlIxUzJSMVMwEjFTMCUBslJRugGyUlGxAbJSUbwBslJRtAAWAgGyUlG6AbJSUbQP2AQBslJRugGyUlGyABYHCgoP6woKACoKCg/sDAwAEAJRugGyUlG6AbJQEAJRvAGyUlG8AbJWCgJRugGyUlG6AbJWBgJRugGyUlG6AbJaBg/sCgoKCgoALgwAAAAAADAAD/2wP9AyEAVACUANMAAAEyFh8BNzY3MzIeAg8BFxYfAhYGDwEGFRQXFhcWHwEWFxYfARUUBg8CFAYPASEiJic3NDY3Njc+AT8BNTQmLwEmJy4BPwE2Ny8CJj8BPgMXIgcGBxQWFxYGDwEOAQcGFh8BHgEXFAcGBwYPAQ4BHQEhNScuAS8BLgEnJicmNTQ2PwE+AS8BLgE/ATY3NicmFyIPARcWDwEXFh8BFgYPAg4BFTQfARYXHgEfAR4BFxUzNSYnJi8BLgInJjU0Nj8BNjc1JyYvASY3NicuAQGiMUQjCAUcOB0tQTQOCwMCBQQDAwcQFCwiERUVLzELMRcLAQMKD8cBCQsF/SANEgEBDBIXHEp7EQYQFCoFBRMQBAIFCQICAQIFCQUlOEgnWSQdAQQDBgYLBQICAQEICiMrGwEZImcqLhUPEQKWAQEJEggbUCMrGikZITQKCAEBDw4EAggCBSEfyDwWBQMVEQMCCgUDBg0TBzAYEwYHEyUbQRgLLCgEpQEDAQYYGEU/HSUZIiYMAQMIBQMIBCEqDycDIBofBwMNAiJKXz8MAQYHBwcXMxUsIQ4BCgwJFAsCCBkMDxJKFRABAQUTEAEBFg89ExcOEggTMRMHAQUVFCkGBhwsFA4aCxEREiIjNB43KBVBOC5MFC0IDBoIAwEDBAkWCyMsKhgfGyMlDwwGBAgDJA8RDQgDAgQZDxMTHiIbLyI0ChQGAQQZDwokJVsuLDAKAwdMYw4BCg0IFzMWCS8ZGwwCBQUOEQsVBQIHICEJJAcHAwEDBBYaFBwgGi0hJQ4KAgEDBgUNDng6FRMAAAQAAP9/BAADgQAoAFAAUQBdAAABMh4BFxUUBg8BBQYPAREUBg8CDgEuAS8BETQvASUuASc9ATQ+ATczBSEjDgEHHQEWHwEFFxYfAREWFx4BPwI2NzUTNzY/ASU2Nz0BLgEnBTMhMhUxFCMhIjUxNAN/ITkjAxYVCP7vDgIBGRcJWhxCPCUCAQwF/u8WGgMfNyAKAv/9BAcSGgMBDQYBFQoeAwEBBwojEAZdEAMBAQcgCAEUDQMBGRL9ujABHzAw/uEwA4AfNSEzGzIRB8oKEQf+sx00EgY7EwQdNiAKAYsRDQTKEC8bCyohNyMDTQEYEgYuEg0FzQkeKgv+cQwJDwkHBD0MEwgBUw0qHAfMDBIHLRIaAnMwMDAwAAAAAwAA/4AEAAOAABgALQA5AAABMhceARcWFAcOAQcGIicuAScmNDc+ATc2FyIHBgcGFBcWFxYyNzY3NjQnJicmHwEHFwcnByc3JzcXAgBoX1yOJygoJ45cX9BfXI4nKCgnjlxfaH1saD0/Pz1obPpsaD0/Pz1obEokx8ckx8ckx8ckxwOAKCeOXF/QX1yOJygoJ45cX9BfXI4nKDM/PWhs+mxoPT8/PWhs+mxoPT/7JMjHJMfHJMfIJMcAAAAE////fwQAA4EAGAAtAE8AWQAAATIXHgEXFhQHDgEHBiInLgEnJjQ3PgE3NhciBwYHBhQXFhcWMjc2NzY0JyYnJgM1NDc2NzY3NjU0JiMiBwYVMzQ3NjMyFhUUBwYHBgcGHQEXMjYuAQYHBh4BAgBoX1yOJygoJ45cX9BfXI4nKCgnjlxfaHpoZTw9PTxlaPRoZTw9PTxlaGAPDBc1Ch1WS1IvLj4YHTgyNBYLED8ODyATHAEbKAwPARsDgCgnjlxf0F9cjicoKCeOXF/QX1yOJyhAPTxlaPRoZTw9PTxlaPRoZTw9/b4SIBkVFC8MJzNFUDMwUTghJTQuHx4MDzkgHCcSkRsmGwENDSYbAAAAAAMAAP+jA9ADZgAwAGIAiwAAARYXFhcWFxYHBgcGBwYHBg8BBgcGBwYHBi8BJicmJyYnJic3Njc2NzY3Njc2NzY3NiUGBwYHBgcGBwYXFhcWFxYXJyYnJicmJyYnJicmJyYvASYnJjc2NzY/AjY3Njc2NzYlFhcWFxYXFhcWHwEWFRQHBgcGBycmJyYnJicmJyYnJicmBzc2NzY3NgO+AgEEAwQBAgICCAkQERodJhIWGiUlLy42MwkLCxAPEw8TDhUbHikpMi83LzcrMCMl/YcDAgcFCQUHAwMDAwsMFhgkDA8QFhYcGR4aHRgaEhUKBAMBAgUFDxEdCAcICxAUGB0iAXsLCxsbJyApHyMUAgMFBg0QGRAVGSIjLSw1Mzs3Pjk/OQYiLUtSbgHwBgYPERgZHx8kIyglKSUpJA8SERgQFQkLBwIDBgkOEhgcJQcIDA8TFhkeICUnLC4z6wsLGyArLDc1PjpBOUE1Oy0EBAcJDA4SFRkcICUpLjMWHB0qJzErMigMBggGCQYHAQGWBAQLDxQZHiQqMAgLDRMTGRoeHg8TFB0aIhwhGh4SFQcICQYgHC0PFQAABAAA/9kDywMoAB8ASwBYAIgAAAEhIw4BDwIXHgEfAREeAjMlNz4BNRE3PgE3NScuAQMXHgEzNzI3MxUXFQ4BKwE1LgErAQ4BHQEjLgE9ATMWMzc+ATc1Fx4BMjY3BzIWFxUHIyc1NDY/AQEyFh8BFQ4BIyIuAT0BJy4BDwEOARUUDgEiLgE9AScuAQ4BBxQOASMuASc/AT4BNwMx/aUHGygHRAEBBCEaCgEbLRsCNggmMAMfJQFJCSy8BRZIKQkSDgICAhoRowIfFoAVHKcRGAISFwkoRhUFFkhUSxZSBggBA4oDBwYDAWQJEANEBEMuIDUgAQMOCAMHCh82PzYgAQMOEAsBHzYgMUQCRAIEDgkDJwIiG+wJFCM+Fwj+9yM5IQEBB0oyAQQBF0wsCPUZH/52CSMpAQXuAgUdKaQWHwIiF54DLR3uBgECLCUBCSMpLSfiCQeTBASQBwoBAQI2DgrqBzA9IjohBAQICQIBAQ0IIjkiIjohBgMICAMNCSI5IgJCM+kECAkBAAAABgAA/6cD0ANZABoAOABOAGEAgQCXAAABNxcWFxYHBg8BBgcGDwEvASYnJic3Njc2NzYBBwYHBhcWHwEnJicmJyYvASYnJjc2PwE2NzY/ATIBBwYHBg8BFxYXFh8BFjc2PwE2NzY3ASMGDwIGBwYfARYfASY/ATY3ARcWFxYXFh8BFgcGDwEnJicmJyYvASIPATc2NzY3MxYPARcWHwEWHwE3Ni8CJi8BJi8CJgO4BgQLAQIaIU0QKjdhXBAQERgaMB4cVFWDXXr9qQYUCQ8PFEgKDC0tSTNEGgUGAQMNECsKChMhLAwgAnoBX59HTy4EDAwJBwJjbx4bDjQiFgz9YAkWFAgHGg0cDQQYVAkjBgEEDgGXGR8jOy49HgcIBQcvCRY6RGhjgm8RGRoRBio7YmoQOq0IFHWBFUVCJwEPAwEGGzkOKjARFncB4BAOLjVTS2NMDyYeNQIBAQIEFSZOCRwpPktjATQZVl2SeJ5jDQQOGik9T2oWICdDPFE7DQwKEQIB/nsBZVUmIRIFEAoHAgEMQRIVCy4+KS4BVwMKBAolK1ZoFnhRCH2lGFFUAQ8ICxIeKDZBEBUfOTwLFDUxSy48BgEDAgYpHzUDAVACBiFPDSw0IQMfGAUNNy8LIBYHCSYAAAMAAP/kA8sDKAAuADsAawAAARceATsBNj8BERcVDgErATUuASsBBw4BHQErAS4BNREXFjsBPgE/ARceATMyNjcDMhYfAQcjJzU0NjczATIWFxMVDgIiLgE9AScuAQ8BDgEVFA4BIi4BPQEnLgEOARUUDgEuAicTNz4BMwKlBhlSLwoVEAICAh4TuQMjGYwGGCC5BRMcAxQaCi5QFwEFGlEvMVUZXQYKAQEEnQQIBgQBlQwSA00DJTtGPSUBAxAJAwgMJD1IPSQBAxATDSQ9Sj0kAU0CBREJAaUKKC4BBQH+8AIGIS+7GiMBAiYatQQzIQEQAQYCMyoBCiguMyz+/goHqAQEpAgMAQKFDwz+9QgkOB8mQiYEBQkKAgEBDwknQSYmQiYGBAkJBA4KJ0EmASM8JwEJBQkLAAMAAP+fA+ADYAAmAFUAWAAACQERFAYHIyEiLgE2PwEhMjY/AREhESEiBg8BERQOASYvARE0NjczEx4BDwEOAS8CJicmNj8CNh4BBg8CMzIeAg4BByMiLgE2PwEzMj4BJicrAQEVMwLNARMyJQn+wAwTAg8MBgFADBECAf8A/mAMEQIBERgUAgEyJQkSCQcFAgcWCwW7BgQHAgoFuwsYEAIJBGjWK0gsAydGK4oMEwIPDAaAJjgEMyYJ1gI2kwNg/u39syU3BBEYFAIBDwsGAiABAA8LBv7ADBMCDwwGAUAlNwT8+wcWCwUJBwUCfQUFCxoIBX0GAxQYCQRFKUdVSi4DERgUAgE1TToEAlOTAAAAAf///6MEAwNjACwAAAEDJyYGDwE1ATYuAQYHAQYdARQWNj8BFxY2NxM2LgEHAQ4CFh8BFj4BJi8BA6a9sAwcCVEBigkCFx4K/m0IFx8LfcAQIwXbBA8aDvxJCQsBCQm3DRwRCA17AwH9H20IBAtegQGyCxwSAgv+RAkN7w8UAgySdwoNEgNVDRcJBv5mAxAUEQRmCAcYHAdFAAAAAwAA/4ADxQOAAAUACwAmAAAJAREJARElBREFJREHFgYPAQURFA4BJi8BESUuAT8BPgEfAQUlNhYCAAHF/jv+OwHF/nsBhQGFQQUFCQX+6hEYFAIB/uoLCAMCBhULBgEYARgMGQOA/wD+AP8AAQACALfc/krb2wG2LgsWCAOU/tgNEgIPDAYBKJQGFQsGCgkEApaWBggAAAABAAD/pwOyA1kAFAAAATcXETMyFhURFAYjISImNRE0NjMhAmBhYEEhLi4h/TwhLi4gAcMBr05OAaovIPzsIC8vIAMUIC8AAAACAAD/gAPFA4AABQAgAAAJAREJAREFLgEHBSUnJgYPAQYWFwURFx4BPgE1ESU3PgECAAHF/jv+OwMJBxkM/uj+6AYLFQYCAwgLARYBAhQYEQEWBQkFA4D/AP4A/wABAAIAUwsIBpaWAgQJCgYLFQaU/tgGDA8CEg0BKJQDCBYAAAEAAP+nA9oDWgBbAAAlHgEXFhcWFxYXFgcVFAYjISImPQEmNzY3Njc+ATc2FQc3NCcmJyYnJicmJzQ2NyY0NzY3Nj8BJj4BNzYzNhcWFxYXFhcWFxYHBgcWFxYVBgcGBwYHBgcGHwE1NAKJEEcjSzIqFw4GBQIXEPyeEBcDGxkoMkojRxACAQIBBA8NIw4MIAMICQYFAREOGAcEBRQRDA0uHHJOKhQYCwQBBwMBAwkEAwMgDA4jDg4EAgEByQkSBQ0gGycWGBUTFhAXFxAVLCwpGR8NBRIJAgEEBRAPJRwZJg8QLTcPEwogThwfHRgUBw0cFQQDAwIJJRQVHSgNCSk6FBUJDQoNNy0QDyYZHCUWCQQDAQAAAAAEAAD/pgPZAzIAFwAgACkAMgAAATIWFREUBiMhBw4BLgE9ASMiJjURNDYzASIGFBYyNjQmIyIGFBYyNjQmISIGFBYyNjQmA4ogLy8g/nbkCRYUDGcgLy8gAZMUHBwnHR3YFBwcKBwcAXYUHBwnHR0DMS4h/cchLqsGAgoTC4suIQI5IS7+xRwoHBwoHBwoHBwoHBwoHBwoHAAAAAAFAAD/pgPZAzIAFwAuADcAQABJAAABMhYVERQGIyEHDgEuAT0BIyImNRE0NjMFISIGDwERFBYfATMVNyEyNj8BETQmJwUyFhQGIiY0NiMyFhQGIiY0NiEyFhQGIiY0NgOKIC8vIP525AkWFAxnIC8vIAMU/OwFCAEBBgUEp84BnwUIAQEGBf57FBwcKBwcsRQcHCgcHAGeEx0dJxwcAzEuIf3HIS6rBgIKEwuLLiECOSEuQAYFBP3HBQgBAZqaBgUEAjkFCAL7HCgcHCgcHCgcHCgcHCgcHCgcAAAAAwAA/6cDsgNZAA8AIwAtAAABMhYVERQGIyEiJjURNDYzBSEiBgcVERQWHwEhMjY3NRE0Ji8BETcXETMRJwcRA2IhLi4h/TwhLi4gAsX9PAUIAgYFBALEBQgCBgXmQUBAgIEDWS8g/OwgLy8gAxQgL0AGBQT87AUIAQEGBQQDFAUIAUH+mTQ0AWf+E2hoAe0AAgAA/64D0wNTAFwAvAAAAQ8CDgEPARQVFwcGBwYPAQYfAQYVFh8CFhcWHwE3BgcGDwEGBw4BBxUUFjMhMjY9ATYnJicmJyYvASYvAzc+AT8BPgE3NC8BJi8BPwE2LwEmJyYnJicmJyYDNzE3NicmJyYvAiYnJic0PwI+AScmPwE2Nz4BPwE2LwE3NhcWFxYXFhcWFRYHDgEfARYXFRYVBwYHBg8CBgcGBwYfASceARcWFxYXFh8BFh0BITUmNjc2PwE2NzYBiwsJBhQYAwEBARkOEgECBgcBEAMiBhQfDQ0DAQIOHw8PJEoxKzABHRUDPhUdAQUGDhkqMkoVFxYZDQUBAxYaFRcaAgQDAgQDAgICBAICAwobHjpEXyQDAgMDAwQPDyAZBw8GAwEBBgcEAQIJBQIBDAkdBwQDAgMMISFjQh8MDwcDBwMBBgoEAgIBAQECBw4FECcQEgQDAwMBBSopJSQ8Jx4QBQr83gEgHyc8FhwWSANQAQECBRgRCAYFBgEVGR4hDjY2BhMbOS4JFiMXGSEVAQgIBAMGDCAbTi0cFB0dFBUTFhkXKhkgDQMEBgcFAxUfLB4XGT8hDwsHBgYDDRUuIhILCycgIBYaBwL9aAQJDiAqIB0lHAoVGAsLAgEGCgcLCTQ1DxQTEBkLCAoKCAECAgcgDg0SGwgHIjIUJg0EAgIBAgIGCAgaEwcSKx8iLSAOCQMQGgoKBAsZExsIFBMPBh81ExkKAwUGEgAEAAD/gAOuA44AFgAtAEIAVwAAEzY3NhcWHwEWFxYHBg8BCQEmJyY3NjcXBgcGFxYfAjc2NzYnJi8BJicmBwYHFyciDgEVFB4CMj4CNTQmLwEuAQcyFh8BHgEVFA4CIyIuATU0PgLkTWhmZWhPC04dHBgZSgz+2v7aTh0cGBlKOkIZGBQVPgv5+EIZGBQVPgw/VlRWWEXxDTdeNh85S1FLOR8aGAkbQzMcMxQHEBIVKDMcJUAmFSczAw1LGxoZGksLUGtoaW1SDf7UASxQa2hpbFMgRFpYWltHDP39Q1tYWltHDEEaGRITO0wBN103KUo5Hx85SyglRBwKGh89FRQIEi8ZGzQnFSVAJhs0JxUAAAIAAP+AA88DjgAVACoAAAE2NzYXFhcWFxYHBgcJASYnJjc2PwEFIg4CFRQeATMyPgI1NCYvAS4BAQRQa2hna01QHBwcHFD+2v7aUBwcHBxQBQEhIj8wGi5PLyI/MBoWFAkYPwMNTRoaHR5PUm9ra29S/tQBLFJva2tvUgWJGjA/Ii9OLhowPyIfOhcJGBoAAAQAAP9/A9cDgQAcAFwA3wEhAAA3ETQ2OwEyPwE2PwIRIi8BJi8BJi8BJgcjIiY1ATIXFh8BFhcRBgcGBwYuAS8BJi8BLgEvASYvAS4BKwEiLwImLwEmJxE/ATY3Nj8BNjcyFzsBMjY/BTYXMx8CFh8BFh8FFh8BFhceARUXFh8BFh0BFA8BBg8DBg8DBg8BBg8BBg8BBg8CBisBIiYnJi8BLgE/ATY3Nj8BMj8CNj8DNj8CNj8BNjc0PgI/ATQnJjQvCCYvAiMiJy4BLwImND4DOwEXMhcWHwIWHwEWFxUXFhUXFhUHBg8CBg8CDgEPAQYnIyIvASYvATY/AjY/ATY0Ji8CJi8BJi8BPwE2NzYzQgQGkAIDCgsJxjUDBDMFBrcQCgkOK1oDAwHACwUIBhIJAQEOCQwKFBcTEwsFCQUWBRkMFnEEBgmMBQIDBgsJEAQBAgICBAkPBA4ZDx8YNwUDBGaiCA0IA5EGFRcvCRIKBQsLGUgRDQIDBwQEAwMFAQECBAICAQIGCwcIBgslBwkGCRQMRxQNEQgRCQQCAgMLCwcEAgECAQIBAwoGDwsDAzsXDRIPIggMBQwFDQQHBQECAQIBAQMBAQ0YFRYQFxEEHhEmHQQCAwgKBAEBAgYHCgUGBRoIEg0MER4BAgYBAQIBAQEBAQEPBwMFCBADEgQaBQsCAwICCgYEAQcwBwUHBwUJCAMTBxASBAECAwYDBQcNvgF7BAIBBAYHsC38pAQrBgSdDQICAwEBAgLCAQEEEQwO/GITDQoEBAIKEREIBQgFEQYVCBRiBAMBAQEFCRUJCgGVCwUHBQ8IAgYCAQEDWpAGBgICdwUGEgUKBQMIBxNQHBoDBxEIDwoGAxUDBw0aEh8ODQ4KDRsiDhUKFDQIDAUIEwksCgQFBAMCAgEEBwQFAwcDBQUMBgQDAwEXDQgODCMKDwgUChgOFw8IAwgICwM0EAwCDAMwNyAbERQNAxQHDgkBAwgHAQMICgwIBQHcDAkKEi8DBRICBQUDAwMJCwcWCwMvDgYGCxMEDgMPAQEBAQUKDwwJJggGDhIVHiENBhYHCg0HCAUNCQQDBAAAAAQAAP9/A9cDgACBAMQA/QEYAAABHwIWHwEWHwUWHwEWFx4BHwEWHwEeAR0BFA8BBg8EBg8DBg8BBg8BBg8BBg8CBisBIiYnJi8BJjQ/ATY3Nj8BMj8CNj8DNj8CNj8BNjc0PgI/ATQnJjQvByYvAiMiJy4BLwImND4DMxcyFxYfAhYfARYXFRcWFRcWFQcGDwIGDwIOAQ8BBiMnIi8BJi8BNDY/AjY/ATY0Ji8CJi8BJi8BPwE2NzYzAzIfAhYXFREUBwYHBi4BLwEmLwMuAScjIi8CJi8CJic1ET8BNj8BNjcyFzsBMjclPwMPAg4BKwEnIwYjDwERFzMyHwgRApUSGTAJEgoFCwsYSBINAgMHBAQDAgEFAQECAQMCAgECAwQKBwgGCyYGCgUJFAxHFA4QCBIIBAICAwsLBwUBAQMBAgMKBg4MAwM7Fw0SDyIIDAULBg0EBwUBAgECAQEDAQENFxYXDxcVHhEmHQQCAwgKBAEBAwcHCgUGHwgSDQwRHgECBgEBAQIBAQEBAQ8HAwUIEAQRBBoFCwIDAgIKBgQFAzAGBQgHBQkIBBIHEBIEAgEDBgMFBw2rEQcGEgcCDgkMChQXEywFChIogwQEBpEFAgMGCAYGEAMCAgMIDwoOGQ8fGDsDAgELCA0FBnceagoZDEglDwkGBAECgx0TB4oOJQ0YFQgDCQQHEwQKBQMIBxNQHBoDBxEIDwoGAxUDBwgGJQYfDg0OCg0OEB8PFAoVNQYMBQgTCSwKBAUEBAECAQQHBAUDBwMFBQwGBAMDARcNCA4MIwoPCBMMGAwZDwcDCAgLAzQQDAIMAzA0IxwQFBAUBw4JAQQHBwEEBwoMCAUB3AwJChIvAwUSAgUFAwMDCQsHFgsDLw4GBgsTBA4DDwEBAQEFCg8FDQMmCAYOEhUeIQ0GFgYLDQcIBQ0JBAMEAVMDAxEJCwf8YxMNCgQEAgoRJgUIDyJyAwIBAQEBAwUGFQcHBQGVCwkRCwUGAgEC7AYGAQKyGl4JCgEBAQH+egIMBncMHwoWEQgDagAAAAAC////nwQEA2cADgAiAAAJAQYPAQ4BJwMmNjcBNhY3AQYWHwETHgE2PwEXFjI2NxM2JgM//nEMAhIBCQRNAgUGAfkYBXn8WigCKONcAhsgCXfpDCMWAasFHQKX/nANE7oPAQ8BBQgPBQFWEAev/moRKw5M/s0SFQYOhMANGxADYR8cAAAC////fwQBA4EAIABbAAABFgYHBg8BDgEuAjY/ASEiJjQ2MyEnLgE+AhYfARYXJRYOASIuAT0BND4CMyEyHgEVERQOAiMhIi4CPQE0PgEyHgEHFRQeATMhMj4BNRE0LgEjISIOARUC0QUBBgMEtQgXFhAGBghv/hARGRkRAfBvCAcGERYXCLUGA/2EAQsVFxQLHjhJKAJyNls2HjhJKP2OKEk4HgsUFxULAR80HwJyHzQfHzQf/Y4fNB8BkwoWCQYFtQgGBhAWFwhuGSMZbwgXFhAGBgi2BQjXDBQMDBQMTydKOB42Wzb9jihJOB4eOEkoTAwUDAwUDEwfNB8fNB8Cch80Hx80HwAC////gAQAA4AAJwA3AAABIgYVERQGIyEiJjURNDYzITI2NCYjISIOARURFB4BMyEyPgE1ETQmBTI3ATY0JiIHASIOAR4BNgPYERckGf0ZGSMjGQHgERcXEf4gJkAmJkAmAucmQSYY/hgRCwHYCxchC/4oDhYHCxcbAhQXEf4gGSMjGQLoGSMXIhcmQCb9GCZAJiZAJgHgERi9DAHYCyEXC/4oEBsZDgQAAAAADgAA/4AEAAOAAAMABwALAA8AEwAXABsAHwAjACcALQAxADUAOQAAESERIRczFSMBESERAyM1MwUzNSMDIREhFzMVIwEjFTMBMzUjNxUzNRcjFTM1IzUzNSMhFTM1ATM1IwHi/h548fEBpgHiePHx/S14eLUB4v4eePHxAtN4eP7TeXl5eHl58Xh4eP6Wef4eeHgBngHiePEBaf4eAeL+l/G1ePy1AeJ58QLTeP0tePHx8fF48Xh5eXn+03gAAAAAA////4AEAAOAABoAQwBNAAABDgEHBgcGIicmJyMuAS8BERQWMyEyNjURFQYDIzU0JichDgEdASMiBh0BFxYXHgEXMzY3NjIXFhc+ATc2NzY/ATU0JikBNTQ2FyE2FhUDqUW6agUJFDoUCQUDkudABjcmA0UnNiI6kB8Y/kgYH5AmNwEHJTjXhgQEBhQ5FAMGZLBBOCIOCAE2/uD+rAoGATMHCgE0Gx8ECwkUFAkLBTctBP56Jjc3JgGEARcBhnEYJAQEJBhxNiahAh0aJjEFBgYUFQMJAx4ZFR4MEgGrJjY+BwoBAQoHAAIAAP/ABAADQAARACIAABMXNjc2MzIXFhcWFRQWHwEHARcBISImPwE2NzY3Njc+ATU0KLInO0NXaExAIx8OD9co/CiqAq381hAOBQQCBgcLKRcYFgNAmTshJjYvTkVGdJszuDEDT9T9sxIOCgYHCAgbLjKsjycAAAMAAP+ABAUDiAACAAYAGAAABScDAScBFwE2JyYvASYnJicmBwYPARc3NgEisnADXrj9678CpRAHAwYPEhQbGSMjEgtfwSwuBK/+1QKsvv3yxgKnEiERDg8TEhkSGQoFCl/ALTAAAAAAAv///58EBQNgADEATgAAARYXFh8BBR4BBwYHBg8BExYGDwEiJyYvAQcGByMuAScmJyY1EycmNjc2NyU3PgE3MzIBNzYfAQMmNj8BJS4BLwEHJw8BBgcFFyMfAgM3AiELBQgFhAEEHSEFAwMFB7YgAyAbCA0GCgry7wsMCBUjCQUBASC2EwIVFQ4BBYMIHhIIEv7j7xsh8yADCQu2/vwQGQWEBAGLBQ0Q/vwBAsECAyMGA1gHBQcJ4zQFMh0MBgkIv/7+GysGAQEBBWxsBQIBFhMHCwYOAQLAFToTDQQ04w8TAvyGbAsLbAECDx4KwDUCEw3jBgLuBQsDNQHMBQf+5QIAAAAK////3wQBAyEADwAfAC8APwBPAF8AbwB/AI8AnwAAEyMiBhURFBY7ATI2NRE0JiEjIgYVERQWOwEyNjURNCYBMzI2NRE0JisBIgYVERQWITMyNjURNCYrASIGFREUFjsBMjY1ETQmKwEiBhURFBYhMzI2NRE0JisBIgYVERQWByMiBh0BFBY7ATI2PQE0JiEjIgYdARQWOwEyNj0BNCYhIyIGFxUUFjsBMjY9ATQmISMiBh0BFBY7ATI2JzU2JkA3BAUFBDcEBQUDszcEBQUENwQFBfyggAQFBQSABAUFAXM3AwYGAzcEBQWUywQFBQTLBAYG/uA3BAUFBDcDBgZXgAMGBgOABAUFASI3BAUFBDcDBgYBIcsEBgEFBMsEBQX+RDYEBgYENgQGAQEGAyAGA/zSAwYGAwMuAwYGA/zSAwYGAwMuAwb9VwYEApYDBgYD/WoEBgYEApYDBgYD/WoEBgYEApYDBgYD/WoEBgYEApYDBgYD/WoEBksGBDkDBgYDOQQGBgQ5AwYGAzkEBgYEOQMGBgM5BAYGBDkDBgYDOQQGAAAD////gAQBA4AAMwBdAH8AAAEzFSMiBhQWOwEVFBYyNj0BMzI2LgErATUzMjYuASsBNzY0JiIPAScmIgYUHwEjIgYVHgETIgcOAQcGHQEUFxYXFhcWFRYHBgcGBwYXFhcWMyEyNz4BNzY0Jy4BJyYDIQYmNzY/ATY3NicmLwEmJyY1NDc2NzYyFxYXFhQHBgcGAVSIiA0UFA2IFBsUhw4UARMOh4cOFAETDlJYCRMeCX59Ch0TCVdXDRQEFbloX1yOJygEBhMZLhMBDggWGAkOAgMUEhIBpmhfXI4nKCgnjlxfaP6xHAoJBw0LGAUECQURDDgXEjw6ZGbwZmQ6PDw6ZGYBkkUUGxRPDhMTDk8UGxRFFBsTWAkeEwp9fQoTHglYEw4OEwHuKCeOXF9oBDAfODA9MRUSEBAKExQLExMVDQwoJ41cX9FfXI4nKPxIAQ0LCAkIERIPEgsWEVJMOjp4ZmQ6PDw6ZGbwZmQ6PAAAAAj///9/BAIDgQASACYAMgBAAFMAZwBzAH8AAAE2FhcWFREUBiMhIiY1ETQ2MyEVISIGDwERFBYfASEyNzY3NRE0JgUyFhQGIyEiJjQ2MyUyHgEUDgEnISImNDYzAzIXHgEXEQ4BIyEiJjURNDYzIRUhIgYPAREUFhczITI3Nj8BETQmBTIWFAYjISImNDYzJTIWFAYjISIuATYzAX8TIg0bNib+3SY3NyYBI/7dCw8CAQ0KBgEjDAgGAhECUg4VFQ7+aQ4VFQ4BlwoRCgoRCv5pDhUVDscnGw0OAQE2Jv7dJjc3JgEj/t0LDwIBDQoGASMLCQYCARECUQ4VFQ7+aQ4VFQ4Blw4VFQ7+aQ4UARUOAVkBDg0cJv7fJjY2JgEhJjdBDAoG/uALDwIBCAYJBQEhDBH+FRwUFB0U5wkQFBAJARQcFQJ9Gw0iEv7fJjY2JgEhJjZADQoF/t8KEAIIBggGASAMEf4UHRQUHRTnFB0UFRwUAAX///+/BAEDAAATADAATQBaAGMAAAEyHgEVERQOASMhIi4BNRE0PgEzASYiDwEGIi8BLgEPAQ4BHQEUFjMhMjY1IzU0JicDISIGFRE1Nj8BNhYfARYyPwE2Mh8BHgEXMxE0JgUyHgEUDgEiLgE0PgEXIiY0NjIWFAYDjh80Hx80H/zkHzQfHzQfAqgUNxOdEzcUNhI4E8UTHSEYAxwYIQMaEwb85BghCwbEIlgiNwQUBJwjWyJ9AwgDAyL9PB41Hh41PTQfHzQfGCEhLyEhAwAeMx79nh4zHh4zHgJiHjMe/qUNDbkNDSYPAQ16DTIXFhchIRfIFzUMAXohF/4rAQsCehcCGCYEBLcXF1YCCAEBIBchbx4zPDMeHjM8Mx6nIC8gIC8gAAAAAwAA/4AEAAOAABMAOABYAAAXIi4BNRE0PgEzITIeARURFA4BIwEiBw4BFREUHgEzITI+ATURNCYnJgcVBhURFAYjISImNRE0JyYFMhYdARQWOwEyNicRNCYjISIGFREUFjMhMjY3NTQ2N+c/aj4+aj8CMj9qPj5qP/1vAwMcICVAJgJeJkAlIBwFBgUsIP28Hy0FAwH/GSMIBUAMEQEHBf28BgcRDAFSBQcBIxmAPmo/AjI/aj4+aj/9zj9qPgOMAhM7If2yJT4kJD4lAk4hOxMDAgECB/7THisrHgEuBgMBXiUZnQYHEQwBSwUHBwX+tQwRBwWdGiQBAAAABAAA/4AEAQOAAAwAGQBCAGMAACUyHgEUDgEiLgE0PgEhMh4BFA4BIi4BND4BATMeAR8CEx4BHwEzIRceARQGDwEFJy4BLwEDJyYvAisBLgE0Nj8BBTMeARcVBwMOAQ8BBSMuAScmNzY/AgMjLgE1NDc2NzMBShsuGhouNi0bGy0CFxstGxstNi0bGy39KwgiNQoDJD4CCgcFBAJQBQ4TEAwI/a4IITQKAz4kBQ8FBDEGDhIPDQcDZQouPgIBRQg5Jw39tgsQFQECDQgKCBlRCxEVAgUNEkIaLTQtGhotNC0aGi00LRoaLTQtGgM+AyogC83+UwgMAgIBAxUbFAQBAQEDKiAKAa/LEAcBAQMVGxQEAmsEOisMCv65Hy8FAiMCFA0RCwgDAgIBowMSDhEIDQQAAAACAAD/gAPBA4AARgCnAAABMzI2PQEzMjY9ASEVFBY7ARUUFjsBFBcWFx4BFxYPAQYHBhUjIgYdASMiBh0BITU0JisBNS4BKwE0JyYvASY3ND8BMTY3NgcGBwYHBgcGByMGFxYXFiMXFhcxFhcWFyM2LwEmLwEmNTY3Njc2PwE2NzY3NSMVFhcWHwEWFxYXFhUUDwEGDwEGFyM2NzY/ATY/ASI3Njc2JyMmJyYnJi8BJicmJyEGBwYDPAQUHCAUHPyAHBMgHBQEHiBBFxoBAR8BSyUiBBQcIBMcA4AcEyEBGxQEIiVLAR8BDSg/IB2kAwMJCw0PHgUBAwUHHBkCBBIIKRMLAVICMwIEESIWAQgEFAsXCgcEAgHRAQMDBwsWDBMECRUjEAUCMwJTAQsTKQYJCwQCGRwHBQMBBR4PDQsJBikTCwEBwAELEwLZGxMlGxMmJhMbJRMbWEdONBQbCBAaATRSS14bEyUbEyYmExslExteS1E1ARoQCA4kNE1GrgQDCgoODSEWFhYlGxcDEAsmVDE1TkcDBxQrHC8bKxQdEB0NCQkHBgUFBgcJCQ0dEB0UKxsvHCsUBwNHTjUxVCYHCgoDFxslFhYWIQ0OCgoHJlMyNDQyUwAACP///38EAQOBABMAJwA6AE0AYgB1AIkAnAAAATIeAR0BFA4BKwEiLgE9ATQ+ATMFMh4BHQEUDgErASIuAT0BND4BMyUjIgYHHQEUFhc7ATI2PwE1NCYFIyIGDwEVFBYXOwEyNjc9ATQmAzIeARURFA4CKwEiLgE1ETQ+ATMXIyIGDwERFBYXOwEyNjc1ETQmJTIeAR0BFA4BKwEuAj0BND4BMxcjIgYHHQEUFh8BMzI2PwE1NCYBYiE2ICA2IewgNiAgNiADFCA2ICA2IOwhNiAgNiH+xOwUHwMbFAfsFR8CASACEewVHwIBHBQH7BQfAyAWIDYgEiErGOwhNiAgNiHs7BUfAgEcFAfsFB8DIP3CITYgIDYh7CA2ICA2IOzsFB8DGxQH7BUfAgEgAVkgNiDtIDYgIDYg7SA2IJ4gNiBPIDYgIDYgTyA2IF4bFQbtFB8DGxUG7RYgnhsUB08UHwMbFAdPFiADBSA2IP52FywhEiA2IAGKIDYgQBsUB/52FB8DGxQHAYoWIEAgNiDsIDcgAR83IOwgNiBAGxQH7BUfAgEcFAfsFiAAAAAEAAD/gAPcA4EAMABDAFMAXAAAATEuAgcOAh0BITIeARURFA4BIyEiLgE1ETQ+ATsBNTY3Njc2MzIXHgEXMRQGIiYBLgI+Ah4CDgEHFRQGIiY1ASIGFREUFjMhMjY1ETQmIwEyNjQmIgYUFgMLCVeFSURuPwJ+HzQfHzQf/SgfNB8fNB8VAS4tTk9dVkxKXggUHBT+0yQ0FhIyRkg0FRE0JBQcFP6/FyIiFwLCFyEhF/6fHCgoOCgoAl5FbTcICEdvQEMcMR3+Vx0xHR0xHQGpHDEdQ1dKSCsrJyWFUQ0TE/4xCC9BRDEUEDBBRDIJYw0TEw0Bnh8W/m0WICAWAZMWH/8AJjUlJTUmAAAAAv///6QD3AOBAF8AcAAAAQYHBgcGJyY/ATY3NjU0JwYHDgImJyYHBgcGBwYVFBcWFxYXFgcGJyYnJicjIiY9ATQ2OwE2NzY3Njc2FzMyFxYXFhczMhYdARQGBw4CBw4BKwEuATQ2NzMyFz4BNwUuAT4BFxYyNzYeAQYPAQYiA2IZIQYLEAwQDwkTBwuHAgUNO1NaKB0oLB4aDxENCBIMAgMKDw4KBiIaTBMaGhMeES4vSE1gGBoOcVtWODYSHxIaGBIZaZRWBRcOWhIZGRJaFA1zryT92QgECxIIPXk+CBILAwgBSZQBDConBwUHCg4cFioZKTSHhhAQLEQkAhQNBQQZFhsfIDApFyEWCQ8LCgYEBycrGxK0ExpaSk0xNA0FATIuU1BkGhOzEhoBVIlbEQ0RARokGgEQFphvbQYSDwQFKSkFAw8TBQEwAAAIAAD/9AQAA0AADAAYACAALQA5AEEAagCIAAABFBY7ATI2NCYrASIGBSMiJjQ2OwEyHgEGJSIUOwEyNCMFFBY7ATI2NCYrASIGBSMiJjQ2OwEyFg4BJSIUOwEyNCMTISIuAT0BFxYzMjY0JiMHBisBNTQ+ATMhMh4BHQEjIgYUFjsBFRQOAQEVFBYzITI2PQEuATQ2NzU0JiMhIgYdAR4CFA4BAXUKB/QHCgoH9AcKAQX0DRMTDfQNEgET/v8CAvQCAv77Cgf0BwoKB/QHCgEF9A0TEw30DRMBEv7/AgL0AgL3/R4nQScyAwsbKSkbCAwHJSZCJwLiJ0EnJhspKRsmJ0H8sygcAuIcKC47Oy4oHP0eHCgkPCQkPAH4BwoKDQoKJhMaEhIbEiEHB7kHCgoNCgomExoSEhoTIQcH/rMqSCrPEgEwQjABArkqSCoqSCq5MEIwuSpIKgEOciEwMCF0DVRqVA10ITAwIWwDK0VQRSsAAAAEAAD/gAQBA4AADAAZAEIAbAAAJTIeARQOASIuATQ+ASEyHgEUDgEiLgE0PgEBMx4BHwITHgEfATMhFx4BFAYPAQUnLgEvAQMnJi8CKwEuATQ2PwEFITMeARcVBwMOAQ8BBSMuAjY/AiU2PwETNTYnJi8BIyEnLgE0Nj8BAUobLhoaLjYtGxstAhcbLRsbLTYtGxst/SsIIjUKAyQ+AgoHBQQCUAUOExAMCP2uCCE0CgM+JAUPBQQxBg4SDw0HAQMCdAknNAIBOggwIQv+EAoNEgIODAcFAfAQCQI6AQkDBAQD/YkGDhIPDQdCGi00LRoaLTQtGhotNC0aGi00LRoDPgMqIAvN/lMIDAICAQMVGxQEAQEBAyogCgGvyxAHAQEDFRsUBAJrBDorDAr+uSAuBQIjAhQaFgQCASMDDgUBRAYPCwQCAQECFhoVBAEAAAAE//f/jwQJA2IATQCNAJoApwAAARYXHgEHBh4CFx4BFxYHDgEHDgMXFgYHBgcGJicuASIGBw4BJyYnLgE3Ni4CJy4BJyY3PgE3PgMnJjY3Njc2FhceATI2Nz4BFwcOASYvAQYPARcWBg8BDgEPARUGHwEzHgEfAR4BDwEXFh8BNz4BFh8BNj8BJyY+AT8BNTYvAi4CPwEjJicHIg4BFB4BMj4BNC4BBzIeARQOASIuATQ+AQKrWkgIBQQOBidAJgsQARISAg8LJkAnBg4EBQhIWgoVBxhGTkYYBxUKWkgIBQQOBidAJgsPAhISAg8LJkAnBg4EBQhIWgoVBxhGTkYYBxUHAit0di0MMCoSAQsIFAYWQikRBwUCAypGFwgVDgkEASkvEwIrdHYtDDAqEgEQHlE7DwcFAgM8ViQNBAEpL7s/aj8/an5qPz9qPytJKipJVkkqKkkDXiA+BxULJE1ELAYCDwteXgoQAQcsQ00lChUHPiAEBgkeISEeCQYEID4HFQolTUQsBgEQCl5eCw8CBixETSQLFQc+IAQGCR4hIR4JBkcCLCEaKQwUHg0DKlYmDSU3DgUBMTIaCzMkDCZVKhEBIBUJAiwhGykLFB4NAzx1WRMEATIyGQEQVXM9DyAWsj5rfmo+Pmp+az5JK0lWSCsrSFZJKwADAAD/fwQAA4EAEwAnADcAAAEyHgEVERQOASMhIi4BNRE0PgEzBSEiBg8BERQWHwEhMjY/ARE0JicDNh4BBg8BCQEuAT4BHwEFA1UvTi4uTi/9Vi9OLi5OLwKq/VYhMAQBLCAKAqohMAQBLCBGDB8SAQoF/rr+ug0EEhoNBQEZA4AuTi/9Vi9OLi5OLwKqL04uVSwgCv1WITAEASwgCgKqITAE/vgLBRseDAX+7QETCiMbBwcE7QAACf///5UEAQNAAD0AUwBnAGgAdAB1AIEAggCOAAA3NTQ2Nz4BNzY/ATYnLgE1JicmNDc2MyYnJj0BNDY7ATIWHQEUBwYHMhcWFAcGBxQGBwYfARYXHgEXHgEdARMyHgEVERQOAiMhIi4CNRE0PgEzBSEiBg8BERQWFzMhMjY/ARE0JicFOwEyFTEUKwEiNTE0BzMhMhUxFCMhIjUxNBc7ATIVMRQrASI1MTSACg0HLw8aTwICBA8ZCAYFAQMJBQEBPC0OLTwBAQUJAwEFBggZDwYGKy4QDy8HDQr3Jj4lFSYyHP0SHDImFSU+JgLu/RIbJgMBIxoIAu4bJgMBIxr+1iDrICDrICogARUgIP7rIFUgwCAgwCBrDhgZCQUVCAckCQsICzMRBBUQEQUICggFDA8pMzMpDwwFCAoIBREQFQQRMwsODhMTBQgVBQkZGA4C1SU+Jv1nGzInFRUnMhsCmSY+JUQjGgj9ZxonAyIaCAKZGyYD5iAgICCAICAgIIAgICAgAAYAAP+/A8EDQQAlAE0AeACjAM8A+gAAJSImJyY+AhceATY/AT4BLgIGDwEGLgE0PwE+AR4CBg8BDgEBIiYnLgE2PwE+ARYXFg4BIicuAQYPAQ4BHgI2PwE2MhYUDwEOASMVIi4CNDY/AT4BMhYXFg4BIicuASIGDwEOARQeAjI2PwE2MhYUDwEOARMiBg8BDgEUHgIyNj8BNjQmIg8BDgEiLgI0Nj8BPgEyFhcWMjY0Jy4BEzEiJicmNDYyFx4BMjY/AT4BJicuASIGDwEGIiY0PwE+ATIeAhQGDwEOAScGFBceATI2PwE+ATQuAiIGDwEGFB4BPwE+ATIWFx4BBg8BDgEiJicmIgI9JUYbBwEOFAgbR0gavBsSEjVIRxufBxUPB54lYmJJGhokvBxG/qUlRhwkGhokvCViYiUHAQ8UCBtHSBq8GxISNUhHG58HFg8InxtGJShJOB4eHLwcSVBIHQkBFBsKEjA0MBK8EhQUJDA0MBKeCxwUCp4cSpUlQhq8GRwcM0NIQxmfBQoOBZ8VNjo2KhYWFbwUNzo2FQUOCwUaQ1YnShwKFB0KEy80MBK8GRISGRIwNC8TngscFAqeHEpPSTgeHhy8HEmoBgYZQ0lCGrwZHBwzQ0hDGZ8ECg0FnxU2OzUVHRMTHbwUNzo2FQUO/xwcBxUOAQcbEhIbvBtHRzYSEhueCAEPFAifJBoaSWJiJbscHP7KHBslYmIluyUaGiUHFQ8HGxISG7wbR0c2EhIbnggPFgefGxwJHjhJUEgdux0eHh0KGxQJEhQUErwSMDQwJRMTE54LFRwKnxweAjkcGrwZQ0lCMxwcGZ8FDgoFnhUWFik3OjYVvBUWFhUFCg4FGhz+/R4cCh0UChIUFBK8GUNDGRIUFBKfChUcCp8cHh44SVBIHbsdHl8FDgUaHBwavBlDSUIzHBwZnwUOCQEFnhUWFhUcTEwcvBUWFhUFAAAABQAA/40D+ANzACAALQA5AEUAUwAAASIOARQXFhcOAh0BFBY7ATI2JzU0NzY3NjMyPgE0LgEDIi4BND4BMh4BFA4BASMiBhQWOwEyNjQmJyEiBhQWMyEyNjQmNzQmIyEiBhQWMyEyNjUB5E2CSyYlP2CUUhQMAw4QAjc2XF9vTYFLS4FNPGU6OmV4ZDs7ZAG48Q4REQ7xDhERDv67DhISDgFFDhEREREO/mkOEREPAZYOEgNzR3mPPjwkHoS1ZCALEBMNHmxfWzc4RnmReUf+KjdecV43N15xXjf+KxAbEBAbELAQGxAQGxCTDRAQGxAQDgAAAAP///9/BAADgQAYAC0ARAAAATIXHgEXFhQHDgEHBiInLgEnJjQ3PgE3NhciBwYHBhQXFhcWMjc2NzY0JyYnJhM2Fh8BFgYHAwcGJi8CJjY3NhYfATcCAGhfXI4nKCgnjlxf0F9cjicoKCeOXF9oeGdkOzw8O2Rn8GdkOzw8O2RnKRErEQUNAg7zBhEtEIoFDAUPEjARXckDgCgnjlxf0F9cjicoKCeOXF/QX1yOJyhGPDtkZ/BnZDs8PDtkZ/BnZDs8/uQMAg8GESoP/vsFDgMQiwYSKg4RARFe2QABAAAAAAQAAqUAEQAAJTMBJiIGFBcBFjI3ATY0JiIHAegw/iIKHBQKAd4KHAoB3goUHAqZAgELFh0L/f8LCwIBCx0WCwAAAAAE////fwQBA4EAEAAhAC8APAAAASIOAhQeAjI+AjQuAgcyHgIUDgIiLgI0PgIBISIOARQeATMhMjY0JiciBhURFBYyNjURNCYCAGa8kE5NkbzMvJBOTpC8ZlmhfUNDfKOwo3xDQ3yjASn+XgsSCwsSCwGiERcX4hAXFyAXFwOATpC8zbuQTk6QvMy8kE5GQ3yjsKN8Q0N8o7GhfUP+bQoSFhIKFyAX0hcR/l4RFxcRAaIRFwABAAD/fwPlA4AATwAAASYiBwEOASImLwEuATY3AT4BMhYXHgEGBwEGIiY0NwE+AS8BJiIHAQ4BFh8BHgEyNjcBPgEmLwIuASIGBwEGBwYXFh8BHgEyNjcBPgEnJgPVDCIM/m8fUFdQHwMpHhknAboTMDUwExgSEBj+TQ4lGw0BsQwBCwIMIwz+TxcSDxYEEi8yLxEBtScdGyYDAh5OVU8e/k04FRUSEjYLKm54bioBkgwDCQMBqQwM/m0fISEfBCltbyoBvBMUFBMYQ0Ma/kUOGyYNAbIMIQ0DDAz+TBdAQBkEEhQUEgG1KWtsKQMHHiEhHv5IOE1KS046DCswLioBlAsfDQMAAAABAAD/gAMlA4AAEQAAATUBFhQGIicBJjQ3ATYyFhQHARkCAQsWHQv9/wsLAgELHRYLAWgw/iIKHBQKAd4KHAoB3goUHAoAAAABAAAAAAQAAqUAEQAAATMBBiImNDcBNjIXARYUBiInAegw/iIKHBQKAd4KHAoB3goUHAoCZ/3/CxYdCwIBCwv9/wsdFgsAAAAC////fwQAA4EAEwAZAAABMh4BFREUDgEjISIuATURND4BMwkBJwcXAQMARnVFRXVG/gBGdUVFdUYCQ/5brCXUAcUDgEV1Rv4ARnVFRXVGAgBGdUX/AP6SjTfoAdwAAAAC////fwQAA4EAEwArAAABMh4BFREUDgEjISIuATURND4BMwUhIg4BBxURFB4BFzMhMj4BNzURNC4BJwMARnVFRXVG/gBGdUVFdUYCAP4AMlY1AzBTMgsCADJWNQMwUzIDgEV1Rv4ARnVFRXVGAgBGdUVAMFMyC/4AMlY1AzBTMgsCADJWNQMAAQAA/4ADJQOBABEAAAE1AQYUFjI3ATY0JwEmIgYUFwLn/f8LFh0LAgELC/3/Ch4WCwFoMP4iChwUCgHeChwKAd4KFBwKAAAAAgAAAAAEAAKAAAQACQAAARUFFyUBBSE1JQQA/OBc/sQCxAE8/AADIAEgPASg4AFg4DwEAAL///9/BAADgQAXADQAAAEiDgIVFBceARcWMjc+ATc2NCcuAScmEwYiLwEHBiImND8BJyY0NjIfATc2MhYUDwEXFhQCAGa8kE4oJ45bYNBgW44nKCgnjltgbwsdC6SkCx0VCqSkChUdC6SkCx0VCqSkDQOATpC8ZmhgW44nKCgnjltg0GBbjico/SkKCqSkChUdC6SkCx0VCqSkChUdC6SkCSAAAv///38EAAOBABgAHgAAATIXHgEXFhQHDgEHBiInLgEnJjQ3PgE3NgkBJwcXAQIAaF9cjicoKCeOXF/QX1yOJygoJ45cXwGr/lusJdQBxQOAKCeOXF/QX1yOJygoJ45cX9BfXI4nKP8A/pKNN+gB3AAAAAAE//sAAAQGAwEAFQAwADkARgAAExYXFhcWMjc2NzY3JicmJyYiBwYHBgEiJyYnJicmNzY3Njc2IBcWFxYXFgcGBwYHBgMiBhQWMjY0JgMiLgE0PgEyHgEUDgFbIStES2LQYkxDKyEhK0RLYtBiTEMrAYSPgl1OKBgJCRcpTl2CAR6CXU4oGAkJGChOXYKPIzIyRjIyIy5PLi5PXE8uLk8BgDg0US8/Py9RNDg4NFEvPz4wUTT+SFtCazcuExMuN2tCW1tCazcuExMvNmtCWwHVMkYyMkYy/wAuT1xPLi5PXE8uAAAB//0AAAQDAoEAVQAAASYnJiIGBwYHBgcGBwYiJyYnJicmJyYnJiIHBgcOAR8BFhcHBhUUFhceATY/ARYXBwYWFzMyNj8BFjcXHgEzMjY1PgEvATY3FxYyNjQvATY3Nj8BNiYD7Q0GCxMRBAojKzNBQU+RT0FBMi0fDQwHChELBg0PBQ4GMS5GEwgFBhodCVlGRiAFFRcMEhwFIFFIIAUcEgYGExIFIFM5Wg4pHQ5NJB0bCgYKCAJzBwIECgkQIislLxohIhswJCsfEQYDBAQDBg8pDgc1KlMJHQkSBQkHBwlgMxpyFSYFFw9zCQlzDxcCBAUnFHMjKVkOHCkPUxscGQ8HCSgAAAAC////gAQAA4AAPQBPAAAFMiQ3IwYHBiMiJyY1NDc2NzYzMhcWFRQHBiMiNTQ3EyMHJiMiBwYVFBYzMjcWMzI3NjU0JyYjIgcGFRQXFhMiJjU0NzYzMhcWFRQPAg4BAhCfAQlIXzhfa4/Gc4AhID16vLFpYklAPyYRYFgUIWJ6WF1sVGVGCFZpWltye9bqlpCQjJczNUZAWSgbFwoEHhFhgIN8UTA1bXfKXVJQP35pYZOBX1EiGDwBaE1ob26cWnVeW3J6krF2gpuQ2eeMiQEnQjh5V1YhHCUHKhJxN1MAAAX///9/BAEDgQATACwANQA+AEcAAAEyHgIUDgIjISIuATURND4CFyIHBgcOAQ8BERQWHwEhMjc+AjQnLgIBHgEyNjQmIgYXHgEyNjQmIgYXFBYyNjQmIgYCAGa8kE5OkLxm/pYpRShOkLxmU0xKOTY9BAEYEQcBalNMSnI/IR9ylv6iASMyJCQyI84BIzIkJDIjziQyIyMyJAOATpC8zLyQTihFKQFqZryQTmYhHzg2i0wV/pYSGwIBIR9ylqVMSnI//l8YIyMxIyMZGCMjMSMjGRgjIzEjIwAAAAADAAD/gAQAA4EAGAAuADQAAAUiJy4BJyY0Nz4BNzYyFx4BFxYUBw4BBwYDIgcGBwYUFxYXFjMWPgInNCcmJyYDByc3FwcCAGlfXI0nKCgnjVxf0l9cjScoKCeNXF9pd2dlOj08OmRneVijfUMBPTtkZ3e2M+npM4AoJ41cX9JfXI0nKCgnjVxf0l9cjScoA7o8OmRn8GdlOj0BQ32jWHdnZDs9/nC2L+npLwAAAQAA/4AEAAOAACQAAAkBNjQvASYiBwkBJiIPAQYUFwkBBhQfARYyNwkBFjI/ATY0JwECTwGhEBACEC0Q/l/+XxAsEAMQEAGh/l8PDwMQLBABoQGhEC0QAhAQ/l8BgAGhEC0QAhAQ/l4BohAQAhAtEP5f/l8QLRACEBABof5fEBACEC0QAaEAAAL//wAABAABuQAAAAwAABEzITIVMRQjISI1MTQ5A445OfxyOQG5OTk5OQAABgAA/4kEAANBAAMABwALAC4ATABVAAABIRUhFSEVIRUhFSElNCYnNTQuASMhIg4BHQEjFTMVIxUzFRQeATMhMj4BPQE+AQMhLgE9ATM1IzUzNSM1NDYzITIWHQEOARQWFxUWBhMiJjQ2MhYUBgEAAbP+TQGz/k0Bs/5NAwA8LhwxHf2FHTEcR0dHRxwxHQJ7HTEcLjzU/YUPFUdHR0cVDwJ7DxQuOzsuARU4HikqOikpAoBLlkuWS/IyTg3gHjIeHjIet0nbSbceMh4eMh7gDU7+oAEVD7dJ20m3DxYWD+ANTmVODOEPFQFIKz0rKz0rAAAAAAEAAAAABAADAAACAAAJASECAP4ABAADAP0AAAAJAAD/sQQFA0EADAAXACIALwA6AEMAUABbAGQAACU2HgEUDgEuAjQ+AQcUFyMiJjQ2OwEGJTYeARQOASchNicTMh4BFA4BIi4BND4BBxQXISImNDYzIQYlMhYUBisBNicBMh4BFA4BIi4BND4BBxQXIyImNDY7AQYlMhYUBiMhNicBkR82ICA2PTMeHjONCrQYISEYtAoC5A8cEBAcD/5oFBS0HzUeHjU+NB4eNIsJ/fcYISEYAgkJAY4XIiIXQxUV/ZgfNB8fND40Hx80iwlCGCEhGEIJA1UXIiIX/fYUFJUBHjU+Nh4CHjQ9NB9xHhshLyEbGwEPGx8bDwE5OQGOHzQ+NB8fND40H3IeGyEvIhwcIi8hOTkBjh80PjQfHzQ+NB9yHRwiLyEcHCEvIjk5AAAAAAIAAP+AA8oDgAARACMAAAE1AQYUFjI3ATY0JwEmIgYUFwE1AQYUFjI3ATY0JwEmIgYUFwIL/gALFR4LAgEKCv3/Cx0WCwOA/gALFR4LAgEKCv3/Cx0WCwFoMP4iChwUCgHeChwKAd4KFBwK/iIw/iIKHBQKAd4KHAoB3goUHAoAAQAA/4EEAQOBACIAAAEyFhURITIeARQOASMhERYOASIuATcRIQYuATQ+ARchETQ2AgIXIQGNDxsPDxsP/nMBDxsfGw8B/nMQGxAQGxABjSEDgCEY/nMPGh4bD/5zDxwQEBwPAY0BDxsfGw8BAY0YIQAAAAAFAAD/fwQCA4AAJgAyAEAATACLAAAFIS4BNxEmNjchHgEHERQWMjY1ETQuASMhIg4BFxEGHgEzITI2NCYBIgYUFjMhMjY0JiMHNCYnISIGFBYzIT4BNQcyNjQmKwEiBhQWMwEvATc2NCcuAQ8BJi8DJicmIw4BIw4BFhcWHwIWFwYPAgYHBhcWFx4BPwI2NzIxNxcWNjc2NzYnJicCHP5sHCgBASgcAs8cKAEUHRQkPib9MSU/JAEBJD8lAZQPFBT+yw8UFA8B5g8VFQ9AFA7+fA8UFA8Bgw8Upw8VFQ//DxQUDwLwcgGDBQUKHAyABhMHTAgLBwsPAggCCQoECAUMClsEBgEFaAYMBAYEAQIJHQwfWQQFAQGCDBwKBAMECAULOAEoHQLlHSgBASgd/ogPFBQPAXgmQCYmQCb9GyZAJhUcFQL1FR0VFR0V3g8UARUdFQEUD+oUHRUVHRT+03MBgQoWCQsFCIEBFgdLCQwFBwECBhUVCgYKCVsGBAQEaQUKBwsOBgUMBQcgWQUEAYQIAwoGBw4MCAoAAAAAAf//AAAEAQKAABAAAAkBFjI2NCcBJiIHAQYUFjI3AgABxgocFAr+IgsaC/4iChQcCgI8/oUIEBkHAY8ICP5xCBgQCAAEAAD/pgQBA0EANABCAEwAWQAAEzIWFAYHKwEiBg8BERQWFzMhMjY/ARE0Ji8BISImNDY3MyEyFhcVERQGDwEhIiYnNRE0NjczMhYUBgcrASImNDY3MwE3FwcnBycBJwEDMh4BFA4BIi4BND4BjhAXEw8FNAUGAQEFBAQDTAUGAQEFBAT96hAWEw4FAhYjNAMvIwj8tCM0Ay8jzRAXEw4GJw8XEw4GASHz4jOq6cv+9jkBMy8cLxsbLzgvGxsvA0AYIBcCBgQD/SMFBwEFBAQC3QQHAQEXIRcCMiQI/SMlNgMBMiUIAt0kNwMYIBcCFyEXAv29/MY4lfFt/twyAVEBNRwvNy8cHC83LxwABf///38EAAOBABgALQA2AD8ASAAAATIXHgEXFhQHDgEHBiInLgEnJjQ3PgE3NhciBwYHBhQXFhcWMjc2NzY0JyYnJgEyFhQGIiY0NjMyFhQGIiY0NjMyFhQGIiY0NgIAaF9cjicoKCeOXF/QX1yOJygoJ45cX2h4Z2Q7PDw7ZGfwZ2Q7PDw7ZGf+wBwnJzgoKOMcJyc4JyfjHCgoOCcnA4AoJ45cX9BfXI4nKCgnjlxf0F9cjicoRjw7ZGfwZ2Q7PDw7ZGfwZ2Q7PP6JJjcnJzcmJjcnJzcmJjcnJzcmAAAC////fwQAA4EAGAAtAAABMhceARcWFAcOAQcGIicuAScmNDc+ATc2FyIHBgcGFBcWFxYyNzY3NjQnJicmAgBoX1yOJygoJ45cX9BfXI4nKCgnjlxfaHpoZTw9PTxlaPRoZTw9PTxlaAOAKCeOXF/QX1yOJygoJ45cX9BfXI4nKEA9PGVo9GhlPD09PGVo9GhlPD0AA////38EAAOBABgALQBSAAABMhceARcWFAcOAQcGIicuAScmNDc+ATc2FyIHBgcGFBcWFxYyNzY3NjQnJicmFz4BHgIGDwEXFg8BDgImLwEHDgEvASY0PwEnLgE/ATYyHwECAGhfXI4nKCgnjlxf0F9cjicoKCeOXF9oeGdkOzw8O2Rn8GdkOzw8O2RnFwobHRYICAyLjxEDAgQWHh0LjI0QKREEERCLjA8BDQUQLhGMA4AoJ45cX9BfXI4nKCgnjlxf0F9cjicoRjw7ZGfwZ2Q7PDw7ZGfwZ2Q7PNMJBgcWHh4KiIwTGgYQFgcIC4mKDgENBBAvEImJECoQBRAQiQAAAAABAAD/2wQAAwAABQAAETcFARcBOQEJAoc3/UcBSFfeAj85/RQAAAAAAQAA/4AEAQOBADIAAAUiJy4BJyY0Nz4BNzYzMhYUBiMiBwYHBhQXFhcWMjc2NzY1NiYnJjQ+ARceARQHDgEHBgIAaF9cjicoKCeOXF9oDxYWD3dmYzo8PDpjZu5mYzo8AUhBCxUdC01TKCeOXF+AKCeOXF/QX1yOJygWHhY8OmNm7mZjOjw8OmNmd1qmPgsdFgEJScLRX1yOJygAAQAA/7gD6ANcACIAACUHBi4CPwEnLgE+AT8CPgEyFh8CHgIGDwEXFg4CJwIA6RAjHA4CILAMCAsaEv18CB8iHwh8/RIaCwgMsCACDhwjEC1tCAMVIBL/vA0iIRgDMOIPEhIP4jADGCEiDbz/EiAVAwgAAAAE////vgQBA0EAOwBLAFsAawAAASM1ITUzMjY9ATQmKwEiBh0BFBY7ARUhFSMiBh0BFBY7ATI2PQE0JisBNSEVIyIGHQEUFjsBMjY9ATQmBTYWBxUWBisBIiY9ATQ2FwEiJj0BNDY7ATIWHQEUBiMBFAYrASImNzUmNhczNhYVA7Jg/tBWIS4uIfggLi4gWv7NWSAuLiD4IS4uIV4CKVchLi4h+CAuLv10BggBAQgG+AUICAUBMwYHBwb4BQgIBQFGCAX4BggBAQgG+AUIARCTTC4gtSAuLiC1IC5Mky4htSAuLiC1IS5SUi4htSAuLiC1IS5CAQgGtQUICAW1BggBAWIIBbUFCAgFtQUI/dwFCAgFtQYIAQEIBgAAAAMAAP+ABAADgQAYAC4ANAAAASIHDgEHBhQXHgEXFjI3PgE3NjQnLgEnJgMiJyYnJjQ3Njc2MzYeAgcUBwYHBgMnBxc3JwIAaV9cjScoKCeNXF/SX1yNJygoJ41cX2l3Z2U6PTw6ZGd5WKN9QwE9O2Rnd7Yz6ekzA4AoJ41cX9JfXI0nKCgnjVxf0l9cjSco/EY8OmRn8GdlOj0BQ32jWHdnZDs9AZC2L+npLwACAAD/gAPKA4AAEQAjAAATNQEWFAYiJwEmNDcBNjIWFAcDNQEWFAYiJwEmNDcBNjIWFAc+AgEKFR4L/gALCwIACx4VCoECAQoVHgv+AAsLAgALHhUKAWgw/iIKHBQKAd4KHAoB3goUHAr+IjD+IgocFAoB3gocCgHeChQcCgAAAAH//wAABAECgQAQAAAlATYyFhQHAQYiJwEmNDYyFwIAAcYLGxQK/iILGgv+IgoUGwv9AXsIEBkH/nEICAGPBxkQCAAABP///38EAAOBAA4AJwA8AEUAAAEyFhURFA4BIi4BNRE0NhMyFx4BFxYUBw4BBwYiJy4BJyY0Nz4BNzYXIgcGBwYUFxYXFjI3Njc2NCcmJyYDMhYUBiImNDYCABIZDBQWFAwZEmhfXI4nKCgnjlxf0F9cjicoKCeOXF9oemhlPD09PGVo9GhlPD09PGVoehIZGSQZGQKAGRL/AAsUCwsUCwEAEhkBACgnjlxf0F9cjicoKCeOXF/QX1yOJyhAPTxlaPRoZTw9PTxlaPRoZTw9/ZkZJBkZJBkAAQAAAAAEAAMAAAIAACEBIQIA/gAEAAMAAAAAAAUAAP9/BAIDgAAwADQARABSAFYAAAEyFh8BFTMyFh8BFREUBg8BIxUUBg8CISImJz0BIyImLwE1ETQ+ATc7ATU0Nj8CASERIRMhIgYPAREzNSEVMxE0JicFHgIGByMhIi4BNj8BASEVIQMKGScCAUsjPgcBIhQGeBoVBwf94hghA3gSJAUCGy0ZCU4cFQcHAgn+AQH/ivztEBgCATsC8jsUEP5wFR8CGhUH/u0VHgMbFAcCE/4BAf8DgCEYB6I1JAgJ/moUJQMBohciBQEBHhgHpR4SBwYBlhkvHwOiFyIFAQH9af7jAoYUEAb+hYiIAXsQFwJAAR0pIQMdKiADAQEjlgAAAv/z/38D2wOGAB0AMwAABSc2NzY3NicmJy4BDgEHBgcGFxYXHgE2NxcWMjY0ASYnJjc2Nz4CFhcWFxYHBgcOAiYDzvkIBksUFCQlVz+fp5U2SxQUJCVXSbe7Tv0MHxb86kceHRAQPS16iYI0Rx4dEBA9LXqJgj70CAhXcW1obEs3NA1MP1hwbWlsSj8xIjj4CxcgARs+WFZZXEc0PworLT1YVllcSDQ+CioAAAQAAAAABAADGgADABEAFQAZAAA3IRUhEwEhFhQHISYvATcXMwMBIxczJSMXM5oCvf1D6wEFAQB2dv0yLmsjVl7HZAJfzCqi/hHBIbRGNQMJ/oodsCQgn7MrrAFD/phEREQAAAAFAAAAAAQCArgAAwATACgANgBbAAA1IRUhJTQmKwEiBh0BFBY7ATI2NS8CJicmJyYnIgcGDwEXITI2JzQnJS4BDwEGFxYXNzY3PgEFITU3NicmJwcGBwYHMTUBNzY3Njc2FhcWFxYfAhYXFgcGBwYEAPwAA6wPCv8LDg4L/woPJWEFBwkNDxwdFxcRDzg1AQQSDgED/psGKx7+CQ0KC+4eDBIOAXb8YrQHBAcShwsHBAEB/xogIS4pM08tJCYcGRQFBQEBBggUGJE21goODgoMCg8PCp6GBwcHCgYKAQYEBx6rCggGBiskGAuEHRYSBUkJBwkf8CQ4CxMaCEcGCgUDPQEYDhIMEgUHGjUqQS42LA8SERkSFw4PAAAAAAf/9QAABAECgQAIABQANQA+AE4AXgBuAAAlFBYyNjQmIgYFFB4BMj4BJzQmIgYBISIGBwYXHgE7ASY+ATIeAQchJj4BMh4BBzMyNjURNCYFByM2Nz4BOwEXFAYrASImPQE0NjsBMhYVFxQGKwEiJj0BNDY7ATIWFRcUBisBIiY9ATQ2OwEyFhUC0So7KSk7Kv3OEiInIRMBKjopAyL8vSAyCS8OARgQWAsVN0M3FQsBbQsVNkQ3FQtcERgk/QkydQUVBBgOY/MIBnwGCAgGfAYI7wkGewYJCQZ7BgnuCAZ8BggIBnsGCb8eKio7KiodFCITEyITHSkpAaUmHp7aEBYgQScnQSAgQScnQSAYEQF8GSTTJlZHDRKKBggIBnwGCAgGfAYICAZ8BggIBnwGCAgGfAYICAYAABH//gAABAICtAADAAcACwAPABMAFwAbAB8AIwArADgAkQCeAKoAtQDHANoAAAEzFSsBMxUjJzMVKwEzFSMnMxUrATMVIyczFSsBMxUjJzMVIwEnIwc2NzYXBwYHBgcGBxYXFhcWNwUWFxUWBg8BNS8BLgIiBgcOARchNiYnLgEiBgcGDwEXJy4BNzU2PwEyMzc+AS4BDwE1Njc2NzY3Njc2NzM3PgE7ATIWFRcWFxYXFh8BHgEdASMiBhQWMzcnJi8BJicmIwc2PwEmFyYiBw4BHgEXMjY0JSYiBhQWMz4CJicyHgEVFA4CIiYnLgE2Nz4BITIWFx4BBgcOASImJy4BNjc+AQKQKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgBYgS0CygpODqANCkcLysuBwcaIkRqAcoLAgEMCikLAQolMjYyExYVBP6aBBUWEzI2MhMWCwcCKwoMAQIMBAMCKQYHAgoHJgELJz48Pjw1OCUBEAEJBdAHCQUlMyg2JSQOCAkrBwkJByzqFw4BFg42NQkoTloIQgoeCggECBILDxX9gQoeFRUPCxIIBCEbLhsPHCUoJQ4TDg4TDiUCiBQlDhMNDRMOJSglDhMNDRMOJQF8KClRKClRKClRKClRKAENMjQFAQEFLQIHBCAcKAICBwICBZgGDRQKDwIFEDECFyUUFRMWOyAgOxYTFRUTFh03DQUCDwoUDgU+CAELDAgBBwcOBhoTEwk2IyUGSwYHCQdHCigfNQQLBQINCBAJDQoBcCkMAQwCBXoCBgYS3QsLCBUUDAEWHgoLFR4WAQwUFVMbLhsVJRwPDw8TNDMUDg8PDhQzNBMPDw8PEzQzFA4PAAAAAgAA/4gEAAOAABsARQAAARYXFhQOASIuATY3NjcuAjU0PgEyHgEVFA4BJTEVFA4BBxYXFhUOASImJzQ3NjcuAjURMxUUFjI2PQEzFRQWMjY9ATMBJwsJBxgrMiwYAQcICy9LKj5pfWo+K0oCqSpLLwsIBwE1SzYBBwkLMEoqWxsmG1wbJhtcAWN0gm0yLBkZLDJtgnQRTWw9S39KSn9LPWxN+AI9bE0RdIJtGSU0NCUZbYJ0EU1sPQEW6BMbGxPo6BMbGxPoAAAIAAD/nwPgA2EARgBQAGAAagCvALgAzADVAAAlFgcGBwYPARYHFAc3FRQXFjI3Nj0BMxEDJicmJyYnJiIHBgcGBwYHAzY/ATY3NjMhMhcWHwEWBwYjIRYfARYXFh8CFhcWAyEiJjYzITIWBhMUBisBIiY9ATQ2OwEyFhUBFRQXFjI3Nj0BASMnJicmJyYnJiMiBwYHBgcGBw4BFSMiBwYVFBYfAQYHBgcGHQEUFjsBMjY9ASEVFBY7ATI2PQE0JyYnJic3MjY1NCcmBSImPgEyHgEGJzY3Njc2IBcWFxYXBwYHBiInJicFLgE0PgEWFAYC/wIIBgsJCgkTAQ9jEQ8sDxFCGQcgFTAoS1F+UEsoMRUgBxYdLRYDCQsXAe4XCwkDHgIGCBP+8hMPAwYMCQwKDxALDwT+vg8MDA8BQg8MDKAMClkJDQ0JWQoM/WoRDywQEQEPCgYDEhYQGzE1Sk01MRgTFBEEAQUJJBENCwg0AwYJBAYNCTMJDQGlDggrCQ0GBAkGAjIHCw0R/e8NEwESGhIBESUOFw4PJQENJg4PFg4QNyVBgEIlNwG1DRAQGhIS0BMQDQoHBQQaHRgfAT8bEQ4OERs/AZQBJSQYDxUQDhAQDhAVDxgk/vgYDZ0VCgsLChXVEgoNICIIEQ0IBgMICwwSAgIYGBgY/dUJDQ0JJgkNDQn/AAcbEQ4OERsHARkSDSQrFSARExMRIBUrIg8ECgQWERgHDAMGDRsmFCEZQgoXFwoZFgsZGQtCGiETJhsNBg0JFhAWzRMaEREbEpVDLRwPLCwPHC1DBxcKEhIKF40BEhgSARIaEgAAAAX//v+YBAwDSQARAFYAlgCqALwAAAEzMh8CHgEOAQcjLgI+AgMWFxYXHgEXFhceATM2FhcWDwEWFy8BLgErAQcOAxcjBgcGBwYHBi8BJicmNTQ3JyY3Njc2FzI2NzY3PgE3Nj8BFzYBDwEvAS4BDgEfAyMiDgEWFzsBFSMiDgEWFzsBFRQeATY/ATU7AT4BPwEnJicrATUzMj4BJi8BIz8BNi4BBiUGFhcWHwEHFjc2NzYmJyYnJgcGAQYHBgcGDwEWIDcnJicuASMmAvIVRjsODD0tL3tNJ0NwQAFDcEUNG0ojGygIHyIDDwUeMwUEBDkDAgsNJFUsFA8+bEsdDNQDBgUDBAVJSRQSAQMDNgICDhAWJAUOAx0VD1Q2ECAkAm0BSwNGQwMGDgwEAgIjIDgJDAEJCAVKSgkMAQkIBUoMEQ8BAUkEBgkBAQEDDAVJSQgMAgoHBTg7AgMFDA79HwcQGBQpEgIcGhYLAg4HPkETDBABFDQyGA0XJg2kAU+kDxoJBjAfnQGMJQkJMJWUXwQCRXKFcUMBrQMGDgoIJxtcWQgQBiUfERARFBQJChobAQQ6YXg8DR4cCxECDQoDGR8rUZpNDw0OJBAVAw8HSEk2SAUDBQYCEf3QBGRkBAQBCA4HBDIqCxANAhgLEA0CKwkNAQoJBCsBCQYFBA0DGQsQDQEBXQQHDggBMSMnBQQEAQECBQUVBhcDHhcHBQYBgAIOBRU1bickJC5QJiAnBwAAAgAA/4AEAAOBABcAMQAAASEyPgE0LgEjISYnJiMiDgEdARQXFhcWAzQnJiMiBhURFBYzMj4BPQEhFRQWMjY1ESEBKwJ/FCgaGigU/isCJyI1IjsjEg4XEp4VEhkWKikXDx4TAwApLin8gAGrGicoKBlBIh0iOyNVHBURCwgBlR8SDykX/HcWIRMeD8DAFiohFgHJAAX///+ABAADQAADAAcAIAAwADcAAAEhNSEVIRUhFxEUBiMhIiY1ETMRNDY7ATU0NjMhMhYVEQERMx4BMjY3MxE0JiMhIgYDMxEjIgYVAyD+gAGA/oABgOAlG/yAGyVAEw2gEw0CgA0T/YAwEk9eTxLwEw3+AA0TwIBgDRMCKEC4QJD+4BslJRsBIAHADRNgDRMTDf3AAgD+ACs1NSsCAA0TE/3zAaATDQAAAAADAAD/ngPfA2EAJQBHAHoAAAEhNzY3NicmLwEmJyYHBgcGBwYHBicmJyYnJiMGBwYHBgcGFxYXBRYXFhcVHgEfARYHBgcGBwYnIQYnJicmJyY3PgE3NTY3MRcmIgYUHwEjIgYUFjsBFSMiBhQWOwEVFBYyNj0BMzI2NCYrATUzMjY0JisBNzY0JiIPAQF7AQkvLwQHAQIYGhUIDgoFDxYRHiQdFg4TDQcLCxgaIAoQBgkPF0gBCggJFRZYhysEDwsKGyk5HSH93CEeOSgdCgoUK4dYJBgnDCMYDFhLEhgYEmhoEhgYEmgZIhhpERkZEWlpERcXEUxYDBgiDGQCj0NGCBAMEwUFBQECAgEGCQUIAQEGAwkHAgMBAgMEBQwRGCRnKgYGEBQCT8BuDDA4NiIxEQkBAQkRMSU6PTBuwU4CIBBjDBgjDFgYIhhTGCMYaREYGBFpGCIZUxgiGFgMIxgMZAAAAAMAAP+/A58DRAAeACYALgAAEyY2NzE+ARYfATc+ARYXMR4BBzMyHgEdASE1ND4BMwERIyIuATURKQERFA4BKwHuDAwYFTc4FUxLFTg3FRgNDVQbLhv8oRsuGwEq+RstGwGfAVwbLRv5AqoeQRcVDw8VS0sVDw8VF0EeGy0bZWUbLRv+9f4hGy4bAXv+hRsuGwAAAAAG////7AQBAyAAFgAjAC8APQBwAHwAAAE2JyYnLgEHBgcGFRQXFhceATc2NzY1ASEOAQchMjY9ATQmIxMhFhczMjY9ATQmIyUzMjY9ATQmIyEWFxYXBRc3NjIWFA8BMzIWFAYrARUzMhYUBisBFRQGIiY9ASMiJjQ2OwE1IyImNDY7AScmNDYyATIWHQIUBisBNjcCvQEwLk9SvVJQLzEvLk9SvlJQLzABGf7IL4JKAjgQFRQXA/77IQbfEhUVEv7OohEUFRL+kWRIEhH+XVhXCx4VC01DDxUVD1xcDxUVD1wWHhVcDxUVD1xcDxUVD0NNCxUeApsPFBQOxyMIAYliVFEwMQEwMFBTYGNVUjAyATEwUVRh/vg7TQ0VEUMXFQG/Rk8VEkYTFUsVEkYTFSBLExcsWFcLFR4LTRUeFkgVHxVcDxUVD1wVHxVJFR4VTQseFf74FQ4oJw8URk8AAAAABAAA/6UEAQNBACAAPgBOAF4AAAEhIgYdARQWOwE1IyImNDYzITIWFAYrARUzPgE9ATQmIwchIgYVER4BNzY3MTYyHwEWMj8BNjIfARY2NRE0JgMhIi4BND4BMyEyHgEUDgEnISIuATQ+ATMhMh4BFA4BA8n8bhcgIBdJBBMaGhMDCRIbGxIFSRcgIBeS/ZIPFQEPCAmFBxAHhQgRCI0HEAeLCA4Vdf5eChEKChEKAaIKEQoKEQr+XgoRCgoRCgGiChEKChEDQCAX/RcgiBslGholG4gBIBb9FyC2FQ/9UQgJBAVQBARUAwNUBQVUBAgIAq8PFf5rCRETEQkJERMRCZ8JERMRCQkRExEJAAUAAP+AA8EDgAAPADMAQABMAFgAAAEzMjY9ATQmKwEiBh0BFBYlIyIGFSMOASsBIiYnIzQmKwEiDgEVERQeATMhMj4BNREuAgMUBgchLgE0NjMhMhYnIS4BNDYzITIWFAYnIS4BNDYzITIWFAYBq6kXHx8XqRYgIAGTJg8WMgQrHb4dKwQzIhEYKUUpKUUpAlIpRSkBKUU8Fg/+KQ8WFg8B1w8WJf4pDxYWDwHXDxYWD/4pDxYWDwHXDxYWAxEgFgMWICAWBBUgSRYPHSYmHQ8WKUYp/VYpRikpRikCqipFKf0fDxUBARUeFhaxARUeFhYeFeQBFR4WFh4VAAP/9v//BAQDQQAOADoAbwAAJTIWFxYGIyEiJicmNzYXAR4CFRQWFxYXFRYfARYXFhceAQ4BIyEiJicmNjc2NzY3Njc2Nz4BNT4CByYOARQfASMiDgEUHgE7ARUjDgEUFhczFR4BMjY3NTM+ATQmJyM1Mz4BNCYnIzc2NC4BDwEDsSMpAgMmIvyLGSIGDiATGQHAIjohCQzLSgYBAQQGCRcUFAgkGfyLHyYDAxweCgMDASKVLzgPCwEjOyQIGREIQDcJDwgIDwlMTA0QEA1MAREZEQFMDBERDExMDBERDDdACBEZCUiBHhwfKBYUKh0QAQLAASE5Ig0MBEnRAhAJBRcJDwQDLC0cHBocJgcCBQQJsGwiEgUODyI4IeUIAREYCUAIDhEOCDwBERkRAUwNEBANTAERGREBPAERGREBQAkYEQEISQAAAAAD////3QQAA0cABwAgACkAAAEuAQcFBgchEzU0JiMhIgYHER4BMyEyNj0BByMiJjQ2MwcUFjI2NCYiBgOWCkUn/Y8RDwMmSzgo/MAnNwIBOCcDQCg4CMAoODgoIBciFxciFwL/IyQJmQQK/uaUJTQyI/4fJDE0JJUBNEo0WQ8WFh8VFQAFAAD/gAO+A4EAEwA+AEwAXwCTAAABNDY7ATIWHQEzNTQmIyEiBh0BMxM1PgEyFhcVNjc1PgEyFhcVMzIXNTQmIyEiBhURFBY7ARQWMjY1My4BNjcHFg4BIi4BNxE+ATIWFwUuASsBJg4CHgEXMzI+Ai4BBzIWFAYrARUUBiImPQEjIiY0NjsBNSMiJjQ2OwEvASY+ARYfATc+AR4BDwEzMhYUBisBFQFGEgzfDBFNNCX/ACU1TGwDEhYSAzM7AxIWEgMIUUgtIP25IC0tIEAeKh5qNScgMm8DBxEVEQcCBBEXEQMCAyJOKgdIfEsFQndIGjpoSyMNOmEJDQ0KTg4UDlAKDQ0KUFAKDQ0KPSMlBQMPEwVISwUSEAMFQD0JDg4JTwMVDRESDC9AJTU0JUH+ccALDQ0LgCINUAsODgtIJ/MfLS0f/WYgLRUeHhU7lZc94goUDAwUCgGhCw4OC7EYGQFDeJB8TQMvVG5xYuYNEw0tCg4OCi0NEw0aDRMNLTYHEwoDCGtsCAMLEghjDRMNGgAAAAEAAAAABAECYQAQAAAJARYyNjQnASYiBwEGFBYyNwIAAcYKHBQK/iILGgv+IgoUHAoCHf6LCA8ZBwGJCAj+dwcZDwgAAQAA/58DTANqAEEAAAEXNzYyHwEWFA8BMzIWHQEUBisBFTMyFh0BFAYrARUUBisBIiY9ASMiJj0BNDYzNzUjIiY9ATQ2OwEnJjQ/ATYyFwFIvr4OJw4iDg6pmxQcHBTOzhQcHBTOHBQvFBzOFBwcFM7OFBwcFJupDg4iDicOA1y+vQ4OIQ4oDqkcFDAUHI8dEzAUHM4UHBwUzhwULxQcAY8cFDAUHKkOKA4iDg4AAAAEAAD/6gQBA0AADAAWACMAMAAAEyEyMzU0JiMhIgYdAhEUFjMhMjY1EQU0NjMhMhYUBiMhIiYFFAYjISImNDYzITIWAgP5AgMrH/yUHysrHwNsHyv8cxUPASwPFRUP/tQPFQIvFQ/+GQ8VFQ8B5w8VAlefHiwsHp9F/iMfKysfAd3GDhUVHRUVlQ8VFR4VFQAEAAD/7APBA0EAGwArADUARQAAASMzNTQmIyEiBh0BMyMiBhURFBYzITI2NRE0JgEUBisBIiY1ETQ2MzEyFhUlITU0NjMhMhYVExQGIzEiJjURNDY7ATIWFQNmlxEoG/7GGygLkSU1NCYCzCU1NP3LEw0BDRQUDQ4TAU7+sAwJASYJDEYUDQ4TEw0BDRQCjX8XHR0XfzUl/hMlNDQlAe0lNf4bDhMTDgEoDhMTDr1oAQYGAf2zDhMTDgEoDhMTDgAFAAD/gAQvA4EAGAAtADYAPwBIAAABMhceARcWFAcOAQcGIicuAScmNDc+ATc2FyIHBgcGFBcWFxYyNzY3NjQnJicmATIWFAYiJjQ2MzIWFAYiJjQ2MzIWFAYiLgE2Ai9oX1yNJykpJ41cX9FfXI0nKCgnjVxfaXlnZDo9PTpkZ/FnZDo9PTpkZ/6/HCgoNygn5BsoKDcoKOMcJyc4JwEoA4AoJ45cX9BfXI4nKCgnjlxf0F9cjicoRjw7ZGfwZ2Q7PDw7ZGfwZ2Q7PP6JJjcnJzcmJjcnJzcmJjcnJzcmAAQAAP/dA9IDIwAxAD0ARwBQAAATMhYUBgcjIgYHFREUFh8BITI2NzURNC8BISImNDY3MyEyFhcRFAYHIyEiJicRNDY3OwEyFhQGByMiJjQ2NwE3FwcnBycDJwEDMhYUBiImNDawDhUSDTQEBgEEBAMDAAQGAQgD/hoOFRINBAHmIC4DKx8H/QAgLgMrHwe0DhUSDCkOFRINAQzdzS6b1LjyNAEXKyc3N003NwMjFh0VAgUEA/1mBAYBAQUEAwKaCQIBFh0VAi0h/V4iMQMtIQKiIjEDFh0VAhYdFQL98eWzM4fbY/73LQEyARk2TTc3TTYAAAADAAD/gAQBA4EAGAAtAFIAAAEyFx4BFxYUBw4BBwYiJy4BJyY0Nz4BNzYXIgcGBwYUFxYXFjI3Njc2NCcmJyYXPgEeAgYPARcWDwEOAiYvAQcOAS8BJjQ/AScuAT8BNjIfAQIAaF9cjicoKCeOXF/QX1yOJygoJ45cX2h4Z2Q7PDw7ZGfwZ2Q7PDw7ZGcXChsdFggJC4uPEQQBBBYeHgqMjRApEQQREIuMDwENBRAtEowDgCgnjlxf0F9cjicoKCeOXF/QX1yOJyhGPDtkZ/BnZDs8PDtkZ/BnZDs80wkGBxYeHgqIjBMaBhAWBwgLiYoOAQwFEC4SiIkPKxAFEBCJAAAAAAMAAP+ABAEDgQAYAC0ARAAAATIXHgEXFhQHDgEHBiInLgEnJjQ3PgE3NhciBwYHBhQXFhcWMjc2NzY0JyYnJhM2Fh8BFgYHAwcGJi8CJjY3NhYfATcCAGhfXI4nKCgnjlxf0F9cjicoKCeOXF9oeGdkOzw8O2Rn8GdkOzw8O2RnKRErEQUNAg7zBhEtEIoFDAUPEjARXckDgCgnjlxf0F9cjicoKCeOXF/QX1yOJyhGPDtkZ/BnZDs8PDtkZ/BnZDs8/uQMAg8GESoP/vsFDgMQiwYSKg4RARFe2QADAAD/qgPWA1YAEAAjACkAAAUGLgI0PgIyHgIUDgIDIg4CFB4DPgInNCcmJyYDByc3FwcCAF2thEhIhK26rYRISIStXVGVcj09cpWilXM9ATc3W19tpi/V1S9VAUiErbqthEhIhK26rYRIA2s9cpWilXI9AT1zlVFtX1s3N/6RpivV1SsAAAAAAwAA/6oD1gNWABAAIwApAAABJg4CFB4CMj4CNC4CAyIuAjQ+Ax4CBxQHBgcGAycHFzcnAgBdrYRISIStuq2ESEiErV1RlXI9PXKVopVzPQE3N1tfbaYv1dUvA1UBSIStuq2ESEiErbqthEj8lT1ylaKVcj0BPXOVUW1fWzc3AW+mK9XVKwAAAAQAAAAAA2cC5wARACQANgBIAAABMzIeAh0BIyIuAj0BND4BEzMVFA4CKwEiLgI9ATQ+AgEzMh4BHQEUDgIrATU0PgIDMzIeAh0BFA4BKwEiLgI1ATYXHzosGLQfOS0XKkgqtBgsOh8XHzktFxctOQGcFypIKhctOR+0GCw6frQfOS0XKkgqFx86LBgC5hctOR+0GCw6HxcqSCr+hLQfOS0XFy05HxcfOiwYAXwqSCoXHzosGLQfOS0X/oQYLDofFypIKhctOR8ABAAA/44D8gNyABkAKQAzAEIAABMjIgYVERQWMyEyNjURNCYrAREUBiMhIiY1AyEyFhURFAYjISImNRE0NhcRFBYzITI2NREHMhYdARQOASIuAT0BNDbkaw8VFQ8DDg8VFQ9rKR7+Vh4pjwNWHSoqHfyqHSoq8xUOAWQOFWoOFQkRExAKFQMrFQ/88g8VFQ8DDg8V/pwdKiodAasqHfyqHSoqHQNWHSpH/sAPFRUPAUBHFQ+OChAKChAKjg8VAAAAAwAA/+YDfwMaAD4AbgB2AAAlJyYjIg8BBiIvAS4BIyIPAQYiLwEuASMiDwEOAR4BPwE2Mh8BHgEzMj8BNjIfAR4BMzI/ATYyHwEWMzI3NiYTJzU0Ji8BNTQmIgYdAQcGHQEHDgEfARYXFh8BFjI/AT4BMhYXFjI3PgE3Mj8BNiYlJg8BNTcXFQNhPRckIB0kCBoHIgshESQZJwgXBycLIRElFjsJAQ8YCj0IFwcnDCARJBomCBcHJAwhER8eJAgXBz4ICg0KCAEBZwoIuCIyIrsSZAsGB5oCCygfAwYTBgIUMzozFAYTBg8oFQULmQYH/p0UFLvPyho1FxkkCAgkDA0ZJwcHJwwNGTMIGBMBCDYICCQMDhomCAgjDA4aIwgINQgKCBcBqSuDCQ8ESBIZIiIZEkoIEoMrBhcK9QUGBx8CBgYCExYWEwYGEBUECvYIFpoJCU9UUFBUAAAABQAAAAADswK0AEAAVQBhAHEAfAAAASMGBycmJyYjISIHBg8BJisBIgYdARQWMxcGFQcXBh0BFBY7ATI2PQEhFRQWOwEyNj0BNCc2NSc0JzcyNj0BNCYlNzU+AT8BIRceAR8CDgEjISImJxMiLgE0PgEXMhYUBiUUBisBIiY9ATQ2OwEyFhUXIi4BNjc2MhYUBgOcTwYEJAgeHCn+sSsdGwgkBQZPCQ0NCR4PCwEBFxE8EBcCAxcRPBAXAQELDx0JDQ39bxsBBQUGAZkGBQUBGwkBKRb+fRYpARwQGxARHA8ZIiQBNAoIpwcKCgenCAp/Eh4NBwwSMSMjAfEBAmssGBYaGChrAw0JEwkNBh4ifgsEA5gQFxYRMTERFhYRmAMEBgV+JB0FDAoTCQ0WRQIHCAUHBgYIB0cnFB4eFP7dEBwgGxABIzEjLAcKCgcyBwsLB10UISMNESIyIgAAAgAAAAADyQJcACgANwAAAQYPAQYjBicmJyYnNxY/AS8BJjc2NzYXBRcWMzI/AjY3NhcWFxYHBgUmJyYnNzY3NhcWFxYfAQNF8vINERMZGB8aIBlkGR5yqwMDBAYSFioBAAYJCg8QqxMWFB0TGAkTMRz8/hwPCAICBAgKEBMaDx0RATpGRwMEAQYGEBMeKggKHP0ICQcJAgIJxQIDBTgFBAEBCAkWKyEUQx8bDgcICgUGAwUVDBIKAAIAAAAAA0EC5QApAEkAACUmJyYnJj0BNDc+ATM3NCYrASIGHQEWFxYdARQHBgcGBxcUFjMhMjY9AQM1NCYrASIGHQEOAhYXNy4BPgEeAgYHFz4CLgICzzkgKhUXDgwkDQEGBcIFBhYYGxgVKiE5AQYFAY0FBpQGBGwFBlyDI0dNHjMfNXWMci8lNRw0QxgaRmdVBAgMFxwvQwsLCg1qBQYGBWgBDQ4RQy8cGAsKAjMEBgYEMQJkIAUGBgUhFYe4rjVgL4mCTQRSg4gtWSNpentmRQAACAAAAAAD3AKAAAgALgA/AFAAXABsAH0AiQAANxQWMjY0JiIGASEiBhURFBY7ASY+AjIeAgchJj4CMh4CBzMyNjURNC4CBRQGKwEiJj0BNDY7ATIWHQEXIiY9ATQ2OwEyFh0BFAYrAQUjIiY0NjsBMhYUBjcUBisBIiY9ATQ2OwEyFhUXFAYrASImPQE0NjsBMhYdAQcUHgEyPgE1NCYiBsE3TDc3TDcCof1JHCgRCyMFDSMyNjIjDQUBGAUOIjI2MiMOBR8MEhMiLf2qBASAAwQNCXIDBT0EBQUEhgQEBASGAROoBgkJBqgGCAg2BAN9BAUFBHwDBf0JBo0SGgcFbx8t4xgrMisZNk02zSc2Nk02NgGMKBz+lwsRGzUqFxcqNRsbNSoXFyo1GxIMATEZLCMSpgMFBQNiCg0FA3EHBQNvBAUFBHADBcYIDAkJDAjNAwQFA3AEBQUEkgYJGhNwBQcsIE7qGSsZGSsZJjY2AAABAAAAAALAAkAAGwAAATIWFAYrARUUBiImPQEjIiY0NjsBNTQ2MhYdAQKaEBYWEHQWIBZ0EBYWEHQWIBYBphYgFnQQFhYQdBYgFnQQFhYQdAAAAAABAAAAAAMAAoAACwAAAScHJwcXBxc3FzcnAv8e4eEe4eEe4eEe4QJhH+LhHuHhHuHhHuEADQAA/4QD+wM9ABAAHQAqADwASABUAHIAfgCPAKAArQC6AMYAAAUjIiY0NjsBNTQ2MhYdARQGAyImPQE0NjIWHQEUBgMiJj0BNDYyFh0BFAYDIiY9ASMiJjQ2OwEyFh0BFAYBIyImNDY7ATIWFAYDIyImNDY7ATIWFAYDMhYUBisBFRQGIiY9ASMiJjQ2OwE1ND4BMh4BHQEDIyImNDY7ATIWFAYBIyImPQE0NjIWHQEzMhYUBgMjFRQGIiY9ATQ2OwEyFhQGBzIWHQEUBiImPQE0NhMyFh0BFAYiJj0BNDYBMzIWFAYrASImNDYD5YIIDQ0IbQwSDQ0JCQwMEg0NCQkMDBINDQkJDG0IDQ0IggkNDf70ggkNDQmCCQwMCYIJDQ0JggkMDCISGhoSghkkGYISGRkSggsVFxQLaYIJDAwJggkNDf7zggkMDBINbAkNDQlsDRIMDAmCCQ0NiwkNDRIMDAkJDQ0SDAwBDYIJDQ0JggkMDHwNEgxsCQ0NCYEJDQEEDAmCCQ0NCYIJDAEDDQmCCQwMCYIJDQEEDQlsDBINDQmBCQ389Q0SDAwSDQONDBINDRIM/noZJBmCEhkZEoIZJBmCDBQLCxQMggGGDBINDRIM/HMNCYIIDQ0IbQwSDQONbAkNDQmBCQ0NEgzZDAmCCQ0NCYIJDP79DQmCCQwMCYIJDf56DBINDRIMAAAAAwAA/6wE7AOAAAMABwALAAABIRUhASEVIQEhFSECdgJ2/Yr9igTs+xQBGAPU/CwDgIz+6Iz+6IwAAAAAAwAA/4AEAAOAAAAADAAfAAARMyEyFREUIyEiNRE0CQEGIi8BJjY7ATIfARM2OwEyFoADAICA/QCAAvH+8wwqDKAEBgY8FQxcyQwVPAYGA4CA/QCAgAMAgP6w/ooREd0FCxF+ARcRCwAFAAD/gAQBA4AAGAApADYARABiAAAFIicuAScmNDc+ATc2MhceARcWFAcOAQcGAyIOAhQeAjI+AjQuAgMGIi8BJjQ2Mh8BHgEnJjQ/ATYyFhQPAQYiJwEjIiY0NjsBMj4BNC4BKwEGJjQ2OwEyFhcWFAcOAQIAZ19cjicpKSeOXF/OX1yOJykpJ45cX2dYpHxERHyksKR8RER8pG8JGwmCCRIbCnsOArkKCn8KHBMKfwkcCgEx4Q8TEw/nHzIcHDIf5w8TEw/nMFEYGRsZVIApJ45cX85fXI4nKSknjlxfzl9cjicpA7xEfKSwpHxERHyksKR8RP4JCgp/ChsUCn8KG2UJHAl/ChMcCYAKCv7iEyATHjQ+NB4FESAUMCkrZyonLAAAAgAA/5ID9gN2ADUASAAAAR4BDgImJyYnJgcOAQcGFx4BFxYXFjY3Njc2JyY+ARYXFgcGBw4BJyYnLgEnJjc+ATc2FxYDPgEeAQ8BDgEvAS4BPgIWHwEDWgoHBxMZGglGXVxdYZkmJQcHalZTX2KwOTcODiIGESUkCCoSEEZH3Hp3aGuECgkvML95dXJ1cg4oHgIN5A4qD4AJBwcTGRoJXALZCRoaEgcHCkUcHBISe1pYX2GmMC4EA1dQTl5hXBMkDRASdHl2YWNtBAQ6PM96d25wmhcVIiP+2A8CGykP+RABD4UJGRoSBgcJXwAIAAD/lQPdA2QACwAXACAALAA5AEUAUQBdAAABFg4BIi4BNz4BMhYDJg4BFB4BNz4BNCYlIiY0NjIWFAYlNi4BIg4BFx4BMjYTHgEOAi4CPgIWAQ4BHgI2NzY0JiITDgEuAjY3Nh4CAS4BDgIWFxY+AgJyARkuNC0aAQE4TjhfFygXFygXIi8vAWwZIyMyIyP9KwEaLTQuGQEBOE44WhINDSUxMiUNDSUyMQHPDgsKHCUmDhQqO0AJGRkSBwcJDicbAf3iEjMyJQ4PExxOOAEDBhouGxsuGic3N/0RARcnLigWAQExRDH/IzIjIzIjPBouGxsuGic3NwGFEzEyJQ0NJTIxJQ0N/aoOJiYbCgoOFjsqAcoKBgYTGRkJDQEbJ/4lEg8OJTIyExsBOE4AAAAABQAA/34EAwOAACYAMgA/AEsAigAABSEiJjcRJjY3IR4BFREUFjI2NRE2LgEjISIOARcRBh4BFyE+ATQmASIGFBYzITI2NCYjBzQmJyEOARQWFyEyNgc+ATQmJyEOARQWFwEnJjE1NzY0Jy4BDwEmLwMmJyYjDgEHDgEWFxYfAhYXBg8CBgcGFxYXHgE/AjY/ARcWNjc2NzYnJicCHf5rHCgBASgcAs8dJxQcFAEkPyb9MSU/JAEBJD8lAZUOFBT+yw8UFA8B5w4VFQ5BFA7+fA4UFA4BhA4Upg4TEw7/AA4UFA4C8HEBggYGCR0MgAYTB0wICgcMDwIIAQoKBAkFCwpbBAYBBWgGCwQHBAEDCRwNHloEBQGDCxwLBAIECAQMOCkcAuYdKAEBKB3+hw4VFQ4BeSZAJiZAJv0aJUAmAQEUHRQC9hUdFRUdFd4PFAEBFRwUARXcARQdFAEBFB0UAf7UcgEBgQkWCgsEB4ICFgdLCQwECAIBAQYUFgkGCglbBgUDBGkGCgYMDgYFCwUHIFgFBAGDCAIKBwcNDQcLAAAGAAD/pAQBA1wAAwAHAAsALgBMAFUAAAEhFSEVIRUhFSEVIQE0Jic1NC4BIyEiDgEdASMVMxUjFTMVFB4BMyEyPgE9AT4BAyEiJj0BMzUjNTM1IzU0NjMhMhYdAQ4BFBYXFRQGEyImNDYyFhQGARoBqP5YAaj+WAGo/lgC5jwuHDEd/YUdMRxHR0dHHDEdAnsdMRwuPNT9hQ8VR0dHRxUOAnwPFC48PC4UOB0qKjopKQKASZJKkkkBADJPDOEdMx0dMx23SdxJtx0zHR0zHeEMT/6gFQ+3SdxJtw8VFQ/hDE9kTwzhDxUBSSs8Kys8KwAEAAD/lwS+A30AOwBLAFsAawAAASM1ITUzMjY9ATQmIyEiBh0BFBY7ARUhFSMiBh0BFBYzITI2PQE0JisBNSEVIyIGHQEUFjMhMjY9ATQmBTIWHQEUBiMhIiY9ATQ2MwEiJj0BNDYzITIWHQEUBiMBFAYjISImPQE0NjMhMhYVBGZq/q5gJDMzJP7tJDMzJGT+q2MkMzMkARQkMzMkaQJmYSQzMyQBEyQzM/0tBggIBv7sBggIBgFUBggIBgEUBggIBgFqCQb+7QYJCQYBEwYJAQ6kVDMkyCQzMyTIJDNUpDMkySQzMyTJJDNcXDMkySQzMyTJJDNICQbJBggIBskGCQGICQbIBgkJBsgGCf2gBggIBskGCQkGAAAAAAL///+4A8gDgQAvADkAAAEmJy4BDgEXHgEVFAcGBwYiJyYnJic+AxcWPgEmJyYjIg4CFB4CMj4CNTQlJw8BFwc3Fyc3A6kdNw0rIAQOLC40MldZz1lWMjQBAWGpxlkTKBMNE2dzYLKISkqIssCyiEr+fWFh2Z0lwsIlnAJFT0EQAxsqETN/RGdZVzI0NDJXWWdjrmgILAoNJikJNEqIssCyiEpKiLJgWCDExCCY2GZm2JgAAAP///9/BAADgQASACsAQAAAASMiDwEnJisBJgYfARYyNxM2JgMiBw4BBwYUFx4BFxYyNz4BNzY0Jy4BJyYDIicmJyY0NzY3NjIXFhcWFAcGBwYC1jYTC7NRCxM2BQUDjgslC/EDBdtoX1yOJygoJ45cX9BfXI4nKCgnjlxfaHNkYDg6OjhgZOZkYDg6OjhgZAI2D/pxDwELBMYPDwFOBQoBSignjlxf0F9cjicoKCeOXF/QX1yOJyj8Vzo4YGTmZGA4Ojo4YGTmZGA4OgAAAAAD////fwQAA4EAGAAtAEEAAAEiBw4BBwYUFx4BFxYyNz4BNzY0Jy4BJyYDIicmJyY0NzY3NjIXFhcWFAcGBwYTJxE0JisBIgYVERQfARY2PwE2JgIAaF9cjicoKCeOXF/QX1yOJygoJ45cX2hzZGA4Ojo4YGTmZGA4Ojo4YGRVowYDNwQGBL0DCAIhAgEDgCgnjlxf0F9cjicoKCeOXF/QX1yOJyj8Vzo4YGTmZGA4Ojo4YGTmZGA4OgEYdgEbBAUFBP7FBAOKAgEDLQMHAAAADAAAAAAEAAMUAAgAEQAeACcAMAA5AEYAUgBbAGQAcQB6AAABMhYUBiMhNicjBhcjIiY0NjMlIg4BFB4BMj4BNC4BBzIWFAYiJjQ2AQYXISImNDYzITIWFAYrATYvASIOARQeATI+ATQuAQcyHgEUDgEjIiY0NgEyFhQGIyE2JyMGFyEiJjQ2MyUiDgEUHgEyPgE0LgEHMhYUBiImNDYD5AsREQv9eQ0NggwMvwsREQsBABotGhotNS0aGi0bExoaJRoaAZkNDf15CxERCwPICxERC78MDEEbLRoaLTUtGhotGgsVDAwVCxMaGgETCxERC/5dDAyCDAz+XQsREQsB4xotGhotNS0aGi0bExoaJRoaAs4TGhMgICAgExoTRRouNC0bGy01LRo1GiUaGiUa/tMgIBMaExMaEyAgRhstNS0aGi01LRs2DBQYFQwaJRr+1BMaEyAgICATGhNFGi01LRoaLTUtGjUaJRoaJRoAAAACAAD/gAQAA4AAEwAjAAABISIOARURFB4BMyEyPgE1ETQuAQUhMhYVERQGIyEiJjURNDYDYP1AK0orK0orAsArSisrSv0VAsAoODgo/UAoODgDgCtKK/1AK0orK0orAsArSitAOCj9QCg4OCgCwCg4AAAAAAMAAAAABAADAAADAAcACwAAJRUhNQEVITUBFSE1BAD8AAQA/AAEAPwAOzs7AWM8PAFiOzsAAAAAEAAAAAADAQLEAAsAMQAzADYAOAA6ADwAPgBAAEIARABHAEoATABOAFAAACUyNjQmIyEiBhQWMxM2HgIUBg8BDgEVFBY7ATIWFAYjISImNDY7ATI+ASYnLgE+ATcTMycyIyczJxcnFyczJxcnFScVNR0BNwcVNxU3FTcVAsAOEhIO/kANExMNySJENB0eHBAKDB0UXyEvLyH+YiIwLiFhEBoJCw0pJxBDL3EBCwEBCwEMAgwDMwEOARQLAQECAwRAExoTExoTAn4FEy4/R0EXCwcWDBQcL0MvMEMuEx4fCRlZYEYL/u4EBQYBBwIsFAIpAjkBDQICFAMDFAIQAQ8BAAMAAP+/A8EDQQASACcAPAAAASMiDwEnJisBIgYfARYyNxM2JgMiBwYHBhQXFhcWMjc2NzY0JyYnJgMiJyYnJjQ3Njc2MhcWFxYUBwYHBgK7LxAKnUcKEC8FBAN8CiAK0gMEwHpoZTw9PTxlaPRoZTw9PTxlaHplV1QxMzMxVFfKV1QxMzMxVFcCHw3aYg4JBK0NDQEkBAkBIT08ZWj0aGU8PT08ZWj0aGU8PfzMMzFUV8pXVDEzMzFUV8pXVDEzAAMAAP+/A8EDQQAUACkAPQAAASIHBgcGFBcWFxYyNzY3NjQnJicmAyInJicmNDc2NzYyFxYXFhQHBgcGNyc1NCYrASIGFREUHwEWNj8BNiYCAHpoZTw9PTxlaPRoZTw9PTxlaHplV1QxMzMxVFfKV1QxMzMxVFdKjwUDMAMFA6YCBwIdAQEDQD08ZWj0aGU8PT08ZWj0aGU8PfzMMzFUV8pXVDEzMzFUV8pXVDEz9Wf4AwUFA/7tBAN4AgECJwMGAAX///9/BAADgQAYADcAQwBPAFsAACEXFjMyNzY3NjQnJicmIgcGBwYVFBYfAQcFIicHBi4CPwEuATU0Nz4BNzYyFx4BFxYUBw4BBwYBFA4BIi4BNzQ2MhYXFA4BIi4BNTQ2MhYXFA4BIi4BNTQ2MhYBLwtdaXdmZDo8PDpkZu5mZDo8KyoMNQGLc2e3ECAVBgUvKy0oJ45cX9BfXI4nKCgnjlxf/tUNFxoXDQEcKB30DRcaFw0dKB30DRcaFw0dKB0GLzw6Y2XuZWM6PDw6Y2Z2RoM4EZZYMScDChohEIY/k0xoX1yOJygoJ45cX9BfXI4nKAIADRcODhcNFR0dFQ0XDg4XDRUdHRUNFw4OFw0VHR0AAAUAAP+AA8ADQQAlACkAPQBBAE0AABciJj0BIyImNRE0PgE7ATU0NjMhMhYdATMyHgEVERQGKwEVFAYjJzUhFSURNCYjISIGFREzNTQ2MyEyFh0BAzUhFQciJjQ2MyEyFhQGI+ATG48OFSI6IjQbEwIAExs1IjkiFQ6PGxMb/jYCfB8V/TsWH2kEAwJOAwRJ/jYlDxUVDwEKDxUVD38bE74UDwFkIjohoRMbGxOhIjki/pwPFL4TG0n8/OwBPhYeHhb+wlIDBAQDUgG7hobdFh4VFR4WAAAAAAEAAP/hA+cDgAAJAAAlBRMnJRsBBQcTAgD+0zr0AVGWlgFR9DqAngFP7TEBMf7PMe3+sQABAAAAAALhAwEAQAAAARc3NjIfARYUDwEzMhYdARQGKwEVMzIWHQEUBiMnFRQGKwEiJj0BIyImPQE0NjsBNSMiJj0BNDY7AScmND8BNjIBbYODDigOBw4OdGYUHBwUi4sUHBwUixwUChQcixQcHBSLixQcHBRmdA4OBw4oAvKDgw4OBw4oDnQcFAoUHGocFAoTHQGMFBwcFIwcFAkUHGocFAoUHHQOKA4HDgAAAwAA/8ADwAOAAAsAHQAvAAABNTMVMxUjESMRIzUTBQMGBwYHBg8BJyYnJicmJwMlBRMWFxYXFh8BNzY3Njc2NxMB4ECgoECgwAHAEwU3NFhabR4ebVpYNDcFEwHA/oMPBS8uTE1eFRVeTUwuLwUPAgCAgED/AAEAQAGAcP5mbV9dPD4PBAQPPjxdX20Bmi5f/ptfUk80NgwDAww2NE9SXwFlAAAEAAD/gAPDA4EAJQA9AFEAdAAAJSc1NC4BJy4BIgcGBw4CHQEHBgcGFRQWMyEyNjc2NzY1NicmJwEeAh0BFyE3NTQ+AT8BNTQ3NjMyFhcVBxQXFjMeARcUFjMyNjUmJyYnIgYTJiIHBgcGBwYiJyYnJicuAQYHBhUGFx4BMjY3Njc2NCcmJwOldDRgQAU5RhkTEUNjNW4JBQUqHQLxCiAJCQYFAwcEDP6LOVUtdP0ihy9VNxMKCxIOEwUgBgYOIi0EFRIQFwUwJjkLHJoEEgoNDBobEScMEA0PEAQmIAcJCQkeVWtUHQwFAggFDMZ600N2WxkcJBQOHhNYfEbTeggRDwsYKAgFCREOCw8MBwwCPxBGYDftjJPmNmFGEAYUCwkMEQ8UTBEKDAU2KxAXFRJCLiUREP13BAQHDS4SDAQGDxIhDgsLBQYJExM7Pzw+DAwGEQYEBwAAAAQAAAAABAACwQAMABkANgBTAAABMh4BFA4BIi4BND4BFyIOARQeATI+ATQuAScyFxYXFhcWFAcGBwYHBiInJicmJyY0NzY3Njc2FyIHBgcGBwYUFxYXFhcWMjc2NzY3NjQnJicmJyYCADRYNDRYaFg0NFg0IzojIzpGOiMjOiNkZFdLRCooKCpES1dkyGRXS0QqKCgqREtXZGRXV0xCPCUjIyU8QkxXrldMQjwlIyMlPEJMVwJANFhoWDQ0WGhYNEAjOkY6IyM6RjojwCUhODI3NkY2NzI4ISUlITgyNzZGNjcyOCElQB4aLSgsKzgrLCgtGh4eGi0oLCs4KywoLRoeAAAABf/+AAAD1QKDABMAHwArADcAQwAAEx4BIDY3Ni4BBgcOASAmJy4BDgEXBwYeATY/ATYuAQYXBwYeATY/ATYuAQYFFx4BPgEvAS4BDgE3FxYyNjQvAS4BBhQVNeQBV+Q1BQsYFwMvxP7OxS4EFxgKWmUIBBUYB2YHBBQZrScDDBkWAyYEDRgWAT1GBRgXCQZGBRgXCdF2CRgTCHYIGhICVZmampkMGAoMDIWEhIUMDAoYi5QLGhAEC5QLGhAFmpsMFwcNDZsNFgcNGKkMCgsZDKkMCQsYaYQKEhoKhAkBExoAAAAAAf//AAAEAAMBABMAAAE1NCYjISIGFREUFjMhMjY9ARcRAxwhGP1WGCEhGAKrFyHkAfjNGSIiGf22GSIiGc3rAoYAAAAEAAD/wAQAA0EAEAAoACwAOQAAATIeAhQOAiIuAjQ+AgEzNzY7ATIfATMyFhURFAYjISImNRE0NiUjByEDMj4BNC4BIg4BFB4BAgEaLiUTEyUuNC8kExMlLv5Zx28LDuIQCXDGGiYmGvyAGiYmAj/KOgE+njRYNDRYaFg0NFgBwBMlLjQvJBMTJC8zLyUTAQF2CQl2Jhr9fxomJhoCgRomPT39vzNZaFg0NFhoWTMAAAP////ABAADQAAPABwAJQAAEyEyFhURFAYjISImNRE0NgUhERM+AR8BNzYWFxMBMhYUBiImNDZAA4AbJSUb/IAbJSUDm/yA7AccC5quCiQI6P0gGyUlNiUlA0AlG/0AGyUlGwMAGyVA/TYBXAwECX3zDgIQ/kACVSU2JSU2JQAAB////7gDyAOAAA8AIwA3AEsAXwBzAIcAAAEyFhURFAYjISImNRE0NjMTIw4BHQIeATsCPgE9AScuASMzIw4BHQIeATMhMz4BPQIuASMBIw4BHQIeATsBNz4BPQEnLgEjMyMOAR0CHgEzITc+AT0CLgEjASMOAR0CHgE7ATc+AT0BJy4BIzMjDgEdAh4BMyE3PgE9Ai4BIwNvJTMzJfzpJDQ0JBoECgwCDwlPBQoMAQEPCogEBwoCCwgCEQQICQEMCP0YBAoMAg8JTwUKDAEBDwqIBAcKAgsIAhEECAkBDAj9GAQKDAIPCU8FCgwBAQ8KiAQHCgILCAIRBAgJAQwIA4A0JPzpJTMzJQMXJDT9FAIQCx0FCw0CEAsdBQsNAhALHQULDQIQCx0FCw0BNAIQCx0GCg4BAhALHQULDQIQCx0GCg4BAhALHQULDQE0AhEKHgUKDgEBEQoeBQoOAhEKHgUKDgEBEQoeBQoOAAYAAAAAA4kDAAAPAB8ALwA/AE8AXwAANyMiBh0BFBY7ATI2PQE0JgMjIgYdARQWOwEyNj0BNCYDIyIGHQEUFjsBMjY9ATQmASEiBh0BFBYzITI2PQE0JgMhIgYdARQWMyEyNj0BNCYDISIGHQEUFjMhMjY9ATQmsFQMEBAMVAwQEAxUDBAQDFQMEBAMVAwQEAxUDBAQArb9zgkNDQkCMgoNDQr9zgkNDQkCMgoNDQr9zgkNDQkCMgoNDXISDR8NExMNHw0SAUcSDR8NEhINHw0SAUcSDR8NEhINHw0S/XISDR8NExMNHw0SAUcSDR8NEhINHw0SAUcSDR8NEhINHw0SAAAAAgAA/4AEAQOBABgAHAAAATIXHgEXFhQHDgEHBiInLgEnJjQ3PgE3NgEhFSECAGhfXI4nKCgnjlxf0F9cjicoKCeOXF8BaP4AAgADgCgnjlxf0F9cjicoKCeOXF/QX1yOJyj+Fy4AAAABAAAAAAMAAwAABQAAAQcJARcBAUBAAXD+kEABwAMAO/67/rs7AYAAAQAA/4EEAQOBACIAAAEyFhURITIeARQOASMhERYOASIuATcRIQYuATQ+ARchETQ2AgIXIQGNDxsPDxsP/nMBDxsfGw8B/nMQGxAQGxABjSEDgCEY/nMPGh4bD/5zDxwQEBwPAY0BDxsfGw8BAY0YIQAAAAAC////gAQBA4EAGwAsAAABMhceARcWFRQHDgEHBiMiJy4BJyY1NDc+ATc2FyIGFREUHwEWMjY0LwE1NCYB+mphXY8nKCgnj11hamZeW4wnKCgnjFtecgoNCa0GEg0GqA0DgCgnj11hamZeW4wnKCgnjFteZmphXY8nKNwNCf74CwetBg0SBqn/CQ0AAAT///+KA/YDgAAYAC0AMQA1AAABMhceARcWFAcOAQcGIicuAScmNDc+ATc2FyIHBgcGEBcWFxYgNzY3NhAnJicmAxUjNRMRIxEB+2deW4wnKCgnjFtezl5bjSYoKCaNW15ngnBsP0JCP2xwAQRvbT9CQj9tb3QcHBwDgCgmjVtezl5bjCcoKCeMW17OXluNJigcQj9scP78b20/QkI/bW8BBHBsP0L9eFRUAaf+rgFSAAAAAAT///+KA/YDgAAYAC0AMQA1AAABMhceARcWFAcOAQcGIicuAScmNDc+ATc2FyIHBgcGEBcWFxYgNzY3NhAnJicmCQE3AQMBJwEB+2deW4wnKCgnjFtezl5bjSYoKCaNW15ngnBsP0JCP2xwAQRvbT9CQj9tb/6zAY8U/nEEAY8U/nEDgCgmjVtezl5bjCcoKCeMW17OXluNJigcQj9scP78b20/QkI/bW8BBHBsP0L+2v5xFAGP/lsBjhT+cgAAAAP///9/BAADgQAYADEANwAAATIXHgEXFhQHDgEHBiInLgEnJjQ3PgE3NhciBw4BBwYUFx4BFxYyNz4BNzY0Jy4BJyYBBxcBJwECAGhfXI4nKCgnjlxf0F9cjicoKCeOXF9oYlpXhiUmJiWGV1rEWleGJSYmJYZXWv6rFK4BRxT+zQOAKCeOXF/QX1yOJygoJ45cX9BfXI4nKBwmJYZXWsRaV4YlJiYlhldaxFpXhiUm/hYUtAFKFP7LAAAAA///AAAEAAIBAAwAGQAmAAATFA4BIi4BND4BMh4BJTIeARQOASIuATQ+ASEyHgEUDgEiLgE0PgHNHC83LxwcLzcvHAEzHC8bGy84LxsbLwG2Gy8cHC83LxwcLwGaHC8cHC83LxwcL0scLzcvHBwvNy8cHC83LxwcLzcvHAAAAAABAAAAAAOCAnoABwAAJQEHJwEXCQEDgf6BAgL+gU4BMwEz2wGfAwP+YVUBTf6zAAABAAAAAAOCAnoABwAACQEnBwE3CQEDgf6BAgL+gU4BMwEzAiX+YQMDAZ9V/rMBTQAC////fwQAA4EAGAA0AAABIgcOAQcGFBceARcWMjc+ATc2NCcuAScmEx4BBiIvAQcGIiY0PwEnLgE2Mh8BNzYyFhQPAQIAaF9cjicoKCeOXF/QX1yOJygoJ45cX4kJARMaCsTEChoTCsPDCQETGgrExAoaEwrDA4AoJ45cX9BfXI4nKCgnjlxf0F9cjico/UEKGhMJwMAJExsJv78KGhMJwMAJExsJvwACAAD/wAPAA0AAGgAvAAAFJwYHBiMiJyYnJjQ3Njc2MhcWFxYVFAcGBxcBIgcGBwYUFxYXFjI3Njc2NCcmJyYDg9M0QEg8ZlhVMjMzMlVYzFdVMjMTEiLY/fhRRUQnKSknREWhRUQnKSknREVA4ykbHjQzV1nRWVczNDQzV1lpPTo4MNwC6yooREelR0QpKSkpREelR0QoKgAAAAACAAD/gAQBA4AAGAAqAAABMhceARcWFAcOAQcGIicuAScmNDc+ATc2ASYiBwEnJg4BFB8BFjI3ATY0AgBoX1yOJygoJ45cX9BfXI4nKCgnjlxfAWEHEwf+3Y0HEw0GnQcTBwE0BwOAKCeOXF/QX1yOJygoJ45cX9BfXI4nKP6zBwf+3Y0GAQ0SB50HBwEzBxQAAAAAAQAAAAADgAKAAAUAAAkBJwcXAQMu/nyeTOoB1gKA/mCoV/EB8AAAAAIAAAAAArACgAATACQAAAEUHgEyPgE1MxQOAQcVIzUuAjU3Mh4BHQEUDgEiLgE9ATQ+AQFtKENQQygdK0ktHi1JK7AcLxwcLzgvHBwvAYcnRCcnRCctTTEEWFgEMU0t+RwvHJEcLxwcLxyRHC8cAAABAAD/gANBA4AAEQAAARUBNjQmIgcBBhQXARYyNjQnAT0B+QoVHQv+BwoKAfkLHRUKAZgwAd4KHBQK/iIKHAr+IgoUHAoAAAAEAAD/mAQAA4AAAwAaAC8ASAAAJTM1IxMiBwYXMyY3FhcWDwEGBwYXMyY3NicmAyInJicmNDc2NzYyFxYXFhQHBgcGAyIHDgEHBhQXHgEXFjI3PgE3NjQnLgEnJgHXRkYtPSo9AkACYU4IBjsFLwkOAz0ISEMDCI90ZGE5Ozs5YWToZGE5Ozs5YWR0aF9cjicoKCeOXF/QX1yOJygoJ45cX3pIAcUgKVlsAwNPKDEFLxgbNEozPDl9/W06N19h42FfODk5OF9h42FfNzoDlicmi1ldy11ZiyYnJyaLWV3LXVmLJicAAAAABf///7MDywN+AA8AGwAnADMAPwAAASEiBh0BFBYzITI2PQE0JgE1IxEUFjMhNSMiJhE0NjsBNSEiBh0BMwEUBisBFSEyNjURIxMhFTMyFh0BMzU0JgOx/GgKDw8KA5gKDw/8llEqHgEW1xcfHxfX/uoeKlEDKB8W2AEWHipRCf7q2BYfUSoBzg8KHgsPDwseCg/+bPP+zh4qUSAC0xYgUCoe+/4AFx9RKh4BMgJRUSAWvfseKwAAAAX//f+PA+UDgQAXADMAPABFAE4AAD8BJy4BNTQ+AjIWFx4BFAYHDgEjIicjASYnJicmIgcGBwYHBhYXFhcVNxYzMjc2Nz4BNAUyNjQmIgYUFiciBhQWMjY0JgUyNjQmIgYUFvsCAVJlQnidrJ09OkREOj2dVjM1AQI0J0RGWF7JXVdHRCcqBjAzVNwvLWZcWEZETv4OGyYmNiYm3BsmJjYmJgHTGycnNiYmCo0BMaFdTYdoODg1MoiZiDI1OAwCE1E7PiAjIyA+O1FXwlRaO+KICCMgPjuitZwmNyYmNyaDJjcmJjcmgyY3JiY3JgAAAAL///+FBAEDRQBvAJMAAAEmBgcOAgcUFxYXFhcWFxYGBwYPAQYPAQYHBgcGBwYPAQYVFBcWPgE3Nj8BNDc2NzY3Nj8BNjc2NzY0Ji8BJicmJyY3PgIeARcWBwYHBg8BBgcGBwYWFzI7ATI3NicmNSY3PgE3Njc+AScmJy4BATU0JisBIgYdASMiBh0BFBY7ARUUFjsBMjY9ATMyNj0BNCYjAfEsWichMRoBCAkPCQ0TBQUCBgoZAREhJTEgLRMLBAIBAgIOCRkTAgEBBAIDFA0WITEbJRItDgkPDAsMBBIGBwYHNlVaPwkHBAUPBgUODgoKAQEECQULIQsDAQQCAQ4EEwQVCgoBCQsZGEIBNQ4KEgkOnAkODgmcDgkSCg6bCg4OCgM6Cg0XEjtJNjIuMh4TDhMNChUHCg4BCRATGhYfHhIVCxYgFAkVCwcBEAsFCjsOBhASDQ8VGg0SChseEisoEQ0OCB88OCgvPBsUOzAkNjokDAgQERQWFQsXAQkEBwUCEBUGFgcgMS1iJi0hHij9WZsKDg4Kmw4KEgkOrAoODgqsDQoSCg4AAAAABAAA/7gDyAOBAAwAGQAwAEUAAAEiLgE0PgEyHgEUDgEnMj4BNC4BIg4BFB4BEyInLgE1NDc+ATc2MhceARcWFRQGBwYnMjc+ATU0LgEnJiIHDgIVFBYXFgHkSHlHR3mPekdHekc7ZTw8ZXdlOztlPLFibWQpKItVWrJZVYsoKWRsY7CdX2FaSn9MUqFSTH9KWmJeAZxBb4RvQUFvhG9BLDZabFs1NVtsWjb98Q4QTUY8QD1oHh8fHmg9QDxGTRAOLAwMNi0zcF8cHh4cX3AzLTYMDAACAAD/uAPIA4EADAAjAAABIi4BND4BMh4BFA4BAyInLgE1NDc+ATc2MhceARcWFRQGBwYB5Eh5R0d5j3pHR3pHsWJtZCkoi1VasllViygpZGxjAZxBb4RvQUFvhG9B/h0OEE1GPEA9aB4fHx5oPUA8Rk0QDgAAAAADAAD/uAPIA4AAQQB/AMsAAAEzFhcWFxYXFh0BBgcGDwEGBwYHFRQWHwEWFxYdARYOASMhIiYnJic1NDY3Nj8BPgE3NSYnJi8BJicmJzU0NzY3NhcGBwYdARYXFh8BFhcWFxYVFA4BDwEOAR0BHgIzITI+AT0BNCcmLwIuATU0NzY3Nj8BNjc2NzU0JyYnIwEzMj4BJzU0JicmLwEuAj0BNjc2PwE2NzY3NTQnJicmJyYrASIGFBY7ARYXFh0BFAYHBgcGBxQVFB4BHwEWFxYdARQOASsBDgEUFgGaDxkaHhovGBoBBwsbCAcGDAEZJUVUIiUBDx8W/UQWIAcGASUoJUIkKRwBAQwGBwgaDAcBGhgvMTMqI0wBBgoTCAgIEQMBEScmOkdAAQQKCQK8CQkFJiVTIxIsIAEDEQcJCBMKBgFMJy4NAeIHFx8OAScqJ0YeGxsJBAoEBgUaDQoBGxkxGh0YFgwJDAwJDColUBUTCwgRAxAnJQpgKSwFCgkHCQwMA1QBBwkRHjE0RxEsK0YkCggKEw8IExsVJjAkJi49EiMUFBIOD0MhOB4aJRMXGxIMDxMKCAokRissEUc0MR4fLAQXL3MRKCc6GgkKDhwZBQYZJCEVICk8G0MFDAUFDAVCHiIgLhMKGi0iBgUZHAwMCRo6JygRcjAZA/y/FCISPiE5HxwnEBAVFA8FExAIBwYfPzEyF0o0Mx0PCAcNEg0DFTB4DTJmFg0OHBkFBRkjIRUGNCMlIT4IDgUBDBMMAAACAAD/uAPIA4AAQQCNAAABMxYXFhcWFxYdAQYHBg8BBgcGBxUUFh8BFhcWHQEWDgEjISImJyYnNTQ2NzY/AT4BNzUmJyYvASYnJic1NDc2NzYBMzI+ASc1NCYnJi8BLgI9ATY3Nj8BNjc2NzU0JyYnJicmKwEiBhQWOwEWFxYdARQGBwYHBgcUFRQeAR8BFhcWHQEUDgErAQ4BFBYBmg8ZGh4aLxgaAQcLGwgHBgwBGSVFVCIlAQ8fFv1EFiAHBgElKCVCJCkcAQEMBgcIGgwHARoYLzECHQcXHw4BJyonRh4bGwkECgQGBRoNCgEbGTEaHRgWDAkMDAkMKiVQFRMLCBEDECclCmApLAUKCQcJDAwDVAEHCREeMTRHESwrRiQKCAoTDwgTGxUmMCQmLj0SIxQUEg4PQyE4HholExcbEgwPEwoICiRGKywRRzQxHh/8lBQiEj4hOR8cJxAQFRQPBRMQCAcGHz8xMhdKNDMdDwgHDRINAxUweA0yZhYNDhwZBQUZIyEVBjQjJSE+CA4FAQwTDAAAAAAFAAD/uANyA4EAJgAyAD8AWABqAAAFISImNRE0NjMhMhYVERQWMjY1ETQuASMhIg4BFREUHgEzITI2NCYnMzIWFAYHIyImNDYnNDYzITIWFAYjISImAS8BJiIPAg4BHwEHBhY/ARcWNi8BNzYmAwcGJi8BJjcTPgEfAR4BBwMGAdT+7xkkJBkCRhkkDRINHDEc/bocMB0dMBwBEQkNDb2wCQ0NCbAJDQ0NDgoBMAoODgr+0AoOAXlbMwcUBzNXDQkIOAkBEAxiYQ0QAgk4BwkhJwYJAQcBB+QKIA8GEAcL4AQbJBoC8xokJBr+rgkNDQkBUh0wHR0wHf0NHTEcDRIN2wwTDAENEwxuCgwMEw0NAXoLSAoKSQsCEAtQVAwLBB4eAwsMVFALEf0sCAEGBSINDAE1DQcIAwkkD/7QBgAAAAUAAP9/A4EDgAAQACYAMwBAAFkAAAEyFhURFA4BIyEiJjURNDYzAQcDBh0BFx4BOwE3Nj8BEzYmLwEmBgUjIgYUFh8BMzI2NCY3ISIGFBYXMyEyNjQmAw8BDgEfAQcGFj8BFxY2LwE3NiYvAiYiAyQmNiZAJv2oJjY2JgJFBdkFBwEHBAQkCwoC1woEDAgOH/6nsgkNCgcFsgkNDZL+tgoPDAkEAUoLDw9uNVsOCQg7CQIRDWdmDhABCzsICQ5gNQgVA4A3JvzpJkAmNyYDRiY3/Z0G/tYJCgUfBQYIBAgCASgNHwoFCASREBYQAgERGBCMERYQAhEXEQHGTAwCEgtUWQ0MBCEgBAwNWFYLEQIMTAoAAAX/+/+ABAUDhQAlAEYATwBYAHUAADcnLgE2NwE+ARYfAT4BMzIeAR0BFx4BBg8BFRQOAiMhIi4CNQkBBwYWHwETHgEzIT4BNRE/ATYmLwE3Jy4BIgYdAScmBhMyFhQGIiY0NiEyFhQGIiY0NgUOAiIuASc1NDYyFhcVHgIyPgE3NDc+ATMyFnZRGBERGAGAGUJBGFwJOiUeMR1SGBESGVATJC8a/e0aLyQTAVD+gAUUAxZeAQIvIAIaICtfBRQDFmABAQIjMSSsGD/DDRMTGhMT/s0NExMaExMBrQtJbX5tSQsNEQ0BCj1aZ1k9CgIDCwYKDf9KGUJCGQFbGREQGFMkLh4xHqVKGUJDGkj+Gi8kFBQkLxoDOP6mBhlAFlb+5iArAy8gARNWBhhAF1a5BxcgJBpLmxUD/nATGhMTGhMTGhMTGhPTQ2w+PmtDAwcKCQcCNlcxMVc2AgUGBQkAAAAEAAD/gAQAA4AAHQAmAC8ATAAAASc1NCYiBh0BJyYiBwEGFB8BERQWMyEyNjURNzY0JTIWFAYiJj4BITIWFAYiJjQ2BQ4CIi4BJzU0NjIWHQEeAjI+ATc0Nz4BMzIWA+ZpJzgothtKG/5aGhpoNCUCSCU1aRr+nBMaGiUbARr+7xIaGiUaGgGiC0txg3FLDA0SDgs/XWtdPwoCBAsGCg0B6F/MHCgoHFOlGxv+gxtLGl/+0iY1NSYBLl8aSwgaJhoaJhoaJhoaJhr7P2c7Omc/AwcJCQYBNFMvL1M0AQQHBAkAAAAAABIA3gABAAAAAAAAABMAAAABAAAAAAABAAgAEwABAAAAAAACAAcAGwABAAAAAAADAAgAIgABAAAAAAAEAAgAKgABAAAAAAAFAAsAMgABAAAAAAAGAAgAPQABAAAAAAAKACsARQABAAAAAAALABMAcAADAAEECQAAACYAgwADAAEECQABABAAqQADAAEECQACAA4AuQADAAEECQADABAAxwADAAEECQAEABAA1wADAAEECQAFABYA5wADAAEECQAGABAA/QADAAEECQAKAFYBDQADAAEECQALACYBY0NyZWF0ZWQgYnkgaWNvbmZvbnRpY29uZm9udFJlZ3VsYXJpY29uZm9udGljb25mb250VmVyc2lvbiAxLjBpY29uZm9udEdlbmVyYXRlZCBieSBzdmcydHRmIGZyb20gRm9udGVsbG8gcHJvamVjdC5odHRwOi8vZm9udGVsbG8uY29tAEMAcgBlAGEAdABlAGQAIABiAHkAIABpAGMAbwBuAGYAbwBuAHQAaQBjAG8AbgBmAG8AbgB0AFIAZQBnAHUAbABhAHIAaQBjAG8AbgBmAG8AbgB0AGkAYwBvAG4AZgBvAG4AdABWAGUAcgBzAGkAbwBuACAAMQAuADAAaQBjAG8AbgBmAG8AbgB0AEcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAAcwB2AGcAMgB0AHQAZgAgAGYAcgBvAG0AIABGAG8AbgB0AGUAbABsAG8AIABwAHIAbwBqAGUAYwB0AC4AaAB0AHQAcAA6AC8ALwBmAG8AbgB0AGUAbABsAG8ALgBjAG8AbQAAAgAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC9AQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE3ATgBOQE6ATsBPAE9AT4BPwFAAUEBQgFDAUQBRQFGAUcBSAFJAUoBSwFMAU0BTgFPAVABUQFSAVMBVAFVAVYBVwFYAVkBWgFbAVwBXQFeAV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFzAXQBdQF2AXcBeAF5AXoBewF8AX0BfgF/AYABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+AAlzLW1vcmUtbzEIcy1kZWxldGUIcy1iYWNrLW8Gcy1zY2FuEHMtb3JnYW5pemF0aW9uLW8Jcy1ncm91cC1vCXMtZmlsdGVyMQlzLWNsZWFyLW8Ocy1pbGx1c3RyYXRlLW8Icy1tb21lbnQIcy1zaG9wLW8Kcy1tb21lbnQtbwZzLXNob3AKcy1yZXZva2UtbwpzLXN1Ym1pdC1vB3MtYXBwLW8Gcy1ib29rBXMtYXBwBHMtbXkJcy1jb21tZW50C3MtY29tbWVudC1vCHMtYm9vay1vBnMtbXktbwxzLWxvY2F0aW9uLW8Kcy1sb2NhdGlvbgZzLW5ld3MIcy1uZXdzLW8Jcy1TZW5kaW5nCnMtSW1wb3J0LW8Icy1FZGl0LW8Icy1RUmNvZGULcy1CcmllZmNhc2URcy1Ob3RpZmljYXRpb25vZmYIcy1QZW5jaWwIcy1TdGFyLW8Jcy1CYXJDb2RlD3MtU2FsZU1lc3NhZ2UtbwxzLUxpc3R2aWV3LW8Lcy1QaWN0dXJlLW8Ocy1TYXZlRmlsbGV0LW8Ocy1TaG9wcGluZ2NhcnQJcy1QZW5kaW5nDnMtRXhwYW5kdmlldy1vCHMtTG9jay1vCXMtU2VydmljZQpzLVdhbGxldC1vEHMtU2hvcHBpbmdjYXJ0LW8Lcy1TZXR0aW5nLW8Ncy1VbmZvbGRSZWMtbwlzLVByb2ZpbGUGTGluay1vDVVzZXJTZXR0aW5nLW8Jcy1hZ3JlZS1vDHMtYXJyb3ctZG93bgdzLWFkZC1vB3MtYW5uZXgMcy1hcnJvdy1sZWZ0CnMtYXJyb3ctdXAScy1jaGVja2JveC1jaGVja2VkCnMtY2hlY2tib3gHcy1hcnJvdwpzLWV4Y2hhbmdlB3MtY2xlYXIJcy1jaGVja2VkB3MtZXllLW8Lcy1jbG9zZS1leWUEcy1hdAxzLWZlZWRiYWNrLW8Pcy1mb2xkLWNpcmNsZS1vB3MtY3Jvc3MHcy1taW51cwZzLWZpbGUPcy1mb2xkLXRyaWFuZ2xlCHMtZmlsdGVyCXMtZm9yd29yZAZzLXBsdXMJcy1maWxlZGVsCHMtZm9sZC1vCXMtaW1hZ2UtbwhzLW1vcmUtbw5zLXJlZGlvLWNpcmNsZQpzLXJlamVjdC1vCXMtc3VjY2VzcwlzLXJlZnJlc2gGcy1zdGFyDXMtcHJvY2Vzc2Zsb3cRcy11bmZvbGQtY2lyY2xlLW8Icy1yZXdpbmQKcy11bmZvbGQtbwtzLXdhcm5pbmctbxFzLXVuZm9sZC10cmlhbmdsZQlzLXByaW50LW8Kcy1zZWFyY2gtbwhBaXJwbGFuZQVUcmFpbgNCdXMEVGF4aQxvdmVydGltZW1lYWwTZm0taS10cmFmZmljZGV0YWlscw9mbS1pLXRyYWZmaWNzdWITZm0taS1hY2NvbW1vZGF0aW9uMQ1mbS1pLWJ1c2luZXNzC2ZtLWktYnVkZ2V0CWZtLWktZ2lmdBFmbS1pLWNhbmNlbGxhdGlvbgxmbS1pLWludm9pY2UJZm0taS1saXN0CmZtLWktbWVhbHMIZm0taS1wYXkMZm0taS1zdWJzaWR5B3Nob3V6aGUTZm0taS1jb3N0YWxsb2NhdGlvbgxmbS1pLXBheW1lbnQOZm0taS1JdGluZXJhcnkOZm0taS1tb3JleGUwMmQPZm0taS1pbWFnZXhlMDJlEGZtLWktcmVqZWN0eGUwMmYPZm0taS1hZ3JlZXhlMDMxDWZtLWktY2FyZGZvbGQPZm0taS1jYXJkdW5mb2xkEWZtLWktdHJhZmZpY290aGVyD2ZtLWktYm90dG9tc2F2ZRBmbS1pLXRyYWZmaWNib2F0D2ZtLWktdHJhZmZpY2NhchFmbS1pLXRyYWZmaWNwbGFuZRFmbS1pLXRyYWZmaWN0cmFpbg9mbS1pLXRyYWZmaWNidXMMZm0taS1hZGRncmF5CmZtLWktY2xvc2UIZm0taS1hZGQJZm0taS1tb3JlCmZtLWktY2hlY2sPZm0taS1iYWNrY2lyY2xlCmZtLWktYWdyZWUMZm0taS1sb2FkaW5nDGZtLWktZmlsZWRlbAlmbS1pLWZpbGUQZm0taS1wcm9jZXNzZmxvdwxmbS1pLXJlZHN0YXIQZm0taS1yaWdodGNpcmNsZQ9mbS1pLXRpbWVjaXJjbGUOZm0taS1zY3JlZW5pbmcMZm0taS11bmNoZWNrDmZtLWktb3BlcmF0aW9uE2ZtLWktYXBwcm92YWxhbW91bnQLZm0taS1hZ3JlZWQOZm0taS1pbnByb2Nlc3MNZm0taS1mZWVkYmFjawpmbS1pLXByaW50DmZtLWktaW1wb3J0YW50GmZtLWktYW1vdW50b2ZyZWltYnVyc2VtZW50FGZtLWktc2FmZXR5YXNzaXN0YW50C2ZtLWktcmVtaW5kDWZtLWktZXllb3BwZW4NZm0taS1leWVjbG9zZRBmbS1pLVBob3RvZ3JhcGh5D2ZtLWktcGhvdG9ncmFwaA9mbS1pLWFkZHBpY3R1cmUTZm0taS10b3Bfb3RoZXItZmFjZQ5mbS1pLXRvcF9vdGhlcgtmbS1pLWRlbGV0ZQ1mbS1pLW5leHRwYWdlDmZtLWktYWRkYnV0dG9uFmZtLWktd2FpdGZvcnByb2Nlc3NpbmcTZm0taS13YXJuaW5nbWVzc2FnZRJmbS1pLWZhaWx1cmVwcm9tcHQUZm0taS1zdWNjZXNzZnVsaGludHMKZm0taS1vdGhlcgxmbS1pLXJldHJhY3QOZm0taS1kcm9wLWRvd24LZm0taS1jYW5jZWwLZm0taS1zZWFyY2gTZm0taS1tdWx0aXBsZWNob2ljZRFmbS1pLXNpbmdsZWNob2ljZQ9mbS1pLW1pY3JvcGhvbmUXZm0taS1hcnJvdy1jaGV2cm9uLWxlZnQPZm0taS1oZWxwY2VudGVyDmZtLWktc3dlZXBjb2RlDmZtLWktZ3JvdXBjaGF0DmZtLWktYWRkZnJpZW5kC2ZtLWktdG9wX215EGZtLWktdG9wX215LWZhY2UPZm0taS10b3BfZnJpZW5kFGZtLWktdG9wX2ZyaWVuZC1mYWNlFWZtLWktdG9wX3B1YmxpY3ByYWlzZRpmbS1pLXRvcF9wdWJsaWNwcmFpc2UtZmFjZQ1mbS1pLXRvcF9ob21lEmZtLWktdG9wX2hvbWUtZmFjZQAAAAA=) format("truetype")}@keyframes fm-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fm-fade-out{0%{opacity:1}to{opacity:0}}.fm-fade-enter-active{animation:.3s fm-fade-in both ease-out}.fm-fade-leave-active{animation:.3s fm-fade-out both ease-in}.fm-slide-up-enter-from,.fm-slide-up-leave-to{transform:translate3d(0,100%,0)}.fm-slide-down-enter-from,.fm-slide-down-leave-to{transform:translate3d(0,-100%,0)}.fm-slide-left-enter-from,.fm-slide-left-leave-to{transform:translate3d(-100%,0,0)}.fm-slide-right-enter-from,.fm-slide-right-leave-to{transform:translate3d(100%,0,0)}.fm-slide-up-enter-active,.fm-slide-down-enter-active,.fm-slide-left-enter-active,.fm-slide-right-enter-active{transition-timing-function:ease-out}.fm-slide-up-leave-active,.fm-slide-down-leave-active,.fm-slide-left-leave-active,.fm-slide-right-leave-active{transition-timing-function:ease-in}.fm-slide-in-enter-active,.fm-slide-in-leave-active,.fm-slide-out-enter-active,.fm-slide-out-leave-active{will-change:transform;transition:all .3s;height:100%;width:100%;top:0;position:absolute;backface-visibility:hidden;perspective:1000}.fm-slide-in-leave-to,.fm-slide-out-enter-from{transform:translate(-100%);opacity:0}.fm-slide-in-enter-from,.fm-slide-out-leave-to{transform:translate(100%);opacity:0}@keyframes fm-drop-down-in{0%{height:0;opacity:0}to{opacity:1}}@keyframes fm-drop-down-out{0%{opacity:1}to{height:0;opacity:0}}.fm-drop-down-enter-active{animation:.3s fm-drop-down-in both ease-out}.fm-drop-down-leave-active{animation:.3s fm-drop-down-out both ease-in}@keyframes fm-rotate{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}:root{--fm-button-height: 42px;--fm-button-padding: 0 14px;--fm-button-radius: 2px;--fm-button-border-width: 1px;--fm-button-color: var(--fm-white);--fm-button-line-height: var(--fm-line-height);--fm-button-font-size: var(--fm-font-size);--fm-button-plain-background: var(--fm-white);--fm-button-lg-height: 46px;--fm-button-lg-font-size: 18px;--fm-button-md-height: 38px;--fm-button-md-font-size: 14px;--fm-button-sm-height: 34px;--fm-button-sm-padding: 0 8px;--fm-button-sm-font-size: 12px;--fm-button-xs-height: 28px;--fm-button-xs-font-size: 10px;--fm-button-secondary-color: var(--fm-blue-light)}.fm-button{position:relative;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;text-align:center;margin:0;border:none;transition:opacity .2s;color:var(--fm-button-color);height:var(--fm-button-height);padding:var(--fm-button-padding);font-size:var(--fm-button-font-size);line-height:var(--fm-button-line-height);border-radius:var(--fm-button-radius)}.fm-button--primary,.fm-button--info{background:var(--fm-primary-color)}.fm-button--secondary{color:var(--fm-primary-color);background:var(--fm-button-secondary-color)}.fm-button--danger{background-color:var(--fm-danger-color)}.fm-button--warning{background-color:var(--fm-warning-color)}.fm-button--success{background-color:var(--fm-success-color)}.fm-button--plain{box-shadow:none;background:var(--fm-button-plain-background)}.fm-button--plain.fm-button--primary,.fm-button--plain.fm-button--info{color:var(--fm-primary-color);border:var(--fm-button-border-width) solid var(--fm-primary-color)}.fm-button--plain.fm-button--success{color:var(--fm-success-color);border:var(--fm-button-border-width) solid var(--fm-success-color)}.fm-button--plain.fm-button--danger{color:var(--fm-danger-color);border:var(--fm-button-border-width) solid var(--fm-danger-color)}.fm-button--plain.fm-button--warning{color:var(--fm-button-warning-color);border:var(--fm-button-border-width) solid var(--fm-button-warning-color)}.fm-button--noborder{border:none!important}.fm-button--large{height:var(--fm-button-lg-height);font-size:var(--fm-button-lg-font-size)}.fm-button--normal{height:var(--fm-button-md-height);font-size:var(--fm-button-md-font-size)}.fm-button--small{height:var(--fm-button-sm-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-sm-font-size)}.fm-button--mini{height:var(--fm-button-xs-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-xs-font-size)}.fm-button--block{display:flex;width:100%}.fm-button--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-button--loading:before,.fm-button--disabled:before{display:none}.fm-button--round{border-radius:var(--fm-radius-max)}.fm-button--square{border-radius:0}.fm-button__loading{display:inline-block;width:20px;max-width:100%;height:20px;max-height:100%;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-button__loading circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}.fm-button__loading-icon-circular{color:#fff}.fm-button__loading-text{margin-left:6px}.fm-button__icon:not(:last-child){margin-right:6px}.fm-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;background-color:#000;border:inherit;border-color:#000;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;content:" "}.fm-button:active:before{opacity:.1}.fm-button-edit__tags{min-height:24px;flex:1;display:flex;overflow:auto}.fm-button-edit__tag:not(:last-child){margin-right:6px}:root{--fm-button-group-gap: 16px}.fm-button-group{display:inline-flex;flex-wrap:nowrap;max-width:100%}.fm-button-group+.fm-button-group{margin-left:var(--fm-button-group-gap)}.fm-button-group__item{margin:0;min-width:0;max-width:100%;white-space:nowrap;flex:0 1 auto;user-select:none}.fm-button-group__item--bare-vertical{display:inline-flex;flex-direction:column;align-items:center;justify-content:space-between;color:#666}.fm-button-group__item--bare-vertical .fm-button-group__item-icon{font-size:20px}.fm-button-group__item--bare-vertical .fm-button-group__item-text{font-size:10px;line-height:16px}.fm-button-group__item--bare-vertical.fm-button-group__item--disabled{cursor:not-allowed;opacity:.5}.fm-button-group--block{display:flex}.fm-button-group--vertical{flex-direction:column}.fm-button-group--block .fm-button-group__item{width:auto;flex:10000 1 0%}.fm-button-group--horizontal.fm-button-group--mode-default .fm-button-group__item+.fm-button-group__item{margin-left:var(--fm-button-group-gap)}.fm-button-group--vertical.fm-button-group--mode-default .fm-button-group__item+.fm-button-group__item{margin-top:var(--fm-button-group-gap)}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:not(:first-child):not(:last-child),.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:not(:first-child):not(:last-child){border-radius:0}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:first-child{border-bottom-left-radius:0;border-bottom-right-radius:0}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:last-child{border-top-left-radius:0;border-top-right-radius:0}.fm-button-group--horizontal.fm-button-group--mode-outline .fm-button-group__item:not(:first-child){border-left:0}.fm-button-group--vertical.fm-button-group--mode-outline .fm-button-group__item:not(:first-child){border-top:0}.fm-button-group--horizontal.fm-button-group--mode-text .fm-button-group__item:not(:last-child){border-right:var(--fm-button-border-width) solid currentColor!important}.fm-button-group--vertical.fm-button-group--mode-text .fm-button-group__item:not(:last-child){border-bottom:var(--fm-button-border-width) solid currentColor!important}.fm-button-group--fill{flex:1}:root{--fm-cell-padding: 10px 16px;--fm-cell-margin: 5px;--fm-cell-line-height: 24px;--fm-cell-font-size: var(--fm-font-size);--fm-cell-background: var(--fm-background-white);--fm-cell-color: var(--fm-text-color);--fm-cell-label-font-size: 12px;--fm-cell-label-line-height: 18px;--fm-cell-label-color: var(--fm-text-color-light);--fm-cell-required-color: var(--fm-danger-color)}.fm-cell{width:100%;padding:var(--fm-cell-padding);background-color:var(--fm-cell-background);color:var(--fm-cell-color);font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);position:relative;display:flex;overflow:hidden}.fm-cell--bottom-border,.fm-cell:not(:last-child){border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-cell--bottom-border:after,.fm-cell:not(:last-child):after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-cell--bottom-border:after,.fm-cell:not(:last-child):after{left:16px!important}.fm-cell.fm-cell-all-width:not(:last-child):after{left:0!important}.fm-cell--clickable{cursor:pointer}.fm-cell--clickable:active{background-color:var(--fm-active-color)}.fm-cell--required .fm-cell-title{position:relative}.fm-cell--required .fm-cell-title .fm-cell-title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-cell__title,.fm-cell__value{flex:1;font-size:inherit}.fm-cell__title{display:inline-block;overflow:hidden}.fm-cell__title-text{display:flex;word-break:break-all}.fm-cell__title-text span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-cell__right{display:flex;overflow:hidden;flex-direction:column}.fm-cell__right-content{display:flex;flex:1}.fm-cell__right--fill{flex:1}.fm-cell__value{position:relative;overflow:hidden;text-align:right;vertical-align:middle;word-wrap:break-word}.fm-cell__value--alone{text-align:left}.fm-cell__label{margin-top:var(--fm-cell-margin);color:var(--fm-cell-label-color);font-size:var(--fm-cell-label-font-size);line-height:var(--fm-cell-label-line-height)}.fm-cell--center{align-items:center}.fm-cell__extra,.fm-cell__left-icon,.fm-cell__right-icon{min-width:1em;font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);display:flex;align-items:center}.fm-cell__left-icon{margin-right:var(--fm-cell-margin)}.fm-cell__extra,.fm-cell__right-icon{margin-left:var(--fm-cell-margin)}.fm-cell--noborder .fm-cell:after{display:none!important}.fm-cell--card{padding-left:0;padding-right:0}.fm-checkbox-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-checkbox-group--vertical{flex-direction:column}.fm-checkbox-group--vertical .fm-checkbox:not(:last-child){margin-bottom:8px}.fm-checkbox{margin-top:4px;margin-bottom:4px}:root{--fm-checker-color: var(--fm-text-color);--fm-checker-font-size: var(--fm-font-size);--fm-checker-icon-color: var(--fm-text-color-light);--fm-checker-icon-background: var(--fm-background-white);--fm-checker-icon-radius: var(--fm-radius-md);--fm-checker-checked-icon-color: var(--fm-primary-color);--fm-checker-button-background: var(--fm-gray-2);--fm-checker-disabled-color: var(--fm-disabled-color);--fm-checker-disabled-icon-color: var(--fm-gray-1)}.fm-checker{display:flex;align-items:center;color:var(--fm-checker-color);font-size:var(--fm-checker-font-size)}.fm-checker__icon{display:inline-block;align-items:center}.fm-checker__icon .fm-icon{display:block;height:20px;width:20px;line-height:18px;font-size:14px;text-align:center;border-radius:var(--fm-checker-icon-radius);border:1px solid var(--fm-checker-icon-color);color:var(--fm-checker-icon-background);background-color:var(--fm-checker-icon-background)}.fm-checker__label{margin-left:8px;margin-right:8px;display:inline-block;line-height:20px}.fm-checker:first-child .fm-checker_button{margin-left:0}.fm-checker--round .fm-checker__icon .fm-icon{border-radius:100%}.fm-checker--button .fm-checker__label{font-size:13px;text-align:center;border-radius:14px;line-height:28px;padding:0 12px;min-width:60px;margin-right:0;color:var(--fm-checker-color);background:var(--fm-checker-button-background)}.fm-checker--checked .fm-checker__icon .fm-icon{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-checked-icon-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--checked.fm-checker--button .fm-checker__label{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--readonly{opacity:var(--fm-readonly-opacity)}.fm-checker--disabled{color:var(--fm-checker-disabled-color)}.fm-checker--disabled .fm-checker__icon .fm-icon{border-color:var(--fm-checker-disabled-color);background-color:var(--fm-checker-disabled-icon-color);color:var(--fm-checker-disabled-icon-color)}.fm-checker--disabled.fm-checker--checked .fm-checker__icon .fm-icon{background-color:var(--fm-checker-disabled-color);border-color:var(--fm-checker-disabled-color)}:root{--fm-icon-font-size: 14px;--fm-icon-color: inherit}.fm-icon{font-family:farrisMobile!important;font-size:var(--fm-icon-font-size);font-style:normal;color:var(--fm-icon-color);display:inline-block;width:1em;height:1em;font-weight:400;line-height:1;vertical-align:middle;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fm-icon:before{display:inline-block}.fm-icon-filter:before{content:"\e697"}.fm-icon-cardfold:before{content:"\e6b7"}.fm-icon-cardunfold:before{content:"\e6b8"}.fm-icon-trafficother:before{content:"\e6b9"}.fm-icon-bottomsave:before{content:"\e6ba"}.fm-icon-trafficboat:before{content:"\e6bb"}.fm-icon-trafficcar:before{content:"\e6bc"}.fm-icon-trafficplane:before{content:"\e6bd"}.fm-icon-traffictrain:before{content:"\e6be"}.fm-icon-trafficbus:before{content:"\e6bf"}.fm-icon-addgray:before{content:"\e6a7"}.fm-icon-close:before{content:"\e6a8"}.fm-icon-add-line:before{content:"\e6a9"}.fm-icon-more:before{content:"\e6aa"}.fm-icon-check:before{content:"\e6ab"}.fm-icon-backcircle:before{content:"\e6ac"}.fm-icon-agree:before{content:"\e6ad"}.fm-icon-loading:before{content:"\e6ae"}.fm-icon-filedel:before{content:"\e6af"}.fm-icon-file:before{content:"\e6b0"}.fm-icon-processflow:before{content:"\e6b1"}.fm-icon-redstar:before{content:"\e6b2"}.fm-icon-rightcircle:before{content:"\e6b3"}.fm-icon-timecircle:before{content:"\e6b4"}.fm-icon-screening:before{content:"\e6b5"}.fm-icon-uncheck:before{content:"\e6b6"}.fm-icon-operation:before{content:"\e02c"}.fm-icon-approvalamount:before{content:"\e02b"}.fm-icon-agreed:before{content:"\e02a"}.fm-icon-inprocess:before{content:"\e029"}.fm-icon-feedback:before{content:"\e028"}.fm-icon-print:before{content:"\e027"}.fm-icon-important:before{content:"\e026"}.fm-icon-amountofreimbursement:before{content:"\e025"}.fm-icon-safetyassistant:before{content:"\e024"}.fm-icon-remind:before{content:"\e023"}.fm-icon-eyeoppen:before{content:"\e022"}.fm-icon-eyeclose:before{content:"\e01e"}.fm-icon-photography:before{content:"\e021"}.fm-icon-photograph:before{content:"\e020"}.fm-icon-addpicture:before{content:"\e01f"}.fm-icon-top_other-face:before{content:"\e01d"}.fm-icon-top_other:before{content:"\e01c"}.fm-icon-delete:before{content:"\e01b"}.fm-icon-nextpage:before{content:"\e01a"}.fm-icon-addbutton:before{content:"\e019"}.fm-icon-waitforprocessing:before{content:"\e018"}.fm-icon-warningmessage:before{content:"\e017"}.fm-icon-failureprompt:before{content:"\e016"}.fm-icon-successfulhints:before{content:"\e015"}.fm-icon-other:before{content:"\e014"}.fm-icon-retract:before{content:"\e013"}.fm-icon-drop-down:before{content:"\e012"}.fm-icon-cancel:before{content:"\e011"}.fm-icon-search:before{content:"\e010"}.fm-icon-multiplechoice:before{content:"\e00f"}.fm-icon-singlechoice:before{content:"\e00e"}.fm-icon-microphone:before{content:"\e00d"}.fm-icon-arrow-chevron-left:before{content:"\e00c"}.fm-icon-helpcenter:before{content:"\e00b"}.fm-icon-sweepcode:before{content:"\e00a"}.fm-icon-groupchat:before{content:"\e009"}.fm-icon-addfriend:before{content:"\e008"}.fm-icon-top_my:before{content:"\e007"}.fm-icon-top_my-face:before{content:"\e006"}.fm-icon-top_friend:before{content:"\e005"}.fm-icon-top_friend-face:before{content:"\e004"}.fm-icon-top_publicpraise:before{content:"\e003"}.fm-icon-top_publicpraise-face:before{content:"\e002"}.fm-icon-top_home:before{content:"\e001"}.fm-icon-top_home-face:before{content:"\e000"}.fm-icon-s-agree-o:before{content:"\e655"}.fm-icon-s-arrow-down:before{content:"\e656"}.fm-icon-s-add-o:before{content:"\e657"}.fm-icon-s-annex:before{content:"\e658"}.fm-icon-s-arrow:before{content:"\e659"}.fm-icon-s-arrow-up:before{content:"\e65e"}.fm-icon-s-checkbox-checked:before{content:"\e65f"}.fm-icon-s-checkbox:before{content:"\e660"}.fm-icon-s-arrow-left:before{content:"\e661"}.fm-icon-s-exchange:before{content:"\e662"}.fm-icon-s-clear:before{content:"\e663"}.fm-icon-s-checked:before{content:"\e664"}.fm-icon-s-eye-o:before{content:"\e665"}.fm-icon-s-close-eye:before{content:"\e666"}.fm-icon-s-at:before{content:"\e667"}.fm-icon-s-feedback-o:before{content:"\e668"}.fm-icon-s-fold-circle-o:before{content:"\e669"}.fm-icon-s-cross:before{content:"\e66a"}.fm-icon-s-minus:before{content:"\e66b"}.fm-icon-s-file:before{content:"\e66c"}.fm-icon-s-fold-triangle:before{content:"\e66d"}.fm-icon-s-filter:before{content:"\e66e"}.fm-icon-s-forword:before{content:"\e66f"}.fm-icon-s-plus:before{content:"\e670"}.fm-icon-s-filedel:before{content:"\e671"}.fm-icon-s-fold-o:before{content:"\e672"}.fm-icon-s-image-o:before{content:"\e673"}.fm-icon-s-more-o:before{content:"\e674"}.fm-icon-s-redio-circle:before{content:"\e675"}.fm-icon-s-reject-o:before{content:"\e676"}.fm-icon-s-success:before{content:"\e677"}.fm-icon-s-refresh:before{content:"\e678"}.fm-icon-s-star:before{content:"\e679"}.fm-icon-s-processflow:before{content:"\e67a"}.fm-icon-s-unfold-circle-o:before{content:"\e67b"}.fm-icon-s-rewind:before{content:"\e67c"}.fm-icon-s-unfold-o:before{content:"\e67d"}.fm-icon-s-save-o:before{content:"\e67e"}.fm-icon-s-warning-o:before{content:"\e67f"}.fm-icon-s-unfold-triangle:before{content:"\e680"}.fm-icon-s-print-o:before{content:"\e681"}.fm-icon-s-search-o:before{content:"\e682"}.fm-icon-s-news:before{content:"\e683"}.fm-icon-s-news-o:before{content:"\e684"}.fm-icon-s-shop:before{content:"\e68c"}.fm-icon-s-sending:before{content:"\e60b"}.fm-icon-s-import-o:before{content:"\e60c"}.fm-icon-s-edit-o:before{content:"\e60d"}.fm-icon-s-qrcode:before{content:"\e60e"}.fm-icon-s-briefcase:before{content:"\e60f"}.fm-icon-s-notificationoff:before{content:"\e610"}.fm-icon-s-pencil:before{content:"\e611"}.fm-icon-s-star-o:before{content:"\e612"}.fm-icon-s-barcode:before{content:"\e613"}.fm-icon-s-salemessage-o:before{content:"\e614"}.fm-icon-s-listview-o:before{content:"\e615"}.fm-icon-s-picture-o:before{content:"\e616"}.fm-icon-s-savefillet-o:before{content:"\e617"}.fm-icon-s-shoppingcart:before{content:"\e618"}.fm-icon-s-pending:before{content:"\e61d"}.fm-icon-s-expandview-o:before{content:"\e61e"}.fm-icon-s-lock-o:before{content:"\e623"}.fm-icon-s-my:before{content:"\e692"}.fm-icon-s-service:before{content:"\e633"}.fm-icon-s-wallet-o:before{content:"\e634"}.fm-icon-s-shoppingcart-o:before{content:"\e636"}.fm-icon-s-setting-o:before{content:"\e637"}.fm-icon-s-my-o:before{content:"\e696"}.fm-icon-s-unfoldrec-o:before{content:"\e639"}.fm-icon-s-profile:before{content:"\e63a"}.fm-icon-s-link-o:before{content:"\e609"}.fm-icon-s-usersetting-o:before{content:"\e632"}.fm-icon-s-shop-o:before{content:"\e68a"}.fm-icon-s-list:before{content:"\e62a"}.fm-icon-s-location-o:before{content:"\e685"}.fm-icon-s-location:before{content:"\e686"}.fm-icon-s-moment:before{content:"\e689"}.fm-icon-s-moment-o:before{content:"\e68b"}.fm-icon-s-revoke-o:before{content:"\e687"}.fm-icon-s-submit-o:before{content:"\e688"}.fm-icon-s-app-o:before{content:"\e68f"}.fm-icon-s-app:before{content:"\e691"}.fm-icon-s-book-o:before{content:"\e695"}.fm-icon-s-book:before{content:"\e690"}.fm-icon-s-comment:before{content:"\e693"}.fm-icon-s-comment-o:before{content:"\e694"}.fm-icon-s-illustrate-o:before{content:"\e68d"}.fm-icon-s-clear-o:before{content:"\e68e"}.fm-icon-friend:before{content:"\e005"}.fm-icon-scan:before{content:"\e69a"}.fm-icon-back:before{content:"\e69b"}.fm-icon-menu:before{content:"\e69d"}:root{--fm-navbar-background: var(--fm-background-white);--fm-navbar-color: var(--fm-text-color);--fm-navbar-height: 44px;--fm-navbar-title-size: 17px;--fm-navbar-side-size: 16px;--fm-navbar-arrow-size: 18px}.fm-navbar{position:relative;z-index:9;display:flex;align-items:center;line-height:1.5;text-align:center;user-select:none;height:var(--fm-navbar-height);color:var(--fm-navbar-color);background-color:var(--fm-navbar-background)}.fm-navbar.fm-navbar-fixed{position:fixed;top:0;left:0;width:100%}.fm-navbar.fm-navbar-border-bottom{border-bottom:1px solid #eee;position:relative;border-bottom:none}.fm-navbar.fm-navbar-border-bottom:after{content:"";position:absolute;background-color:#eee;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-navbar-title{max-width:60%;margin:0 auto;font-weight:500;font-size:var(--fm-navbar-title-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-navbar-left,.fm-navbar-right{position:absolute;top:0;bottom:0;display:flex;align-items:center;max-width:30%;padding:0 16px;font-size:var(--fm-navbar-side-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;cursor:pointer}.fm-navbar-left{left:0}.fm-navbar-left:active{opacity:var(--fm-active-opacity)}.fm-navbar-left.fm-navbar-left-padding{padding-left:14px}.fm-navbar-right{right:0}.fm-navbar-right .fm-navbar-text:active{opacity:var(--fm-active-opacity)}.fm-navbar .fm-navbar-left-arrow{min-width:1em;margin-right:4px;font-size:var(--fm-navbar-arrow-size)}:root{--fm-input-group-size: var(--fm-font-size);--fm-input-group-color: var(--fm-text-color);--fm-input-group-sub-size: 13px;--fm-input-group-padding: 10px 16px;--fm-input-group-sub-color: var(--fm-text-color-light);--fm-input-group-border-color: var(--fm-gray-2)}.fm-input-group{display:flex;flex-direction:column;background-color:var(--fm-white)}.fm-input-group--padding{padding:var(--fm-input-group-padding)}.fm-input-group__body{flex:1;display:flex;align-items:center;min-height:24px;color:var(--fm-input-group-color);font-size:var(--fm-input-group-size)}.fm-input-group__body--border{border:1px solid var(--fm-input-group-border-color);padding:4px 8px;border-radius:4px}.fm-input-group__control{display:flex;width:100%;min-width:0;margin:0;padding:0;border:0;resize:none;color:inherit;font-size:inherit;outline:none;line-height:inherit;background-color:transparent}.fm-input-group__control::placeholder{color:var(--fm-input-group-sub-color)}.fm-input-group__control:disabled{opacity:1;cursor:not-allowed;color:var(--fm-disabled-color);-webkit-text-fill-color:currentColor}.fm-input-group__control::-webkit-search-cancel-button{display:none}.fm-input-group__control--readonly{cursor:default;color:var(--fm-readonly-color)}.fm-input-group__control--left{justify-content:flex-start;text-align:left}.fm-input-group__control--center{justify-content:center;text-align:center}.fm-input-group__control--right{justify-content:flex-end;text-align:right}.fm-input-group__clear{cursor:pointer;margin-right:-8px;padding:4px 8px;color:var(--fm-input-group-sub-color);flex-shrink:0;box-sizing:content-box}.fm-input-group__left-icon{margin:auto 4px auto 0}.fm-input-group__right-icon{margin:auto 0 auto 4px}.fm-input-group__word-limit{margin-top:4px;line-height:18px;text-align:right;font-size:var(--fm-input-group-sub-size);color:var(--fm-input-group-sub-color)}.fm-radio-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-radio-group--vertical{flex-direction:column}.fm-radio-group--vertical .fm-radio:not(:last-child){margin-bottom:8px}.fm-radio{margin-top:4px;margin-bottom:4px}:root,:host{--fm-rate-icon-size: 20px;--fm-rate-icon-gutter: var(--fm-padding-base);--fm-rate-icon-void-color: var(--fm-gray-4);--fm-rate-icon-full-color: var(--fm-orange-3);--fm-rate-icon-disabled-color: var(--fm-gray-4)}.fm-rate{display:inline-flex;cursor:pointer;user-select:none;flex-wrap:wrap}.fm-rate__item{position:relative}.fm-rate__item:not(:last-child){padding-right:var(--fm-rate-icon-gutter)}.fm-rate__icon{display:block;width:1em;color:var(--fm-rate-icon-void-color);font-size:var(--fm-rate-icon-size)}.fm-rate__icon--half{position:absolute;top:0;left:0;overflow:hidden;pointer-events:none;color:var(--fm-rate-icon-full-color)}.fm-rate__icon--full{color:var(--fm-rate-icon-full-color)}.fm-rate__icon--disabled{color:var(--fm-rate-icon-disabled-color)}.fm-rate--disabled{cursor:not-allowed}.fm-rate--readonly{cursor:default}:root{--fm-form-item-size: var(--fm-font-size);--fm-form-item-color: var(--fm-text-color);--fm-form-item-label-width: 105px;--fm-form-item-sub-size: 13px}.fm-form-item{font-size:var(--fm-form-item-size);color:var(--fm-form-item-color)}.fm-form-item--vertical{flex-direction:column}.fm-form-item--vertical .fm-form-item__label{margin-bottom:4px}.fm-form-item__label{display:flex;flex:none;align-items:flex-start;text-align:left;width:var(--fm-form-item-label-width);margin-right:4px}.fm-form-item__label--left{justify-content:flex-start}.fm-form-item__label--center{justify-content:center}.fm-form-item__label--right{justify-content:flex-end}.fm-form-item__label--required{position:relative}.fm-form-item__label--required .fm-cell__title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-form-item__content{display:flex}.fm-form-item__content .fm-input-group{padding:0;flex:1}.fm-form-item__content--left{justify-content:flex-start}.fm-form-item__content--left input.fm-input-group__control{justify-content:flex-start;text-align:left}.fm-form-item__content--center{justify-content:center}.fm-form-item__content--center input.fm-input-group__control{justify-content:flex-center;text-align:center}.fm-form-item__content--right{justify-content:flex-end}.fm-form-item__content--right input.fm-input-group__control{justify-content:flex-end;text-align:right}.fm-form-item__error-message{color:var(--fm-danger-color);font-size:var(--fm-form-item-sub-size)}.fm-form-item__error-message--left{text-align:left}.fm-form-item__error-message--center{text-align:center}.fm-form-item__error-message--right{text-align:right}:root{--fm-overlay-background: rgba(0, 0, 0, .4);--fm-overlay-zindex: 98}.fm-overlay{width:100%;position:fixed;top:0;left:0;z-index:var(--fm-overlay-zindex);background-color:var(--fm-overlay-background);bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-overlay{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}:root{--fm-popup-background: var(--fm-white);--fm-popup-zindex: var(--fm-zindex-3);--fm-popup-radius: 16px}.fm-popup{position:fixed;max-height:100%;overflow-y:auto;background-color:var(--fm-popup-background);transition:all var(--fm-duration-base);z-index:var(--fm-popup-zindex)}.fm-popup--center{top:50%;left:50%;transform:translate(-50%,-50%)}.fm-popup--center.fm-popup--round{border-radius:var(--fm-popup-radius)}.fm-popup--top,.fm-popup--bottom{left:0;right:0}.fm-popup--top{top:0}.fm-popup--top.fm-popup--round{border-radius:0 0 var(--fm-popup-radius) var(--fm-popup-radius)}.fm-popup--bottom{bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--bottom{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--bottom.fm-popup--round{border-radius:var(--fm-popup-radius) var(--fm-popup-radius) 0 0}.fm-popup--left,.fm-popup--right{top:0;bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--left,.fm-popup--right{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--left{left:0}.fm-popup--left.fm-popup--round{border-radius:0 var(--fm-popup-radius) var(--fm-popup-radius) 0}.fm-popup--right{right:0}.fm-popup--right.fm-popup--round{border-radius:var(--fm-popup-radius) 0 0 var(--fm-popup-radius)}:root{--fm-popover-zindex: var(--fm-zindex-5);--fm-popover-padding: var(--fm-padding-sm);--fm-popover-border-radius: var(--fm-radius-lg);--fm-popover-arrow-size: 8px;--fm-popover-content-font-size: var(--fm-font-size);--fm-popover-content-line-height: var(--fm-line-height);--fm-popover-light-theme-color: var(--fm-gray-7);--fm-popover-light-theme-background: var(--fm-white);--fm-popover-dark-theme-color: var(--fm-white);--fm-popover-dark-theme-background: var(--fm-gray-7);--fm-popover-shadow: 0 6px 30px 5px rgba(0, 0, 0, .05), 0 16px 24px 2px rgba(0, 0, 0, .04), 0 8px 10px -5px rgba(0, 0, 0, .08)}.fm-popover{position:absolute;overflow:visible;top:0;left:0;transition:opacity .15s;background-color:transparent;z-index:var(--fm-popover-zindex)}.fm-popover__wrapper{display:inline-block}.fm-popover__content{position:relative;padding:var(--fm-popover-padding);border-radius:var(--fm-popover-border-radius);font-size:var(--fm-popover-content-font-size);line-height:var(--fm-popover-content-line-height);word-break:break-all}.fm-popover__arrow{position:absolute;width:0;height:0;z-index:1;border-style:solid;border-color:transparent;border-width:var(--fm-popover-arrow-size, 8px)}.fm-popover__arrow--top{border-bottom-width:0;border-top-color:currentColor;margin-bottom:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--right{border-left-width:0;border-right-color:currentColor;margin-left:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--bottom{border-top-width:0;border-bottom-color:currentColor;margin-top:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--left{border-right-width:0;border-left-color:currentColor;margin-right:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover--light .fm-popover__content{background:var(--fm-popover-light-theme-background);color:var(--fm-popover-light-theme-color);box-shadow:var(--fm-popover-shadow)}.fm-popover--light .fm-popover__arrow{color:var(--fm-popover-light-theme-background)}.fm-popover--dark .fm-popover__content{background:var(--fm-popover-dark-theme-background);color:var(--fm-popover-dark-theme-color);box-shadow:var(--fm-popover-shadow)}.fm-popover--dark .fm-popover__arrow{color:var(--fm-popover-dark-theme-background)}:root{--fm-switch-background: var(--fm-text-color-light);--fm-switch-on-color: var(--fm-primary-color)}.fm-switch{position:relative;cursor:pointer;display:inline-block;transition:background-color var(--fm-duration-base);background-color:var(--fm-switch-background)}.fm-switch--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-switch--readonly{cursor:default;opacity:var(--fm-readonly-opacity)}.fm-switch--loading{cursor:default}.fm-switch--on{background-color:var(--fm-switch-on-color)}.fm-switch--on .fm-switch__loadding{color:var(--fm-switch-on-color)}.fm-switch__node{display:flex;align-items:center;justify-content:center;position:absolute;top:1px;left:1px;z-index:1;width:28px;height:28px;border-radius:100%;background-color:var(--fm-white);transition:transform var(--fm-duration-base) cubic-bezier(.3,1.05,.4,1.05)}:root{--fm-toast-zindex: var(--fm-zindex-5);--fm-toast-color: var(--fm-white);--fm-toast-font-size: 16px;--fm-toast-background: var(--fm-gray-7);--fm-toast-icon-font-size: 48px}.fm-toast{position:fixed;top:50%;left:50%;display:-webkit-box;display:-webkit-flex;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:content-box;max-width:70%;padding:16px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;border-radius:7px;transform:translate(-50%,-50%);color:var(--fm-toast-color);z-index:var(--fm-toast-zindex);font-size:var(--fm-toast-font-size);background-color:var(--fm-toast-background)}.fm-toast--top{top:50px;transform:translate(-50%)}.fm-toast--bottom{top:auto;bottom:50px}.fm-toast--info,.fm-toast--success,.fm-toast--warning,.fm-toast--error{width:88px;min-height:88px}.fm-toast__icon-wrapper{margin-bottom:8px}.fm-toast--default{padding:8px 16px}.fm-toast--loading{min-width:84px;min-height:84px}.fm-toast--loading-icon{position:relative;display:inline-block;width:30px;height:30px;margin-bottom:8px;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-toast--loading-icon circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}:root{--fm-notify-color: var(--fm-white);--fm-notify-zindex: var(--fm-zindex-5);--fm-notify-info-background: var(--fm-primary-color);--fm-notify-success-background: var(--fm-success-color);--fm-notify-warning-background: var(--fm-warning-color);--fm-notify-error-background: var(--fm-danger-color)}.fm-notify{position:fixed;left:0;top:0;z-index:var(--fm-notify-zindex);display:flex;align-items:center;justify-content:center;width:100%;max-height:100%;padding:8px 16px;box-sizing:border-box;color:var(--fm-notify-color);font-size:14px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;overflow-y:auto}.fm-notify--info{background-color:var(--fm-notify-info-background)}.fm-notify--success{background-color:var(--fm-notify-success-background)}.fm-notify--warning{background-color:var(--fm-notify-warning-background)}.fm-notify--error{background-color:var(--fm-notify-error-background)}:root{--fm-dialog-background: var(--fm-background-2);--fm-dialog-padding-top: 24px;--fm-dialog-padding-left: 16px;--fm-dialog-header-font-size: 17px;--fm-dialog-header-line-height: 24px;--fm-dialog-content-font-size: 15px;--fm-dialog-content-line-height: 20px;--fm-dialog-footer-height: 50px;--fm-border-color: var(--fm-gray-4)}@media screen and (min-width: 375px){.fm-dialog{width:320px}}@media screen and (min-width: 280px) and (max-width: 375px){.fm-dialog{width:240px}}.fm-dialog{display:flex;flex-direction:column;background-color:var(--fm-dialog-background);overflow:hidden}.fm-dialog__header{padding-top:var(--fm-dialog-padding-top);padding-left:var(--fm-dialog-header-padding-left);padding-right:var(--fm-dialog-header-padding-left);font-weight:var(--fm-font-bold-light);font-size:var(--fm-dialog-header-font-size);color:var(--fm-text-color);line-height:var(--fm-dialog-header-line-height);text-align:center}.fm-dialog__content{max-height:70vh;overflow-y:auto}.fm-dialog__content__message{padding:var(--fm-dialog-padding-top) var(--fm-dialog-padding-left);font-size:var(--fm-dialog-content-font-size);line-height:var(--fm-dialog-content-line-height);white-space:pre-wrap;text-align:center;word-wrap:break-word}.fm-dialog__content__message--has-title{padding-top:11px;color:var(--fm-text-color-light)}.fm-dialog__content--prompt{padding:14px}.fm-dialog__content--prompt__input{display:block}.fm-dialog__footer{display:flex;flex-direction:row;align-items:center;border-top:1px solid var(--fm-border-color);position:relative;border-top:none}.fm-dialog__footer:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}.fm-dialog__footer .fm-button{border:0;height:var(--fm-dialog-footer-height);border-right:1px solid var(--fm-border-color);position:relative;border-right:none}.fm-dialog__footer .fm-button:after{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 0 auto auto;width:1px;height:100%;background:var(--fm-border-color);transform-origin:100% 50%;transform:scaleX(.5)}.fm-dialog__footer .fm-button:last-child{border-right:0}.fm-dialog__footer .fm-button:last-child:after{display:none!important}.fm-dialog__footer .fm-button--default{color:var(--fm-text-color)}.fm-dialog__footer--is-column{flex-direction:column}.fm-dialog__footer--is-column__button{border-top:1px solid var(--fm-border-color);position:relative;border-top:none}.fm-dialog__footer--is-column__button:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}.fm-dialog__footer--is-column__button:first-child{border-top:0}.fm-dialog__footer--is-column__button:first-child:before{display:none!important}.fm-dialog.fm-dialog--relative{position:relative}.fm-dialog.fm-dialog--relative__header{padding-right:40px}.fm-dialog__close{position:absolute;right:16px;top:16px;width:22px;height:22px;line-height:22px;text-align:center}.fm-dialog__close .fm-icon{font-size:15px;color:var(--fm-text-color-2)}:root,:host{--fm-loading-color: var(--fm-gray-5);--fm-loading-text-font-size: 14px;--fm-loading-text-line-height: 1.4}.fm-loading{display:flex;align-items:center;position:relative;color:var(--fm-loading-color)}.fm-loading__text{color:var(--fm-loading-color);font-size:var(--fm-loading-text-font-size);line-height:var(--fm-loading-text-line-height);margin-left:var(--fm-margin-xs)}.fm-loading--vertical{flex-direction:column}.fm-loading--vertical .fm-loading__text{margin-top:var(--fm-margin-xs);margin-left:0}.fm-loading__circular{display:block;animation:fm-rotate 2s linear infinite}.fm-loading__circular circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:3;stroke-linecap:round}.fm-loading__spinner{display:block;position:relative;animation:fm-rotate 1s linear infinite;animation-timing-function:steps(12)}.fm-loading__line{position:absolute;top:0;left:0;width:100%;height:100%}.fm-loading__line-inner{display:block;width:2px;height:25%;margin:0 auto;background-color:currentColor;border-radius:40%}.fm-loading__ring{display:block;animation:fm-rotate .75s linear infinite;border:4px solid;border-right-color:transparent;border-radius:50%}@keyframes fm-circular{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40}to{stroke-dasharray:90,150;stroke-dashoffset:-120}}.fm-loading__line--1{transform:rotate(30deg);opacity:1}.fm-loading__line--2{transform:rotate(60deg);opacity:.9375}.fm-loading__line--3{transform:rotate(90deg);opacity:.875}.fm-loading__line--4{transform:rotate(120deg);opacity:.8125}.fm-loading__line--5{transform:rotate(150deg);opacity:.75}.fm-loading__line--6{transform:rotate(180deg);opacity:.6875}.fm-loading__line--7{transform:rotate(210deg);opacity:.625}.fm-loading__line--8{transform:rotate(240deg);opacity:.5625}.fm-loading__line--9{transform:rotate(270deg);opacity:.5}.fm-loading__line--10{transform:rotate(300deg);opacity:.4375}.fm-loading__line--11{transform:rotate(330deg);opacity:.375}.fm-loading__line--12{transform:rotate(360deg);opacity:.3125}:root,:host{--fm-pull-refresh-head-height: 50px;--fm-pull-refresh-head-font-size: var(--fm-font-size-md);--fm-pull-refresh-head-text-color: var(--fm-text-color-light);--fm-pull-refresh-animation-duration: .3s}.fm-pull-refresh{overflow:hidden}.fm-pull-refresh__track{position:relative;height:100%}.fm-pull-refresh__track--not-pulling{transition:transform ease var(--fm-pull-refresh-animation-duration)}.fm-pull-refresh__head{position:absolute;left:0;width:100%;height:var(--fm-pull-refresh-head-height);color:var(--fm-pull-refresh-head-text-color);font-size:var(--fm-pull-refresh-head-font-size);line-height:var(--fm-pull-refresh-head-height);text-align:center;transform:translateY(-100%);display:flex;justify-content:center;align-items:center;flex-direction:column;overflow:hidden}:root,:host{--fm-list-text-color: var(--fm-gray-5);--fm-list-text-font-size: var(--fm-font-size-md, 14px);--fm-list-text-line-height: 50px;--fm-list-loading-icon-size: 16px}.fm-list__loading,.fm-list__error,.fm-list__load-more,.fm-list__finished-info{color:var(--fm-list-text-color);font-size:var(--fm-list-text-font-size);line-height:var(--fm-list-text-line-height);text-align:center}.fm-list__loading-container{display:flex;height:var(--fm-list-text-line-height);justify-content:center;align-items:center}:root,:host{--fm-listview-checkbox-container-width: 40px;--fm-listview-toolbar-height: 42px;--fm-listview-split-line-color: rgb(230, 235, 235);--fm-listview-empty-text-color: var(--fm-gray-5);--fm-listview-empty-text-font-size: var(--fm-font-size-md, 14px);--fm-listview-empty-text-line-height: 50px}.fm-list-view--fill{height:100%;flex-grow:1;flex-shrink:1;display:flex;flex-direction:column;overflow:hidden}.fm-list-view--fill .fm-list-view__track{flex:1 1 0;overflow:auto;-webkit-overflow-scrolling:touch}.fm-list-view--fill .fm-pull-refresh{min-height:100%}.fm-list-view .fm-list{user-select:none;-webkit-user-select:none}.fm-list-view__item{display:flex;position:relative;overflow:hidden}.fm-list-view__item-checker{display:flex;position:absolute;height:100%;width:var(--fm-listview-checkbox-container-width);justify-content:center;align-items:center}.fm-list-view__item-content{flex:1;transform:translate(0)}.fm-list-view__content--split .fm-list-view__item:not(:last-child):not(.fm-list-view__item--child){border-bottom:1px solid var(--fm-listview-split-line-color)}.fm-list-view--multi-select .fm-list-view__item-content{transform:translate(var(--fm-listview-checkbox-container-width))}.fm-list-view__item--group{display:block}.fm-list-view__item-group-header{padding:10px 16px;line-height:20px;font-size:var(--fm-font-size-md);color:var(--fm-gray-5)}.fm-list-view__empty-message{display:block;color:var(--fm-listview-empty-text-color);font-size:var(--fm-listview-empty-text-font-size);line-height:var(--fm-listview-empty-text-line-height);text-align:center}.fm-list-view__item-text{padding:13px 20px;color:var(--fm-gray-7);font-size:var(--fm-font-size)}.fm-list-view__toolbar{display:flex;align-items:center;height:var(--fm-listview-toolbar-height)}.fm-list-view__toolbar-item{flex:1}:root,:host{--fm-swipe-cell-button-text-color: var(--fm-white);--fm-swipe-cell-button-bg-color: var(--fm-gray-4);--fm-swipe-cell-button-font-size: var(--fm-font-size);--fm-swipe-cell-button-icon-size: var(--fm-font-size);--fm-swipe-cell-button-padding: var(--fm-padding-md)}.fm-swipe-cell{position:relative;overflow:hidden}.fm-swipe-cell__wrapper{transition-timing-function:cubic-bezier(.18,.89,.32,1);transition-property:transform}.fm-swipe-cell__left,.fm-swipe-cell__right{position:absolute;top:0;height:100%;display:flex}.fm-swipe-cell__left{left:0;transform:translate3d(-100%,0,0);flex-direction:row-reverse}.fm-swipe-cell__right{right:0;transform:translate3d(100%,0,0)}.fm-swipe-cell__button{display:inline-flex;justify-content:center;align-items:center;height:100%;padding:0 var(--fm-swipe-cell-button-padding);color:var(--fm-swipe-cell-button-text-color);background-color:var(--fm-swipe-cell-button-bg-color)}.fm-swipe-cell__icon{font-size:var(--fm-swipe-cell-button-icon-size)}.fm-swipe-cell__text{font-size:var(--fm-swipe-cell-button-font-size)}.fm-swipe-cell__icon+.fm-swipe-cell__text:not(:empty){margin-left:6px}:root,:host{--fm-action-sheet-max-height: 80%;--fm-action-sheet-border-radius: 12px;--fm-action-sheet-description-color: var(--fm-gray-5);--fm-action-sheet-description-line-height: 22px;--fm-action-sheet-description-font-size: var(--fm-font-size-md);--fm-action-sheet-description-padding: 12px 16px;--fm-action-sheet-item-default-background: var(--fm-background-white);--fm-action-sheet-item-active-background: #f2f3f5;--fm-action-sheet-item-padding: 13px 16px;--fm-action-sheet-item-text-color: #1a1a1a;--fm-action-sheet-item-disabled-text-color: #bdbdbd;--fm-action-sheet-item-subtitle-color: var(--fm-gray-5);--fm-action-sheet-item-icon-size: 18px;--fm-action-sheet-item-icon-margin-right: 8px;--fm-action-sheet-item-title-font-size: var(--fm-font-size-lg);--fm-action-sheet-item-title-line-height: 24px;--fm-action-sheet-item-subtitle-font-size: var(--fm-font-size-sm);--fm-action-sheet-item-subtitle-line-height: 18px;--fm-action-sheet-item-subtitle-margin-top: 2px;--fm-action-sheet-footer-gap-color: #f5f5f5;--fm-action-sheet-divider-color: #e7e7e7;--fm-action-sheet-cancel-height: 48px;--fm-action-sheet-cancel-color: #1a1a1a;--fm-action-sheet-cancel-font-size: var(--fm-font-size-lg);--fm-action-sheet-cancel-font-weight: 500}.fm-action-sheet{display:flex;flex-direction:column;max-height:var(--fm-action-sheet-max-height);overflow:hidden;user-select:none}.fm-action-sheet--round{border-top-left-radius:var(--fm-action-sheet-border-radius);border-top-right-radius:var(--fm-action-sheet-border-radius)}.fm-action-sheet__description{flex-shrink:0;color:var(--fm-action-sheet-description-color);line-height:var(--fm-action-sheet-description-line-height);font-size:var(--fm-action-sheet-description-font-size);text-align:center;padding:var(--fm-action-sheet-description-padding);position:relative}.fm-action-sheet__description--left{text-align:left}.fm-action-sheet__content{flex:1 auto;overflow-y:auto;-webkit-overflow-scrolling:touch}.fm-action-sheet__item,.fm-action-sheet__cancel{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__item:active,.fm-action-sheet__cancel:active{background-color:var(--fm-action-sheet-item-active-background)}.fm-action-sheet__item{display:flex;position:relative;flex-wrap:wrap;align-items:center;justify-content:center;text-align:center;padding:var(--fm-action-sheet-item-padding);color:var(--fm-action-sheet-item-text-color);cursor:pointer}.fm-action-sheet__item-icon{font-size:var(--fm-action-sheet-item-icon-size);margin-right:var(--fm-action-sheet-item-icon-margin-right)}.fm-action-sheet__item-title{font-size:var(--fm-action-sheet-item-title-font-size);line-height:var(--fm-action-sheet-item-title-line-height)}.fm-action-sheet__item-subtitle{font-size:var(--fm-action-sheet-item-subtitle-font-size);line-height:var(--fm-action-sheet-item-subtitle-line-height);width:100%;margin-top:var(--fm-action-sheet-item-subtitle-margin-top);color:var(--fm-action-sheet-item-subtitle-color);overflow-wrap:break-word}.fm-action-sheet__item--left{text-align:left;justify-content:flex-start}.fm-action-sheet__item--disabled{color:var(--fm-action-sheet-item-disabled-text-color);cursor:not-allowed}.fm-action-sheet__item--disabled:active{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__description:after,.fm-action-sheet__item:after{content:"";display:block;position:absolute;height:1px;bottom:0;left:0;right:0;transform:scaleY(.5);background-color:var(--fm-action-sheet-divider-color)}.fm-action-sheet__footer-gap{height:8px;background-color:var(--fm-action-sheet-footer-gap-color)}.fm-action-sheet__cancel{display:flex;flex-direction:column;justify-content:center;align-items:center;height:var(--fm-action-sheet-cancel-height);cursor:pointer;color:var(--fm-action-sheet-cancel-color);font-size:var(--fm-action-sheet-cancel-font-size);font-weight:var(--fm-action-sheet-cancel-font-weight)}:root{--fm-tab-bar-item-color: var(--fm-text-color);--fm-tab-bar-item-active-color: var(--fm-primary-color);--fm-tab-bar-item-font-size: 16px}.fm-tab-bar-item{flex:1 0 auto;position:relative;display:inline-flex;align-items:center;justify-content:center;margin:0 12px;line-height:44px}.fm-tab-bar-item--actived{color:var(--fm-tab-bar-item-active-color)}.fm-tab-bar-item--disabled{color:var(--fm-disabled-color)}.fm-tab-bar-item--dot .fm-tab-bar-item__text:after{content:"";position:absolute;top:0;right:0;width:8px;height:8px;background-color:var(--fm-danger-color);border-radius:100%;transform:translate(100%,100%)}.fm-tab-bar-item__text{position:relative;display:flex;justify-content:center;min-width:40px}.fm-tab-bar-item__ink{position:absolute;bottom:0;left:0;right:0;height:4px;background-color:var(--fm-tab-bar-item-active-color);border-radius:2px}.fm-tab-bar-item__badge{position:absolute;top:2px;right:0;padding:0 4px;max-width:28px;font-weight:500;font-size:12px;line-height:14px;border-radius:7px;color:var(--fm-background-white);background-color:var(--fm-danger-color);transform:translate(50%)}.fm-tab-bar-item__icon{position:relative;display:flex;align-items:center;justify-content:center;padding-right:4px}:root{--fm-tab-bar-height: 44px;--fm-tab-bar-background: var(--fm-background-white);--fm-tab-bar-color: var(--fm-text-color);--fm-tab-bar-active-color: var(--fm-primary-color);--fm-tab-bar-font-size: 16px}.fm-tab-bar{position:relative;background:var(--fm-tab-bar-background);color:var(--fm-tab-bar-color);font-size:var(--fm-tab-bar-font-size)}.fm-tab-bar--bottom-line{border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-tab-bar--bottom-line:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-tab-bar__scroll-wrapper{position:relative;width:100%;overflow:hidden}.fm-tab-bar__list{display:flex;justify-content:space-between;min-width:100%;transition:all .3s cubic-bezier(.17,.89,.45,1)}.fm-tab-bar__ink{position:absolute;bottom:0;left:0;display:block;height:4px;background-color:var(--fm-tab-bar-active-color);transition:all var(--fm-duration-base);border-radius:2px}.fm-tab-bar__ink--disabled{background-color:var(--fm-disabled-color)}.fm-tabs{overflow:hidden}.fm-tabs__content{display:flex}.fm-tab{display:block;flex-shrink:0;width:100%;height:100%;overflow:auto;word-break:break-all}.fm-tab--collapse{height:0;overflow:visible}:root{--fm-tag-padding: 0 6px;--fm-tag-height: 18px;--fm-tag-font-size: 12px;--fm-tag-border-radius: 2px;--fm-tag-color: var(--fm-white)}.fm-tag{position:relative;display:inline-flex;align-items:center;white-space:nowrap;padding:0 4px;color:var(--fm-tag-color);font-size:var(--fm-tag-font-size);line-height:var(--fm-tag-height);border-radius:var(--fm-tag-border-radius)}.fm-tag--primary{background-color:var(--fm-primary-color)}.fm-tag--success{background-color:var(--fm-success-color)}.fm-tag--danger{background-color:var(--fm-danger-color)}.fm-tag--warning{background-color:var(--fm-warning-color)}.fm-tag--plain{background-color:var(--fm-white)}.fm-tag--plain.fm-tag--primary{border:1px solid var(--fm-primary-color);color:var(--fm-primary-color)}.fm-tag--plain.fm-tag--success{border:1px solid var(--fm-success-color);color:var(--fm-success-color)}.fm-tag--plain.fm-tag--warning{border:1px solid var(--fm-warning-color);color:var(--fm-warning-color)}.fm-tag--plain.fm-tag--danger{border:1px solid var(--fm-danger-color);color:var(--fm-danger-color)}.fm-tag--medium{padding:2px 6px}.fm-tag--large{padding:4px 8px;font-size:14px;border-radius:4px}.fm-tag--round{border-radius:100px}.fm-tag--mark{border-radius:0 100px 100px 0}.fm-tag__close{font-size:8px;margin-left:4px}.fm-tag--large .fm-tag__close{font-size:10px}: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}.fm-picker-panel__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker-panel__toolbar-left,.fm-picker-panel__toolbar-right{padding:0 16px}.fm-picker-panel__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker-panel__content{position:relative;display:flex;cursor:grab}.fm-picker-panel__columns{display:flex;flex:1;overflow:hidden}.fm-picker-panel__column{flex:1}.fm-picker-panel__column-item{display:flex;align-items:center;justify-content:center;height:44px}.fm-picker-panel__mask{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;background-image:linear-gradient(180deg,#ffffffe6,#fff6),linear-gradient(0deg,#ffffffe6,#fff6);background-repeat:no-repeat;background-position:top,bottom;transform:translateZ(0);pointer-events:none}.fm-picker-panel__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(.5)}.fm-picker-group__header{text-align:left}.fm-picker-group__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker-group__toolbar-left,.fm-picker-group__toolbar-right{padding:0 16px}.fm-picker-group__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker-group__tab-bar{display:inline-block}:root{--fm-lookup-panel-background: var(--fm-background);--fm-lookup-panel-search-list-zindex: var(--fm-zindex-3)}.fm-lookup-panel{height:100%;display:flex;flex-direction:column;overflow:hidden;background-color:var(--fm-lookup-panel-background)}.fm-lookup-panel__header{background-color:var(--fm-background-white)}.fm-lookup-panel__header__search{border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-lookup-panel__header__search:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-lookup-panel__header__selected-wrapper{display:flex;padding:6px 16px;overflow:auto}.fm-lookup-panel__header__selected-item{font-size:14px;line-height:20px;word-break:keep-all;white-space:nowrap;padding:4px 6px;color:var(--fm-primary-color);background-color:var(--fm-primary-color-light);border-radius:4px}.fm-lookup-panel__header__selected-item:not(:last-child){margin-right:8px}.fm-lookup-panel__footer{padding:0 16px;height:48px;display:flex;align-items:center;justify-content:space-between;box-shadow:0 0 7px 0 var(--fm-box-shadow-color);border-top:1px solid var(--fm-gray-1);background-color:var(--fm-background-white)}.fm-lookup-panel__content{flex:1;display:flex;overflow:hidden;margin-top:10px;position:relative}.fm-lookup-panel__list{flex:1;overflow-y:auto;background-color:var(--fm-background-white)}.fm-lookup-panel__list-item{display:flex;align-items:center;background-color:#fff}.fm-lookup-panel__list-checker{padding-left:16px}.fm-lookup-panel__search-list{position:absolute;inset:0;display:none;overflow-y:auto;z-index:var(--fm-lookup-panel-search-list-zindex);background-color:var(--fm-background-white)}.fm-lookup-panel__popup-selected{width:100%;display:flex;flex-direction:column}.fm-lookup-panel__popup-selected__footer-left{color:var(--fm-primary-color)}.fm-lookup-panel__selected-list{flex:1;overflow:auto}.fm-lookup-panel__empty{padding:12px 16px}.fm-lookup-panel__empty__text{text-align:center;color:var(--fm-text-color-light)}.fm-lookup-panel__breadcrumb{display:flex;align-items:center;height:42px;padding:0 16px;overflow:auto;border-bottom:1px solid var(--fm-border-color);position:relative;border-bottom:none}.fm-lookup-panel__breadcrumb:after{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-lookup-panel__breadcrumb__item{display:flex;align-items:center;color:var(--fm-primary-color);padding-right:8px;flex-shrink:0}.fm-lookup-panel__breadcrumb__item:last-child{color:var(--fm-text-color-light)}.fm-lookup-panel__breadcrumb__icon{font-size:10px;padding-left:4px}.fm-lookup-panel__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)}: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)}.fm-search{display:flex;align-items:center;padding:8px 12px;color:var(--fm-search-color);background-color:var(--fm-search-background)}.fm-search__input-wrapper{flex:1;padding:5px 8px;border-radius:17px;background-color:var(--fm-search-input-background)}.fm-search__input{background-color:var(--fm-search-input-background)}.fm-search__search-icon{margin-right:4px;color:var(--fm-text-color-light)}.fm-filter-panel{height:100%;display:flex;flex-direction:column;padding:8px 16px}.fm-filter-panel__content{flex:1}.fm-filter-panel__footer{padding:8px 16px}.fm-filter-panel__field:not(:first-child){margin-top:16px}.fm-filter-panel__field__title{display:flex;align-items:center;justify-content:space-between;line-height:22px}.fm-filter-panel__field__content{padding-top:12px}.fm-filter-panel__field__range{display:flex;align-items:center}.fm-filter-panel__field__range__splitter{width:8px;margin:0 8px;border:1px solid #999}.fm-filter-panel__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}.fm-filter__portal{display:flex;align-items:center;padding:8px 16px}.fm-filter__portal__icon{font-size:20px}.fm-filter__portal__search{flex:1;padding:0 0 0 8px}.fm-page-container{flex:1;display:flex;flex-direction:column;background:#f9fafb;overflow:hidden;-webkit-overflow-scrolling:auto;position:absolute;inset:0}.fm-page-body-container{flex-basis:0;flex-shrink:1;flex-grow:1;padding-bottom:12px;overflow:auto;display:flex;flex-direction:column}.fm-page-header-container{flex-shrink:0}.fm-page-footer-container{background-color:#fff}.fm-float-container{position:absolute!important;bottom:60px;right:30px} +@charset "UTF-8";:root{--fm-black: #000;--fm-white: #fff;--fm-gray-1: #f2f3f5;--fm-gray-2: #eee;--fm-gray-3: #ddd;--fm-gray-4: #ccc;--fm-gray-5: #999;--fm-gray-6: #666;--fm-gray-7: #333;--fm-red: #F24645;--fm-red-light: #f9e8e8;--fm-blue: #3A90FF;--fm-blue-2: #65a7ff;--fm-blue-light: #ecf2fe;--fm-green: #5CC171;--fm-green-2: #5AC1C3;--fm-green-light: #e9f5ed;--fm-orange: #FF9800;--fm-orange-2: #FA6400;--fm-orange-3: #FFB400;--fm-orange-light: #faf0e1;--fm-primary-color: var(--fm-blue);--fm-success-color: var(--fm-green);--fm-danger-color: var(--fm-red);--fm-warning-color: var(--fm-orange);--fm-submit-color: var(--fm-green-2);--fm-primary-color-light: var(--fm-blue-light);--fm-success-color-light: var(--fm-green-light);--fm-danger-color-light: var(--fm-red-light);--fm-warning-color-light: var(--fm-orange-light);--fm-text-color: var(--fm-gray-7);--fm-text-color-light: var(--fm-gray-5);--fm-active-color: var(--fm-gray-1);--fm-disabled-color: var(--fm-gray-4);--fm-readonly-color: var(--fm-gray-6);--fm-active-opacity: .7;--fm-readonly-opacity: .6;--fm-disabled-opacity: .5;--fm-background: var(--fm-gray-1);--fm-background-white: var(--fm-white);--fm-box-shadow-color: var(--fm-gray-1);--fm-padding-base: 4px;--fm-padding-xs: 8px;--fm-padding-sm: 12px;--fm-padding-md: 16px;--fm-padding-lg: 24px;--fm-padding-xl: 32px;--fm-padding-horizontal-xs: 0 var(--fm-padding-xs);--fm-padding-horizontal-sm: 0 var(--fm-padding-sm);--fm-padding-horizontal-md: 0 var(--fm-padding-md);--fm-padding-horizontal-lg: 0 var(--fm-padding-lg);--fm-margin-base: 4px;--fm-margin-xs: 8px;--fm-margin-sm: 12px;--fm-margin-md: 16px;--fm-margin-lg: 24px;--fm-margin-xl: 32px;--fm-margin-horizontal-xs: 0 var(--fm-margin-xs);--fm-margin-horizontal-sm: 0 var(--fm-margin-sm);--fm-margin-horizontal-md: 0 var(--fm-margin-md);--fm-margin-horizontal-lg: 0 var(--fm-margin-lg);--fm-font-bold-light: 500;--fm-font-bold: 600;--fm-font-size: 16px;--fm-line-height: 1.2;--fm-line-height-lg: 1.5;--fm-font-size-xs: 10px;--fm-font-size-sm: 12px;--fm-font-size-md: 14px;--fm-font-size-lg: 16px;--fm-gradient-blue: linear-gradient(-45deg,var(--fm-blue-2) 0%, var(--fm-blue) 100%);--fm-gradient-orange: linear-gradient(-45deg,var(--fm-orange) 0%, var(--fm-orange-2) 100%);--fm-base-font: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Segoe UI, Arial, Roboto, "PingFang SC", "miui", "Hiragino Sans GB", "Microsoft Yahei", sans-serif;--fm-price-font: avenir-heavy, "PingFang SC", helvetica neue, arial, sans-serif;--fm-duration-base: .3s;--fm-duration-fast: .2s;--fm-ease-out: ease-out;--fm-ease-in: ease-in;--fm-noborder: none;--fm-radius-sm: 2px;--fm-radius-md: 4px;--fm-radius-lg: 8px;--fm-radius-max: 999px;--fm-zindex-1: 9;--fm-zindex-2: 10;--fm-zindex-3: 99;--fm-zindex-4: 100;--fm-zindex-5: 999;--fm-zindex-6: 1000}*,*:before,*:after{box-sizing:border-box}body,h1,h2,h3,h4,p,figure,blockquote,dl,dd{margin:0}ul[role=list],ol[role=list]{list-style:none}html:focus-within{scroll-behavior:smooth}body{min-height:100vh;text-rendering:optimizeSpeed;line-height:1.5;font-family:-apple-system,Noto Sans,Helvetica Neue,Helvetica,Nimbus Sans L,Arial,Liberation Sans,PingFang SC,Hiragino Sans GB,Noto Sans CJK SC,Source Han Sans SC,Source Han Sans CN,Microsoft YaHei,Wenquanyi Micro Hei,WenQuanYi Zen Hei,ST Heiti,SimHei,WenQuanYi Zen Hei Sharp,sans-serif}a:not([class]){text-decoration-skip-ink:auto}img,picture{max-width:100%;display:block}input,button,textarea,select{font:inherit}@font-face{font-family:farrisMobile;font-style:normal;font-weight:400;src:url(data:font/ttf;base64,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AADmFAAAACUAAOYVAADmFQAAACYAAOYWAADmFgAAACcAAOYXAADmFwAAACgAAOYYAADmGAAAACkAAOYZAADmGQAAAHYAAOYaAADmGgAAAHUAAOYbAADmGwAAAHQAAOYcAADmHAAAAHMAAOYdAADmHQAAACoAAOYeAADmHgAAACsAAOYfAADmHwAAAHAAAOYgAADmIAAAAHEAAOYhAADmIQAAAHIAAOYiAADmIgAAAG8AAOYjAADmIwAAACwAAOYkAADmJAAAAGUAAOYlAADmJQAAAGYAAOYmAADmJgAAAGcAAOYnAADmJwAAAGgAAOYoAADmKAAAAGkAAOYpAADmKQAAAGoAAOYqAADmKgAAAGsAAOYrAADmKwAAAGwAAOYsAADmLAAAAG0AAOYtAADmLQAAAG4AAOYuAADmLgAAAGMAAOYvAADmLwAAAGQAAOYwAADmMAAAAGIAAOYyAADmMgAAADQAAOYzAADmMwAAAC0AAOY0AADmNAAAAC4AAOY2AADmNgAAAC8AAOY3AADmNwAAADAAAOY5AADmOQAAADEAAOY6AADmOgAAADIAAOZVAADmVQAAADUAAOZWAADmVgAAADoAAOZXAADmVwAAADcAAOZYAADmWAAAADgAAOZZAADmWQAAAD0AAOZaAADmWgAAAF4AAOZbAADmWwAAAF8AAOZcAADmXAAAAGAAAOZdAADmXQAAAGEAAOZeAADmXgAAADYAAOZfAADmXwAAADsAAOZgAADmYAAAADwAAOZhAADmYQAAADkAAOZiAADmYgAAAD4AAOZjAADmYwAAAD8AAOZkAADmZAAAAEAAAOZlAADmZQAAAEEAAOZmAADmZgAAAEIAAOZnAADmZwAAAEMAAOZoAADmaAAAAEQAAOZpAADmaQAAAEUAAOZqAADmagAAAEYAAOZrAADmawAAAEcAAOZsAADmbAAAAEgAAOZtAADmbQAAAEkAAOZuAADmbgAAAEoAAOZvAADmbwAAAEsAAOZwAADmcAAAAEwAAOZxAADmcQAAAE0AAOZyAADmcgAAAE4AAOZzAADmcwAAAE8AAOZ0AADmdAAAAFAAAOZ1AADmdQAAAFEAAOZ2AADmdgAAAFIAAOZ3AADmdwAAAFMAAOZ4AADmeAAAAFQAAOZ5AADmeQAAAFUAAOZ6AADmegAAAFYAAOZ7AADmewAAAFcAAOZ8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AV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFzAXQBdQF2AXcBeAF5AXoBewF8AX0BfgF/AYABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+AAlzLW1vcmUtbzEIcy1kZWxldGUIcy1iYWNrLW8Gcy1zY2FuEHMtb3JnYW5pemF0aW9uLW8Jcy1ncm91cC1vCXMtZmlsdGVyMQlzLWNsZWFyLW8Ocy1pbGx1c3RyYXRlLW8Icy1tb21lbnQIcy1zaG9wLW8Kcy1tb21lbnQtbwZzLXNob3AKcy1yZXZva2UtbwpzLXN1Ym1pdC1vB3MtYXBwLW8Gcy1ib29rBXMtYXBwBHMtbXkJcy1jb21tZW50C3MtY29tbWVudC1vCHMtYm9vay1vBnMtbXktbwxzLWxvY2F0aW9uLW8Kcy1sb2NhdGlvbgZzLW5ld3MIcy1uZXdzLW8Jcy1TZW5kaW5nCnMtSW1wb3J0LW8Icy1FZGl0LW8Icy1RUmNvZGULcy1CcmllZmNhc2URcy1Ob3RpZmljYXRpb25vZmYIcy1QZW5jaWwIcy1TdGFyLW8Jcy1CYXJDb2RlD3MtU2FsZU1lc3NhZ2UtbwxzLUxpc3R2aWV3LW8Lcy1QaWN0dXJlLW8Ocy1TYXZlRmlsbGV0LW8Ocy1TaG9wcGluZ2NhcnQJcy1QZW5kaW5nDnMtRXhwYW5kdmlldy1vCHMtTG9jay1vCXMtU2VydmljZQpzLVdhbGxldC1vEHMtU2hvcHBpbmdjYXJ0LW8Lcy1TZXR0aW5nLW8Ncy1VbmZvbGRSZWMtbwlzLVByb2ZpbGUGTGluay1vDVVzZXJTZXR0aW5nLW8Jcy1hZ3JlZS1vDHMtYXJyb3ctZG93bgdzLWFkZC1vB3MtYW5uZXgMcy1hcnJvdy1sZWZ0CnMtYXJyb3ctdXAScy1jaGVja2JveC1jaGVja2VkCnMtY2hlY2tib3gHcy1hcnJvdwpzLWV4Y2hhbmdlB3MtY2xlYXIJcy1jaGVja2VkB3MtZXllLW8Lcy1jbG9zZS1leWUEcy1hdAxzLWZlZWRiYWNrLW8Pcy1mb2xkLWNpcmNsZS1vB3MtY3Jvc3MHcy1taW51cwZzLWZpbGUPcy1mb2xkLXRyaWFuZ2xlCHMtZmlsdGVyCXMtZm9yd29yZAZzLXBsdXMJcy1maWxlZGVsCHMtZm9sZC1vCXMtaW1hZ2UtbwhzLW1vcmUtbw5zLXJlZGlvLWNpcmNsZQpzLXJlamVjdC1vCXMtc3VjY2VzcwlzLXJlZnJlc2gGcy1zdGFyDXMtcHJvY2Vzc2Zsb3cRcy11bmZvbGQtY2lyY2xlLW8Icy1yZXdpbmQKcy11bmZvbGQtbwtzLXdhcm5pbmctbxFzLXVuZm9sZC10cmlhbmdsZQlzLXByaW50LW8Kcy1zZWFyY2gtbwhBaXJwbGFuZQVUcmFpbgNCdXMEVGF4aQxvdmVydGltZW1lYWwTZm0taS10cmFmZmljZGV0YWlscw9mbS1pLXRyYWZmaWNzdWITZm0taS1hY2NvbW1vZGF0aW9uMQ1mbS1pLWJ1c2luZXNzC2ZtLWktYnVkZ2V0CWZtLWktZ2lmdBFmbS1pLWNhbmNlbGxhdGlvbgxmbS1pLWludm9pY2UJZm0taS1saXN0CmZtLWktbWVhbHMIZm0taS1wYXkMZm0taS1zdWJzaWR5B3Nob3V6aGUTZm0taS1jb3N0YWxsb2NhdGlvbgxmbS1pLXBheW1lbnQOZm0taS1JdGluZXJhcnkOZm0taS1tb3JleGUwMmQPZm0taS1pbWFnZXhlMDJlEGZtLWktcmVqZWN0eGUwMmYPZm0taS1hZ3JlZXhlMDMxDWZtLWktY2FyZGZvbGQPZm0taS1jYXJkdW5mb2xkEWZtLWktdHJhZmZpY290aGVyD2ZtLWktYm90dG9tc2F2ZRBmbS1pLXRyYWZmaWNib2F0D2ZtLWktdHJhZmZpY2NhchFmbS1pLXRyYWZmaWNwbGFuZRFmbS1pLXRyYWZmaWN0cmFpbg9mbS1pLXRyYWZmaWNidXMMZm0taS1hZGRncmF5CmZtLWktY2xvc2UIZm0taS1hZGQJZm0taS1tb3JlCmZtLWktY2hlY2sPZm0taS1iYWNrY2lyY2xlCmZtLWktYWdyZWUMZm0taS1sb2FkaW5nDGZtLWktZmlsZWRlbAlmbS1pLWZpbGUQZm0taS1wcm9jZXNzZmxvdwxmbS1pLXJlZHN0YXIQZm0taS1yaWdodGNpcmNsZQ9mbS1pLXRpbWVjaXJjbGUOZm0taS1zY3JlZW5pbmcMZm0taS11bmNoZWNrDmZtLWktb3BlcmF0aW9uE2ZtLWktYXBwcm92YWxhbW91bnQLZm0taS1hZ3JlZWQOZm0taS1pbnByb2Nlc3MNZm0taS1mZWVkYmFjawpmbS1pLXByaW50DmZtLWktaW1wb3J0YW50GmZtLWktYW1vdW50b2ZyZWltYnVyc2VtZW50FGZtLWktc2FmZXR5YXNzaXN0YW50C2ZtLWktcmVtaW5kDWZtLWktZXllb3BwZW4NZm0taS1leWVjbG9zZRBmbS1pLVBob3RvZ3JhcGh5D2ZtLWktcGhvdG9ncmFwaA9mbS1pLWFkZHBpY3R1cmUTZm0taS10b3Bfb3RoZXItZmFjZQ5mbS1pLXRvcF9vdGhlcgtmbS1pLWRlbGV0ZQ1mbS1pLW5leHRwYWdlDmZtLWktYWRkYnV0dG9uFmZtLWktd2FpdGZvcnByb2Nlc3NpbmcTZm0taS13YXJuaW5nbWVzc2FnZRJmbS1pLWZhaWx1cmVwcm9tcHQUZm0taS1zdWNjZXNzZnVsaGludHMKZm0taS1vdGhlcgxmbS1pLXJldHJhY3QOZm0taS1kcm9wLWRvd24LZm0taS1jYW5jZWwLZm0taS1zZWFyY2gTZm0taS1tdWx0aXBsZWNob2ljZRFmbS1pLXNpbmdsZWNob2ljZQ9mbS1pLW1pY3JvcGhvbmUXZm0taS1hcnJvdy1jaGV2cm9uLWxlZnQPZm0taS1oZWxwY2VudGVyDmZtLWktc3dlZXBjb2RlDmZtLWktZ3JvdXBjaGF0DmZtLWktYWRkZnJpZW5kC2ZtLWktdG9wX215EGZtLWktdG9wX215LWZhY2UPZm0taS10b3BfZnJpZW5kFGZtLWktdG9wX2ZyaWVuZC1mYWNlFWZtLWktdG9wX3B1YmxpY3ByYWlzZRpmbS1pLXRvcF9wdWJsaWNwcmFpc2UtZmFjZQ1mbS1pLXRvcF9ob21lEmZtLWktdG9wX2hvbWUtZmFjZQAAAAA=) format("truetype")}@keyframes fm-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fm-fade-out{0%{opacity:1}to{opacity:0}}.fm-fade-enter-active{animation:.3s fm-fade-in both ease-out}.fm-fade-leave-active{animation:.3s fm-fade-out both ease-in}.fm-slide-up-enter-from,.fm-slide-up-leave-to{transform:translate3d(0,100%,0)}.fm-slide-down-enter-from,.fm-slide-down-leave-to{transform:translate3d(0,-100%,0)}.fm-slide-left-enter-from,.fm-slide-left-leave-to{transform:translate3d(-100%,0,0)}.fm-slide-right-enter-from,.fm-slide-right-leave-to{transform:translate3d(100%,0,0)}.fm-slide-up-enter-active,.fm-slide-down-enter-active,.fm-slide-left-enter-active,.fm-slide-right-enter-active{transition-timing-function:ease-out}.fm-slide-up-leave-active,.fm-slide-down-leave-active,.fm-slide-left-leave-active,.fm-slide-right-leave-active{transition-timing-function:ease-in}.fm-slide-in-enter-active,.fm-slide-in-leave-active,.fm-slide-out-enter-active,.fm-slide-out-leave-active{will-change:transform;transition:all .3s;height:100%;width:100%;top:0;position:absolute;backface-visibility:hidden;perspective:1000}.fm-slide-in-leave-to,.fm-slide-out-enter-from{transform:translate(-100%);opacity:0}.fm-slide-in-enter-from,.fm-slide-out-leave-to{transform:translate(100%);opacity:0}@keyframes fm-drop-down-in{0%{height:0;opacity:0}to{opacity:1}}@keyframes fm-drop-down-out{0%{opacity:1}to{height:0;opacity:0}}.fm-drop-down-enter-active{animation:.3s fm-drop-down-in both ease-out}.fm-drop-down-leave-active{animation:.3s fm-drop-down-out both ease-in}@keyframes fm-rotate{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}:root{--fm-button-height: 42px;--fm-button-padding: 0 14px;--fm-button-radius: 2px;--fm-button-border-width: 1px;--fm-button-color: var(--fm-white);--fm-button-line-height: var(--fm-line-height);--fm-button-font-size: var(--fm-font-size);--fm-button-plain-background: var(--fm-white);--fm-button-lg-height: 46px;--fm-button-lg-font-size: 18px;--fm-button-md-height: 38px;--fm-button-md-font-size: 14px;--fm-button-sm-height: 34px;--fm-button-sm-padding: 0 8px;--fm-button-sm-font-size: 12px;--fm-button-xs-height: 28px;--fm-button-xs-font-size: 10px;--fm-button-secondary-color: var(--fm-blue-light)}.fm-button{position:relative;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;text-align:center;margin:0;border:none;transition:opacity .2s;color:var(--fm-button-color);height:var(--fm-button-height);padding:var(--fm-button-padding);font-size:var(--fm-button-font-size);line-height:var(--fm-button-line-height);border-radius:var(--fm-button-radius)}.fm-button--primary,.fm-button--info{background:var(--fm-primary-color)}.fm-button--secondary{color:var(--fm-primary-color);background:var(--fm-button-secondary-color)}.fm-button--danger{background-color:var(--fm-danger-color)}.fm-button--warning{background-color:var(--fm-warning-color)}.fm-button--success{background-color:var(--fm-success-color)}.fm-button--plain{box-shadow:none;background:var(--fm-button-plain-background)}.fm-button--plain.fm-button--primary,.fm-button--plain.fm-button--info{color:var(--fm-primary-color);border:var(--fm-button-border-width) solid var(--fm-primary-color)}.fm-button--plain.fm-button--success{color:var(--fm-success-color);border:var(--fm-button-border-width) solid var(--fm-success-color)}.fm-button--plain.fm-button--danger{color:var(--fm-danger-color);border:var(--fm-button-border-width) solid var(--fm-danger-color)}.fm-button--plain.fm-button--warning{color:var(--fm-button-warning-color);border:var(--fm-button-border-width) solid var(--fm-button-warning-color)}.fm-button--noborder{border:none!important}.fm-button--large{height:var(--fm-button-lg-height);font-size:var(--fm-button-lg-font-size)}.fm-button--normal{height:var(--fm-button-md-height);font-size:var(--fm-button-md-font-size)}.fm-button--small{height:var(--fm-button-sm-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-sm-font-size)}.fm-button--mini{height:var(--fm-button-xs-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-xs-font-size)}.fm-button--block{display:flex;width:100%}.fm-button--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-button--loading:before,.fm-button--disabled:before{display:none}.fm-button--round{border-radius:var(--fm-radius-max)}.fm-button--square{border-radius:0}.fm-button__loading{display:inline-block;width:20px;max-width:100%;height:20px;max-height:100%;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-button__loading circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}.fm-button__loading-icon-circular{color:#fff}.fm-button__loading-text{margin-left:6px}.fm-button__icon:not(:last-child){margin-right:6px}.fm-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;background-color:#000;border:inherit;border-color:#000;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;content:" "}.fm-button:active:before{opacity:.1}.fm-button-edit__tags{min-height:24px;flex:1;display:flex;overflow:auto}.fm-button-edit__tag:not(:last-child){margin-right:6px}:root{--fm-button-group-gap: 16px}.fm-button-group{display:inline-flex;flex-wrap:nowrap;max-width:100%}.fm-button-group+.fm-button-group{margin-left:var(--fm-button-group-gap)}.fm-button-group__item{margin:0;min-width:0;max-width:100%;white-space:nowrap;flex:0 1 auto;user-select:none}.fm-button-group__item--bare-vertical{display:inline-flex;flex-direction:column;align-items:center;justify-content:space-between;color:#666}.fm-button-group__item--bare-vertical .fm-button-group__item-icon{font-size:20px}.fm-button-group__item--bare-vertical .fm-button-group__item-text{font-size:10px;line-height:16px}.fm-button-group__item--bare-vertical.fm-button-group__item--disabled{cursor:not-allowed;opacity:.5}.fm-button-group--block{display:flex}.fm-button-group--vertical{flex-direction:column}.fm-button-group--block .fm-button-group__item{width:auto;flex:10000 1 0%}.fm-button-group--horizontal.fm-button-group--mode-default .fm-button-group__item+.fm-button-group__item{margin-left:var(--fm-button-group-gap)}.fm-button-group--vertical.fm-button-group--mode-default .fm-button-group__item+.fm-button-group__item{margin-top:var(--fm-button-group-gap)}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:not(:first-child):not(:last-child),.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:not(:first-child):not(:last-child){border-radius:0}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:first-child{border-bottom-left-radius:0;border-bottom-right-radius:0}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:last-child{border-top-left-radius:0;border-top-right-radius:0}.fm-button-group--horizontal.fm-button-group--mode-outline .fm-button-group__item:not(:first-child){border-left:0}.fm-button-group--vertical.fm-button-group--mode-outline .fm-button-group__item:not(:first-child){border-top:0}.fm-button-group--horizontal.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after,.fm-button-group--vertical.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after{content:"";display:block;position:absolute;background-color:var(--fm-gray-3)}.fm-button-group--horizontal.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after{width:1px;right:0;top:var(--fm-padding-xs);bottom:var(--fm-padding-xs)}.fm-button-group--vertical.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after{height:1px;bottom:0;left:var(--fm-padding-xs);right:var(--fm-padding-xs)}.fm-button-group--fill{flex:1}:root{--fm-card-background: var(--fm-white);--fm-card-title-color: var(--fm-gray-7)}.fm-card{background-color:var(--fm-card-background)}.fm-card__header{display:flex;justify-content:space-between;align-items:center;padding:11px 16px 10px;border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-card__header:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-card__title{position:relative;padding-left:var(--fm-padding-md);color:var(--fm-card-title-color);font-size:var(--fm-font-size-lg);line-height:var(--fm-line-height-lg);font-weight:var(--fm-font-bold-light);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-card__title:before{content:"";position:absolute;left:0;top:50%;width:3px;height:14px;margin:-7px 0 0;background:var(--fm-primary-color)}.fm-card__footer{border-top:1px solid #ddd;position:relative;border-top:none}.fm-card__footer:before{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}:root{--fm-cell-padding: 10px 16px;--fm-cell-margin: 5px;--fm-cell-line-height: 24px;--fm-cell-font-size: var(--fm-font-size);--fm-cell-background: var(--fm-background-white);--fm-cell-color: var(--fm-text-color);--fm-cell-label-font-size: 12px;--fm-cell-label-line-height: 18px;--fm-cell-label-color: var(--fm-text-color-light);--fm-cell-required-color: var(--fm-danger-color)}.fm-cell{width:100%;padding:var(--fm-cell-padding);background-color:var(--fm-cell-background);color:var(--fm-cell-color);font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);position:relative;display:flex;overflow:hidden}.fm-cell--bottom-border,.fm-cell:not(:last-child){border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-cell--bottom-border:after,.fm-cell:not(:last-child):after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-cell--bottom-border:after,.fm-cell:not(:last-child):after{left:16px!important}.fm-cell.fm-cell-all-width:not(:last-child):after{left:0!important}.fm-cell--clickable{cursor:pointer}.fm-cell--clickable:active{background-color:var(--fm-active-color)}.fm-cell--required .fm-cell-title{position:relative}.fm-cell--required .fm-cell-title .fm-cell-title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-cell__title,.fm-cell__value{flex:1;font-size:inherit}.fm-cell__title{display:inline-block;overflow:hidden}.fm-cell__title-text{display:flex;word-break:break-all}.fm-cell__title-text span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-cell__right{display:flex;overflow:hidden;flex-direction:column}.fm-cell__right-content{display:flex;flex:1}.fm-cell__right--fill{flex:1}.fm-cell__value{position:relative;overflow:hidden;text-align:right;vertical-align:middle;word-wrap:break-word}.fm-cell__value--alone{text-align:left}.fm-cell__label{margin-top:var(--fm-cell-margin);color:var(--fm-cell-label-color);font-size:var(--fm-cell-label-font-size);line-height:var(--fm-cell-label-line-height)}.fm-cell--center{align-items:center}.fm-cell__extra,.fm-cell__left-icon,.fm-cell__right-icon{min-width:1em;font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);display:flex;align-items:center}.fm-cell__left-icon{margin-right:var(--fm-cell-margin)}.fm-cell__extra,.fm-cell__right-icon{margin-left:var(--fm-cell-margin)}.fm-cell--noborder .fm-cell:after{display:none!important}.fm-cell--card{padding-left:0;padding-right:0}.fm-checkbox-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-checkbox-group--vertical{flex-direction:column}.fm-checkbox-group--vertical .fm-checkbox:not(:last-child){margin-bottom:8px}.fm-checkbox{margin-top:4px;margin-bottom:4px}:root{--fm-checker-color: var(--fm-text-color);--fm-checker-font-size: var(--fm-font-size);--fm-checker-icon-color: var(--fm-text-color-light);--fm-checker-icon-background: var(--fm-background-white);--fm-checker-icon-radius: var(--fm-radius-md);--fm-checker-checked-icon-color: var(--fm-primary-color);--fm-checker-button-background: var(--fm-gray-2);--fm-checker-disabled-color: var(--fm-disabled-color);--fm-checker-disabled-icon-color: var(--fm-gray-1)}.fm-checker{display:flex;align-items:center;color:var(--fm-checker-color);font-size:var(--fm-checker-font-size)}.fm-checker__icon{display:inline-block;align-items:center}.fm-checker__icon .fm-icon{display:block;height:20px;width:20px;line-height:18px;font-size:14px;text-align:center;border-radius:var(--fm-checker-icon-radius);border:1px solid var(--fm-checker-icon-color);color:var(--fm-checker-icon-background);background-color:var(--fm-checker-icon-background)}.fm-checker__label{margin-left:8px;margin-right:8px;display:inline-block;line-height:20px}.fm-checker:first-child .fm-checker_button{margin-left:0}.fm-checker--round .fm-checker__icon .fm-icon{border-radius:100%}.fm-checker--button .fm-checker__label{font-size:13px;text-align:center;border-radius:14px;line-height:28px;padding:0 12px;min-width:60px;margin-right:0;color:var(--fm-checker-color);background:var(--fm-checker-button-background)}.fm-checker--checked .fm-checker__icon .fm-icon{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-checked-icon-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--checked.fm-checker--button .fm-checker__label{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--readonly{opacity:var(--fm-readonly-opacity)}.fm-checker--disabled{color:var(--fm-checker-disabled-color)}.fm-checker--disabled .fm-checker__icon .fm-icon{border-color:var(--fm-checker-disabled-color);background-color:var(--fm-checker-disabled-icon-color);color:var(--fm-checker-disabled-icon-color)}.fm-checker--disabled.fm-checker--checked .fm-checker__icon .fm-icon{background-color:var(--fm-checker-disabled-color);border-color:var(--fm-checker-disabled-color)}:root{--fm-icon-font-size: 14px;--fm-icon-color: inherit}.fm-icon{font-family:farrisMobile!important;font-size:var(--fm-icon-font-size);font-style:normal;color:var(--fm-icon-color);display:inline-block;width:1em;height:1em;font-weight:400;line-height:1;vertical-align:middle;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fm-icon:before{display:inline-block}.fm-icon-filter:before{content:"\e697"}.fm-icon-cardfold:before{content:"\e6b7"}.fm-icon-cardunfold:before{content:"\e6b8"}.fm-icon-trafficother:before{content:"\e6b9"}.fm-icon-bottomsave:before{content:"\e6ba"}.fm-icon-trafficboat:before{content:"\e6bb"}.fm-icon-trafficcar:before{content:"\e6bc"}.fm-icon-trafficplane:before{content:"\e6bd"}.fm-icon-traffictrain:before{content:"\e6be"}.fm-icon-trafficbus:before{content:"\e6bf"}.fm-icon-addgray:before{content:"\e6a7"}.fm-icon-close:before{content:"\e6a8"}.fm-icon-add-line:before{content:"\e6a9"}.fm-icon-more:before{content:"\e6aa"}.fm-icon-check:before{content:"\e6ab"}.fm-icon-backcircle:before{content:"\e6ac"}.fm-icon-agree:before{content:"\e6ad"}.fm-icon-loading:before{content:"\e6ae"}.fm-icon-filedel:before{content:"\e6af"}.fm-icon-file:before{content:"\e6b0"}.fm-icon-processflow:before{content:"\e6b1"}.fm-icon-redstar:before{content:"\e6b2"}.fm-icon-rightcircle:before{content:"\e6b3"}.fm-icon-timecircle:before{content:"\e6b4"}.fm-icon-screening:before{content:"\e6b5"}.fm-icon-uncheck:before{content:"\e6b6"}.fm-icon-operation:before{content:"\e02c"}.fm-icon-approvalamount:before{content:"\e02b"}.fm-icon-agreed:before{content:"\e02a"}.fm-icon-inprocess:before{content:"\e029"}.fm-icon-feedback:before{content:"\e028"}.fm-icon-print:before{content:"\e027"}.fm-icon-important:before{content:"\e026"}.fm-icon-amountofreimbursement:before{content:"\e025"}.fm-icon-safetyassistant:before{content:"\e024"}.fm-icon-remind:before{content:"\e023"}.fm-icon-eyeoppen:before{content:"\e022"}.fm-icon-eyeclose:before{content:"\e01e"}.fm-icon-photography:before{content:"\e021"}.fm-icon-photograph:before{content:"\e020"}.fm-icon-addpicture:before{content:"\e01f"}.fm-icon-top_other-face:before{content:"\e01d"}.fm-icon-top_other:before{content:"\e01c"}.fm-icon-delete:before{content:"\e01b"}.fm-icon-nextpage:before{content:"\e01a"}.fm-icon-addbutton:before{content:"\e019"}.fm-icon-waitforprocessing:before{content:"\e018"}.fm-icon-warningmessage:before{content:"\e017"}.fm-icon-failureprompt:before{content:"\e016"}.fm-icon-successfulhints:before{content:"\e015"}.fm-icon-other:before{content:"\e014"}.fm-icon-retract:before{content:"\e013"}.fm-icon-drop-down:before{content:"\e012"}.fm-icon-cancel:before{content:"\e011"}.fm-icon-search:before{content:"\e010"}.fm-icon-multiplechoice:before{content:"\e00f"}.fm-icon-singlechoice:before{content:"\e00e"}.fm-icon-microphone:before{content:"\e00d"}.fm-icon-arrow-chevron-left:before{content:"\e00c"}.fm-icon-helpcenter:before{content:"\e00b"}.fm-icon-sweepcode:before{content:"\e00a"}.fm-icon-groupchat:before{content:"\e009"}.fm-icon-addfriend:before{content:"\e008"}.fm-icon-top_my:before{content:"\e007"}.fm-icon-top_my-face:before{content:"\e006"}.fm-icon-top_friend:before{content:"\e005"}.fm-icon-top_friend-face:before{content:"\e004"}.fm-icon-top_publicpraise:before{content:"\e003"}.fm-icon-top_publicpraise-face:before{content:"\e002"}.fm-icon-top_home:before{content:"\e001"}.fm-icon-top_home-face:before{content:"\e000"}.fm-icon-s-agree-o:before{content:"\e655"}.fm-icon-s-arrow-down:before{content:"\e656"}.fm-icon-s-add-o:before{content:"\e657"}.fm-icon-s-annex:before{content:"\e658"}.fm-icon-s-arrow:before{content:"\e659"}.fm-icon-s-arrow-up:before{content:"\e65e"}.fm-icon-s-checkbox-checked:before{content:"\e65f"}.fm-icon-s-checkbox:before{content:"\e660"}.fm-icon-s-arrow-left:before{content:"\e661"}.fm-icon-s-exchange:before{content:"\e662"}.fm-icon-s-clear:before{content:"\e663"}.fm-icon-s-checked:before{content:"\e664"}.fm-icon-s-eye-o:before{content:"\e665"}.fm-icon-s-close-eye:before{content:"\e666"}.fm-icon-s-at:before{content:"\e667"}.fm-icon-s-feedback-o:before{content:"\e668"}.fm-icon-s-fold-circle-o:before{content:"\e669"}.fm-icon-s-cross:before{content:"\e66a"}.fm-icon-s-minus:before{content:"\e66b"}.fm-icon-s-file:before{content:"\e66c"}.fm-icon-s-fold-triangle:before{content:"\e66d"}.fm-icon-s-filter:before{content:"\e66e"}.fm-icon-s-forword:before{content:"\e66f"}.fm-icon-s-plus:before{content:"\e670"}.fm-icon-s-filedel:before{content:"\e671"}.fm-icon-s-fold-o:before{content:"\e672"}.fm-icon-s-image-o:before{content:"\e673"}.fm-icon-s-more-o:before{content:"\e674"}.fm-icon-s-redio-circle:before{content:"\e675"}.fm-icon-s-reject-o:before{content:"\e676"}.fm-icon-s-success:before{content:"\e677"}.fm-icon-s-refresh:before{content:"\e678"}.fm-icon-s-star:before{content:"\e679"}.fm-icon-s-processflow:before{content:"\e67a"}.fm-icon-s-unfold-circle-o:before{content:"\e67b"}.fm-icon-s-rewind:before{content:"\e67c"}.fm-icon-s-unfold-o:before{content:"\e67d"}.fm-icon-s-save-o:before{content:"\e67e"}.fm-icon-s-warning-o:before{content:"\e67f"}.fm-icon-s-unfold-triangle:before{content:"\e680"}.fm-icon-s-print-o:before{content:"\e681"}.fm-icon-s-search-o:before{content:"\e682"}.fm-icon-s-news:before{content:"\e683"}.fm-icon-s-news-o:before{content:"\e684"}.fm-icon-s-shop:before{content:"\e68c"}.fm-icon-s-sending:before{content:"\e60b"}.fm-icon-s-import-o:before{content:"\e60c"}.fm-icon-s-edit-o:before{content:"\e60d"}.fm-icon-s-qrcode:before{content:"\e60e"}.fm-icon-s-briefcase:before{content:"\e60f"}.fm-icon-s-notificationoff:before{content:"\e610"}.fm-icon-s-pencil:before{content:"\e611"}.fm-icon-s-star-o:before{content:"\e612"}.fm-icon-s-barcode:before{content:"\e613"}.fm-icon-s-salemessage-o:before{content:"\e614"}.fm-icon-s-listview-o:before{content:"\e615"}.fm-icon-s-picture-o:before{content:"\e616"}.fm-icon-s-savefillet-o:before{content:"\e617"}.fm-icon-s-shoppingcart:before{content:"\e618"}.fm-icon-s-pending:before{content:"\e61d"}.fm-icon-s-expandview-o:before{content:"\e61e"}.fm-icon-s-lock-o:before{content:"\e623"}.fm-icon-s-my:before{content:"\e692"}.fm-icon-s-service:before{content:"\e633"}.fm-icon-s-wallet-o:before{content:"\e634"}.fm-icon-s-shoppingcart-o:before{content:"\e636"}.fm-icon-s-setting-o:before{content:"\e637"}.fm-icon-s-my-o:before{content:"\e696"}.fm-icon-s-unfoldrec-o:before{content:"\e639"}.fm-icon-s-profile:before{content:"\e63a"}.fm-icon-s-link-o:before{content:"\e609"}.fm-icon-s-usersetting-o:before{content:"\e632"}.fm-icon-s-shop-o:before{content:"\e68a"}.fm-icon-s-list:before{content:"\e62a"}.fm-icon-s-location-o:before{content:"\e685"}.fm-icon-s-location:before{content:"\e686"}.fm-icon-s-moment:before{content:"\e689"}.fm-icon-s-moment-o:before{content:"\e68b"}.fm-icon-s-revoke-o:before{content:"\e687"}.fm-icon-s-submit-o:before{content:"\e688"}.fm-icon-s-app-o:before{content:"\e68f"}.fm-icon-s-app:before{content:"\e691"}.fm-icon-s-book-o:before{content:"\e695"}.fm-icon-s-book:before{content:"\e690"}.fm-icon-s-comment:before{content:"\e693"}.fm-icon-s-comment-o:before{content:"\e694"}.fm-icon-s-illustrate-o:before{content:"\e68d"}.fm-icon-s-clear-o:before{content:"\e68e"}.fm-icon-friend:before{content:"\e005"}.fm-icon-scan:before{content:"\e69a"}.fm-icon-back:before{content:"\e69b"}.fm-icon-menu:before{content:"\e69d"}:root{--fm-navbar-background: var(--fm-background-white);--fm-navbar-color: var(--fm-text-color);--fm-navbar-height: 44px;--fm-navbar-title-size: 17px;--fm-navbar-side-size: 16px;--fm-navbar-arrow-size: 16px;--fm-navbar-toolbar-item-height: 46px}.fm-navbar{position:relative;z-index:9;display:flex;align-items:center;line-height:1.5;text-align:center;user-select:none;height:var(--fm-navbar-height);color:var(--fm-navbar-color);background-color:var(--fm-navbar-background)}.fm-navbar--fixed{position:fixed;top:0;left:0;width:100%}.fm-navbar--bottom-border{border-bottom:1px solid #e6e6e6;position:relative;border-bottom:none}.fm-navbar--bottom-border:after{content:"";position:absolute;background-color:#e6e6e6;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-navbar__title{max-width:60%;margin:0 auto;font-weight:500;font-size:var(--fm-navbar-title-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-navbar__left,.fm-navbar__right{position:absolute;top:0;bottom:0;display:flex;align-items:center;max-width:30%;padding:0 16px;font-size:var(--fm-navbar-side-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;cursor:pointer}.fm-navbar__left{left:0}.fm-navbar__left:active{opacity:var(--fm-active-opacity)}.fm-navbar__left.fm-navbar-left-padding{padding-left:14px}.fm-navbar__right{right:0}.fm-navbar__right .fm-navbar-text:active{opacity:var(--fm-active-opacity)}.fm-navbar__left-arrow{min-width:1em;margin-right:4px;font-size:var(--fm-navbar-arrow-size)}.fm-navbar__toolbar{padding:0!important}.fm-navbar__toolbar-item{padding:0 var(--fm-padding-sm);height:var(--fm-navbar-toolbar-item-height);line-height:var(--fm-navbar-toolbar-item-height);user-select:none;cursor:pointer}.fm-navbar__toolbar-item:not(:last-child){border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-navbar__toolbar-item:not(:last-child):after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-navbar__toolbar-item--disabled{opacity:var(--fm-disabled-opacity);cursor:not-allowed}:root{--fm-input-group-size: var(--fm-font-size);--fm-input-group-color: var(--fm-text-color);--fm-input-group-sub-size: 13px;--fm-input-group-padding: 10px 16px;--fm-input-group-sub-color: var(--fm-text-color-light);--fm-input-group-border-color: var(--fm-gray-2)}.fm-input-group{display:flex;flex-direction:column;background-color:var(--fm-white)}.fm-input-group--padding{padding:var(--fm-input-group-padding)}.fm-input-group__body{flex:1;display:flex;align-items:center;min-height:24px;color:var(--fm-input-group-color);font-size:var(--fm-input-group-size)}.fm-input-group__body--border{border:1px solid var(--fm-input-group-border-color);padding:4px 8px;border-radius:4px}.fm-input-group__control{display:flex;width:100%;min-width:0;margin:0;padding:0;border:0;resize:none;color:inherit;font-size:inherit;outline:none;line-height:inherit;background-color:transparent}.fm-input-group__control::placeholder{color:var(--fm-input-group-sub-color)}.fm-input-group__control:disabled{opacity:1;cursor:not-allowed;color:var(--fm-disabled-color);-webkit-text-fill-color:currentColor}.fm-input-group__control::-webkit-search-cancel-button{display:none}.fm-input-group__control--readonly{cursor:default;color:var(--fm-readonly-color)}.fm-input-group__control--left{justify-content:flex-start;text-align:left}.fm-input-group__control--center{justify-content:center;text-align:center}.fm-input-group__control--right{justify-content:flex-end;text-align:right}.fm-input-group__clear{cursor:pointer;margin-right:-8px;padding:4px 8px;color:var(--fm-input-group-sub-color);flex-shrink:0;box-sizing:content-box}.fm-input-group__left-icon{margin:auto 4px auto 0}.fm-input-group__right-icon{margin:auto 0 auto 4px}.fm-input-group__word-limit{margin-top:4px;line-height:18px;text-align:right;font-size:var(--fm-input-group-sub-size);color:var(--fm-input-group-sub-color)}.fm-radio-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-radio-group--vertical{flex-direction:column}.fm-radio-group--vertical .fm-radio:not(:last-child){margin-bottom:8px}.fm-radio{margin-top:4px;margin-bottom:4px}:root,:host{--fm-rate-icon-size: 20px;--fm-rate-icon-gutter: var(--fm-padding-base);--fm-rate-icon-void-color: var(--fm-gray-4);--fm-rate-icon-full-color: var(--fm-orange-3);--fm-rate-icon-disabled-color: var(--fm-gray-4)}.fm-rate{display:inline-flex;cursor:pointer;user-select:none;flex-wrap:wrap}.fm-rate__item{position:relative}.fm-rate__item:not(:last-child){padding-right:var(--fm-rate-icon-gutter)}.fm-rate__icon{display:block;width:1em;color:var(--fm-rate-icon-void-color);font-size:var(--fm-rate-icon-size)}.fm-rate__icon--half{position:absolute;top:0;left:0;overflow:hidden;pointer-events:none;color:var(--fm-rate-icon-full-color)}.fm-rate__icon--full{color:var(--fm-rate-icon-full-color)}.fm-rate__icon--disabled{color:var(--fm-rate-icon-disabled-color)}.fm-rate--disabled{cursor:not-allowed}.fm-rate--readonly{cursor:default}:root{--fm-form-item-size: var(--fm-font-size);--fm-form-item-color: var(--fm-text-color);--fm-form-item-label-width: 105px;--fm-form-item-sub-size: 13px}.fm-form-item{font-size:var(--fm-form-item-size);color:var(--fm-form-item-color)}.fm-form-item--vertical{flex-direction:column}.fm-form-item--vertical .fm-form-item__label{margin-bottom:4px}.fm-form-item__label{display:flex;flex:none;align-items:flex-start;text-align:left;width:var(--fm-form-item-label-width);margin-right:4px}.fm-form-item__label--left{justify-content:flex-start}.fm-form-item__label--center{justify-content:center}.fm-form-item__label--right{justify-content:flex-end}.fm-form-item__label--required{position:relative}.fm-form-item__label--required .fm-cell__title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-form-item__content{display:flex}.fm-form-item__content .fm-input-group{padding:0;flex:1}.fm-form-item__content--left{justify-content:flex-start}.fm-form-item__content--left input.fm-input-group__control{justify-content:flex-start;text-align:left}.fm-form-item__content--center{justify-content:center}.fm-form-item__content--center input.fm-input-group__control{justify-content:flex-center;text-align:center}.fm-form-item__content--right{justify-content:flex-end}.fm-form-item__content--right input.fm-input-group__control{justify-content:flex-end;text-align:right}.fm-form-item__error-message{color:var(--fm-danger-color);font-size:var(--fm-form-item-sub-size)}.fm-form-item__error-message--left{text-align:left}.fm-form-item__error-message--center{text-align:center}.fm-form-item__error-message--right{text-align:right}:root{--fm-overlay-background: rgba(0, 0, 0, .4);--fm-overlay-zindex: 98}.fm-overlay{width:100%;position:fixed;top:0;left:0;z-index:var(--fm-overlay-zindex);background-color:var(--fm-overlay-background);bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-overlay{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}:root{--fm-popup-background: var(--fm-white);--fm-popup-zindex: var(--fm-zindex-3);--fm-popup-radius: 16px}.fm-popup{position:fixed;max-height:100%;overflow-y:auto;background-color:var(--fm-popup-background);transition:all var(--fm-duration-base);z-index:var(--fm-popup-zindex)}.fm-popup--center{top:50%;left:50%;transform:translate(-50%,-50%)}.fm-popup--center.fm-popup--round{border-radius:var(--fm-popup-radius)}.fm-popup--top,.fm-popup--bottom{left:0;right:0}.fm-popup--top{top:0}.fm-popup--top.fm-popup--round{border-radius:0 0 var(--fm-popup-radius) var(--fm-popup-radius)}.fm-popup--bottom{bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--bottom{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--bottom.fm-popup--round{border-radius:var(--fm-popup-radius) var(--fm-popup-radius) 0 0}.fm-popup--left,.fm-popup--right{top:0;bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--left,.fm-popup--right{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--left{left:0}.fm-popup--left.fm-popup--round{border-radius:0 var(--fm-popup-radius) var(--fm-popup-radius) 0}.fm-popup--right{right:0}.fm-popup--right.fm-popup--round{border-radius:var(--fm-popup-radius) 0 0 var(--fm-popup-radius)}:root{--fm-popover-zindex: var(--fm-zindex-5);--fm-popover-padding: var(--fm-padding-sm);--fm-popover-border-radius: var(--fm-radius-lg);--fm-popover-arrow-size: 8px;--fm-popover-content-font-size: var(--fm-font-size);--fm-popover-content-line-height: var(--fm-line-height);--fm-popover-light-theme-color: var(--fm-gray-7);--fm-popover-light-theme-background: var(--fm-white);--fm-popover-dark-theme-color: var(--fm-white);--fm-popover-dark-theme-background: var(--fm-gray-7);--fm-popover-shadow: 0 6px 30px 5px rgba(0, 0, 0, .05), 0 16px 24px 2px rgba(0, 0, 0, .04), 0 8px 10px -5px rgba(0, 0, 0, .08)}.fm-popover{position:absolute;overflow:visible;top:0;left:0;transition:opacity .15s;background-color:transparent;z-index:var(--fm-popover-zindex)}.fm-popover__wrapper{display:inline-block}.fm-popover__content{position:relative;padding:var(--fm-popover-padding);border-radius:var(--fm-popover-border-radius);font-size:var(--fm-popover-content-font-size);line-height:var(--fm-popover-content-line-height);word-break:break-all}.fm-popover__arrow{position:absolute;width:0;height:0;z-index:1;border-style:solid;border-color:transparent;border-width:var(--fm-popover-arrow-size, 8px)}.fm-popover__arrow--top{border-bottom-width:0;border-top-color:currentColor;margin-bottom:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--right{border-left-width:0;border-right-color:currentColor;margin-left:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--bottom{border-top-width:0;border-bottom-color:currentColor;margin-top:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--left{border-right-width:0;border-left-color:currentColor;margin-right:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover--light .fm-popover__content{background:var(--fm-popover-light-theme-background);color:var(--fm-popover-light-theme-color);box-shadow:var(--fm-popover-shadow)}.fm-popover--light .fm-popover__arrow{color:var(--fm-popover-light-theme-background)}.fm-popover--dark .fm-popover__content{background:var(--fm-popover-dark-theme-background);color:var(--fm-popover-dark-theme-color);box-shadow:var(--fm-popover-shadow)}.fm-popover--dark .fm-popover__arrow{color:var(--fm-popover-dark-theme-background)}:root{--fm-switch-background: var(--fm-text-color-light);--fm-switch-on-color: var(--fm-primary-color)}.fm-switch{position:relative;cursor:pointer;display:inline-block;transition:background-color var(--fm-duration-base);background-color:var(--fm-switch-background)}.fm-switch--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-switch--readonly{cursor:default;opacity:var(--fm-readonly-opacity)}.fm-switch--loading{cursor:default}.fm-switch--on{background-color:var(--fm-switch-on-color)}.fm-switch--on .fm-switch__loadding{color:var(--fm-switch-on-color)}.fm-switch__node{display:flex;align-items:center;justify-content:center;position:absolute;top:1px;left:1px;z-index:1;width:28px;height:28px;border-radius:100%;background-color:var(--fm-white);transition:transform var(--fm-duration-base) cubic-bezier(.3,1.05,.4,1.05)}:root{--fm-toast-zindex: var(--fm-zindex-5);--fm-toast-color: var(--fm-white);--fm-toast-font-size: 16px;--fm-toast-background: var(--fm-gray-7);--fm-toast-icon-font-size: 48px}.fm-toast{position:fixed;top:50%;left:50%;display:-webkit-box;display:-webkit-flex;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:content-box;max-width:70%;padding:16px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;border-radius:7px;transform:translate(-50%,-50%);color:var(--fm-toast-color);z-index:var(--fm-toast-zindex);font-size:var(--fm-toast-font-size);background-color:var(--fm-toast-background)}.fm-toast--top{top:50px;transform:translate(-50%)}.fm-toast--bottom{top:auto;bottom:50px}.fm-toast--info,.fm-toast--success,.fm-toast--warning,.fm-toast--error{width:88px;min-height:88px}.fm-toast__icon-wrapper{margin-bottom:8px}.fm-toast--default{padding:8px 16px}.fm-toast--loading{min-width:84px;min-height:84px}.fm-toast--loading-icon{position:relative;display:inline-block;width:30px;height:30px;margin-bottom:8px;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-toast--loading-icon circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}:root{--fm-notify-color: var(--fm-white);--fm-notify-zindex: var(--fm-zindex-5);--fm-notify-info-background: var(--fm-primary-color);--fm-notify-success-background: var(--fm-success-color);--fm-notify-warning-background: var(--fm-warning-color);--fm-notify-error-background: var(--fm-danger-color)}.fm-notify{position:fixed;left:0;top:0;z-index:var(--fm-notify-zindex);display:flex;align-items:center;justify-content:center;width:100%;max-height:100%;padding:8px 16px;box-sizing:border-box;color:var(--fm-notify-color);font-size:14px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;overflow-y:auto}.fm-notify--info{background-color:var(--fm-notify-info-background)}.fm-notify--success{background-color:var(--fm-notify-success-background)}.fm-notify--warning{background-color:var(--fm-notify-warning-background)}.fm-notify--error{background-color:var(--fm-notify-error-background)}:root{--fm-dialog-background: var(--fm-background-2);--fm-dialog-padding-top: 24px;--fm-dialog-padding-left: 16px;--fm-dialog-header-font-size: 17px;--fm-dialog-header-line-height: 24px;--fm-dialog-content-font-size: 15px;--fm-dialog-content-line-height: 20px;--fm-dialog-footer-height: 50px;--fm-border-color: var(--fm-gray-4)}@media screen and (min-width: 375px){.fm-dialog{width:320px}}@media screen and (min-width: 280px) and (max-width: 375px){.fm-dialog{width:240px}}.fm-dialog{display:flex;flex-direction:column;background-color:var(--fm-dialog-background);overflow:hidden}.fm-dialog__header{padding-top:var(--fm-dialog-padding-top);padding-left:var(--fm-dialog-header-padding-left);padding-right:var(--fm-dialog-header-padding-left);font-weight:var(--fm-font-bold-light);font-size:var(--fm-dialog-header-font-size);color:var(--fm-text-color);line-height:var(--fm-dialog-header-line-height);text-align:center}.fm-dialog__content{max-height:70vh;overflow-y:auto}.fm-dialog__content__message{padding:var(--fm-dialog-padding-top) var(--fm-dialog-padding-left);font-size:var(--fm-dialog-content-font-size);line-height:var(--fm-dialog-content-line-height);white-space:pre-wrap;text-align:center;word-wrap:break-word}.fm-dialog__content__message--has-title{padding-top:11px;color:var(--fm-text-color-light)}.fm-dialog__content--prompt{padding:14px}.fm-dialog__content--prompt__input{display:block}.fm-dialog__footer{display:flex;flex-direction:row;align-items:center;border-top:1px solid var(--fm-border-color);position:relative;border-top:none}.fm-dialog__footer:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}.fm-dialog__footer .fm-button{border:0;height:var(--fm-dialog-footer-height);border-right:1px solid var(--fm-border-color);position:relative;border-right:none}.fm-dialog__footer .fm-button:after{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 0 auto auto;width:1px;height:100%;background:var(--fm-border-color);transform-origin:100% 50%;transform:scaleX(.5)}.fm-dialog__footer .fm-button:last-child{border-right:0}.fm-dialog__footer .fm-button:last-child:after{display:none!important}.fm-dialog__footer .fm-button--default{color:var(--fm-text-color)}.fm-dialog__footer--is-column{flex-direction:column}.fm-dialog__footer--is-column__button{border-top:1px solid var(--fm-border-color);position:relative;border-top:none}.fm-dialog__footer--is-column__button:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}.fm-dialog__footer--is-column__button:first-child{border-top:0}.fm-dialog__footer--is-column__button:first-child:before{display:none!important}.fm-dialog.fm-dialog--relative{position:relative}.fm-dialog.fm-dialog--relative__header{padding-right:40px}.fm-dialog__close{position:absolute;right:16px;top:16px;width:22px;height:22px;line-height:22px;text-align:center}.fm-dialog__close .fm-icon{font-size:15px;color:var(--fm-text-color-2)}:root,:host{--fm-loading-color: var(--fm-gray-5);--fm-loading-text-font-size: 14px;--fm-loading-text-line-height: 1.4}.fm-loading{display:flex;align-items:center;position:relative;color:var(--fm-loading-color)}.fm-loading__text{color:var(--fm-loading-color);font-size:var(--fm-loading-text-font-size);line-height:var(--fm-loading-text-line-height);margin-left:var(--fm-margin-xs)}.fm-loading--vertical{flex-direction:column}.fm-loading--vertical .fm-loading__text{margin-top:var(--fm-margin-xs);margin-left:0}.fm-loading__circular{display:block;animation:fm-rotate 2s linear infinite}.fm-loading__circular circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:3;stroke-linecap:round}.fm-loading__spinner{display:block;position:relative;animation:fm-rotate 1s linear infinite;animation-timing-function:steps(12)}.fm-loading__line{position:absolute;top:0;left:0;width:100%;height:100%}.fm-loading__line-inner{display:block;width:2px;height:25%;margin:0 auto;background-color:currentColor;border-radius:40%}.fm-loading__ring{display:block;animation:fm-rotate .75s linear infinite;border:4px solid;border-right-color:transparent;border-radius:50%}@keyframes fm-circular{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40}to{stroke-dasharray:90,150;stroke-dashoffset:-120}}.fm-loading__line--1{transform:rotate(30deg);opacity:1}.fm-loading__line--2{transform:rotate(60deg);opacity:.9375}.fm-loading__line--3{transform:rotate(90deg);opacity:.875}.fm-loading__line--4{transform:rotate(120deg);opacity:.8125}.fm-loading__line--5{transform:rotate(150deg);opacity:.75}.fm-loading__line--6{transform:rotate(180deg);opacity:.6875}.fm-loading__line--7{transform:rotate(210deg);opacity:.625}.fm-loading__line--8{transform:rotate(240deg);opacity:.5625}.fm-loading__line--9{transform:rotate(270deg);opacity:.5}.fm-loading__line--10{transform:rotate(300deg);opacity:.4375}.fm-loading__line--11{transform:rotate(330deg);opacity:.375}.fm-loading__line--12{transform:rotate(360deg);opacity:.3125}:root,:host{--fm-pull-refresh-head-height: 50px;--fm-pull-refresh-head-font-size: var(--fm-font-size-md);--fm-pull-refresh-head-text-color: var(--fm-text-color-light);--fm-pull-refresh-animation-duration: .3s}.fm-pull-refresh{overflow:hidden}.fm-pull-refresh__track{position:relative;height:100%}.fm-pull-refresh__track--not-pulling{transition:transform ease var(--fm-pull-refresh-animation-duration)}.fm-pull-refresh__head{position:absolute;left:0;width:100%;height:var(--fm-pull-refresh-head-height);color:var(--fm-pull-refresh-head-text-color);font-size:var(--fm-pull-refresh-head-font-size);line-height:var(--fm-pull-refresh-head-height);text-align:center;transform:translateY(-100%);display:flex;justify-content:center;align-items:center;flex-direction:column;overflow:hidden}:root,:host{--fm-list-text-color: var(--fm-gray-5);--fm-list-text-font-size: var(--fm-font-size-md, 14px);--fm-list-text-line-height: 50px;--fm-list-loading-icon-size: 16px}.fm-list__loading,.fm-list__error,.fm-list__load-more,.fm-list__finished-info{color:var(--fm-list-text-color);font-size:var(--fm-list-text-font-size);line-height:var(--fm-list-text-line-height);text-align:center}.fm-list__loading-container{display:flex;height:var(--fm-list-text-line-height);justify-content:center;align-items:center}:root,:host{--fm-listview-checkbox-container-width: 40px;--fm-listview-toolbar-height: 42px;--fm-listview-split-line-color: rgb(230, 235, 235);--fm-listview-empty-text-color: var(--fm-gray-5);--fm-listview-empty-text-font-size: var(--fm-font-size-md, 14px);--fm-listview-empty-text-line-height: 50px}.fm-list-view--fill{height:100%;flex-grow:1;flex-shrink:1;display:flex;flex-direction:column;overflow:hidden}.fm-list-view--fill .fm-list-view__track{flex:1 1 0;overflow:auto;-webkit-overflow-scrolling:touch}.fm-list-view--fill .fm-pull-refresh{min-height:100%}.fm-list-view .fm-list{user-select:none;-webkit-user-select:none}.fm-list-view__item{display:flex;position:relative;overflow:hidden}.fm-list-view__item-checker{display:flex;position:absolute;height:100%;width:var(--fm-listview-checkbox-container-width);justify-content:center;align-items:center}.fm-list-view__item-content{flex:1;transform:translate(0)}.fm-list-view__content--split .fm-list-view__item:not(:last-child):not(.fm-list-view__item--child){border-bottom:1px solid var(--fm-listview-split-line-color)}.fm-list-view--multi-select .fm-list-view__item-content{transform:translate(var(--fm-listview-checkbox-container-width))}.fm-list-view__item--group{display:block}.fm-list-view__item-group-header{padding:10px 16px;line-height:20px;font-size:var(--fm-font-size-md);color:var(--fm-gray-5)}.fm-list-view__empty-message{display:block;color:var(--fm-listview-empty-text-color);font-size:var(--fm-listview-empty-text-font-size);line-height:var(--fm-listview-empty-text-line-height);text-align:center}.fm-list-view__item-text{padding:13px 20px;color:var(--fm-gray-7);font-size:var(--fm-font-size)}.fm-list-view__toolbar{display:flex;align-items:center;height:var(--fm-listview-toolbar-height)}.fm-list-view__toolbar-item{flex:1}:root,:host{--fm-swipe-cell-button-text-color: var(--fm-white);--fm-swipe-cell-button-bg-color: var(--fm-gray-4);--fm-swipe-cell-button-font-size: var(--fm-font-size);--fm-swipe-cell-button-icon-size: var(--fm-font-size);--fm-swipe-cell-button-padding: var(--fm-padding-md)}.fm-swipe-cell{position:relative;overflow:hidden}.fm-swipe-cell__wrapper{transition-timing-function:cubic-bezier(.18,.89,.32,1);transition-property:transform}.fm-swipe-cell__left,.fm-swipe-cell__right{position:absolute;top:0;height:100%;display:flex}.fm-swipe-cell__left{left:0;transform:translate3d(-100%,0,0);flex-direction:row-reverse}.fm-swipe-cell__right{right:0;transform:translate3d(100%,0,0)}.fm-swipe-cell__button{display:inline-flex;justify-content:center;align-items:center;height:100%;padding:0 var(--fm-swipe-cell-button-padding);color:var(--fm-swipe-cell-button-text-color);background-color:var(--fm-swipe-cell-button-bg-color)}.fm-swipe-cell__icon{font-size:var(--fm-swipe-cell-button-icon-size)}.fm-swipe-cell__text{font-size:var(--fm-swipe-cell-button-font-size)}.fm-swipe-cell__icon+.fm-swipe-cell__text:not(:empty){margin-left:6px}:root,:host{--fm-action-sheet-max-height: 80%;--fm-action-sheet-border-radius: 12px;--fm-action-sheet-description-color: var(--fm-gray-5);--fm-action-sheet-description-line-height: 22px;--fm-action-sheet-description-font-size: var(--fm-font-size-md);--fm-action-sheet-description-padding: 12px 16px;--fm-action-sheet-item-default-background: var(--fm-background-white);--fm-action-sheet-item-active-background: #f2f3f5;--fm-action-sheet-item-padding: 13px 16px;--fm-action-sheet-item-text-color: #1a1a1a;--fm-action-sheet-item-disabled-text-color: #bdbdbd;--fm-action-sheet-item-subtitle-color: var(--fm-gray-5);--fm-action-sheet-item-icon-size: 18px;--fm-action-sheet-item-icon-margin-right: 8px;--fm-action-sheet-item-title-font-size: var(--fm-font-size-lg);--fm-action-sheet-item-title-line-height: 24px;--fm-action-sheet-item-subtitle-font-size: var(--fm-font-size-sm);--fm-action-sheet-item-subtitle-line-height: 18px;--fm-action-sheet-item-subtitle-margin-top: 2px;--fm-action-sheet-footer-gap-color: #f5f5f5;--fm-action-sheet-divider-color: #e7e7e7;--fm-action-sheet-cancel-height: 48px;--fm-action-sheet-cancel-color: #1a1a1a;--fm-action-sheet-cancel-font-size: var(--fm-font-size-lg);--fm-action-sheet-cancel-font-weight: 500}.fm-action-sheet{display:flex;flex-direction:column;max-height:var(--fm-action-sheet-max-height);overflow:hidden;user-select:none}.fm-action-sheet--round{border-top-left-radius:var(--fm-action-sheet-border-radius);border-top-right-radius:var(--fm-action-sheet-border-radius)}.fm-action-sheet__description{flex-shrink:0;color:var(--fm-action-sheet-description-color);line-height:var(--fm-action-sheet-description-line-height);font-size:var(--fm-action-sheet-description-font-size);text-align:center;padding:var(--fm-action-sheet-description-padding);position:relative}.fm-action-sheet__description--left{text-align:left}.fm-action-sheet__content{flex:1 auto;overflow-y:auto;-webkit-overflow-scrolling:touch}.fm-action-sheet__item,.fm-action-sheet__cancel{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__item:active,.fm-action-sheet__cancel:active{background-color:var(--fm-action-sheet-item-active-background)}.fm-action-sheet__item{display:flex;position:relative;flex-wrap:wrap;align-items:center;justify-content:center;text-align:center;padding:var(--fm-action-sheet-item-padding);color:var(--fm-action-sheet-item-text-color);cursor:pointer}.fm-action-sheet__item-icon{font-size:var(--fm-action-sheet-item-icon-size);margin-right:var(--fm-action-sheet-item-icon-margin-right)}.fm-action-sheet__item-title{font-size:var(--fm-action-sheet-item-title-font-size);line-height:var(--fm-action-sheet-item-title-line-height)}.fm-action-sheet__item-subtitle{font-size:var(--fm-action-sheet-item-subtitle-font-size);line-height:var(--fm-action-sheet-item-subtitle-line-height);width:100%;margin-top:var(--fm-action-sheet-item-subtitle-margin-top);color:var(--fm-action-sheet-item-subtitle-color);overflow-wrap:break-word}.fm-action-sheet__item--left{text-align:left;justify-content:flex-start}.fm-action-sheet__item--disabled{color:var(--fm-action-sheet-item-disabled-text-color);cursor:not-allowed}.fm-action-sheet__item--disabled:active{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__description:after,.fm-action-sheet__item:after{content:"";display:block;position:absolute;height:1px;bottom:0;left:0;right:0;transform:scaleY(.5);background-color:var(--fm-action-sheet-divider-color)}.fm-action-sheet__footer-gap{height:8px;background-color:var(--fm-action-sheet-footer-gap-color)}.fm-action-sheet__cancel{display:flex;flex-direction:column;justify-content:center;align-items:center;height:var(--fm-action-sheet-cancel-height);cursor:pointer;color:var(--fm-action-sheet-cancel-color);font-size:var(--fm-action-sheet-cancel-font-size);font-weight:var(--fm-action-sheet-cancel-font-weight)}:root{--fm-tab-bar-item-color: var(--fm-text-color);--fm-tab-bar-item-active-color: var(--fm-primary-color);--fm-tab-bar-item-font-size: 16px}.fm-tab-bar-item{flex:1 0 auto;position:relative;display:inline-flex;align-items:center;justify-content:center;margin:0 12px;line-height:44px}.fm-tab-bar-item--actived{color:var(--fm-tab-bar-item-active-color)}.fm-tab-bar-item--disabled{color:var(--fm-disabled-color)}.fm-tab-bar-item--dot .fm-tab-bar-item__text:after{content:"";position:absolute;top:0;right:0;width:8px;height:8px;background-color:var(--fm-danger-color);border-radius:100%;transform:translate(100%,100%)}.fm-tab-bar-item__text{position:relative;display:flex;justify-content:center;min-width:40px}.fm-tab-bar-item__ink{position:absolute;bottom:0;left:0;right:0;height:4px;background-color:var(--fm-tab-bar-item-active-color);border-radius:2px}.fm-tab-bar-item__badge{position:absolute;top:2px;right:0;padding:0 4px;max-width:28px;font-weight:500;font-size:12px;line-height:14px;border-radius:7px;color:var(--fm-background-white);background-color:var(--fm-danger-color);transform:translate(50%)}.fm-tab-bar-item__icon{position:relative;display:flex;align-items:center;justify-content:center;padding-right:4px}:root{--fm-tab-bar-height: 44px;--fm-tab-bar-background: var(--fm-background-white);--fm-tab-bar-color: var(--fm-text-color);--fm-tab-bar-active-color: var(--fm-primary-color);--fm-tab-bar-font-size: 16px}.fm-tab-bar{position:relative;background:var(--fm-tab-bar-background);color:var(--fm-tab-bar-color);font-size:var(--fm-tab-bar-font-size)}.fm-tab-bar--bottom-line{border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-tab-bar--bottom-line:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-tab-bar__scroll-wrapper{position:relative;width:100%;overflow:hidden}.fm-tab-bar__list{display:flex;justify-content:space-between;min-width:100%;transition:all .3s cubic-bezier(.17,.89,.45,1)}.fm-tab-bar__ink{position:absolute;bottom:0;left:0;display:block;height:4px;background-color:var(--fm-tab-bar-active-color);transition:all var(--fm-duration-base);border-radius:2px}.fm-tab-bar__ink--disabled{background-color:var(--fm-disabled-color)}.fm-tabs{overflow:hidden}.fm-tabs__content{display:flex}.fm-tab{display:block;flex-shrink:0;width:100%;height:100%;overflow:auto;word-break:break-all}.fm-tab--collapse{height:0;overflow:visible}:root{--fm-tag-padding: 0 6px;--fm-tag-height: 18px;--fm-tag-font-size: 12px;--fm-tag-border-radius: 2px;--fm-tag-color: var(--fm-white)}.fm-tag{position:relative;display:inline-flex;align-items:center;white-space:nowrap;padding:0 4px;color:var(--fm-tag-color);font-size:var(--fm-tag-font-size);line-height:var(--fm-tag-height);border-radius:var(--fm-tag-border-radius)}.fm-tag--primary{background-color:var(--fm-primary-color)}.fm-tag--success{background-color:var(--fm-success-color)}.fm-tag--danger{background-color:var(--fm-danger-color)}.fm-tag--warning{background-color:var(--fm-warning-color)}.fm-tag--plain{background-color:var(--fm-white)}.fm-tag--plain.fm-tag--primary{border:1px solid var(--fm-primary-color);color:var(--fm-primary-color)}.fm-tag--plain.fm-tag--success{border:1px solid var(--fm-success-color);color:var(--fm-success-color)}.fm-tag--plain.fm-tag--warning{border:1px solid var(--fm-warning-color);color:var(--fm-warning-color)}.fm-tag--plain.fm-tag--danger{border:1px solid var(--fm-danger-color);color:var(--fm-danger-color)}.fm-tag--medium{padding:2px 6px}.fm-tag--large{padding:4px 8px;font-size:14px;border-radius:4px}.fm-tag--round{border-radius:100px}.fm-tag--mark{border-radius:0 100px 100px 0}.fm-tag__close{font-size:8px;margin-left:4px}.fm-tag--large .fm-tag__close{font-size:10px}: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}.fm-picker-panel__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker-panel__toolbar-left,.fm-picker-panel__toolbar-right{padding:0 16px}.fm-picker-panel__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker-panel__content{position:relative;display:flex;cursor:grab}.fm-picker-panel__columns{display:flex;flex:1;overflow:hidden}.fm-picker-panel__column{flex:1}.fm-picker-panel__column-item{display:flex;align-items:center;justify-content:center;height:44px}.fm-picker-panel__mask{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;background-image:linear-gradient(180deg,#ffffffe6,#fff6),linear-gradient(0deg,#ffffffe6,#fff6);background-repeat:no-repeat;background-position:top,bottom;transform:translateZ(0);pointer-events:none}.fm-picker-panel__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(.5)}.fm-picker-group__header{text-align:left}.fm-picker-group__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker-group__toolbar-left,.fm-picker-group__toolbar-right{padding:0 16px}.fm-picker-group__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker-group__tab-bar{display:inline-block}:root{--fm-lookup-panel-background: var(--fm-background);--fm-lookup-panel-search-list-zindex: var(--fm-zindex-3)}.fm-lookup-panel{height:100%;display:flex;flex-direction:column;overflow:hidden;background-color:var(--fm-lookup-panel-background)}.fm-lookup-panel__header{background-color:var(--fm-background-white)}.fm-lookup-panel__header__search{border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-lookup-panel__header__search:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-lookup-panel__header__selected-wrapper{display:flex;padding:6px 16px;overflow:auto}.fm-lookup-panel__header__selected-item{font-size:14px;line-height:20px;word-break:keep-all;white-space:nowrap;padding:4px 6px;color:var(--fm-primary-color);background-color:var(--fm-primary-color-light);border-radius:4px}.fm-lookup-panel__header__selected-item:not(:last-child){margin-right:8px}.fm-lookup-panel__footer{padding:0 16px;height:48px;display:flex;align-items:center;justify-content:space-between;box-shadow:0 0 7px 0 var(--fm-box-shadow-color);border-top:1px solid var(--fm-gray-1);background-color:var(--fm-background-white)}.fm-lookup-panel__content{flex:1;display:flex;overflow:hidden;margin-top:10px;position:relative}.fm-lookup-panel__list{flex:1;overflow-y:auto;background-color:var(--fm-background-white)}.fm-lookup-panel__list-item{display:flex;align-items:center;background-color:#fff}.fm-lookup-panel__list-checker{padding-left:16px}.fm-lookup-panel__search-list{position:absolute;inset:0;display:none;overflow-y:auto;z-index:var(--fm-lookup-panel-search-list-zindex);background-color:var(--fm-background-white)}.fm-lookup-panel__popup-selected{width:100%;display:flex;flex-direction:column}.fm-lookup-panel__popup-selected__footer-left{color:var(--fm-primary-color)}.fm-lookup-panel__selected-list{flex:1;overflow:auto}.fm-lookup-panel__empty{padding:12px 16px}.fm-lookup-panel__empty__text{text-align:center;color:var(--fm-text-color-light)}.fm-lookup-panel__breadcrumb{display:flex;align-items:center;height:42px;padding:0 16px;overflow:auto;border-bottom:1px solid var(--fm-border-color);position:relative;border-bottom:none}.fm-lookup-panel__breadcrumb:after{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-lookup-panel__breadcrumb__item{display:flex;align-items:center;color:var(--fm-primary-color);padding-right:8px;flex-shrink:0}.fm-lookup-panel__breadcrumb__item:last-child{color:var(--fm-text-color-light)}.fm-lookup-panel__breadcrumb__icon{font-size:10px;padding-left:4px}.fm-lookup-panel__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)}: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)}.fm-search{display:flex;align-items:center;padding:8px 12px;color:var(--fm-search-color);background-color:var(--fm-search-background)}.fm-search__input-wrapper{flex:1;padding:5px 8px;border-radius:17px;background-color:var(--fm-search-input-background)}.fm-search__input{background-color:var(--fm-search-input-background)}.fm-search__search-icon{margin-right:4px;color:var(--fm-text-color-light)}.fm-filter-panel{height:100%;display:flex;flex-direction:column;padding:8px 16px}.fm-filter-panel__content{flex:1}.fm-filter-panel__footer{padding:8px 16px}.fm-filter-panel__field:not(:first-child){margin-top:16px}.fm-filter-panel__field__title{display:flex;align-items:center;justify-content:space-between;line-height:22px}.fm-filter-panel__field__content{padding-top:12px}.fm-filter-panel__field__range{display:flex;align-items:center}.fm-filter-panel__field__range__splitter{width:8px;margin:0 8px;border:1px solid #999}.fm-filter-panel__field__list{display:flex;flex-wrap:wrap;margin:0 -5px}.fm-filter-panel__field__list__item{height:30px;width:89px;font-size:13px;text-align:center;overflow:hidden;padding:6px 8px;margin:0 5px 10px;background:var(--fm-background);border-radius:var(--fm-radius-md);color:var(--fm-primary-color)}.fm-filter-panel__field__list__item--selected{background:var(--fm-primary-color);color:var(--fm-background-white)}.fm-filter-panel__field .fm-input-group .fm-input-group__body{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}.fm-filter__portal{display:flex;align-items:center;padding:8px 16px}.fm-filter__portal__icon{font-size:20px}.fm-filter__portal__search{flex:1;padding:0 0 0 8px}.fm-page-container{flex:1;display:flex;flex-direction:column;background:#f9fafb;overflow:hidden;-webkit-overflow-scrolling:auto;position:absolute;inset:0}.fm-page-container .drag-container{display:inherit;flex-direction:inherit;flex-shrink:1;flex-grow:1;flex-basis:0%;flex-wrap:inherit;justify-content:inherit;align-items:inherit;width:100%;overflow:inherit}.fm-page-body-container{flex-basis:0;flex-shrink:1;flex-grow:1;padding-bottom:12px;overflow:auto;display:flex;flex-direction:column}.fm-page-header-container{flex-shrink:0}.fm-page-footer-container{background-color:#fff}.fm-float-container{position:absolute!important;bottom:60px;right:30px} 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 index 2a472a22171..78f5cd90d18 100644 --- a/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts +++ b/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts @@ -171,6 +171,10 @@ class ComponentNormalizer { * 转换后:{ type: 'Command', name: 'LoadAndAddForCard', viewModelId: 'card-page-component'} */ protected getCommandBinding(propValue: any, viewModelId: string): any { + if (!propValue) { + return null; + } + const commandName = propValue; const commandBinding = { type: 'Command', 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 index a85c20c3d09..10633dc952d 100644 --- a/packages/mobile-render/src/services/page-config/bindings/binding-util.ts +++ b/packages/mobile-render/src/services/page-config/bindings/binding-util.ts @@ -1,4 +1,5 @@ -import { TypeUtil } from '../../../utils/index'; +import { isObject, isString, TypeUtil } from '../../../utils/index'; +import { BindingType } from './types'; /** * 绑定工具类 @@ -6,17 +7,26 @@ import { TypeUtil } from '../../../utils/index'; class BindingUtil { /** - * 全部绑定类型 + * 获取属性Schema */ - public static supportedBindingTypes = [ - 'EntityField', 'Entity', 'EntityList', - 'Variable', 'StatMachine', 'Command' - ]; + public static getPropSchema(propName: string, componentSchema: any): any { + if (!componentSchema || !componentSchema.properties) { + return null; + } + const propSchema = componentSchema.properties[propName] || null; + + return propSchema; + } /** * 判断是否是绑定 */ public static isBinding(bindingConfig: any): boolean { + const supportedBindingTypes = [ + 'EntityField', 'Entity', 'EntityList', + 'Variable', 'StatMachine', 'Command' + ]; + if (!bindingConfig) { return false; } @@ -25,12 +35,91 @@ class BindingUtil { return false; } - if (!this.supportedBindingTypes.includes(bindingConfig.type)) { + if (!supportedBindingTypes.includes(bindingConfig.type)) { return false; } return true; } + + /** + * 获取绑定类型 + */ + public static getBindingType(propName: string, propValue: any, component: any, componentSchema: any): BindingType { + if (this.isEntityFieldBinding(propValue)) { + return BindingType.EntityField; + } else if (this.isEntityListBinding(propValue)) { + return BindingType.EntityList; + } else if (this.isVariableBinding(propValue)) { + return BindingType.Variable; + } else if (this.isStateMachineBinding(propValue)) { + return BindingType.StateMachine; + } else if (this.isCommandBinding(propName, componentSchema)) { + return BindingType.Command; + } else { + return BindingType.Static; + }; + } + + /** + * 是否是实体字段绑定 + */ + public static isEntityFieldBinding(propValue: any): boolean { + if (isObject(propValue) && propValue.type && propValue.field && propValue.path) { + return true; + } + return false; + } + + /** + * 是否是实体绑定 + */ + public static isEntityBinding(): boolean { + return false; + } + + /** + * 是否是实体集合绑定 + */ + public static isEntityListBinding(propName: string): boolean { + if (propName === 'dataSource') { + return true; + } + + return false; + } + + /** + * 是否是变量绑定 + */ + public static isVariableBinding(propValue: any): boolean { + if (isObject(propValue) && propValue.type && propValue.field && propValue.path) { + return true; + } + return false; + } + + /** + * 是否是状态机绑定 + */ + public static isStateMachineBinding(propValue: any): boolean { + if (isString(propValue) && propValue.startsWith('stateMachine')) { + return true; + } + return false; + } + + /** + * 是否是命令绑定 + */ + public static isCommandBinding(propName: any, componentSchema: any): boolean { + const eventPropNames = componentSchema.events || []; + if (eventPropNames.includes(propName)) { + return true; + } + + return false; + } } export { BindingUtil }; diff --git a/packages/mobile-render/src/services/page-config/bindings/types.ts b/packages/mobile-render/src/services/page-config/bindings/types.ts new file mode 100644 index 00000000000..6c2bccde6a3 --- /dev/null +++ b/packages/mobile-render/src/services/page-config/bindings/types.ts @@ -0,0 +1,9 @@ +export enum BindingType { + EntityField = 'EntityField', + Entity = 'Entity', + EntityList = 'EntityList', + Variable = 'Variable', + StateMachine = 'StateMachine', + Command = 'Command', + Static = 'Static' +}; 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 index 75ef9256ca3..d623ff99e32 100644 --- a/packages/mobile-render/src/services/page-config/page-config-binder.ts +++ b/packages/mobile-render/src/services/page-config/page-config-binder.ts @@ -1,7 +1,7 @@ import { reactive, Reactive } from 'vue'; import { Module } from '@farris/devkit-vue'; import { schemaMap } from '@farris/mobile-ui-vue'; -import { JsonUtil } from '../../utils/index'; +import { TypeUtil, JsonUtil } from '../../utils/index'; import { BindingUtil, BindingContext, BindingFactory } from './bindings/index'; /** @@ -57,93 +57,111 @@ class PageConfigBinder { */ public bind(): Reactive { const pageConfig = reactive(JsonUtil.cloneJsonObj(this.originPageConfig)); - this.bindComponentConfig(pageConfig); - this.pageConfig = pageConfig; + const pageSchema = schemaMap['component']; + this.bindComponentConfig(pageConfig, pageSchema); + 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']; - + private bindComponentConfig(componentConfig: any, componentSchema: any) { Object.keys(componentConfig).forEach((propName) => { - if (specialProps.includes(propName)) { - this.bindSpecialProp(propName, componentConfig, componentSchema); + + const propConfig = componentConfig[propName]; + + // 属性值是一个绑定 + const isBinding = BindingUtil.isBinding(propConfig); + if (isBinding) { + this.bindBindingProp(propName, propConfig, componentConfig, componentSchema); return; } - const bindingConfig = componentConfig[propName]; - const isBinding = BindingUtil.isBinding(bindingConfig); - if (!isBinding) { + // 属性值是一个数组 + if (TypeUtil.isArray(propConfig)) { + this.bindArrayProp(propName, propConfig, componentConfig, componentSchema); return; } - const binding = this.bindingFactory.create(bindingConfig.type); - binding.init(bindingConfig, componentConfig, propName, this.bindingContext); + // 属性值是个对象 + if (TypeUtil.isObject(propConfig)) { + this.bindObjectProp(propName, propConfig, componentConfig, componentSchema); + return; + } }); } /** - * 绑定特殊属性 + * 绑定值是绑定的属性 */ - 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); - } + public bindBindingProp(propName: string, propConfig: any, componentConfig: any, componentSchema: any): void { + const binding = this.bindingFactory.create(propConfig.type); + binding.init(propConfig, componentConfig, propName, this.bindingContext); + return; } /** - * 绑定子组件配置 + * 绑定值是数组的属性 */ - private bindChildComponentsChonfigs(childComponentConfigs: any[]): void { - childComponentConfigs.forEach((childComponentConfig) => { - this.bindComponentConfig(childComponentConfig); + private bindArrayProp(arrayPropName: string, arrayPropConfig: any[], componentConfig: any, componentSchema: any): void { + const arrayPropSchema = BindingUtil.getPropSchema(arrayPropName, componentSchema); + arrayPropConfig.forEach((arrayItemConfig: any) => { + const arrayItemSchema = this.getArrayItemSchema(arrayItemConfig, arrayPropSchema); + this.bindComponentConfig(arrayItemConfig, arrayItemSchema); }); } /** - * 绑定编辑器配置 + * 获取数组项的Schema + * @summary + * 子元素可能存在3种情况: + * 1、组件:ContentContainer->contents,从schemaMap中获取子元素Schema; + * 2、类型固定的对象:Toolbar->items,从属性的详细描述中获取子元素Schema; + * 3、类型不固定的数据:Picker->data,没有Schema; */ - private bindEditorConfig(editorConfig: any): void { - this.bindComponentConfig(editorConfig); + private getArrayItemSchema(arrayItemConfig: any, arrayPropSchema: any): any | null { + if (arrayPropSchema && arrayPropSchema.items) { + return arrayPropSchema.items; + } + + if (arrayItemConfig.type) { + const arrayItemType = arrayItemConfig.type; + return schemaMap[arrayItemType] || null; + } + + return null; } /** - * 绑定Items属性 + * 获取对象的Schema */ - private bindItemConfigs(itemConfigs: any[], parentComponentSchema: any) { - itemConfigs.forEach((itemConfig) => { - const itemsPropSchema = parentComponentSchema.properties.items; - this.bindComponentConfig(itemConfig, itemsPropSchema.items); - }); + private bindObjectProp(objPropName: string, objPropConfig: any, componentConfig: any, componentSchema: any): void { + const objPropSchema = BindingUtil.getPropSchema(objPropName, componentSchema); + const objSchema = this.getObjectSchema(objPropConfig, objPropSchema); + this.bindComponentConfig(objPropConfig, objSchema); } /** - * 获取组件描述 + * 获取对象属性值的 + * @summary + * 属性值可能存在3种情况: + * 1、组件:FormGroup->editor,从schemaMap中获取组件的Schema; + * 2、类型固定的对象: FormGroup->appearance,从属性的描述中获取对象的Schema; + * 3、类型不固定的数据:没有Schema; */ - private getComponentSchema(componentType: string): any { - const componentSchema = schemaMap[componentType]; - if (!componentSchema) { - throw new Error(`ComponentScham(type=${componentType}) does not exist`); + private getObjectSchema(objPropConfig: any, objPropSchema: any): any | null { + if (objPropSchema && objPropSchema.properties) { + return objPropSchema; + } + + if (objPropConfig.type) { + const objType = objPropConfig.type; + return schemaMap[objType] || null; } - return componentSchema; + return null; } } diff --git a/packages/mobile-render/src/utils/type-util.ts b/packages/mobile-render/src/utils/type-util.ts index 3ad67ca041c..77106b425f9 100644 --- a/packages/mobile-render/src/utils/type-util.ts +++ b/packages/mobile-render/src/utils/type-util.ts @@ -108,10 +108,17 @@ class TypeUtil { /** * 是否为对象 */ - public static isObject(value: any) { + public static isObject(value: any): boolean { return value !== null && typeof value === 'object'; } + /** + * 是否是数组 + */ + public static isArray(value: any): boolean { + return Array.isArray(value); + } + /** * 是否为字符串 */ -- Gitee From 68bbf7ff0adeff9d119818aa7fade046c77d5dbf Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Tue, 15 Apr 2025 16:59:31 +0800 Subject: [PATCH 237/287] =?UTF-8?q?feature:=20=E8=B0=83=E9=80=9A=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E6=A0=8F=E6=8C=89=E9=92=AE=E7=BB=91=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component-converters/datebox-converter.ts | 5 ++++- .../form/normalizers/button-group-normalizer.ts | 13 ------------- .../form/normalizers/component-normalizer.ts | 3 --- .../navbar/src/schema/schema-mapper.ts | 16 +++++++++++++++- 4 files changed, 19 insertions(+), 18 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 d3d4b2e53e4..11952970fb3 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 @@ -37,9 +37,12 @@ class DateBoxConverter extends InputConverter { /** * 获取显示格式 + * @summary + * 旧格式:YYYY-MM-dd HH:mm:ss + * 新格式:yyyy-MM-dd HH:mm:ss */ private getDisplayFormat(oldFormat: string): string { - return oldFormat.replace('dd', 'DD'); + return oldFormat.replace('YYYY', 'yyyy'); } } 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 index 28922cb8494..202ed1d8da1 100644 --- 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 @@ -10,21 +10,8 @@ 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.ts b/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts index 78f5cd90d18..0779de2de58 100644 --- a/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts +++ b/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts @@ -25,9 +25,6 @@ class ComponentNormalizer { */ public normalize(component: any, componentSchema: any, viewModelId: string): any { this.normalizeComponent(component, componentSchema, viewModelId); - if (component.type === 'navbar') { - console.log(component); - } } /** 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 index 90dc1493e55..11d4d8b82cd 100644 --- a/packages/mobile-ui-vue/components/navbar/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/navbar/src/schema/schema-mapper.ts @@ -1,5 +1,19 @@ import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; +import { ButtonItem } from '@farris/mobile-ui-vue/button-group'; + +export function resolveRightToolbar(key: string, toolbarObj: any) { + const newItems: Array = []; + toolbarObj.items.forEach((item: any) => { + const { id, visible, text, onClick } = item; + const newItem = { id, visible, text, onClick }; + newItems.push(newItem); + }); + + return { toolbarItems: newItems }; +} + export const schemaMapper = new Map([ - ['appearance', resolveAppearance] + ['appearance', resolveAppearance], + ['rightToolbar', resolveRightToolbar] ]); -- Gitee From c3aa9182c49bc910ef072f52011974830b5c999d Mon Sep 17 00:00:00 2001 From: LuPing Zou <“zouluping@inspur.com”> Date: Mon, 14 Apr 2025 19:26:03 +0800 Subject: [PATCH 238/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E7=AB=AFF?= =?UTF-8?q?loatContainer=E6=8E=A7=E4=BB=B6=E8=AE=BE=E8=AE=A1=E6=97=B6?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/properties/container-base-property.ts | 27 ++++++--- .../properties/converter/cascade.converter.ts | 22 +++++++ .../common/src/properties/converter/index.ts | 1 + .../components/common/src/properties/index.ts | 1 + .../content-container.property-config.ts | 6 +- .../components/dynamic-resolver/index.ts | 4 ++ .../src/common/appearance-resolver.ts | 2 +- .../src/common/margin-resolver.ts | 6 ++ .../src/common/padding-resolver.ts | 6 ++ .../src/common/position-resolver.ts | 6 ++ .../src/common/size-resolver.ts | 6 ++ .../dynamic-resolver/src/common/utils.ts | 59 +++++++++++++++++++ .../resolver/schema/use-schema-resolver.ts | 1 + .../src/designer/use-designer-rules.ts | 36 +++++------ .../src/float-container.component.tsx | 11 +--- .../src/float-container.props.ts | 1 + .../float-container/src/float-container.scss | 2 - .../float-container.property-config.ts | 11 +++- .../src/schema/float-container.schema.json | 15 +++++ .../src/schema/schema-mapper.ts | 7 ++- 20 files changed, 188 insertions(+), 42 deletions(-) create mode 100644 packages/mobile-ui-vue/components/common/src/properties/converter/cascade.converter.ts create mode 100644 packages/mobile-ui-vue/components/common/src/properties/converter/index.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/common/margin-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/common/padding-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/common/position-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/common/size-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/common/utils.ts diff --git a/packages/mobile-ui-vue/components/common/src/properties/container-base-property.ts b/packages/mobile-ui-vue/components/common/src/properties/container-base-property.ts index 3f511f440e8..ef59c1314d0 100644 --- a/packages/mobile-ui-vue/components/common/src/properties/container-base-property.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/container-base-property.ts @@ -1,4 +1,5 @@ import { BaseControlProperty } from "./base-property"; +import { sizeConverter, paddingConverter, marginConverter, positionConverter, borderRadiusConverter } from "./converter/cascade.converter"; export class ContainerBaseProperty extends BaseControlProperty { @@ -6,14 +7,6 @@ export class ContainerBaseProperty extends BaseControlProperty { super(componentId, designerHostService); } - protected getAppearanceConfig(propertyData: any = null): any { - return { - title: "外观", - description: "Appearance", - properties: this.getAppearanceProperties(["style"], propertyData), - }; - } - protected getAppearanceProperties( propertyNames: string[] = ["style"], propertyData?: any, @@ -70,6 +63,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: sizeConverter, }, height: { title: "高度(px)", @@ -80,6 +74,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: sizeConverter, } } }, @@ -103,6 +98,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: paddingConverter, }, right: { title: "右侧(px)", @@ -113,6 +109,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: paddingConverter, }, bottom: { title: "下侧(px)", @@ -123,6 +120,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: paddingConverter, }, left: { title: "左侧(px)", @@ -133,6 +131,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: paddingConverter, }, } }, @@ -156,6 +155,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: marginConverter, }, right: { title: "右侧(px)", @@ -166,6 +166,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: marginConverter, }, bottom: { title: "下侧(px)", @@ -176,6 +177,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: marginConverter, }, left: { title: "左侧(px)", @@ -186,6 +188,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: marginConverter, }, } }, @@ -209,6 +212,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: borderRadiusConverter, }, topRight: { title: "右上角(px)", @@ -219,6 +223,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: borderRadiusConverter, }, bottomRight: { title: "右下角(px)", @@ -229,6 +234,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: borderRadiusConverter, }, bottomLeft: { title: "左下角(px)", @@ -239,6 +245,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: borderRadiusConverter, }, } }, @@ -261,6 +268,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: positionConverter, }, right: { title: "右侧偏移(px)", @@ -270,6 +278,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: positionConverter, }, bottom: { title: "下侧偏移(px)", @@ -279,6 +288,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: positionConverter, }, left: { title: "左侧偏移(px)", @@ -288,6 +298,7 @@ export class ContainerBaseProperty extends BaseControlProperty { decimals: 0, nullable: true, }, + $converter: positionConverter, }, } }, diff --git a/packages/mobile-ui-vue/components/common/src/properties/converter/cascade.converter.ts b/packages/mobile-ui-vue/components/common/src/properties/converter/cascade.converter.ts new file mode 100644 index 00000000000..0c227e99e11 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/src/properties/converter/cascade.converter.ts @@ -0,0 +1,22 @@ +import { PropertyConverter, SchemaService } from "@farris/mobile-ui-vue/dynamic-resolver"; + +export function generateCascadePropertyConverter(parentPropertyKey: string): PropertyConverter { + return { + convertTo: (schema: Record, propertyKey: string, propertyValue: any, schemaService: SchemaService) => { + if (!schema[parentPropertyKey] || typeof schema[parentPropertyKey] !== 'object') { + schema[parentPropertyKey] = {}; + } + schema[parentPropertyKey][propertyKey] = propertyValue; + }, + convertFrom: (schema: Record, propertyKey: string, schemaService: SchemaService) => { + return schema[parentPropertyKey]?.[propertyKey]; + }, + }; +} + +export const sizeConverter = generateCascadePropertyConverter('size'); +export const paddingConverter = generateCascadePropertyConverter('padding'); +export const marginConverter = generateCascadePropertyConverter('margin'); +export const borderRadiusConverter = generateCascadePropertyConverter('borderRadius'); +export const positionConverter = generateCascadePropertyConverter('position'); +export const flexBoxConverter = generateCascadePropertyConverter('flexBox'); diff --git a/packages/mobile-ui-vue/components/common/src/properties/converter/index.ts b/packages/mobile-ui-vue/components/common/src/properties/converter/index.ts new file mode 100644 index 00000000000..060b0343df1 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/src/properties/converter/index.ts @@ -0,0 +1 @@ +export * from './cascade.converter'; diff --git a/packages/mobile-ui-vue/components/common/src/properties/index.ts b/packages/mobile-ui-vue/components/common/src/properties/index.ts index cb90eb3e719..599666e40fe 100644 --- a/packages/mobile-ui-vue/components/common/src/properties/index.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/index.ts @@ -1,4 +1,5 @@ export * from './dg-control'; +export * from './converter'; export { SchemaDOMMapping } from './schema-dom-mapping'; export { BaseControlProperty } from './base-property'; export { InputBaseProperty } from './input-base-property'; diff --git a/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts b/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts index 304893a8e58..8ec6e2b8e68 100644 --- a/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts +++ b/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts @@ -1,4 +1,4 @@ -import { ContainerBaseProperty } from "@farris/mobile-ui-vue/common"; +import { ContainerBaseProperty, flexBoxConverter } from "@farris/mobile-ui-vue/common"; export class ContentContainerProperty extends ContainerBaseProperty { @@ -68,11 +68,13 @@ export class ContentContainerProperty extends ContainerBaseProperty { { value: 'column', text: '竖直' }, ], }, + $converter: flexBoxConverter, }, wrap: { title: "是否允许换行", type: "boolean", description: "运行时组件内部子元素是否允许换行显示", + $converter: flexBoxConverter, }, justifyContent: { title: "水平对齐方式", @@ -91,6 +93,7 @@ export class ContentContainerProperty extends ContainerBaseProperty { { value: "around", text: "均匀排列" }, ], }, + $converter: flexBoxConverter, }, alignItems: { title: "竖直对齐方式", @@ -107,6 +110,7 @@ export class ContentContainerProperty extends ContainerBaseProperty { { value: "end", text: "末尾位置" }, ], }, + $converter: flexBoxConverter, }, }, }, diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/index.ts b/packages/mobile-ui-vue/components/dynamic-resolver/index.ts index e53b6e8e712..11a5de746fe 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/index.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/index.ts @@ -3,6 +3,10 @@ export * from './src/props-resolver'; export * from './src/common/appearance-resolver'; export * from './src/common/toolbar-resolver'; export * from './src/common/data-resolver'; +export * from './src/common/position-resolver'; +export * from './src/common/padding-resolver'; +export * from './src/common/margin-resolver'; +export * from './src/common/size-resolver'; export * from './src/binding-resolver'; export * from './src/events-resolver'; export * from './src/selection-item-resolver'; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/appearance-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/appearance-resolver.ts index c5a7cbd2e5b..5d603ec4dec 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/appearance-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/appearance-resolver.ts @@ -1,3 +1,3 @@ export function resolveAppearance(key: string, appearanceObject: { class: string; style: string }) { - return { customClass: appearanceObject.class,customStyle:appearanceObject.style }; + return { customClass: appearanceObject.class, customStyle: appearanceObject.style }; } diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/margin-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/margin-resolver.ts new file mode 100644 index 00000000000..485fb4ea3e9 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/margin-resolver.ts @@ -0,0 +1,6 @@ +import { DirectionalStyleObject, getMarginStyle, concatCustomStyle } from './utils'; + +export function resolveMargin(key: string, marginObject: DirectionalStyleObject, resolvedSchema: any) { + const marginStyle = getMarginStyle(marginObject); + return concatCustomStyle(marginStyle, resolvedSchema); +} diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/padding-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/padding-resolver.ts new file mode 100644 index 00000000000..f1a42dadc86 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/padding-resolver.ts @@ -0,0 +1,6 @@ +import { DirectionalStyleObject, getPaddingStyle, concatCustomStyle } from './utils'; + +export function resolvePadding(key: string, paddingObject: DirectionalStyleObject, resolvedSchema: any) { + const paddingStyle = getPaddingStyle(paddingObject); + return concatCustomStyle(paddingStyle, resolvedSchema); +} diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/position-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/position-resolver.ts new file mode 100644 index 00000000000..7fdb8bdc427 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/position-resolver.ts @@ -0,0 +1,6 @@ +import { DirectionalStyleObject, getPositionStyle, concatCustomStyle } from './utils'; + +export function resolvePosition(key: string, positionObject: DirectionalStyleObject, resolvedSchema: any) { + const positionStyle = getPositionStyle(positionObject); + return concatCustomStyle(positionStyle, resolvedSchema); +} diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/size-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/size-resolver.ts new file mode 100644 index 00000000000..9bea291713c --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/size-resolver.ts @@ -0,0 +1,6 @@ +import { SizeStyleObject, getSizeStyle, concatCustomStyle } from './utils'; + +export function resolveSize(key: string, sizeObject: SizeStyleObject, resolvedSchema: any) { + const sizeStyle = getSizeStyle(sizeObject); + return concatCustomStyle(sizeStyle, resolvedSchema); +} diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/utils.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/utils.ts new file mode 100644 index 00000000000..4aedc631507 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/utils.ts @@ -0,0 +1,59 @@ +export function concatCustomStyle(newStyle: string, resolvedSchema: any): { customStyle: string } { + newStyle = newStyle || ''; + let customStyle: string = resolvedSchema?.customStyle || ''; + if (typeof customStyle !== 'string') { + customStyle = ''; + } + customStyle = customStyle.trim(); + customStyle = newStyle + customStyle; + return { customStyle }; +} + +function convertStyleObject2String(styleObject: any, validPropNames: string[], cssPropNamePrefix?: string): string { + if (typeof styleObject !== 'object' || !styleObject) { + return ''; + } + return Object.keys(styleObject) + .filter((propName) => { + return validPropNames.includes(propName); + }) + .reduce((styleString, propName) => { + const value = styleObject[propName]; + if (typeof value !== 'number') { + return styleString; + } + const fullPropName = cssPropNamePrefix ? `${cssPropNamePrefix}-${propName}` : propName; + return `${styleString}${fullPropName}: ${value}px;`; + }, ''); +} + +export interface DirectionalStyleObject { + top?: number; + right?: number; + bottom?: number; + left?: number; +} + +export interface SizeStyleObject { + width?: number; + height?: number; +} + +const DIRECTIONAL_STYLE_PROPS = ["top", "right", "bottom", "left"]; +const SIZE_STYLE_PROPS = ["width", "height"]; + +export function getPaddingStyle(paddingObject: DirectionalStyleObject): string { + return convertStyleObject2String(paddingObject, DIRECTIONAL_STYLE_PROPS, 'padding'); +} + +export function getMarginStyle(marginObject: DirectionalStyleObject): string { + return convertStyleObject2String(marginObject, DIRECTIONAL_STYLE_PROPS, 'margin'); +} + +export function getPositionStyle(positionObject: DirectionalStyleObject): string { + return convertStyleObject2String(positionObject, DIRECTIONAL_STYLE_PROPS); +} + +export function getSizeStyle(sizeObject: SizeStyleObject): string { + return convertStyleObject2String(sizeObject, SIZE_STYLE_PROPS); +} diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts index 15a77a4a225..da010022278 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/resolver/schema/use-schema-resolver.ts @@ -92,6 +92,7 @@ export function useSchemaResolver(schemaMap: Record, schemaResolver } else { const mapperResult = (mapper as MapperFunction)(propKey, resolvedSchema[propKey], resolvedSchema); Object.assign(resolvedProps, mapperResult); + Object.assign(resolvedSchema, mapperResult); } } else { resolvedProps[propKey] = resolvedSchema[propKey]; diff --git a/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts index aba42f8187a..19d7cd0b4b0 100644 --- a/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts @@ -1,21 +1,20 @@ - /** - * 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. - */ +* 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 { ref } from "vue"; -import { ComponentSchema, DesignerItemContext, UseDesignerRules } from "@farris/mobile-ui-vue/common"; +import { DesignerItemContext, UseDesignerRules } from "@farris/mobile-ui-vue/common"; import { DraggingResolveContext } from "@farris/mobile-ui-vue/common"; import { FloatContainerProperty } from "../property-config/float-container.property-config"; @@ -53,6 +52,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe function checkCanMoveComponent() { return false; } + function checkCanDeleteComponent() { return true; } @@ -84,7 +84,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe } return style; } - + /** * 获取属性配置 */ @@ -92,7 +92,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe const componentProp = new FloatContainerProperty(componentId, designerHostService); const { schema } = designItemContext; return componentProp.getPropertyConfig(schema); - } + } return { canAccepts, 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 index 159f9933d50..2c0f2875bed 100644 --- 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 @@ -1,4 +1,4 @@ -import { SetupContext, defineComponent, computed } from 'vue'; +import { defineComponent } from 'vue'; import { useBem } from '@farris/mobile-ui-vue/common'; import { FLOAT_CONTAINER_NAME, floatContainerProps, FloatContainerProps } from './float-container.props'; @@ -6,16 +6,11 @@ export default defineComponent({ name: FLOAT_CONTAINER_NAME, props: floatContainerProps, emits: [], - setup(props: FloatContainerProps, context: SetupContext) { + setup(props: FloatContainerProps, context) { 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 index c5da6f3797f..6981db95fe6 100644 --- 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 @@ -8,6 +8,7 @@ export const FLOAT_CONTAINER_NAME = 'fm-float-container'; export const floatContainerProps = { customClass: { type: String, default: '' }, + customStyle: { type: String, default: '' }, }; export type FloatContainerProps = ExtractPropTypes; 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 index ccd9b255496..5df63dfc941 100644 --- a/packages/mobile-ui-vue/components/float-container/src/float-container.scss +++ b/packages/mobile-ui-vue/components/float-container/src/float-container.scss @@ -1,5 +1,3 @@ .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/property-config/float-container.property-config.ts b/packages/mobile-ui-vue/components/float-container/src/property-config/float-container.property-config.ts index fd661a5ff67..99bd9446e79 100644 --- a/packages/mobile-ui-vue/components/float-container/src/property-config/float-container.property-config.ts +++ b/packages/mobile-ui-vue/components/float-container/src/property-config/float-container.property-config.ts @@ -1,9 +1,11 @@ -import { BaseControlProperty } from "@farris/mobile-ui-vue/common"; +import { ContainerBaseProperty } from "@farris/mobile-ui-vue/common"; + +export class FloatContainerProperty extends ContainerBaseProperty { -export class FloatContainerProperty extends BaseControlProperty { constructor(componentId: string, designerHostService: any) { super(componentId, designerHostService); } + public getPropertyConfig(propertyData: any) { // 基本信息 this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); @@ -12,4 +14,9 @@ export class FloatContainerProperty extends BaseControlProperty { return this.propertyConfig; } + + protected getAppearanceConfig(propertyData: any) { + const properties = this.getAppearanceProperties(["position"], propertyData); + return super.getAppearanceConfig(propertyData, properties); + } } 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 index 473930001e2..555410aec02 100644 --- 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 @@ -31,6 +31,21 @@ "description": "", "type": "array", "default": [] + }, + "position": { + "description": "", + "type": "object", + "default": {} + }, + "size": { + "description": "", + "type": "object", + "default": {} + }, + "padding": { + "description": "", + "type": "object", + "default": {} } }, "required": [ 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 index 90dc1493e55..e7c0e0a7b6b 100644 --- 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 @@ -1,5 +1,8 @@ -import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; +import { resolveAppearance, resolvePosition, resolveSize, resolvePadding, MapperFunction } from '../../../dynamic-resolver'; export const schemaMapper = new Map([ - ['appearance', resolveAppearance] + ['appearance', resolveAppearance], + ['position', resolvePosition], + ['size', resolveSize], + ['padding', resolvePadding], ]); -- Gitee From b0832d958598b0f040b85c84d0668d491a4afa95 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Tue, 15 Apr 2025 20:27:25 +0800 Subject: [PATCH 239/287] =?UTF-8?q?feature:=20MobileRender=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=B1=9E=E6=80=A7=E7=BB=91=E5=AE=9A=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=9C=BA=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../button-group-converter.ts | 3 +- .../metadata/form/form-metadata-query.ts | 4 -- .../form/normalizers/component-normalizer.ts | 21 ++++--- .../form/normalizers/normalizer-util.ts | 8 +-- .../page-config/bindings/binding-factory.ts | 3 +- .../page-config/bindings/binding-util.ts | 2 +- .../services/page-config/bindings/index.ts | 1 + .../bindings/state-machine-binding.ts | 59 +++++++++++++++++++ .../navbar/src/schema/schema-mapper.ts | 4 ++ .../picker/src/schema/picker.schema.json | 3 +- 10 files changed, 86 insertions(+), 22 deletions(-) create mode 100644 packages/mobile-render/src/services/page-config/bindings/state-machine-binding.ts 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 index 0d4e0141868..8a50ac68010 100644 --- 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 @@ -19,7 +19,8 @@ class ButtonGroupConverter extends ComponentConverter { type: 'button-group', appearance, visible, - disabled + disabled, + mode: 'group' }); buttonGroup.items = this.buildButtonItems(items); } 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 index 6d82587976d..bf139524f9e 100644 --- a/packages/mobile-render/src/services/metadata/form/form-metadata-query.ts +++ b/packages/mobile-render/src/services/metadata/form/form-metadata-query.ts @@ -167,10 +167,6 @@ class FormMetadataQuery { }; 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); 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 index 0779de2de58..6ea43f243d4 100644 --- a/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts +++ b/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts @@ -77,8 +77,11 @@ class ComponentNormalizer { * 标准化对象属性值 */ private normalizeObjectPropValue(objPropName: string, objPropValue: any, component: any, componentSchema: any, viewModelId: string): void { + if (!isObject(objPropValue)) { + return; + } const objectPropSchema = NormalizerUtil.getPropSchema(objPropName, componentSchema); - if (objectPropSchema.type !== 'object' || !objectPropSchema.properties || !isObject(objPropValue)) { + if (objectPropSchema.type !== 'object' || !objectPropSchema.properties) { return; } @@ -89,10 +92,15 @@ class ComponentNormalizer { * 标准化数组属性值 */ private normalizeArrayPropValue(arrayPropName: string, arrayPropValue: any, component: any, componentSchema: any, viewModelId: string): void { + if (!isArray(arrayPropValue)) { + return; + } + const arrayPropSchema = NormalizerUtil.getPropSchema(arrayPropName, componentSchema); - if (arrayPropSchema.type !== 'array' || !arrayPropSchema.items || !isArray(arrayPropValue)) { + if (arrayPropSchema.type !== 'array' || !arrayPropSchema.items || !arrayPropSchema.items.properties) { return; } + const arrayItemSchema = arrayPropSchema.items; arrayPropValue.forEach((arrayItem: any) => { this.normalizeComponent(arrayItem, arrayItemSchema, viewModelId); @@ -145,15 +153,10 @@ class ComponentNormalizer { * 转换后:{ bindingType: 'StateMachine', bindingPath: '/canInput', isTwoWay: false, viewModelId: 'cad-page-component' } */ private getStateMachineBinding(propValue: any, currentViewModelId: string): any { - const matchArray = propValue.match(/stateMachine\['(.*?)'\]/); - if (!matchArray) { - return propValue; - } - - const renderState = matchArray[1]; + const { field } = propValue; const binding = { type: 'StateMachine', - path: `/${renderState}`, + path: `/${field}`, direction: 'OneWay', viewModelId: currentViewModelId }; diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/normalizer-util.ts b/packages/mobile-render/src/services/metadata/form/normalizers/normalizer-util.ts index 53bf3c27439..edab3c7c1c7 100644 --- a/packages/mobile-render/src/services/metadata/form/normalizers/normalizer-util.ts +++ b/packages/mobile-render/src/services/metadata/form/normalizers/normalizer-util.ts @@ -1,4 +1,4 @@ -import { isObject, isString } from '../../../../utils/index'; +import { isObject } from '../../../../utils/index'; import { PropBindingType } from './types'; /** @@ -42,7 +42,7 @@ class NormalizerUtil { * 是否是实体字段绑定 */ public static isEntityFieldBinding(propValue: any): boolean { - if (isObject(propValue) && propValue.type && propValue.field && propValue.path) { + if (isObject(propValue) && propValue.type === 'Form') { return true; } return false; @@ -70,7 +70,7 @@ class NormalizerUtil { * 是否是变量绑定 */ public static isVariableBinding(propValue: any): boolean { - if (isObject(propValue) && propValue.type && propValue.field && propValue.path) { + if (isObject(propValue) && propValue.type === 'Variable') { return true; } return false; @@ -80,7 +80,7 @@ class NormalizerUtil { * 是否是状态机绑定 */ public static isStateMachineBinding(propValue: any): boolean { - if (isString(propValue) && propValue.startsWith('stateMachine')) { + if (isObject(propValue) && propValue.type === 'StateMachine') { return true; } return false; 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 index a0a0bf99cd2..92647e6159a 100644 --- a/packages/mobile-render/src/services/page-config/bindings/binding-factory.ts +++ b/packages/mobile-render/src/services/page-config/bindings/binding-factory.ts @@ -2,6 +2,7 @@ import { Binding } from './binding'; import { EntityFieldBinding } from './entity-field-binding'; import { EntityListBinding } from './entity-list-binding'; import { CommandBinding } from './command-binding'; +import { StateMachineBinding } from './state-machine-binding'; /** * 绑定工厂 @@ -36,7 +37,7 @@ class BindingFactory { * 初始化绑定集合 */ private initBindings() { - const bindingCtors = [EntityFieldBinding, EntityListBinding, CommandBinding]; + const bindingCtors = [EntityFieldBinding, EntityListBinding, StateMachineBinding, CommandBinding]; this.bindings = new Map(); bindingCtors.forEach((bindingCtor) => { 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 index 10633dc952d..ed71ff5bf45 100644 --- a/packages/mobile-render/src/services/page-config/bindings/binding-util.ts +++ b/packages/mobile-render/src/services/page-config/bindings/binding-util.ts @@ -24,7 +24,7 @@ class BindingUtil { public static isBinding(bindingConfig: any): boolean { const supportedBindingTypes = [ 'EntityField', 'Entity', 'EntityList', - 'Variable', 'StatMachine', 'Command' + 'Variable', 'StateMachine', 'Command' ]; if (!bindingConfig) { diff --git a/packages/mobile-render/src/services/page-config/bindings/index.ts b/packages/mobile-render/src/services/page-config/bindings/index.ts index 511efd5ab82..655068e8281 100644 --- a/packages/mobile-render/src/services/page-config/bindings/index.ts +++ b/packages/mobile-render/src/services/page-config/bindings/index.ts @@ -2,6 +2,7 @@ export * from './binding'; export * from './entity-field-binding'; export * from './entity-list-binding'; export * from './command-binding'; +export * from './state-machine-binding'; export * from './binding-util'; export * from './binding-context'; diff --git a/packages/mobile-render/src/services/page-config/bindings/state-machine-binding.ts b/packages/mobile-render/src/services/page-config/bindings/state-machine-binding.ts new file mode 100644 index 00000000000..82c1122162b --- /dev/null +++ b/packages/mobile-render/src/services/page-config/bindings/state-machine-binding.ts @@ -0,0 +1,59 @@ +import { Binding } from './binding'; +import { BindingContext } from './binding-context'; + +/** + * 状态机绑定绑定 + */ +class StateMachineBinding extends Binding { + + /** + * 绑定名称 + */ + public name = 'StateMachine'; + + /** + * 初始化 + */ + public init(bindingConfig: any, target: any, propName: string, bindingContext: BindingContext): void { + const { viewModelId } = bindingConfig; + const stateMachine = this.getStateMachine(viewModelId, bindingContext); + + bindingContext.registerDep(stateMachine, 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 getStateMachine(viewModelId: string, bindingContext: BindingContext): any { + const viewModel = bindingContext.getViewModel(viewModelId); + if (!viewModel) { + return; + } + const { stateMachine } = viewModel; + + return stateMachine; + } + + /** + * 获取属性值 + */ + private getValue(bindingConfig: any, bindingContext: BindingContext): void { + const { path, status, viewModelId } = bindingConfig; + const stateMachine = this.getStateMachine(viewModelId, bindingContext); + const stateName = path.slice(1); + const value = stateMachine.getValue(stateName); + + return status === true ? value : !value; + } +} + +export { StateMachineBinding }; 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 index 11d4d8b82cd..97bd4cfaa80 100644 --- a/packages/mobile-ui-vue/components/navbar/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/navbar/src/schema/schema-mapper.ts @@ -2,6 +2,10 @@ import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; import { ButtonItem } from '@farris/mobile-ui-vue/button-group'; export function resolveRightToolbar(key: string, toolbarObj: any) { + if (!toolbarObj || !toolbarObj.items) { + return []; + } + const newItems: Array = []; toolbarObj.items.forEach((item: any) => { const { id, visible, text, onClick } = item; diff --git a/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json b/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json index 19a83d6350b..0e4a685c00e 100644 --- a/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json +++ b/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json @@ -85,7 +85,6 @@ "ignore": [ "id", "type", - "appearance", - "binding" + "appearance" ] } \ No newline at end of file -- Gitee From 88d3760b0abaf6b117d0961f3c02ea4526c2c495 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Wed, 16 Apr 2025 08:46:21 +0800 Subject: [PATCH 240/287] =?UTF-8?q?fix:=20=E7=A7=BB=E5=8A=A8input-group?= =?UTF-8?q?=E3=80=81number=E3=80=81textarea=E8=AE=BE=E8=AE=A1=E6=97=B6?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E8=A1=A5=E5=85=A8=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../input-group/src/composition/use-number.ts | 6 +- .../src/composition/use-textarea.ts | 6 +- .../input-group/src/input-group.component.tsx | 10 ++-- .../input-group/src/input-group.props.ts | 4 +- .../components/input-group/src/types/index.ts | 3 +- .../number-input.design.component.tsx | 5 +- .../src/number-input.component.tsx | 30 ++-------- .../number-input/src/number-input.props.ts | 6 +- .../number-input.property-config.ts | 57 ++++++++++--------- .../designer/textarea.design.component.tsx | 17 +++--- .../textarea.property-config.ts | 15 +++-- .../textarea/src/schema/schema-mapper.ts | 3 +- .../textarea/src/schema/textarea.schema.json | 3 +- .../textarea/src/textarea.component.tsx | 27 +-------- .../components/textarea/src/textarea.props.ts | 16 ++---- .../mobile-ui-vue/demos/input/text-area.vue | 2 +- 16 files changed, 81 insertions(+), 129 deletions(-) diff --git a/packages/mobile-ui-vue/components/input-group/src/composition/use-number.ts b/packages/mobile-ui-vue/components/input-group/src/composition/use-number.ts index 98ff4314120..e6020bade91 100644 --- a/packages/mobile-ui-vue/components/input-group/src/composition/use-number.ts +++ b/packages/mobile-ui-vue/components/input-group/src/composition/use-number.ts @@ -16,13 +16,13 @@ import { InputProps } from '../input-group.props'; import { formatToNumber, isDef, parseFloat } from '@farris/mobile-ui-vue/common'; import { Instance } from './types'; -import { InputTypeMap, InputUpdateOn, InputUpdateOnMap } from '../types'; +import { InputType, InputUpdateOn, InputUpdateOnMap } from '../types'; export function useNumber(props: InputProps): Instance { - const allowDot = props.type === InputTypeMap.number; + const allowDot = props.type === InputType.number; const updateOn: InputUpdateOn = InputUpdateOnMap.blur; const placeholder = '请输入数字'; - const inputType = allowDot ? InputTypeMap.text : InputTypeMap.number; + const inputType = allowDot ? InputType.text : InputType.number; const inputMode = allowDot ? 'decimal' : 'numeric'; const formatValue = (value: string | number) => { diff --git a/packages/mobile-ui-vue/components/input-group/src/composition/use-textarea.ts b/packages/mobile-ui-vue/components/input-group/src/composition/use-textarea.ts index 62f5441e55d..4ded8f74fad 100644 --- a/packages/mobile-ui-vue/components/input-group/src/composition/use-textarea.ts +++ b/packages/mobile-ui-vue/components/input-group/src/composition/use-textarea.ts @@ -18,16 +18,16 @@ import { addUnit } from '@farris/mobile-ui-vue/common'; import { InputProps } from '../input-group.props'; import { Instance } from './types'; import { useCommon } from './use-common'; -import { InputTypeMap } from '../types'; +import { InputType } from '../types'; export function useTextarea(props: InputProps, inputRef: Ref): Instance { const { placeholder, updateOn, inputMode, formatValue, getModelValue } = useCommon(props); - const inputType = InputTypeMap.textarea; + const inputType = InputType.textarea; const adjustSize = () => { const input = unref(inputRef); - if (!(props.type === InputTypeMap.textarea && props.autoHeight) || !input) { + if (!(props.type === InputType.textarea && props.autoHeight) || !input) { return; } 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 06291c23313..5b4cd229ec4 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 @@ -19,7 +19,7 @@ import { preventDefault, stopPropagation, useBem } from '@farris/mobile-ui-vue/c import { Icon } from '@farris/mobile-ui-vue/icon'; import { INPUT_NAME, InputProps, inputProps } from './input-group.props'; import { useInputState, useInputEvent, useInputExpose } from './composition'; -import { InputTypeMap } from './types'; +import { InputType } from './types'; export default defineComponent({ name: INPUT_NAME, @@ -60,7 +60,7 @@ export default defineComponent({ }; }); - const isTextArea = computed(() => props.type === InputTypeMap.textarea); + const isTextArea = computed(() => props.type === InputType.textarea); const renderControl = () => { return isTextArea.value ? ( @@ -108,10 +108,10 @@ export default defineComponent({ }; const renderWordLimit = () => - props.showWordLimit && - props.maxLength && ( + props.showWordLimit && (
    - {String(innerValue.value).length}/{props.maxLength} + {String(innerValue.value).length} + { props.maxLength && /{props.maxLength} }
    ); 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 13a26c3e1d6..6db6873bb24 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,5 +1,5 @@ import { ExtractPropTypes, PropType } from 'vue'; -import { InputTextAlign, InputTextAlignMap, InputType, InputTypeMap, InputUpdateOn } from "./types"; +import { InputTextAlign, InputTextAlignMap, InputType, InputUpdateOn } from "./types"; import { getPropsResolverGenerator } from '../../dynamic-resolver'; import inputGroupSchema from './schema/input-group.schema.json'; import { schemaMapper } from './schema/schema-mapper'; @@ -12,7 +12,7 @@ export const inputCommonProps = { name: { type: String, default: '' }, - type: { type: String as PropType, default: InputTypeMap.text }, + type: { type: String as PropType, default: InputType.text }, placeholder: { type: String, default: '' }, diff --git a/packages/mobile-ui-vue/components/input-group/src/types/index.ts b/packages/mobile-ui-vue/components/input-group/src/types/index.ts index 0a89559108a..b6f652a3389 100644 --- a/packages/mobile-ui-vue/components/input-group/src/types/index.ts +++ b/packages/mobile-ui-vue/components/input-group/src/types/index.ts @@ -9,7 +9,7 @@ export enum InputUpdateOnMap { blur = 'blur' } -export enum InputTypeMap { +export enum InputType { text = 'text', textarea = 'textarea', number = 'number', @@ -25,4 +25,3 @@ export type InputTextAlign = `${InputTextAlignMap}`; export type InputUpdateOn = `${InputUpdateOnMap}`; -export type InputType = `${InputTypeMap}`; diff --git a/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx b/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx index bb0e15f4c5e..ec373e0d663 100644 --- a/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx +++ b/packages/mobile-ui-vue/components/number-input/src/designer/number-input.design.component.tsx @@ -6,7 +6,7 @@ import { useDesignerComponent } from '@farris/mobile-ui-vue/common'; import { useDesignerRules } from './use-designer-rules'; -import InputGroup from '../number-input.component'; +import NumberInput from '../number-input.component'; import { numberInputProps } from '../number-input.props'; export default defineComponent({ @@ -35,12 +35,11 @@ export default defineComponent({ const inputProps = computed(()=>{ return { ...props, - type: 'number', editable: false, enableNull: true }; }); - return () => ; + return () => ; } }); 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 index c17b190c06e..94c12ba6f74 100644 --- 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 @@ -1,38 +1,16 @@ -/** - * 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 { defineComponent } from 'vue'; import { useBem } from '@farris/mobile-ui-vue/common'; import InputGroup from "@farris/mobile-ui-vue/input-group"; -import { NUMBER_INPUT_NAME, numberInputProps, NumberInputProps } from './number-input.props'; +import { NUMBER_INPUT_NAME, numberInputProps } from './number-input.props'; export default defineComponent({ name: NUMBER_INPUT_NAME, props: numberInputProps, - emits: ['update:modelValue'], - setup(props: NumberInputProps, context: SetupContext) { + setup(props) { const { bem } = useBem(NUMBER_INPUT_NAME); - const { emit } = context; - - const handleValueChange = (value: string | number) => { - emit('update:modelValue', value); - }; 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 index b07dd2f0f18..a82429e61fd 100644 --- 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 @@ -1,5 +1,5 @@ import { ExtractPropTypes } from 'vue'; -import { inputCommonProps } from '@farris/mobile-ui-vue/input-group'; +import { inputProps } from '@farris/mobile-ui-vue/input-group'; import { getPropsResolverGenerator } from '@farris/mobile-ui-vue/dynamic-resolver'; import numberInputSchema from './schema/number-input.schema.json'; import { schemaMapper } from './schema/schema-mapper'; @@ -8,9 +8,7 @@ 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 } + ...inputProps }; export type NumberInputProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts b/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts index 6dc50cb6fdd..fd36c058e1a 100644 --- a/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts +++ b/packages/mobile-ui-vue/components/number-input/src/property-config/number-input.property-config.ts @@ -1,32 +1,33 @@ -import { InputBaseProperty } from "@farris/mobile-ui-vue/common"; +import { InputBaseProperty } from '@farris/mobile-ui-vue/common'; export class NumberInputProperty extends InputBaseProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } - constructor(componentId: string, designerHostService: any) { - super(componentId, designerHostService); - } - - - getEditorProperties(propertyData: any) { - return this.getComponentConfig(propertyData, {}, { - precision: { - description: "", - title: "精度", - type: "number" - }, - max: { - description: "", - title: "最大值", - type: "number", - visible: false - }, - min: { - description: "", - title: "最小值", - type: "number", - visible: false - }, - }); - } - + getEditorProperties(propertyData: any) { + return this.getComponentConfig( + propertyData, + {}, + { + precision: { + description: '', + title: '精度', + type: 'number' + }, + max: { + description: '', + title: '最大值', + type: 'number', + visible: false + }, + min: { + description: '', + title: '最小值', + type: 'number', + visible: false + } + } + ); + } } diff --git a/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx b/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx index bf4acc310bd..d346aec2569 100644 --- a/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx +++ b/packages/mobile-ui-vue/components/textarea/src/designer/textarea.design.component.tsx @@ -12,7 +12,7 @@ import Textarea from '../textarea.component'; export default defineComponent({ name: 'FmTextareaDesign', inheritAttrs: false, - props: extractProperties(textareaProps, ['placeholder', 'rows', 'showWordLimit']), + props: extractProperties(textareaProps, ['placeholder', 'rows', 'showWordLimit', 'maxLength']), setup(props, context) { const elementRef = ref(); const designerHostService = inject('designer-host-service'); @@ -32,15 +32,16 @@ export default defineComponent({ onMounted(() => { elementRef.value.componentInstance = componentInstance; }); - - const inputProps = computed(() => ({ - ...props, - type: 'textarea', - editable: false, - })); - + context.expose(componentInstance.value); + const inputProps = computed(() => { + return { + ...props, + editable: false, + }; + }); + return () => { return ; }; diff --git a/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts b/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts index b501e4ba78f..4992591ddb6 100644 --- a/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts +++ b/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts @@ -20,7 +20,15 @@ export class TextareaProperty extends InputBaseProperty { title: '文本区域可见的行数', type: 'number', editor: { - min: 0, + min: 1, + nullable: true + } + }, + maxLength: { + description: '最大字数', + title: '最大长度', + type: 'number', + editor: { nullable: true } }, @@ -29,11 +37,6 @@ export class TextareaProperty extends InputBaseProperty { title: '展示输入文本数量', type: 'boolean' }, - maxLength: { - description: '文本最大长度', - title: '最大长度', - type: 'number' - }, autoHeight: { description: '', title: '自动高度', diff --git a/packages/mobile-ui-vue/components/textarea/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/textarea/src/schema/schema-mapper.ts index 42b3a02141c..55ccab23420 100644 --- a/packages/mobile-ui-vue/components/textarea/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/textarea/src/schema/schema-mapper.ts @@ -2,5 +2,6 @@ import { MapperFunction, resolveAppearance } from '@farris/mobile-ui-vue/dynamic export const schemaMapper = new Map([ ['appearance', resolveAppearance], - ['binding', 'modelValue'] + ['binding', 'modelValue'], + ['showCount', 'showWordLimit'], ]); 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 index 44635921d58..d35c7170477 100644 --- a/packages/mobile-ui-vue/components/textarea/src/schema/textarea.schema.json +++ b/packages/mobile-ui-vue/components/textarea/src/schema/textarea.schema.json @@ -62,7 +62,8 @@ }, "rows": { "description": "最大行数", - "type": "number" + "type": "number", + "default": 2 }, "autoHeight": { "description": "自动高度", diff --git a/packages/mobile-ui-vue/components/textarea/src/textarea.component.tsx b/packages/mobile-ui-vue/components/textarea/src/textarea.component.tsx index 3c626226999..8714bcd9b5e 100644 --- a/packages/mobile-ui-vue/components/textarea/src/textarea.component.tsx +++ b/packages/mobile-ui-vue/components/textarea/src/textarea.component.tsx @@ -1,35 +1,14 @@ -/** - * 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 InputGroup from "@farris/mobile-ui-vue/input-group"; -import { TEXTAREA_NAME, textareaProps, TextareaProps } from './textarea.props'; +import { TEXTAREA_NAME, textareaProps } from './textarea.props'; export default defineComponent({ name: TEXTAREA_NAME, props: textareaProps, - setup(props: TextareaProps, context) { - const { emit } = context; - - const handleValueChange = (value: string | number) => { - emit('update:modelValue', value); - }; + setup(props) { return () => ( - + ); } }); 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 c2e86cc6b97..18f8b328dac 100644 --- a/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts +++ b/packages/mobile-ui-vue/components/textarea/src/textarea.props.ts @@ -1,5 +1,5 @@ -import { ExtractPropTypes } from 'vue'; -import { inputCommonProps } from '@farris/mobile-ui-vue/input-group'; +import { ExtractPropTypes, PropType } from 'vue'; +import { inputProps, InputType } from '@farris/mobile-ui-vue/input-group'; import { getPropsResolverGenerator } from '@farris/mobile-ui-vue/dynamic-resolver'; import textareaSchema from './schema/textarea.schema.json'; import { schemaMapper } from './schema/schema-mapper'; @@ -8,17 +8,9 @@ import { schemaResolver } from './schema/schema-resolver'; export const TEXTAREA_NAME = 'FmTextarea'; export const textareaProps = { - ...inputCommonProps, + ...inputProps, - autoHeight: { type: Boolean, default: undefined }, - - rows: { type: Number, default: undefined }, - - maxHeight: { type: Number, default: undefined }, - - minHeight: { type: Number, default: undefined }, - - showWordLimit: { type: Boolean, default: undefined } + type: { type: String as PropType, default: InputType.textarea }, }; export type TextareaProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/demos/input/text-area.vue b/packages/mobile-ui-vue/demos/input/text-area.vue index 4be137c5d50..1b4af6f69c1 100644 --- a/packages/mobile-ui-vue/demos/input/text-area.vue +++ b/packages/mobile-ui-vue/demos/input/text-area.vue @@ -3,5 +3,5 @@ - + -- Gitee From d629f35189ef24471a244a754162e4af1ca25af5 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Wed, 16 Apr 2025 11:50:26 +0800 Subject: [PATCH 241/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8check?= =?UTF-8?q?=E5=8F=8Araido=E7=BB=84=E4=BB=B6=E5=8A=9F=E8=83=BD=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E5=8F=8A=E8=AE=BE=E8=AE=A1=E6=97=B6=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/checkbox-group.component.tsx | 23 +-- .../src/checkbox-group.props.ts | 16 +- .../checkbox-group.design.component.tsx | 132 ++++++------- .../src/designer/use-designer-rules.ts | 4 +- .../checkbox-group.property-config.ts | 7 +- .../src/schema/checkbox-group.schema.json | 157 ++++++++-------- .../src/schema/schema-mapper.ts | 11 +- .../src/schema/schema-resolver.ts | 10 +- .../checkbox/src/checkbox.component.tsx | 55 ++---- .../components/checkbox/src/checkbox.props.ts | 2 +- .../checker/src/checker.component.tsx | 10 +- .../components/checker/src/checker.props.ts | 18 +- .../input-group.property-config.ts | 5 +- .../src/schema/input-group.schema.json | 137 +++++++------- .../picker/src/schema/picker.schema.json | 175 +++++++++--------- .../designer/radio-group.design.component.tsx | 128 ++++++------- .../src/designer/use-designer-rules.ts | 4 +- .../radio-group/src/radio-group.component.tsx | 19 +- .../radio-group/src/radio-group.props.ts | 8 +- .../src/schema/radio-group.schema.json | 21 +-- .../radio-group/src/schema/schema-mapper.ts | 11 +- .../radio-group/src/schema/schema-resolver.ts | 10 +- .../components/radio/src/radio.component.tsx | 8 +- .../components/radio/src/radio.props.ts | 8 +- 24 files changed, 453 insertions(+), 526 deletions(-) diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.component.tsx b/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.component.tsx index 844917718c1..ddf46838896 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.component.tsx +++ b/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.component.tsx @@ -1,34 +1,17 @@ -/** - * 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, ref, toRaw, watch } from 'vue'; +import { computed, defineComponent, ref, toRaw, watch } from 'vue'; import { isArray, isString, useBem, useLink } from '@farris/mobile-ui-vue/common'; import Checkbox from '@farris/mobile-ui-vue/checkbox'; +import { useGroupItems } from './composition'; import { CHECKBOX_GROUP_NAME, CheckboxGroupContext, - CheckboxGroupProps, checkboxGroupProps } from './checkbox-group.props'; -import { useGroupItems } from './composition'; export default defineComponent({ name: CHECKBOX_GROUP_NAME, props: checkboxGroupProps, - setup(props: CheckboxGroupProps, context: SetupContext) { + setup(props, context) { const { emit, slots } = context; const checkeds = ref<(string | number)[]>([]); diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.props.ts b/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.props.ts index b823c42c2c9..1cdf9b3da8f 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.props.ts +++ b/packages/mobile-ui-vue/components/checkbox-group/src/checkbox-group.props.ts @@ -1,5 +1,5 @@ import { ExtractPropTypes, PropType } from 'vue'; -import { CheckerShape, CheckerShapeMap, CheckerType, CheckerTypeMap } from '@farris/mobile-ui-vue/checker'; +import { CheckerShape, CheckerType } from '@farris/mobile-ui-vue/checker'; import { schemaMapper } from './schema/schema-mapper'; import { schemaResolver } from './schema/schema-resolver'; import inputSchema from './schema/checkbox-group.schema.json'; @@ -11,13 +11,11 @@ export type CheckboxItem = { [key: string]: any; }; -export const enum CheckboxDirectionMap { +export const enum CheckboxDirection { Vertical = 'vertical', Horizontal = 'horizontal' } -export type CheckboxDirection = `${CheckboxDirectionMap}`; - export const CHECKBOX_GROUP_NAME = 'fm-checkbox-group'; export const checkboxGroupProps = { @@ -27,11 +25,11 @@ export const checkboxGroupProps = { readonly: { type: Boolean, default: false }, - shape: { type: String as PropType, default: CheckerShapeMap.Square }, + shape: { type: String as PropType, default: CheckerShape.Square }, - type: { type: String as PropType, default: CheckerTypeMap.Check }, + type: { type: String as PropType, default: CheckerType.Check }, - direction: { type: String as PropType, default: CheckboxDirectionMap.Vertical }, + direction: { type: String as PropType, default: CheckboxDirection.Vertical }, options: { type: Array as PropType, default: undefined }, @@ -40,7 +38,7 @@ export const checkboxGroupProps = { textField: { type: String, default: 'text' }, showDisabledItem: { type: Boolean, default: true }, -} as Record; +}; export type CheckboxGroupProps = ExtractPropTypes; @@ -50,5 +48,5 @@ export type CheckboxGroupContext = { updateChecked: (value: string | number, checked: boolean) => void; }; -export const propsResolverGenerator = getPropsResolverGenerator(checkboxGroupProps, inputSchema, schemaMapper, schemaResolver); +export const propsResolverGenerator = getPropsResolverGenerator(checkboxGroupProps, inputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/designer/checkbox-group.design.component.tsx b/packages/mobile-ui-vue/components/checkbox-group/src/designer/checkbox-group.design.component.tsx index f0b846951aa..d394591c00e 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/src/designer/checkbox-group.design.component.tsx +++ b/packages/mobile-ui-vue/components/checkbox-group/src/designer/checkbox-group.design.component.tsx @@ -1,74 +1,74 @@ - -/** - * 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, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; -import { CheckboxGroup, checkboxGroupProps, CheckboxGroupProps } from '../..'; -import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common'; -import { useCheckBoxGroupProperty } from './use-designer-rules';; +import { computed, defineComponent, inject, onMounted, ref } from 'vue'; +import { + DesignerHostService, + DesignerItemContext, + extractProperties, + useDesignerComponent +} from '@farris/mobile-ui-vue/common'; +import { useCheckBoxGroupProperty } from './use-designer-rules'; +import { checkboxGroupProps } from '../checkbox-group.props'; +import CheckboxGroup from '../checkbox-group.component'; export default defineComponent({ - name: 'FmEnumFieldInputDesign', - props: checkboxGroupProps, - emits: [] as (string[] & ThisType) | undefined, - setup(props: CheckboxGroupProps, context: SetupContext) { - const elementRef = ref(); - const designerHostService = inject('designer-host-service'); - const designItemContext = inject('design-item-context') as DesignerItemContext; - const designerRulesComposition = useCheckBoxGroupProperty(designItemContext, designerHostService); - const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + name: 'FmCheckboxGroupDesign', + props: extractProperties(checkboxGroupProps, [ + 'options', + 'textField', + 'valueField', + 'direction', + 'type' + ]), + setup(props, context) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject( + 'design-item-context' + ) as DesignerItemContext; + const designerRulesComposition = useCheckBoxGroupProperty( + designItemContext, + designerHostService + ); + const componentInstance = useDesignerComponent( + elementRef, + designItemContext, + designerRulesComposition + ); - onMounted(() => { - elementRef.value.componentInstance = componentInstance; - }); + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); - /** - * 解决在设计时,数据为空数组,界面不显示内容的问题 - */ - const realEnumData = computed(() => { - if (!props.options || props.options.length === 0) { - const result = [] as any; - [ - { value: 'example1', name: '示例一' }, - { value: 'example2', name: '示例二' } - ].map(item => { - const tempData = {}; - tempData[props.valueField] = item['value']; - tempData[props.textField] = item['name']; - result.push(tempData); - }); - return result; - } - return props.options; + /** + * 解决在设计时,数据为空数组,界面不显示内容的问题 + */ + const realEnumData = computed(() => { + if (!props.options || props.options.length === 0) { + const result = [] as any; + [ + { value: 'example1', name: '示例一' }, + { value: 'example2', name: '示例二' } + ].map((item) => { + const tempData = {}; + tempData[props.valueField] = item['value']; + tempData[props.textField] = item['name']; + result.push(tempData); }); + return result; + } + return props.options; + }); + + context.expose(componentInstance.value); - const inputGroupProps = computed(() => ({ - ...props, - editable: false, - readonly: true, - modelValue:null, - options:realEnumData.value, - type:null - })); - - context.expose(componentInstance.value); + const checkboxGroupProps = computed(() => ({ + ...props, + editable: false, + readonly: true, + options: realEnumData.value + })); - return () => { - return ( - - ); - }; - } + return () => { + return ; + }; + } }); diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/checkbox-group/src/designer/use-designer-rules.ts index f65d878e312..0c4a681f89e 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/checkbox-group/src/designer/use-designer-rules.ts @@ -6,8 +6,8 @@ export function useCheckBoxGroupProperty(designItemContext: DesignerItemContext, // 构造属性配置方法 function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { - const radioGroupProps = new CheckBoxGroupProperty(componentId, designerHostService); - return radioGroupProps.getPropertyConfig(schema, componentInstance); + const radioGroupProps = new CheckBoxGroupProperty(componentId, designerHostService); + return radioGroupProps.getPropertyConfig(schema, componentInstance); } return { getPropsConfig } as UseDesignerRules; diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts b/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts index 1ec557f202c..08de93cf4d8 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts +++ b/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts @@ -9,14 +9,11 @@ export class CheckBoxGroupProperty extends InputBaseProperty { const self = this; const editorProperties = self.getComponentConfig( propertyData, - {}, + { type: 'check-group' }, { placeholder: { visible: false }, - disabled: { - visible: false - }, data: { description: '', title: '数据', @@ -43,7 +40,7 @@ export class CheckBoxGroupProperty extends InputBaseProperty { readonly: true } }, - (changeObject, parameters) => { + (changeObject) => { if (!changeObject) { return; } diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/schema/checkbox-group.schema.json b/packages/mobile-ui-vue/components/checkbox-group/src/schema/checkbox-group.schema.json index 0a7a1f7c964..2cc30d0d6c0 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/src/schema/checkbox-group.schema.json +++ b/packages/mobile-ui-vue/components/checkbox-group/src/schema/checkbox-group.schema.json @@ -1,88 +1,77 @@ { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://farris-design.gitee.io/check-group.schema.json", - "title": "check-group", - "description": "A Farris Input Component", - "type": "object", - "properties": { - "id": { - "description": "The unique identifier for a Input Group", - "type": "string" - }, - "type": { - "description": "The type string of Input Group component", - "type": "string", - "default": "check-group" - }, - "appearance": { - "description": "", - "type": "object", - "properties": { - "class": { - "type": "string" - }, - "style": { - "type": "string" - } - }, - "default": {} - }, - "binding": { - "description": "", - "type": "object", - "default": {} - }, - "readonly": { - "type": "string", - "default": false - }, - "title": { - "description": "", - "type": "string", - "default": "" - }, - "label": { - "description": "", - "type": "string", - "default": "" - }, - "lableWidth": { - "description": "", - "type": "number" - }, - "visible": { - "description": "", - "type": "boolean", - "default": true - }, - "data": { - "description": "", - "type": "array", - "default": [] - }, - "direction": { - "description": "", - "type": "string", - "default": "horizontal" - }, - "textField": { - "description": "", - "type": "string", - "default": "name" + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/check-group.schema.json", + "title": "check-group", + "description": "A Farris Input Component", + "type": "object", + "properties": { + "id": { + "description": "The unique identifier for a Input Group", + "type": "string" + }, + "type": { + "description": "The type string of Input Group component", + "type": "string", + "default": "check-group" + }, + "appearance": { + "description": "", + "type": "object", + "properties": { + "class": { + "type": "string" }, - "valueField": { - "description": "", - "type": "string", - "default": "value" + "style": { + "type": "string" } + }, + "default": {} + }, + "binding": { + "description": "", + "type": "object", + "default": {} + }, + "required": { + "description": "必填", + "type": "boolean", + "default": false + }, + "readonly": { + "type": "string", + "default": false + }, + "visible": { + "description": "", + "type": "boolean", + "default": true + }, + "data": { + "description": "", + "type": "array", + "default": [] + }, + "direction": { + "description": "", + "type": "string", + "default": "vertical" + }, + "textField": { + "description": "", + "type": "string", + "default": "name" + }, + "valueField": { + "description": "", + "type": "string", + "default": "value" }, - "required": [ - "type" - ], - "ignore": [ - "id", - "appearance", - "binding", - "visible" - ] -} \ No newline at end of file + "checkerType": { + "description": "", + "type": "string", + "default": "default" + } + }, + "required": ["type"], + "ignore": ["id", "appearance", "binding", "visible"] +} diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-mapper.ts index cbfb41ab584..c414d91b7f5 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-mapper.ts @@ -1,7 +1,10 @@ -import { MapperFunction, resolveAppearance, resolveData } from '@farris/mobile-ui-vue/dynamic-resolver'; +import { + MapperFunction, + resolveAppearance +} from '@farris/mobile-ui-vue/dynamic-resolver'; export const schemaMapper = new Map([ - ['appearance', resolveAppearance], - ['data', resolveData], + ['appearance', resolveAppearance], + ['data', 'options'], + ['checkerType', 'type'] ]); - diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-resolver.ts index 7c8af7fc63d..1e756819460 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-resolver.ts +++ b/packages/mobile-ui-vue/components/checkbox-group/src/schema/schema-resolver.ts @@ -1,5 +1,9 @@ -import { DynamicResolver } from "@farris/mobile-ui-vue/dynamic-resolver"; +import { DynamicResolver } from '@farris/mobile-ui-vue/dynamic-resolver'; -export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { - return schema; +export function schemaResolver( + resolver: DynamicResolver, + schema: Record, + context: Record +): Record { + return schema; } diff --git a/packages/mobile-ui-vue/components/checkbox/src/checkbox.component.tsx b/packages/mobile-ui-vue/components/checkbox/src/checkbox.component.tsx index 5510e7d5ae2..cb4537077d0 100644 --- a/packages/mobile-ui-vue/components/checkbox/src/checkbox.component.tsx +++ b/packages/mobile-ui-vue/components/checkbox/src/checkbox.component.tsx @@ -1,22 +1,6 @@ -/** - * 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, defineComponent } from 'vue'; -import { useLink } from '@farris/mobile-ui-vue/common'; -import { Checker, CheckerRoleMap, CheckerShapeMap } from '@farris/mobile-ui-vue/checker'; +import { useBem, useLink } from '@farris/mobile-ui-vue/common'; +import { Checker, CheckerRole } from '@farris/mobile-ui-vue/checker'; import { CHECKBOX_GROUP_NAME, CheckboxGroupContext } from '@farris/mobile-ui-vue/checkbox-group'; import { CHECKBOX_NAME, @@ -30,6 +14,8 @@ export default defineComponent({ setup(props: CheckboxProps, context) { const { emit } = context; + const { bem } = useBem(CHECKBOX_NAME); + const { getParent } = useLink(CHECKBOX_GROUP_NAME); const checkboxGroup = getParent(); @@ -37,30 +23,25 @@ export default defineComponent({ checkboxGroup?.updateChecked(props.name, checked); emit('change', checked); }; - const handlerUpdateModelValue = (value: boolean) => { - emit('update:modelValue', value); - }; const innerValue = computed(() => { return checkboxGroup?.getChecked ? checkboxGroup.getChecked(props.name) : props.modelValue; }); - const renderCheckbox = () => { - return ( - - ); - }; + const renderCheckbox = () => ( + + ); - return () =>
    {renderCheckbox()}
    ; + return () =>
    {renderCheckbox()}
    ; } }); diff --git a/packages/mobile-ui-vue/components/checkbox/src/checkbox.props.ts b/packages/mobile-ui-vue/components/checkbox/src/checkbox.props.ts index 6fe9e2469b6..dd1666b80fd 100644 --- a/packages/mobile-ui-vue/components/checkbox/src/checkbox.props.ts +++ b/packages/mobile-ui-vue/components/checkbox/src/checkbox.props.ts @@ -1,7 +1,7 @@ import { ExtractPropTypes } from 'vue'; import { checkerProps } from '@farris/mobile-ui-vue/checker'; -export const CHECKBOX_NAME = 'fm-checkbox'; +export const CHECKBOX_NAME = 'FmCheckbox'; export const checkboxProps = { ...checkerProps, diff --git a/packages/mobile-ui-vue/components/checker/src/checker.component.tsx b/packages/mobile-ui-vue/components/checker/src/checker.component.tsx index 82bb9de3ee5..2f18ae5b9b5 100644 --- a/packages/mobile-ui-vue/components/checker/src/checker.component.tsx +++ b/packages/mobile-ui-vue/components/checker/src/checker.component.tsx @@ -17,7 +17,7 @@ import { computed, defineComponent, ref, watch } from 'vue'; import { Icon } from '@farris/mobile-ui-vue/icon'; import { useBem } from '@farris/mobile-ui-vue/common'; -import { CheckerProps, checkerProps, CHECKER_NAME, CheckerTypeMap, CheckerShapeMap, CheckerRoleMap } from './checker.props'; +import { CheckerProps, checkerProps, CHECKER_NAME, CheckerType, CheckerShape, CheckerRole } from './checker.props'; export default defineComponent({ name: CHECKER_NAME, @@ -67,8 +67,8 @@ export default defineComponent({ [bem('', 'readonly')]: props.readonly, [bem('', 'disabled')]: props.disabled, [bem('', 'checked')]: innerValue.value, - [bem('', 'round')]: props.shape === CheckerShapeMap.Round, - [bem('', 'button')]: props.type === CheckerTypeMap.Button + [bem('', 'round')]: props.shape === CheckerShape.Round, + [bem('', 'button')]: props.type === CheckerType.Button }; }); @@ -76,7 +76,7 @@ export default defineComponent({ if (props.readonly || props.disabled) { return; } - if(props.role === CheckerRoleMap.Radio && innerValue.value) { + if(props.role === CheckerRole.Radio && innerValue.value) { return; } innerValue.value = !innerValue.value; @@ -86,7 +86,7 @@ export default defineComponent({ return () => (
    - {props.type === CheckerTypeMap.Check && renderIcon()} + {props.type === CheckerType.Check && renderIcon()} {props.label && renderLabel()}
    ); diff --git a/packages/mobile-ui-vue/components/checker/src/checker.props.ts b/packages/mobile-ui-vue/components/checker/src/checker.props.ts index 9befeef8cf3..085de6d4d98 100644 --- a/packages/mobile-ui-vue/components/checker/src/checker.props.ts +++ b/packages/mobile-ui-vue/components/checker/src/checker.props.ts @@ -1,26 +1,20 @@ import { ExtractPropTypes, PropType } from 'vue'; -export const enum CheckerRoleMap { +export const enum CheckerRole { Checkbox = 'checkbox', Radio = 'radio' } -export const enum CheckerShapeMap { +export const enum CheckerShape { Square = 'square', Round = 'round' } -export const enum CheckerTypeMap { +export const enum CheckerType { Check = 'default', Button = 'button' } -export type CheckerType = `${CheckerTypeMap}`; - -export type CheckerShape = `${CheckerShapeMap}`; - -export type CheckerRole = `${CheckerRoleMap}`; - export const CHECKER_NAME = 'fm-checker'; export const checkerProps = { @@ -32,11 +26,11 @@ export const checkerProps = { readonly: { type: Boolean, default: false }, - type: { type: String as PropType, default: CheckerTypeMap.Check }, + type: { type: String as PropType, default: CheckerType.Check }, - role: { type: String as PropType, default: CheckerRoleMap.Checkbox }, + role: { type: String as PropType, default: CheckerRole.Checkbox }, - shape: { type: String as PropType, default: CheckerShapeMap.Square }, + shape: { type: String as PropType, default: CheckerShape.Square }, labelLimit: { type: Number, default: undefined }, }; diff --git a/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts b/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts index 7cfd630ed80..27d9818b323 100644 --- a/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts +++ b/packages/mobile-ui-vue/components/input-group/src/property-config/input-group.property-config.ts @@ -25,12 +25,11 @@ export class InputGroupProperty extends InputBaseProperty { { maxLength: { description: '文本字数最大长度', - title: '最大长度', + title: '最大字数', type: 'number', editor: { nullable: true, - min: 0, - useThousands: false + min: 0 } } }, 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 658e623f094..e9cd461e15f 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 @@ -1,77 +1,68 @@ { - "$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": {} - }, - "required": { - "description": "必填", - "type": "boolean", - "default": false - }, - "readonly": { - "description": "只读", - "type": "boolean", - "default": false - }, - "disabled": { - "description": "禁用", - "type": "boolean", - "default": false - }, - "placeholder": { - "description": "提示文本", - "type": "string" - }, - "formatValidation": { - "description": "验证类型", - "type": "object", - "default": {} + "$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" }, - "onUpdate:modelValue": { - "description": "值更新事件", - "type": "string", - "default": "" + "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" + }, + "formatValidation": { + "description": "验证类型", + "type": "object", + "default": {} }, - "events": [ - "onUpdate:modelValue" - ], - "required": [ - "type" - ], - "ignore": [ - "id", - "appearance", - "binding", - "visible" - ] -} \ No newline at end of file + "onUpdate:modelValue": { + "description": "值更新事件", + "type": "string", + "default": "" + } + }, + "events": ["onUpdate:modelValue"], + "required": ["type"], + "ignore": ["id", "appearance", "binding", "visible"] +} diff --git a/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json b/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json index 19a83d6350b..f1be8e455c9 100644 --- a/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json +++ b/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json @@ -1,91 +1,92 @@ { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://farris-design.gitee.io/enum-field.schema.json", - "title": "picker", - "description": "A Farris Picker Component", - "type": "object", - "properties": { - "id": { - "description": "标志", - "type": "string" - }, - "type": { - "description": "控件类型", - "type": "string", - "default": "picker" - }, - "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": "" - }, - "valueField": { - "description": "值字段", - "type": "string", - "default": "id" - }, - "textField": { - "description": "显示字段", - "type": "string", - "default": "name" - }, - "data": { - "description": "数据", - "type": "array", - "default": [] + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/enum-field.schema.json", + "title": "picker", + "description": "A Farris Picker Component", + "type": "object", + "properties": { + "id": { + "description": "标志", + "type": "string" + }, + "type": { + "description": "控件类型", + "type": "string", + "default": "picker" + }, + "appearance": { + "description": "外观", + "type": "object", + "properties": { + "class": { + "type": "string" }, - "onUpdate:modelValue": { - "description": "值更新事件", - "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 + }, + "editable": { + "description": "", + "type": "boolean", + "default": false + }, + "enableClear": { + "description": "", + "type": "boolean", + "default": false + }, + "placeholder": { + "description": "提示文本", + "type": "string" + }, + "title": { + "description": "标题", + "type": "string", + "default": "" + }, + "valueField": { + "description": "值字段", + "type": "string", + "default": "value" + }, + "textField": { + "description": "显示字段", + "type": "string", + "default": "name" + }, + "data": { + "description": "数据", + "type": "array", + "default": [] }, - "events": [ - "onUpdate:modelValue" - ], - "required": [ - "type" - ], - "ignore": [ - "id", - "type", - "appearance", - "binding" - ] -} \ No newline at end of file + "onUpdate:modelValue": { + "description": "值更新事件", + "type": "string" + } + }, + "events": ["onUpdate:modelValue"], + "required": ["type"], + "ignore": ["id", "type", "appearance", "binding"] +} diff --git a/packages/mobile-ui-vue/components/radio-group/src/designer/radio-group.design.component.tsx b/packages/mobile-ui-vue/components/radio-group/src/designer/radio-group.design.component.tsx index fd1e3df35f2..ea8a890658c 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/designer/radio-group.design.component.tsx +++ b/packages/mobile-ui-vue/components/radio-group/src/designer/radio-group.design.component.tsx @@ -1,74 +1,74 @@ - -/** - * 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, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; -import { RadioGroup, RadioGroupProps, radioGroupProps } from '../..'; -import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common'; +import { computed, defineComponent, inject, onMounted, ref } from 'vue'; +import { + DesignerHostService, + DesignerItemContext, + extractProperties, + useDesignerComponent +} from '@farris/mobile-ui-vue/common'; import { useRadioGroupDesignerRules } from './use-designer-rules'; +import { radioGroupProps } from '../radio-group.props'; +import RadioGroup from '../radio-group.component'; export default defineComponent({ - name: 'FmRadioGroupDesign', - props: radioGroupProps, - emits: [] as (string[] & ThisType) | undefined, - setup(props: RadioGroupProps, context: SetupContext) { - const elementRef = ref(); - const designerHostService = inject('designer-host-service'); - const designItemContext = inject('design-item-context') as DesignerItemContext; - const designerRulesComposition = useRadioGroupDesignerRules(designItemContext, designerHostService); - const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + name: 'FmRadioGroupDesign', + props: extractProperties(radioGroupProps, [ + 'options', + 'textField', + 'valueField', + 'direction', + 'type' + ]), + setup(props, context) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject( + 'design-item-context' + ) as DesignerItemContext; + const designerRulesComposition = useRadioGroupDesignerRules( + designItemContext, + designerHostService + ); + const componentInstance = useDesignerComponent( + elementRef, + designItemContext, + designerRulesComposition + ); - onMounted(() => { - elementRef.value.componentInstance = componentInstance; - }); + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); - /** - * 解决在设计时,数据为空数组,界面不显示内容的问题 - */ - const realEnumData = computed(() => { - if (!props.options || props.options.length === 0) { - const result = [] as any; - [ - { value: 'example1', name: '示例一' }, - { value: 'example2', name: '示例二' } - ].map(item => { - const tempData = {}; - tempData[props.valueField] = item['value']; - tempData[props.textField] = item['name']; - result.push(tempData); - }); - return result; - } - return props.options; + /** + * 解决在设计时,数据为空数组,界面不显示内容的问题 + */ + const realEnumData = computed(() => { + if (!props.options || props.options.length === 0) { + const result = [] as any; + [ + { value: 'example1', name: '示例一' }, + { value: 'example2', name: '示例二' } + ].map((item) => { + const tempData = {}; + tempData[props.valueField] = item['value']; + tempData[props.textField] = item['name']; + result.push(tempData); }); + return result; + } + return props.options; + }); - const inputGroupProps = computed(() => ({ - ...props, - editable: false, - readonly: true, - modelValue:null, - options:realEnumData.value, - type:"default" - })); + const radioGroupProps = computed(() => ({ + ...props, + editable: false, + readonly: true, + options: realEnumData.value + })); - context.expose(componentInstance.value); + context.expose(componentInstance.value); - return () => { - return ( - - ); - }; - } + return () => { + return ; + }; + } }); diff --git a/packages/mobile-ui-vue/components/radio-group/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/radio-group/src/designer/use-designer-rules.ts index ec88e3ba081..1a9e02c9d13 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/radio-group/src/designer/use-designer-rules.ts @@ -6,8 +6,8 @@ export function useRadioGroupDesignerRules(designItemContext: DesignerItemContex // 构造属性配置方法 function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { - const radioGroupProps = new RadioGroupProperty(componentId, designerHostService); - return radioGroupProps.getPropertyConfig(schema, componentInstance); + const radioGroupProps = new RadioGroupProperty(componentId, designerHostService); + return radioGroupProps.getPropertyConfig(schema, componentInstance); } return { getPropsConfig } as UseDesignerRules; diff --git a/packages/mobile-ui-vue/components/radio-group/src/radio-group.component.tsx b/packages/mobile-ui-vue/components/radio-group/src/radio-group.component.tsx index cd552d70c4f..706fc0443ef 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/radio-group.component.tsx +++ b/packages/mobile-ui-vue/components/radio-group/src/radio-group.component.tsx @@ -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 { SetupContext, computed, defineComponent, ref, watch } from 'vue'; import { useBem, useLink } from '@farris/mobile-ui-vue/common'; import { useGroupItems } from '@farris/mobile-ui-vue/checkbox-group'; @@ -21,14 +5,13 @@ import Radio from '@farris/mobile-ui-vue/radio'; import { RADIO_GROUP_NAME, RadioGroupContext, - RadioGroupProps, radioGroupProps } from './radio-group.props'; export default defineComponent({ name: RADIO_GROUP_NAME, props: radioGroupProps, - setup(props: RadioGroupProps, context: SetupContext) { + setup(props, context: SetupContext) { const { emit, slots } = context; const innerValue = ref(props.modelValue); diff --git a/packages/mobile-ui-vue/components/radio-group/src/radio-group.props.ts b/packages/mobile-ui-vue/components/radio-group/src/radio-group.props.ts index 2148d888b13..23a3b0f22e0 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/radio-group.props.ts +++ b/packages/mobile-ui-vue/components/radio-group/src/radio-group.props.ts @@ -1,5 +1,5 @@ import { ExtractPropTypes, PropType } from 'vue'; -import {CheckerShape, CheckerShapeMap } from '@farris/mobile-ui-vue/checker'; +import {CheckerShape } from '@farris/mobile-ui-vue/checker'; import { CheckboxGroupContext, checkboxGroupProps } from '@farris/mobile-ui-vue/checkbox-group'; import { getPropsResolverGenerator } from '@farris/mobile-ui-vue/dynamic-resolver'; import inputSchema from './schema/radio-group.schema.json'; @@ -11,10 +11,10 @@ export const RADIO_GROUP_NAME = 'fm-radio-group'; export const radioGroupProps = { ...checkboxGroupProps, - shape: { type: String as PropType, default: CheckerShapeMap.Round }, + shape: { type: String as PropType, default: CheckerShape.Round }, modelValue: { type: [String, Number] , default: '' } -} as Record; +}; export type RadioGroupProps = ExtractPropTypes; @@ -24,4 +24,4 @@ type Merge = { export type RadioGroupContext = Merge void }>; -export const propsResolverGenerator = getPropsResolverGenerator(radioGroupProps, inputSchema, schemaMapper, schemaResolver); +export const propsResolverGenerator = getPropsResolverGenerator(radioGroupProps, inputSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json b/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json index 7fad6675bf4..f0f9b950068 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json +++ b/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json @@ -36,20 +36,6 @@ "type": "string", "default": false }, - "title": { - "description": "", - "type": "string", - "default": "" - }, - "label": { - "description": "", - "type": "string", - "default": "" - }, - "lableWidth": { - "description": "", - "type": "number" - }, "visible": { "description": "", "type": "boolean", @@ -63,7 +49,7 @@ "direction": { "description": "", "type": "string", - "default": "horizontal" + "default": "vertical" }, "textField": { "description": "", @@ -74,6 +60,11 @@ "description": "", "type": "string", "default": "value" + }, + "checkerType": { + "description": "", + "type": "string", + "default": "default" } }, "required": ["type"], diff --git a/packages/mobile-ui-vue/components/radio-group/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/radio-group/src/schema/schema-mapper.ts index bf5fa0c7c60..98eb00913b3 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/radio-group/src/schema/schema-mapper.ts @@ -1,6 +1,11 @@ -import { MapperFunction, resolveAppearance, resolveData } from '@farris/mobile-ui-vue/dynamic-resolver'; +import { + MapperFunction, + resolveAppearance, + resolveData +} from '@farris/mobile-ui-vue/dynamic-resolver'; export const schemaMapper = new Map([ - ['appearance', resolveAppearance], - ['data', resolveData], + ['appearance', resolveAppearance], + ['data', 'options'], + ['checkerType', 'type'] ]); diff --git a/packages/mobile-ui-vue/components/radio-group/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/radio-group/src/schema/schema-resolver.ts index 7c8af7fc63d..1e756819460 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/schema/schema-resolver.ts +++ b/packages/mobile-ui-vue/components/radio-group/src/schema/schema-resolver.ts @@ -1,5 +1,9 @@ -import { DynamicResolver } from "@farris/mobile-ui-vue/dynamic-resolver"; +import { DynamicResolver } from '@farris/mobile-ui-vue/dynamic-resolver'; -export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { - return schema; +export function schemaResolver( + resolver: DynamicResolver, + schema: Record, + context: Record +): Record { + return schema; } diff --git a/packages/mobile-ui-vue/components/radio/src/radio.component.tsx b/packages/mobile-ui-vue/components/radio/src/radio.component.tsx index fb7a6bf9ff8..1d6c235b1ea 100644 --- a/packages/mobile-ui-vue/components/radio/src/radio.component.tsx +++ b/packages/mobile-ui-vue/components/radio/src/radio.component.tsx @@ -15,7 +15,7 @@ */ import { defineComponent } from 'vue'; -import { Checker, CheckerRoleMap, CheckerShapeMap } from '@farris/mobile-ui-vue/checker'; +import { Checker, CheckerRole, CheckerShape } from '@farris/mobile-ui-vue/checker'; import { useBem, useLink } from '@farris/mobile-ui-vue/common'; import { RADIO_GROUP_NAME, RadioGroupContext } from '@farris/mobile-ui-vue/radio-group'; import { RADIO_NAME, RadioProps, radioProps } from './radio.props'; @@ -45,10 +45,10 @@ export default defineComponent({ : props.modelValue; return ( , default: CheckerRole.Radio }, + + shape: { type: String as PropType, default: CheckerShape.Round }, }; export type RadioProps = ExtractPropTypes; -- Gitee From f6152d9b3134977113fbd4a3a78ee4e5297d5700 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Wed, 16 Apr 2025 14:15:08 +0800 Subject: [PATCH 242/287] =?UTF-8?q?fix:=20=E7=A7=BB=E5=8A=A8radio=E5=8F=8A?= =?UTF-8?q?checkbox=E8=AE=BE=E8=AE=A1=E6=97=B6=E5=B1=9E=E6=80=A7=E8=A1=A5?= =?UTF-8?q?=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/property-config/checkbox-group.property-config.ts | 1 - .../components/common/src/properties/schema-dom-mapping.ts | 3 ++- .../components/date-picker/src/schema/schema-mapper.ts | 2 +- .../src/property-config/date-picker.property-config.ts | 2 +- .../components/date-time-picker/src/schema/schema-mapper.ts | 2 +- .../src/property-config/radio-group.property-config.ts | 1 - .../radio-group/src/schema/radio-group.schema.json | 5 +++++ .../textarea/src/property-config/textarea.property-config.ts | 2 +- 8 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts b/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts index 08de93cf4d8..66d4c07288c 100644 --- a/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts +++ b/packages/mobile-ui-vue/components/checkbox-group/src/property-config/checkbox-group.property-config.ts @@ -18,7 +18,6 @@ export class CheckBoxGroupProperty extends InputBaseProperty { description: '', title: '数据', type: 'array', - $converter: '/converter/enum-data.converter', ...self.getItemCollectionEditor( propertyData, propertyData.editor.valueField, diff --git a/packages/mobile-ui-vue/components/common/src/properties/schema-dom-mapping.ts b/packages/mobile-ui-vue/components/common/src/properties/schema-dom-mapping.ts index 6dcc589367d..0ae16cfa3e0 100644 --- a/packages/mobile-ui-vue/components/common/src/properties/schema-dom-mapping.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/schema-dom-mapping.ts @@ -36,7 +36,8 @@ export class SchemaDOMMapping { { key: DgControl['date-picker'].type, value: DgControl['date-picker'].name } ], DateTime: [ - { key: DgControl['date-picker'].type, value: DgControl['date-picker'].name } + { key: DgControl['date-picker'].type, value: DgControl['date-picker'].name }, + { key: DgControl['datetime-picker'].type, value: DgControl['datetime-picker'].name } ], Boolean: [ { key: DgControl['switch'].type, value: DgControl['switch'].name }, diff --git a/packages/mobile-ui-vue/components/date-picker/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/date-picker/src/schema/schema-mapper.ts index 70f3c0e7744..728769ef54e 100644 --- a/packages/mobile-ui-vue/components/date-picker/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/date-picker/src/schema/schema-mapper.ts @@ -3,5 +3,5 @@ import { MapperFunction, resolveAppearance } from '@farris/mobile-ui-vue/dynamic export const schemaMapper = new Map([ ['appearance', resolveAppearance], ['binding', 'modelValue'], - ['displayFormat','format'] + ['valueFormat','format'] ]); diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts b/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts index 5fd91541b73..482d93fac08 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts +++ b/packages/mobile-ui-vue/components/date-time-picker/src/property-config/date-picker.property-config.ts @@ -10,7 +10,7 @@ export class DateTimePickerProperty extends InputBaseProperty { const displayFormatOptions = this.getDateFormatOptions(propertyData?.editor); return this.getComponentConfig( propertyData, - {}, + { type: 'datetime-picker' }, { title: { description: '', diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/date-time-picker/src/schema/schema-mapper.ts index a14506b5dd6..35c0af70ce5 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/date-time-picker/src/schema/schema-mapper.ts @@ -3,6 +3,6 @@ import { MapperFunction, resolveAppearance } from '@farris/mobile-ui-vue/dynamic export const schemaMapper = new Map([ ['appearance', resolveAppearance], ['binding', 'modelValue'], - ['displayFormat','format'] + ['valueFormat','format'] ]); diff --git a/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts b/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts index 066c73425c9..705b099375e 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts +++ b/packages/mobile-ui-vue/components/radio-group/src/property-config/radio-group.property-config.ts @@ -21,7 +21,6 @@ export class RadioGroupProperty extends InputBaseProperty { description: '', title: '数据', type: 'array', - $converter: '/converter/enum-data.converter', ...self.getItemCollectionEditor( propertyData, propertyData.editor.valueField, diff --git a/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json b/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json index f0f9b950068..d993339cf0d 100644 --- a/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json +++ b/packages/mobile-ui-vue/components/radio-group/src/schema/radio-group.schema.json @@ -32,6 +32,11 @@ "type": "object", "default": {} }, + "required": { + "description": "必填", + "type": "boolean", + "default": false + }, "readonly": { "type": "string", "default": false diff --git a/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts b/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts index 4992591ddb6..bf92847b94a 100644 --- a/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts +++ b/packages/mobile-ui-vue/components/textarea/src/property-config/textarea.property-config.ts @@ -26,7 +26,7 @@ export class TextareaProperty extends InputBaseProperty { }, maxLength: { description: '最大字数', - title: '最大长度', + title: '最大字数', type: 'number', editor: { nullable: true -- Gitee From e82e1f2a31e8b6355263e63c8fce9345fdaffc74 Mon Sep 17 00:00:00 2001 From: LuPing Zou <“zouluping@inspur.com”> Date: Wed, 16 Apr 2025 09:08:20 +0800 Subject: [PATCH 243/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E7=AB=AFC?= =?UTF-8?q?ard=E6=8E=A7=E4=BB=B6=E8=AE=BE=E8=AE=A1=E6=97=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../use-mobile-designer-context.ts | 4 +- .../mobile-ui-vue/components/card/index.ts | 19 ++---- .../components/card/src/card.component.tsx | 11 +++- .../components/card/src/card.props.ts | 5 +- .../src/designer/card.design.component.tsx | 40 ++++++++++++ .../card/src/designer/use-designer-rules.ts | 41 ++++++++++++ .../property-config/card.property-config.ts | 28 +++++++++ .../card/src/schema/card.schema.json | 41 +++++++++--- .../card/src/schema/schema-mapper.ts | 4 +- .../use-designer-component.ts | 3 + .../src/properties/container-base-property.ts | 62 +++++++++++++++++++ .../common/src/properties/dg-control.ts | 8 ++- .../common/src/types/designer-component.ts | 2 +- .../common/src/types/designer-rule.ts | 7 ++- .../src/designer/use-designer-rules.ts | 27 +++++++- .../content-container.property-config.ts | 2 +- .../src/designer/use-designer-rules.ts | 28 ++------- .../src/schema/float-container.schema.json | 8 ++- .../src/designer/use-designer-rules.ts | 6 +- .../src/designer/use-designer-rules.ts | 8 ++- .../src/designer/use-designer-rules.ts | 9 ++- .../src/designer/use-designer-rules.ts | 9 ++- .../components/register-designer.ts | 2 +- packages/mobile-ui-vue/components/register.ts | 3 +- 24 files changed, 309 insertions(+), 68 deletions(-) create mode 100644 packages/mobile-ui-vue/components/card/src/designer/card.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/card/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/card/src/property-config/card.property-config.ts diff --git a/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts b/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts index e3da548d7ae..9b7b3bc8a30 100644 --- a/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts +++ b/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts @@ -4,7 +4,7 @@ import SupportedControllers from '../../composition/command/supported-controller import { Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, Picker, NumberInput, Textarea, DatePicker, DateTimePicker, - ContentContainer, FloatContainer, Navbar, ListView, Form, FormItem, InputGroup, Button, registerDesignerComponents, Switch, CheckboxGroup, RadioGroup, + ContentContainer, Card, FloatContainer, Navbar, ListView, Form, FormItem, InputGroup, Button, registerDesignerComponents, Switch, CheckboxGroup, RadioGroup, } from '@farris/mobile-ui-vue'; import { useMobileControlCreator } from "../control-creator/use-mobile-control-creator"; import { FormComponent, UseFormSchema } from "../../../components/types"; @@ -21,7 +21,7 @@ export function useMobileDesignerContext(): UseDesignerContext { /** 要注册的UI组件 */ const componentsToRegister: any[] = [ Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, - ContentContainer, FloatContainer,Textarea,DatePicker,DateTimePicker, + ContentContainer, Card, FloatContainer,Textarea,DatePicker,DateTimePicker, Navbar, ListView,Picker,NumberInput,Switch,CheckboxGroup,RadioGroup, Form, FormItem, InputGroup, Button diff --git a/packages/mobile-ui-vue/components/card/index.ts b/packages/mobile-ui-vue/components/card/index.ts index 92b7b6fd0cd..9f7c7702a59 100644 --- a/packages/mobile-ui-vue/components/card/index.ts +++ b/packages/mobile-ui-vue/components/card/index.ts @@ -1,22 +1,15 @@ -import { Plugin } from 'vue'; -import { withInstall } from '@farris/mobile-ui-vue/common'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import CardInstallless from './src/card.component'; -import { propsResolver } from './src/card.props'; +import { propsResolverGenerator } from './src/card.props'; +import CardDesign from './src/designer/card.design.component'; const CARD_REGISTERED_NAME = 'card'; const Card = withInstall(CardInstallless); -Card.register = ( - componentMap: Record, - propsResolverMap: Record, - configResolverMap: Record, - resolverMap: Record, -) => { - componentMap[CARD_REGISTERED_NAME] = Card; - propsResolverMap[CARD_REGISTERED_NAME] = propsResolver; -}; +withRegister(Card, { name: CARD_REGISTERED_NAME, propsResolverGenerator }); +withRegisterDesigner(Card, { name: CARD_REGISTERED_NAME, propsResolverGenerator, designerComponent: CardDesign }); export * from './src/card.props'; export { Card }; -export default Card as typeof Card & Plugin; +export default Card; diff --git a/packages/mobile-ui-vue/components/card/src/card.component.tsx b/packages/mobile-ui-vue/components/card/src/card.component.tsx index e03ab80aa91..94e9eee1dfe 100644 --- a/packages/mobile-ui-vue/components/card/src/card.component.tsx +++ b/packages/mobile-ui-vue/components/card/src/card.component.tsx @@ -1,4 +1,4 @@ -import { defineComponent, computed } from 'vue'; +import { defineComponent, ref, computed } from 'vue'; import { useBem } from '@farris/mobile-ui-vue/common'; import { ButtonGroup } from '@farris/mobile-ui-vue/button-group'; import { CARD_NAME, cardProps, CardProps } from './card.props'; @@ -10,6 +10,7 @@ export default defineComponent({ setup(props: CardProps, context) { const { bem } = useBem(CARD_NAME); const { slots } = context; + const elementRef = ref(); const toolbarItemCount = computed(() => props.toolbarItems?.length ?? 0); @@ -23,6 +24,8 @@ export default defineComponent({ return props.showFooter && !isFooterEmpty; }); + context.expose({ elementRef }); + function renderHeader() { if (slots.header) { return slots.header(); @@ -58,7 +61,11 @@ export default defineComponent({ } return () => ( -
    +
    {shouldRenderHeader.value && renderHeader()} {renderContent()} {shouldRenderFooter.value && renderFooter()} diff --git a/packages/mobile-ui-vue/components/card/src/card.props.ts b/packages/mobile-ui-vue/components/card/src/card.props.ts index 62957ef6da7..5b5499cb584 100644 --- a/packages/mobile-ui-vue/components/card/src/card.props.ts +++ b/packages/mobile-ui-vue/components/card/src/card.props.ts @@ -20,9 +20,12 @@ export const cardProps = { /** 按钮工具栏 */ toolbarItems: { type: Array, default: [] }, + + customClass: { type: String, default: '' }, + customStyle: { type: String, default: '' }, }; -export const propsResolver = getPropsResolverGenerator( +export const propsResolverGenerator = getPropsResolverGenerator( cardProps, cardSchema, schemaMapper, diff --git a/packages/mobile-ui-vue/components/card/src/designer/card.design.component.tsx b/packages/mobile-ui-vue/components/card/src/designer/card.design.component.tsx new file mode 100644 index 00000000000..babedc37e2d --- /dev/null +++ b/packages/mobile-ui-vue/components/card/src/designer/card.design.component.tsx @@ -0,0 +1,40 @@ +import { computed, defineComponent, inject, onMounted, ref } from 'vue'; +import { cardProps, CardProps } from '../card.props'; +import { useDesignerRulesForCard } from './use-designer-rules'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common'; +import { Card } from '@farris/mobile-ui-vue/card'; + +export default defineComponent({ + name: 'FCardDesign', + props: cardProps, + emits: [], + setup(props: CardProps, context) { + const cardRef = ref(); + const elementRef = computed(() => { + return cardRef.value?.elementRef; + }); + + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useDesignerRulesForCard(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + context.expose(componentInstance.value); + + return () => { + return ( + + {context.slots.default && context.slots.default()} + + ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/card/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/card/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..e0e932536a5 --- /dev/null +++ b/packages/mobile-ui-vue/components/card/src/designer/use-designer-rules.ts @@ -0,0 +1,41 @@ +import { DesignerItemContext } from "@farris/mobile-ui-vue/common"; +import { CardProperty } from "../property-config/card.property-config"; +import { DesignerHostService, DraggingResolveContext, UseDesignerRules } from "@farris/mobile-ui-vue/common"; + +export function useDesignerRulesForCard(designItemContext: DesignerItemContext, designerHostService?: DesignerHostService): UseDesignerRules { + + function canAccepts(draggingContext: DraggingResolveContext): boolean { + return true; + } + + function getStyles() { + return ''; + } + + function checkCanMoveComponent() { + return true; + } + + function checkCanDeleteComponent() { + return true; + } + + function hideNestedPaddingInDesginerView() { + return true; + } + + function getPropsConfig(componentId: string) { + const componentProp = new CardProperty(componentId, designerHostService); + const { schema } = designItemContext; + return componentProp.getPropertyConfig(schema); + } + + return { + canAccepts, + getStyles, + checkCanMoveComponent, + checkCanDeleteComponent, + hideNestedPaddingInDesginerView, + getPropsConfig + }; +} diff --git a/packages/mobile-ui-vue/components/card/src/property-config/card.property-config.ts b/packages/mobile-ui-vue/components/card/src/property-config/card.property-config.ts new file mode 100644 index 00000000000..89e883bca74 --- /dev/null +++ b/packages/mobile-ui-vue/components/card/src/property-config/card.property-config.ts @@ -0,0 +1,28 @@ +import { ContainerBaseProperty } from "@farris/mobile-ui-vue/common"; + +export class CardProperty extends ContainerBaseProperty { + + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + public getPropertyConfig(propertyData: any) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData, { showTitle: true }); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + // 行为 + this.propertyConfig.categories['behavior'] = this.getBehaviorConfig(propertyData); + + return this.propertyConfig; + } + + protected getAppearanceConfig(propertyData: any) { + return { + title: "外观", + description: "Appearance", + properties: this.getAppearanceProperties(["style", "padding", "margin"], propertyData), + }; + } + +} diff --git a/packages/mobile-ui-vue/components/card/src/schema/card.schema.json b/packages/mobile-ui-vue/components/card/src/schema/card.schema.json index 4d1160f7ec4..008cf63cac8 100644 --- a/packages/mobile-ui-vue/components/card/src/schema/card.schema.json +++ b/packages/mobile-ui-vue/components/card/src/schema/card.schema.json @@ -14,10 +14,38 @@ "type": "string", "default": "card" }, + "contents": { + "description": "子组件集合", + "type": "array", + "default": [] + }, + "appearance": { + "description": "外观", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "padding": { + "description": "内边距", + "type": "object", + "default": {} + }, + "margin": { + "description": "外边距", + "type": "object", + "default": {} + }, "title": { "description": "显示的标题", "type": "string", - "default": "" + "default": "卡片" }, "showHeader": { "description": "是否显示头部区域", @@ -28,15 +56,14 @@ "description": "是否显示尾部区域", "type": "boolean", "default": true - }, - "toolbarItems": { - "description": "按钮工具栏", - "type": "array", - "default": [] } }, "required": [ "id", - "type" + "type", + "title", + "contents", + "showHeader", + "showFooter" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/card/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/card/src/schema/schema-mapper.ts index 47415f8117f..de0117f8568 100644 --- a/packages/mobile-ui-vue/components/card/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/card/src/schema/schema-mapper.ts @@ -1,5 +1,7 @@ -import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; +import { resolveAppearance, resolvePadding, resolveMargin, MapperFunction } from '../../../dynamic-resolver'; export const schemaMapper = new Map([ ['appearance', resolveAppearance], + ['padding', resolvePadding], + ['margin', resolveMargin], ]); diff --git a/packages/mobile-ui-vue/components/common/src/compositions/use-designer-component/use-designer-component.ts b/packages/mobile-ui-vue/components/common/src/compositions/use-designer-component/use-designer-component.ts index 0c31d5f8fd8..7d820cfddb9 100644 --- a/packages/mobile-ui-vue/components/common/src/compositions/use-designer-component/use-designer-component.ts +++ b/packages/mobile-ui-vue/components/common/src/compositions/use-designer-component/use-designer-component.ts @@ -78,6 +78,9 @@ export function useDesignerComponent( } function getDraggableDesignItemElement(context: DesignerItemContext = designItemContext as DesignerItemContext): Ref | null { + if (designerRules?.getDraggableDesignItemElement) { + return designerRules.getDraggableDesignItemElement(context); + } const { componentInstance, designerItemElementRef } = context; if (!componentInstance || !componentInstance.value) { return null; diff --git a/packages/mobile-ui-vue/components/common/src/properties/container-base-property.ts b/packages/mobile-ui-vue/components/common/src/properties/container-base-property.ts index ef59c1314d0..dac188cef7d 100644 --- a/packages/mobile-ui-vue/components/common/src/properties/container-base-property.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/container-base-property.ts @@ -1,6 +1,11 @@ import { BaseControlProperty } from "./base-property"; +import { DgControl } from "./dg-control"; import { sizeConverter, paddingConverter, marginConverter, positionConverter, borderRadiusConverter } from "./converter/cascade.converter"; +interface BasicPropOptional { + showTitle?: boolean; +} + export class ContainerBaseProperty extends BaseControlProperty { constructor(componentId: string, designerHostService: any) { @@ -305,4 +310,61 @@ export class ContainerBaseProperty extends BaseControlProperty { }; } + public getBasicPropConfig(propertyData: any, optional?: BasicPropOptional) { + const optionalProperties = [ + { + id: { + description: '组件标识', + title: '标识', + type: 'string', + readonly: true + } + }, + optional?.showTitle && { + title: { + description: '组件名称', + title: "名称", + type: "string", + } + }, + { + type: { + description: '组件类型', + title: '控件类型', + type: 'select', + editor: { + type: 'combo-list', + textField: 'name', + valueField: 'value', + idField: 'value', + editable: false, + data: [{ + value: propertyData.type, + name: DgControl[propertyData.type] && DgControl[propertyData.type].name + }], + } + } + }, + ]; + const properties = optionalProperties.filter((property) => { + return typeof property === 'object' && !!property; + }).reduce((result, newProperty) => { + return Object.assign(result, newProperty); + }, {}); + return { + description: 'Basic Information', + title: '基本信息', + properties, + setPropertyRelates(changeObject: any) { + const propertyID = changeObject?.propertyID; + if (!propertyID) { + return; + } + if (propertyID === 'title') { + changeObject.needRefreshControlTree = true; + } + }, + }; + } + } diff --git a/packages/mobile-ui-vue/components/common/src/properties/dg-control.ts b/packages/mobile-ui-vue/components/common/src/properties/dg-control.ts index e230774a9f9..ad7cb877589 100644 --- a/packages/mobile-ui-vue/components/common/src/properties/dg-control.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/dg-control.ts @@ -1,4 +1,5 @@ -export const DgControl = { +export const DgControl = { + 'module': { type: 'Module', name: '模块', icon: 'Module' }, 'component': { type: 'component', name: '组件', icon: 'Component' }, @@ -15,6 +16,8 @@ export const DgControl = { 'float-container': { type: 'float-container', name: '浮动容器', icon: 'ContentContainer' }, + 'card': { type: 'card', name: '卡片', icon: 'section' }, + 'list-view': { type: 'list-view', name: '列表', icon: 'ListView' }, 'button': { type: 'button', name: '按钮', icon: 'Button' }, @@ -36,7 +39,7 @@ export const DgControl = { 'radio-group': { type: 'radio-group', name: '单选组', icon: 'RadioGroup' }, 'check-group': { type: 'check-group', name: '多选组', icon: 'CheckGroup' }, - + 'check-box': { type: 'check-box', name: '复选框', icon: 'CheckBox' }, 'combo-list': { type: 'combo-list', name: '下拉列表', icon: 'EnumField' }, @@ -46,5 +49,4 @@ export const DgControl = { 'navbar': { type: 'navbar', name: '导航栏', icon: 'NavBar' }, 'picker': { type: 'picker', name: '选择器', icon: 'EnumField' }, - }; diff --git a/packages/mobile-ui-vue/components/common/src/types/designer-component.ts b/packages/mobile-ui-vue/components/common/src/types/designer-component.ts index 6ca1bb9c26e..f30ca3c44d4 100644 --- a/packages/mobile-ui-vue/components/common/src/types/designer-component.ts +++ b/packages/mobile-ui-vue/components/common/src/types/designer-component.ts @@ -78,7 +78,7 @@ export interface DesignerComponentInstance { getCustomButtons?: () => DesignerComponentButton[]; /** 控件属性变更后事件 */ - onPropertyChanged?: (event:any) => void; + onPropertyChanged?: (event: any) => void; } export interface DesignerItemContext { diff --git a/packages/mobile-ui-vue/components/common/src/types/designer-rule.ts b/packages/mobile-ui-vue/components/common/src/types/designer-rule.ts index ed261cb18f6..6375578d0fb 100644 --- a/packages/mobile-ui-vue/components/common/src/types/designer-rule.ts +++ b/packages/mobile-ui-vue/components/common/src/types/designer-rule.ts @@ -1,5 +1,5 @@ import { Ref } from "vue"; -import { ComponentSchema, DesignerComponentButton, DesignerComponentInstance } from "./designer-component"; +import { ComponentSchema, DesignerComponentButton, DesignerComponentInstance, DesignerItemContext } from "./designer-component"; import { DesignFormVariable, DesignViewModelField, FormSchemaEntity, FormSchemaEntityField } from "./entity-schema"; export interface DesignerHTMLElement extends HTMLElement { @@ -143,5 +143,8 @@ export interface UseDesignerRules { getCustomButtons?: () => DesignerComponentButton[]; /** 控件属性变更后事件 */ - onPropertyChanged?: (event:any) => void; + onPropertyChanged?: (event: any) => void; + + /** 获取可拖拽的上层容器 */ + getDraggableDesignItemElement?: (context: DesignerItemContext) => Ref | null; } diff --git a/packages/mobile-ui-vue/components/component/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/component/src/designer/use-designer-rules.ts index e0d0aef98ea..42ed7e2a757 100644 --- a/packages/mobile-ui-vue/components/component/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/component/src/designer/use-designer-rules.ts @@ -11,10 +11,16 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe } function checkCanDeleteComponent() { - return false; + if (designItemContext?.schema?.componentType === 'page') { + return false; + } + return true; } function checkCanMoveComponent() { + if (designItemContext?.schema?.componentType === 'page') { + return false; + } return true; } @@ -23,6 +29,10 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe } function getStyles(): string { + const componentType = designItemContext?.schema?.componentType; + if (componentType === 'page') { + return `flex: 1;position: relative;`; + } return ''; } @@ -121,5 +131,18 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe removeViewModelComponent(); } - return { canAccepts, checkCanDeleteComponent, checkCanMoveComponent, hideNestedPaddingInDesginerView, getStyles, getPropsConfig, onRemoveComponent }; + function getDraggableDesignItemElement(context: DesignerItemContext) { + return context.designerItemElementRef; + } + + return { + canAccepts, + checkCanDeleteComponent, + checkCanMoveComponent, + hideNestedPaddingInDesginerView, + getStyles, + getPropsConfig, + onRemoveComponent, + getDraggableDesignItemElement, + }; } diff --git a/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts b/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts index 8ec6e2b8e68..b99dd69f138 100644 --- a/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts +++ b/packages/mobile-ui-vue/components/content-container/src/property-config/content-container.property-config.ts @@ -8,7 +8,7 @@ export class ContentContainerProperty extends ContainerBaseProperty { public getPropertyConfig(propertyData: any) { // 基本信息 - this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData, { showTitle: true }); // 外观 this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); // 布局 diff --git a/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts index 19d7cd0b4b0..635dc2a1615 100644 --- a/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/float-container/src/designer/use-designer-rules.ts @@ -25,27 +25,6 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe const schema = ref(designItemContext.schema); function canAccepts(draggingContext: DraggingResolveContext): boolean { - const acceptableControlTypes = [ - 'navbar', - 'content-container', - 'html-template', - ]; - const uniqueControlTypes = [ - 'navbar', - ]; - const { sourceType, parentComponentInstance } = draggingContext; - if (!acceptableControlTypes.includes(sourceType)) { - return false; - } - const shouldBeUnique = uniqueControlTypes.includes(sourceType); - if (shouldBeUnique) { - const parentComponent = parentComponentInstance?.parent?.value; - const contents: any[] = parentComponent?.contents || []; - const hasSameTypeControl = !!contents.find((content) => content.type === sourceType); - if (hasSameTypeControl) { - return false; - } - } return true; } @@ -94,6 +73,10 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe return componentProp.getPropertyConfig(schema); } + function getDraggableDesignItemElement(context: DesignerItemContext) { + return context.designerItemElementRef; + } + return { canAccepts, checkCanMoveComponent, @@ -101,6 +84,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe hideNestedPaddingInDesginerView, getDesignerClass, getStyles, - getPropsConfig + getPropsConfig, + getDraggableDesignItemElement, }; } 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 index 555410aec02..6189e397e38 100644 --- 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 @@ -35,7 +35,10 @@ "position": { "description": "", "type": "object", - "default": {} + "default": { + "right": 30, + "bottom": 60 + } }, "size": { "description": "", @@ -51,6 +54,7 @@ "required": [ "id", "type", - "contents" + "contents", + "position" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/page-body-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/page-body-container/src/designer/use-designer-rules.ts index 9f065533d83..c94334a2b7c 100644 --- a/packages/mobile-ui-vue/components/page-body-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/page-body-container/src/designer/use-designer-rules.ts @@ -54,6 +54,9 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe return componentProp.getPropertyConfig(schema); } + function getDraggableDesignItemElement(context: DesignerItemContext) { + return context.designerItemElementRef; + } return { canAccepts, @@ -63,6 +66,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe checkCanDeleteComponent, hideNestedPaddingInDesginerView, getDesignerClass, - getPropsConfig + getPropsConfig, + getDraggableDesignItemElement, }; } diff --git a/packages/mobile-ui-vue/components/page-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/page-container/src/designer/use-designer-rules.ts index c4c351beae7..efe4894171d 100644 --- a/packages/mobile-ui-vue/components/page-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/page-container/src/designer/use-designer-rules.ts @@ -62,7 +62,6 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe return PAGE_CONTAINER_NAME; } - /** * 获取属性配置 */ @@ -72,6 +71,10 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe return componentProp.getPropertyConfig(schema); } + function getDraggableDesignItemElement(context: DesignerItemContext) { + return context.designerItemElementRef; + } + return { canAccepts, triggerBelongedComponentToMoveWhenMoved, @@ -81,6 +84,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe hideNestedPaddingInDesginerView, getStyles, getDesignerClass, - getPropsConfig + getPropsConfig, + getDraggableDesignItemElement, }; } diff --git a/packages/mobile-ui-vue/components/page-footer-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/page-footer-container/src/designer/use-designer-rules.ts index 1f356be804a..2020dc0f0eb 100644 --- a/packages/mobile-ui-vue/components/page-footer-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/page-footer-container/src/designer/use-designer-rules.ts @@ -39,7 +39,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe } function getDesignerClass(): string { - return PAGE_FOOTER_CONTAINER_NAME; + return `${PAGE_FOOTER_CONTAINER_NAME} position-relative`; } /** @@ -51,6 +51,10 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe return componentProp.getPropertyConfig(schema); } + function getDraggableDesignItemElement(context: DesignerItemContext) { + return context.designerItemElementRef; + } + return { canAccepts, triggerBelongedComponentToMoveWhenMoved, @@ -59,6 +63,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe checkCanDeleteComponent, hideNestedPaddingInDesginerView, getDesignerClass, - getPropsConfig + getPropsConfig, + getDraggableDesignItemElement, }; } diff --git a/packages/mobile-ui-vue/components/page-header-container/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/page-header-container/src/designer/use-designer-rules.ts index a77016a4d92..4015500d20a 100644 --- a/packages/mobile-ui-vue/components/page-header-container/src/designer/use-designer-rules.ts +++ b/packages/mobile-ui-vue/components/page-header-container/src/designer/use-designer-rules.ts @@ -50,7 +50,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe } function getDesignerClass(): string { - return PAGE_HEADER_CONTAINER_NAME; + return `${PAGE_HEADER_CONTAINER_NAME} position-relative`; } /** @@ -62,6 +62,10 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe return componentProp.getPropertyConfig(schema); } + function getDraggableDesignItemElement(context: DesignerItemContext) { + return context.designerItemElementRef; + } + return { canAccepts, triggerBelongedComponentToMoveWhenMoved, @@ -70,6 +74,7 @@ export function useDesignerRules(designItemContext: DesignerItemContext, designe checkCanDeleteComponent, hideNestedPaddingInDesginerView, getDesignerClass, - getPropsConfig + getPropsConfig, + getDraggableDesignItemElement, }; } diff --git a/packages/mobile-ui-vue/components/register-designer.ts b/packages/mobile-ui-vue/components/register-designer.ts index 69cb383b457..a92dd6fd9b6 100644 --- a/packages/mobile-ui-vue/components/register-designer.ts +++ b/packages/mobile-ui-vue/components/register-designer.ts @@ -16,7 +16,7 @@ function registerDesignerComponents(components: any[]) { } componentsRegistered = true; - const registerContext:RegisterContext = { + const registerContext: RegisterContext = { schemaMap: schemaMapForDesigner, propertyConfigSchemaMap: propertyConfigSchemaMapForDesigner, propertyEffectMap: propertyEffectMapForDesigner, diff --git a/packages/mobile-ui-vue/components/register.ts b/packages/mobile-ui-vue/components/register.ts index c3ee8994d30..e56de043543 100644 --- a/packages/mobile-ui-vue/components/register.ts +++ b/packages/mobile-ui-vue/components/register.ts @@ -20,6 +20,7 @@ import PageHeaderContainer from './page-header-container'; import PageFooterContainer from './page-footer-container'; import Component from './component'; import ContentContainer from './content-container'; +import { Card } from './card'; import FloatContainer from './float-container'; import Listview from './list-view'; @@ -47,7 +48,7 @@ function registerComponents() { const componentsToRegister = [ Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, - ContentContainer, FloatContainer, + ContentContainer, FloatContainer, Card, Button, ButtonGroup, Navbar, Listview, Form, FormItem, InputGroup, Textarea, NumberInput, Switch, DatePicker, DateTimePicker, Picker ]; -- Gitee From 4c9b8458ffc1c996fb902ed6f81aa8d4278d6aa3 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Wed, 16 Apr 2025 20:29:04 +0800 Subject: [PATCH 244/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E5=B8=AE?= =?UTF-8?q?=E5=8A=A9=E8=AE=BE=E8=AE=A1=E6=97=B6=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/designer/src/app-providers.ts | 5 +- .../use-mobile-designer-context.ts | 4 +- .../src/schema/datetime-picker.schema.json | 160 ++++++------- packages/mobile-ui-vue/components/designer.ts | 1 + packages/mobile-ui-vue/components/index.ts | 3 + .../components/input-group/index.ts | 2 - .../designer/input-group.design.component.tsx | 3 +- .../src/designer/input-group.design.props.ts | 7 - .../mobile-ui-vue/components/lookup/index.ts | 13 +- .../src/components/footer.component.tsx | 4 +- .../src/composition/use-render-component.tsx | 4 +- .../src/designer/lookup.design.component.tsx | 42 ++++ .../lookup/src/designer/use-designer-rules.ts | 15 ++ .../components/lookup/src/lookup.props.ts | 6 + .../converters/lookup-property.converter.ts | 119 ++++++++++ .../property-config/lookup.property-config.ts | 219 ++++++++++++++++++ .../lookup/src/schema/lookup.schema.json | 120 ++++++++++ .../lookup/src/schema/schema-mapper.ts | 35 +++ .../lookup/src/schema/schema-resolver.ts | 5 + .../mobile-ui-vue/components/picker/index.ts | 2 +- .../picker/src/schema/picker.schema.json | 2 +- 21 files changed, 666 insertions(+), 105 deletions(-) delete mode 100644 packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.props.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/designer/lookup.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/lookup/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/property-config/converters/lookup-property.converter.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/property-config/lookup.property-config.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/schema/lookup.schema.json create mode 100644 packages/mobile-ui-vue/components/lookup/src/schema/schema-mapper.ts create mode 100644 packages/mobile-ui-vue/components/lookup/src/schema/schema-resolver.ts diff --git a/packages/designer/src/app-providers.ts b/packages/designer/src/app-providers.ts index ffd9aed5702..71db35c8b35 100644 --- a/packages/designer/src/app-providers.ts +++ b/packages/designer/src/app-providers.ts @@ -1,6 +1,7 @@ -import { FLoadingService, FTooltipDirective, FMessageBoxService, F_MODAL_SERVICE_TOKEN, FModalService, LookupSchemaRepositoryToken, FieldSelectorRepositoryToken, F_NOTIFY_SERVICE_TOKEN, FNotifyService, ControllerSchemaRepositorySymbol, FormSchemaRepositorySymbol } from "@farris/ui-vue/components"; import { App } from "vue"; +import { FLoadingService, FTooltipDirective, FMessageBoxService, F_MODAL_SERVICE_TOKEN, FModalService, LookupSchemaRepositoryToken, FieldSelectorRepositoryToken, F_NOTIFY_SERVICE_TOKEN, FNotifyService, ControllerSchemaRepositorySymbol, FormSchemaRepositorySymbol } from "@farris/ui-vue/components"; +import { LookupSchemaRepositoryToken as MobileLookupSchemaRepositoryToken, FieldSelectorRepositoryToken as MobileFieldSelectorRepositoryToken } from "@farris/mobile-ui-vue"; import { MetadataService } from "./components/composition/metadata.service"; import { MetadataPathToken, MetadataServiceToken } from "./components/types"; import { LookupFieldSelectorService, LookupSchemaService } from "./components/composition/schema-repository"; @@ -26,6 +27,8 @@ export default { app.provide(LookupSchemaRepositoryToken, new LookupSchemaService(metadataService)); app.provide(FieldSelectorRepositoryToken, new LookupFieldSelectorService(metadataService)); + app.provide(MobileLookupSchemaRepositoryToken, new LookupSchemaService(metadataService)); + app.provide(MobileFieldSelectorRepositoryToken, new LookupFieldSelectorService(metadataService)); app.provide(F_NOTIFY_SERVICE_TOKEN, new FNotifyService()); app.provide(ControllerSchemaRepositorySymbol, new ControllerSelectorSchemaService(metadataService,designerContext)); app.provide(FormSchemaRepositorySymbol, new FormSelectorSchemaService(metadataService)); diff --git a/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts b/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts index e3da548d7ae..5fbd807d013 100644 --- a/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts +++ b/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts @@ -3,7 +3,7 @@ import ToolboxItems from '../../types/toolbox/mobile-toolbox.json'; import SupportedControllers from '../../composition/command/supported-controllers/mobile-supported-controller.json'; import { - Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, Picker, NumberInput, Textarea, DatePicker, DateTimePicker, + Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, Picker, NumberInput, Textarea, DatePicker, DateTimePicker, Lookup, ContentContainer, FloatContainer, Navbar, ListView, Form, FormItem, InputGroup, Button, registerDesignerComponents, Switch, CheckboxGroup, RadioGroup, } from '@farris/mobile-ui-vue'; import { useMobileControlCreator } from "../control-creator/use-mobile-control-creator"; @@ -21,7 +21,7 @@ export function useMobileDesignerContext(): UseDesignerContext { /** 要注册的UI组件 */ const componentsToRegister: any[] = [ Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, - ContentContainer, FloatContainer,Textarea,DatePicker,DateTimePicker, + ContentContainer, FloatContainer,Textarea,DatePicker,DateTimePicker,Lookup, Navbar, ListView,Picker,NumberInput,Switch,CheckboxGroup,RadioGroup, Form, FormItem, InputGroup, Button diff --git a/packages/mobile-ui-vue/components/date-time-picker/src/schema/datetime-picker.schema.json b/packages/mobile-ui-vue/components/date-time-picker/src/schema/datetime-picker.schema.json index 73f07942ace..d254d0e16d9 100644 --- a/packages/mobile-ui-vue/components/date-time-picker/src/schema/datetime-picker.schema.json +++ b/packages/mobile-ui-vue/components/date-time-picker/src/schema/datetime-picker.schema.json @@ -1,88 +1,80 @@ { - "$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": "datetime-picker" - }, - "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" + "$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": "datetime-picker" + }, + "appearance": { + "description": "外观", + "type": "object", + "properties": { + "class": { + "type": "string" }, - "onUpdate:modelValue": { - "description": "值更新事件", - "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" }, - "events": [ - "onUpdate:modelValue" - ], - "required": [ - "type" - ], - "ignore": [ - "id", - "type", - "appearance" - ] -} \ No newline at end of file + "onUpdate:modelValue": { + "description": "值更新事件", + "type": "string" + } + }, + "events": ["onUpdate:modelValue"], + "required": ["type"], + "ignore": ["id", "appearance", "binding", "visible"] +} diff --git a/packages/mobile-ui-vue/components/designer.ts b/packages/mobile-ui-vue/components/designer.ts index 13f136e5afd..49fc635cbda 100644 --- a/packages/mobile-ui-vue/components/designer.ts +++ b/packages/mobile-ui-vue/components/designer.ts @@ -1,2 +1,3 @@ export * from './dynamic-resolver'; export * from './register-designer'; +export { LookupSchemaRepositoryToken, FieldSelectorRepositoryToken } from './lookup'; diff --git a/packages/mobile-ui-vue/components/index.ts b/packages/mobile-ui-vue/components/index.ts index c9268ed1ad0..8078076ff25 100644 --- a/packages/mobile-ui-vue/components/index.ts +++ b/packages/mobile-ui-vue/components/index.ts @@ -32,6 +32,7 @@ import Loading from './loading'; import PullRefresh from './pull-refresh'; import List from './list'; import ListView from './list-view'; +import Lookup from './lookup'; import TabBar from "./tab-bar"; import SwipeCell from './swipe-cell'; import ActionSheet from './action-sheet'; @@ -92,6 +93,7 @@ const components = [ PullRefresh, List, ListView, + Lookup, SwipeCell, ActionSheet, Tabs, @@ -154,6 +156,7 @@ export { PullRefresh, List, ListView, + Lookup, SwipeCell, ActionSheet, Tabs, diff --git a/packages/mobile-ui-vue/components/input-group/index.ts b/packages/mobile-ui-vue/components/input-group/index.ts index a9c8bff602c..bead9f222b0 100644 --- a/packages/mobile-ui-vue/components/input-group/index.ts +++ b/packages/mobile-ui-vue/components/input-group/index.ts @@ -13,7 +13,5 @@ withRegisterDesigner(InputGroup, { name: INPUT_GROUP_REGISTERED_NAME, propsResol export * from './src/input-group.props'; export * from './src/types'; -export * from './src/designer/input-group.design.props'; - export { InputGroup }; export default InputGroup; diff --git a/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx b/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx index ebdf2badda9..052a1a13397 100644 --- a/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx +++ b/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.component.tsx @@ -21,9 +21,8 @@ import { useDesignerComponent } from '@farris/mobile-ui-vue/common'; import { useInputGroupDesignerRules } from './use-designer-rules'; -import { InputProps, inputProps } from '../input-group.props'; +import { inputProps } from '../input-group.props'; import InputGroup from '../input-group.component'; -import { inputDesignProps } from './input-group.design.props'; export default defineComponent({ name: 'FmInputGroupDesign', diff --git a/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.props.ts b/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.props.ts deleted file mode 100644 index b4dbda59adf..00000000000 --- a/packages/mobile-ui-vue/components/input-group/src/designer/input-group.design.props.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { inputProps } from "../input-group.props"; - -export const inputDesignProps = { - placeholder: inputProps.placeholder, - rows: inputProps.rows, - showWordLimit: inputProps.showWordLimit -}; diff --git a/packages/mobile-ui-vue/components/lookup/index.ts b/packages/mobile-ui-vue/components/lookup/index.ts index f51566db69f..885ec8fbd5e 100644 --- a/packages/mobile-ui-vue/components/lookup/index.ts +++ b/packages/mobile-ui-vue/components/lookup/index.ts @@ -1,9 +1,20 @@ -import { withInstall } from '@farris/mobile-ui-vue/common'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import LookupInstallless from './src/lookup.component'; import { LOOKUP_HTTP_SERVICE_TOKEN } from './src/lookup.props'; import { LookupDisplayType } from './src/composition'; +import { propsResolverGenerator } from './src/lookup.props'; +import LookupDesign from './src/designer/lookup.design.component'; + +export { LookupSchemaRepositoryToken, FieldSelectorRepositoryToken } from './src/property-config/lookup.property-config'; const Lookup = withInstall(LookupInstallless); +// 注册运行时及设计时 + +const LOOKUP_REGISTERED_NAME = 'lookup'; +withRegister(Lookup, { name: LOOKUP_REGISTERED_NAME, propsResolverGenerator }); +withRegisterDesigner(Lookup, { name: LOOKUP_REGISTERED_NAME, propsResolverGenerator, designerComponent: LookupDesign }); + + export { Lookup, LOOKUP_HTTP_SERVICE_TOKEN, LookupDisplayType }; export default Lookup; 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 index b5da66bcc9e..6840cf90720 100644 --- a/packages/mobile-ui-vue/components/lookup/src/components/footer.component.tsx +++ b/packages/mobile-ui-vue/components/lookup/src/components/footer.component.tsx @@ -1,6 +1,6 @@ import { computed, defineComponent } from 'vue'; import { useBem } from '@farris/mobile-ui-vue/common'; -import { Checker, CheckerShapeMap } from '@farris/mobile-ui-vue/checker'; +import { Checker, CheckerShape } from '@farris/mobile-ui-vue/checker'; import Button from '@farris/mobile-ui-vue/button'; import { useLookupPanelState } from '../composition'; import { LOOKUP_PANEL_NAME } from '../lookup-panel.props'; @@ -28,7 +28,7 @@ export default defineComponent({ class={bem('footer-checker')} label={isSelectedAllValue.value ? '取消全选' : '全选'} modelValue={isSelectedAllValue.value} - shape={CheckerShapeMap.Round} + shape={CheckerShape.Round} onChange={handleSelecteAll} >}
    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 3dbd6e6523f..6616b4583a1 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,6 +1,6 @@ import { computed } from "vue"; import { getValue, stopPropagation, useBem } from "@farris/mobile-ui-vue/common"; -import { Checker, CheckerShapeMap } from "@farris/mobile-ui-vue/checker"; +import { Checker, CheckerShape } from "@farris/mobile-ui-vue/checker"; import Icon from "@farris/mobile-ui-vue/icon"; import Cell from "@farris/mobile-ui-vue/cell"; import { ListDataItem, LookupDisplayType, UseRenderComponent } from "./types"; @@ -34,7 +34,7 @@ export const useRenderComponent: UseRenderComponent = (events) => { handleChange(item)} > ); diff --git a/packages/mobile-ui-vue/components/lookup/src/designer/lookup.design.component.tsx b/packages/mobile-ui-vue/components/lookup/src/designer/lookup.design.component.tsx new file mode 100644 index 00000000000..17407092fa7 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/designer/lookup.design.component.tsx @@ -0,0 +1,42 @@ +import { computed, defineComponent, inject, onMounted, ref } from 'vue'; +import { + DesignerHostService, + DesignerItemContext, + extractProperties, + useDesignerComponent +} from '@farris/mobile-ui-vue/common'; +import { lookupProps } from '../lookup.props'; +import { usePickerDesignerRules } from './use-designer-rules'; +import InputGroup from '@farris/mobile-ui-vue/input-group'; + +export default defineComponent({ + name: 'FmPickerDesign', + inheritAttrs: false, + props: extractProperties(lookupProps, ['placeholder']), + setup(props, context) { + const elementRef = ref(); + const designerHostService = inject('designer-host-service'); + const designItemContext = inject( + 'design-item-context' + ) as DesignerItemContext; + const designerRulesComposition = usePickerDesignerRules(designItemContext, designerHostService); + const componentInstance = useDesignerComponent( + elementRef, + designItemContext, + designerRulesComposition + ); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + + context.expose(componentInstance.value); + + const inputProps = computed(() => ({ + ...props, + editable: false + })); + + return () => ; + } +}); diff --git a/packages/mobile-ui-vue/components/lookup/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/lookup/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..9db02ba77e2 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/designer/use-designer-rules.ts @@ -0,0 +1,15 @@ +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext, UseDesignerRules } from "@farris/mobile-ui-vue/common"; +import { LookupProperty } from "../property-config/lookup.property-config"; +export function usePickerDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { + + const schema = designItemContext.schema as ComponentSchema; + + // 构造属性配置方法 + function getPropsConfig(componentId: string, componentInstance: DesignerComponentInstance) { + const lookupProps = new LookupProperty(componentId, designerHostService); + return lookupProps.getPropertyConfig(schema, componentInstance); + } + + return { getPropsConfig } as UseDesignerRules; + +} diff --git a/packages/mobile-ui-vue/components/lookup/src/lookup.props.ts b/packages/mobile-ui-vue/components/lookup/src/lookup.props.ts index 20fa4fbc3ed..aca051ceb15 100644 --- a/packages/mobile-ui-vue/components/lookup/src/lookup.props.ts +++ b/packages/mobile-ui-vue/components/lookup/src/lookup.props.ts @@ -1,6 +1,10 @@ import { ExtractPropTypes } from 'vue'; import { buttonEditProps } from '@farris/mobile-ui-vue/button-edit'; import { lookupPanelProps } from './lookup-panel.props'; +import { getPropsResolverGenerator } from '@farris/mobile-ui-vue/dynamic-resolver'; +import lookupSchema from './schema/lookup.schema.json'; +import { schemaMapper } from './schema/schema-mapper'; +import { schemaResolver } from './schema/schema-resolver'; export * from './lookup-panel.props'; @@ -12,3 +16,5 @@ export const lookupProps = { }; export type LookupProps = ExtractPropTypes; + +export const propsResolverGenerator = getPropsResolverGenerator(lookupProps, lookupSchema, schemaMapper, schemaResolver); diff --git a/packages/mobile-ui-vue/components/lookup/src/property-config/converters/lookup-property.converter.ts b/packages/mobile-ui-vue/components/lookup/src/property-config/converters/lookup-property.converter.ts new file mode 100644 index 00000000000..4980fd32460 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/property-config/converters/lookup-property.converter.ts @@ -0,0 +1,119 @@ +function generateSourceUri(ctrlId: string) { + let code = 'form_group_' + Date.now(); + if (ctrlId) { + code = ctrlId.replaceAll('-', '_').replaceAll('.', '_'); + } + return 'lookup.' + code; +} + + +export const lookupDataSourceConverter = { + convertFrom: (schema: Record, propertyKey: string) => { + return schema.editor[propertyKey]?.displayName; + }, + convertTo: (schema: Record, propertyKey: string, propertyValue: any[]) => { + if (propertyValue && propertyValue.length > 0) { + const datasource = propertyValue[0]; + const { name, id, metadataContent, code } = datasource; + + if (!schema.editor.dataSource) { + schema.editor.dataSource = {}; + } + + schema.editor.dataSource.displayName = `${name}(${code})`; + schema.editor['helpId'] = id; + + const { displayType, idField, textField } = metadataContent; + schema.editor.displayType = displayType; + schema.editor.dataSource.idField = idField; + schema.editor.textField = textField; + schema.editor.dataSource.type = "ViewObject"; + + + const { pageInfo, treeInfo } = metadataContent.dataSource; + // setPageInfo(schema.editor, pageInfo); + + if (treeInfo) { + const { onlySelectLeaf, loadDataType } = treeInfo; + schema.editor.loadTreeDataType = loadDataType || 'default'; + schema.editor.onlySelectLeaf = onlySelectLeaf == null ? false: onlySelectLeaf; + } + + if (!schema.editor.dataSource.uri) { + schema.editor.dataSource.uri = generateSourceUri(schema.id); + } + } + } +}; + +export const lookupIdFieldConverter = { + convertFrom: (schema: Record, propertyKey: string) => { + return schema.editor.dataSource?.idField; + }, + convertTo: (schema: Record, propertyKey: string, propertyValue: any) => { + if (propertyValue && propertyValue.length > 0) { + const fieldInfo = propertyValue[0]; + schema.editor.dataSource.idField = fieldInfo?.bindingPath; + } + } +}; + +export const lookupTextFieldConverter = { + convertFrom: (schema: Record, propertyKey: string) => { + return schema.editor?.textField; + }, + convertTo: (schema: Record, propertyKey: string, propertyValue: any) => { + if (propertyValue && propertyValue.length > 0) { + const fieldInfo = propertyValue[0]; + schema.editor.textField = fieldInfo?.bindingPath; + } + } +}; + +export const lookupDisplayTypeConverter = { + convertFrom: (schema: Record, propertyKey: string) => { + return schema.editor.displayType ? schema.editor.displayType.toUpperCase() : 'LIST'; + }, + convertTo: (schema: Record, propertyKey: string, propertyValue: any) => { + schema.editor.displayType = propertyValue; + } +}; + +export const lookupDialogOptionsConverter = { + convertFrom: (schema: Record, propertyKey: string) => { + const options = schema.editor.dialog || {}; + if (propertyKey === 'title') { + return options[propertyKey] || ''; + } + + if (propertyKey === 'width') { + if (schema.editor.displayType?.toUpperCase().startsWith('NAV')) { + return options[propertyKey] || 960; + } + return options[propertyKey] || 590; + } + + if (propertyKey === 'height') { + return options[propertyKey] || 620; + } + + if (propertyKey === 'rememberSize') { + return options[propertyKey] === undefined ? !!schema.editor.enableUserData : options[propertyKey]; + } + + if (propertyKey === 'navigatorWidth') { + return options[propertyKey] || 300; + } + + const keys = ['showMaxButton', 'showCloseButton', 'resizeable', 'draggable', 'enableEsc']; + if (keys.includes(propertyKey)) { + return options[propertyKey] == null ? true : options[propertyKey]; + } + + }, + convertTo: (schema: Record, propertyKey: string, propertyValue: any) => { + schema.editor.dialog = schema.editor.dialog || {}; + schema.editor.dialog[propertyKey] = propertyValue; + } +}; + diff --git a/packages/mobile-ui-vue/components/lookup/src/property-config/lookup.property-config.ts b/packages/mobile-ui-vue/components/lookup/src/property-config/lookup.property-config.ts new file mode 100644 index 00000000000..5600972331d --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/property-config/lookup.property-config.ts @@ -0,0 +1,219 @@ +import { InputBaseProperty } from '@farris/mobile-ui-vue/common'; +import { lookupDataSourceConverter, lookupTextFieldConverter } from './converters/lookup-property.converter'; + +export const LookupSchemaRepositoryToken = Symbol('schema_repository_token'); + +export const FieldSelectorRepositoryToken = Symbol('Field_Selector Component Repository Service Token'); + +export class LookupProperty extends InputBaseProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + getEditorProperties(propertyData: any) { + const self = this; + + const editorOptions = propertyData.editor; + + const editorProperties = self.getComponentConfig( + propertyData, + { type: 'lookup' }, + { + dataSource: { + description: "数据源", + title: "数据源", + type: "string", + refreshPanelAfterChanged: true, + editor: { + type: "schema-selector", + title: "选择数据源", + editorParams: { + propertyData: editorOptions, + formBasicInfo: this.formSchemaUtils.getFormMetadataBasicInfo() + }, + displayFormatter: (items) => { + if (items && items.length) { + return items.map((item) => `${item['name']}(${item['code']})`).join(','); + } + return ''; + }, + viewOptions: [ + { + id: 'recommend', title: '推荐', type: 'List', + dataSource: 'Recommand', + enableGroup: true, + groupField: 'category', + groupFormatter: (value, data) => { + return `${value === 'local' ? '本地元数据' : '最近使用'}`; + } + }, + { id: 'total', title: '全部', type: 'List', dataSource: 'Total' } + ], + repositoryToken: LookupSchemaRepositoryToken, + onSubmitModal: (dataSourceSchema: any) => { + if (dataSourceSchema) { + delete editorOptions.mappingFields; + const formInfo = this.formSchemaUtils.getFormMetadataBasicInfo(); + // 获取数据源详细配置信息 + return this.metadataService.getPickMetadata(formInfo.relativePath, dataSourceSchema[0].data) + .then((res: any) => { + const metadata = JSON.parse(res?.metadata.content); + return metadata; + }); + } + } + }, + $converter: lookupDataSourceConverter + }, + displayType: { + description: "类型: 树列表、列表、双列表、左树右列表", + title: "展示类型", + type: "string", + editor: { + type: "combo-list", + disabled: true, + data: [ + { text: '列表', value: 'List' }, + { text: '树列表', value: 'TreeList' }, + { text: '左树右列表', value: 'NavTreeList' } + ], + textField: 'text', + valueField: 'value' + } + }, + idField: { + description: "数据源标识字段", + title: "标识字段", + type: "string", + visible: false + }, + textField: { + description: "显示文本字段", + title: "文本字段", + type: "string", + $converter: lookupTextFieldConverter, + editor: { + type: "field-selector", + textField: 'bindingPath', + idField: 'bindingPath', + editorParams: { + propertyData: editorOptions, + formBasicInfo: this.formSchemaUtils.getFormMetadataBasicInfo() + }, + columns: [ + { field: 'name', title: '名称' }, + { field: 'code', title: '编号' }, + { field: 'bindingPath', title: '绑定字段' }, + ], + repositoryToken: FieldSelectorRepositoryToken + } + }, + mappingFields: { + description: "字段映射", + title: "字段映射", + type: "string", + editor: { + type: "mapping-editor", + modalWidth: 800, + modalHeight: 600, + editable: false, + editorParams: { + propertyData: editorOptions, + formBasicInfo: this.formSchemaUtils.getFormMetadataBasicInfo() + }, + fromData: { + editable: false, + formatter: (cell, data) => { + return `${data.raw['name']} [${data.raw['bindingPath']}]`; + }, + idField: 'id', + textField: 'bindingPath', + valueField: 'bindingPath', + repositoryToken: FieldSelectorRepositoryToken + }, + toData: { + idField: 'id', + textField: 'bindingPath', + valueField: 'bindingPath', + dataSource: this.designViewModelUtils.getAllFields2TreeByVMId(this.viewModelId), + formatter: (cell, data) => { + return `${data.raw['name']} [${data.raw['bindingPath']}]`; + } + } + } + }, + multiSelect: { + description: "启用多选", + title: "启用多选", + type: "boolean", + editor: { + type: 'combo-list', + enableClear: false, + editable: false + }, + refreshPanelAfterChanged: true, + visible: this.isSimpleStringField() + }, + loadTreeDataType: { + description: "树形数据加载方式", + title: "数据加载方式", + type: "string", + editor: { + type: 'combo-list', + editable: false, + data: [ + { value: 'all', text: '全部加载' }, + { value: 'async', text: '分层加载' }, + { value: 'default', text: '默认' } + ], + textField: 'text', + valueField: 'value' + }, + visible: this.showLoadType(editorOptions) + }, + onlySelectLeaf: { + description: "仅选择叶子节点", + title: "仅选择叶子节点", + type: "boolean", + visible: this.showOnlySelectLeaf(editorOptions), + } + }, + (changeObject) => { + if (!changeObject) { + return; + } + switch (changeObject.propertyID) { + case 'data': { + break; + } + } + } + ); + return editorProperties; + } + + private isSimpleStringField() { + const fullPath = this.designViewModelField?.path || ''; + if (fullPath) { + const field = fullPath.indexOf('.') > -1 ? fullPath.split('.')[0] : fullPath; + const fields = this.designViewModelUtils.getAllFields2TreeByVMId(this.viewModelId); + if (fields && fields.length) { + const fieldInfo = fields.map(node => node.data).find(data => data.code === field); + return fieldInfo?.type?.$type === "StringType" && fieldInfo?.$type === 'SimpleField'; + } + return false; + } + return true; + } + + private getDisplayType(editorOptions: any) { + return editorOptions.displayType ? editorOptions.displayType.toUpperCase() : ''; + } + private showLoadType(editorOptions: any) { + const displayType = this.getDisplayType(editorOptions); + return (displayType === 'TREELIST' || displayType === 'NAVTREELIST'); + } + private showOnlySelectLeaf(editorOptions: any) { + return this.getDisplayType(editorOptions) === 'TREELIST'; + } +} diff --git a/packages/mobile-ui-vue/components/lookup/src/schema/lookup.schema.json b/packages/mobile-ui-vue/components/lookup/src/schema/lookup.schema.json new file mode 100644 index 00000000000..853b9375ff1 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/schema/lookup.schema.json @@ -0,0 +1,120 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/lookup.schema.json", + "title": "lookup", + "description": "A Farris Lookup Component", + "type": "object", + "properties": { + "id": { + "description": "标识", + "type": "string" + }, + "type": { + "description": "控件类型", + "type": "string", + "default": "lookup" + }, + "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 + }, + "enableClear": { + "description": "", + "type": "boolean", + "default": false + }, + "placeholder": { + "description": "提示文本", + "type": "string" + }, + "displayType": { + "description": "", + "type": "string" + }, + "title": { + "description": "标题", + "type": "string", + "default": "" + }, + "idField": { + "description": "值字段", + "type": "string", + "default": "value" + }, + "textField": { + "description": "显示字段", + "type": "string", + "default": "name" + }, + "mappingFields": { + "description": "帮助字段映射", + "type": "object", + "default": {} + }, + "uri": { + "type": "string", + "default": "" + }, + "dataSource": { + "type": "object", + "default": null + }, + "multiSelect": { + "type": "boolean", + "default": false + }, + "loadTreeDataType": { + "type": "string", + "default": "default" + }, + "onlySelectLeaf": { + "type": "boolean", + "default": false + }, + "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/lookup/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/lookup/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..cbdfe5f71e0 --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/schema/schema-mapper.ts @@ -0,0 +1,35 @@ +import { MapperFunction, resolveAppearance } from '@farris/mobile-ui-vue/dynamic-resolver'; + +function converMappingFieldsToObject(mappingFields: any) { + if (typeof mappingFields == 'string' && mappingFields.startsWith('{') && mappingFields.endsWith('}')) { + mappingFields = mappingFields.replace(/'/g, '"'); + return {mappingFields: JSON.parse(mappingFields)}; + } + + return {mappingFields}; +} + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance], + ['binding', 'modelValue'], + ['mappingFields', (key: string, value: any, resolvedSchema) => { + if (value) { + return converMappingFieldsToObject(value); + } + + const {mappingFields} = resolvedSchema; + return converMappingFieldsToObject(mappingFields); + }], + ['uri', (key: string, value: any, resolvedSchema) => { + if (value) { + return {uri: value}; + } + return {uri: resolvedSchema?.dataSource?.uri}; + }], + ['idField', (key: string, value: any, resolvedSchema) => { + if (value) { + return {idField: value}; + } + return {idField: resolvedSchema?.dataSource?.idField}; + }] +]); diff --git a/packages/mobile-ui-vue/components/lookup/src/schema/schema-resolver.ts b/packages/mobile-ui-vue/components/lookup/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..7c8af7fc63d --- /dev/null +++ b/packages/mobile-ui-vue/components/lookup/src/schema/schema-resolver.ts @@ -0,0 +1,5 @@ +import { DynamicResolver } from "@farris/mobile-ui-vue/dynamic-resolver"; + +export function schemaResolver(resolver: DynamicResolver, schema: Record, context: Record): Record { + return schema; +} diff --git a/packages/mobile-ui-vue/components/picker/index.ts b/packages/mobile-ui-vue/components/picker/index.ts index 8f007d133f4..1ae96803550 100644 --- a/packages/mobile-ui-vue/components/picker/index.ts +++ b/packages/mobile-ui-vue/components/picker/index.ts @@ -14,11 +14,11 @@ const PickerPanel = withInstall(PickerPanelInstallless); export * from './src/picker.props'; export * from './src/composition/use-picker-state'; -const PICKER_REGISTERED_NAME = 'picker'; const Picker = withInstall(PickerInstallless); // 注册运行时及设计时 +const PICKER_REGISTERED_NAME = 'picker'; withRegister(Picker, { name: PICKER_REGISTERED_NAME, propsResolverGenerator }); withRegisterDesigner(Picker, { name: PICKER_REGISTERED_NAME, propsResolverGenerator, designerComponent: PickerDesign }); diff --git a/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json b/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json index f1be8e455c9..55f8e95fdac 100644 --- a/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json +++ b/packages/mobile-ui-vue/components/picker/src/schema/picker.schema.json @@ -88,5 +88,5 @@ }, "events": ["onUpdate:modelValue"], "required": ["type"], - "ignore": ["id", "type", "appearance", "binding"] + "ignore": ["id", "appearance", "binding", "visible"] } -- Gitee From 11085f38964c0282206964a5c34c5ce093e91f1b Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Thu, 17 Apr 2025 10:43:33 +0800 Subject: [PATCH 245/287] =?UTF-8?q?feature:=20=E6=8F=90=E4=BE=9Bcollection?= =?UTF-8?q?-property-editor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../collection-property-editor/index.ts | 29 +++ .../collection-property-editor.component.tsx | 110 ++++++++++ .../src/collection-property-editor.props.ts | 16 ++ ...ollection-property-container.component.tsx | 206 ++++++++++++++++++ .../collection-property-container.props.ts | 35 +++ .../collection-property-editor.schema.json | 57 +++++ .../src/schema/schema-mapper.ts | 5 + .../src/schema/schema-resolver.ts | 5 + .../dynamic-form-group.component.tsx | 2 + .../src/composition/use-type-resolver.ts | 2 + .../components/dynamic-form/src/types.ts | 2 +- .../dynamic-view/src/components/maps.ts | 2 + 12 files changed, 470 insertions(+), 1 deletion(-) create mode 100644 packages/ui-vue/components/collection-property-editor/index.ts create mode 100644 packages/ui-vue/components/collection-property-editor/src/collection-property-editor.component.tsx create mode 100644 packages/ui-vue/components/collection-property-editor/src/collection-property-editor.props.ts create mode 100644 packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.component.tsx create mode 100644 packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.props.ts create mode 100644 packages/ui-vue/components/collection-property-editor/src/schema/collection-property-editor.schema.json create mode 100644 packages/ui-vue/components/collection-property-editor/src/schema/schema-mapper.ts create mode 100644 packages/ui-vue/components/collection-property-editor/src/schema/schema-resolver.ts diff --git a/packages/ui-vue/components/collection-property-editor/index.ts b/packages/ui-vue/components/collection-property-editor/index.ts new file mode 100644 index 00000000000..67f6dcef488 --- /dev/null +++ b/packages/ui-vue/components/collection-property-editor/index.ts @@ -0,0 +1,29 @@ + +/** + * 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 { App } from 'vue'; +import FCollectionPropertyEditor from './src/collection-property-editor.component'; +import { propsResolver } from './src/collection-property-editor.props'; + +export default { + install(app: App): void { + app.component(FCollectionPropertyEditor.name as string, FCollectionPropertyEditor); + }, + register(componentMap: Record, propsResolverMap: Record, configResolverMap: Record, resolverMap: Record): void { + componentMap['collection-property-editor'] = FCollectionPropertyEditor; + propsResolverMap['collection-property-editor'] = propsResolver; + } +}; diff --git a/packages/ui-vue/components/collection-property-editor/src/collection-property-editor.component.tsx b/packages/ui-vue/components/collection-property-editor/src/collection-property-editor.component.tsx new file mode 100644 index 00000000000..ee7c906dee2 --- /dev/null +++ b/packages/ui-vue/components/collection-property-editor/src/collection-property-editor.component.tsx @@ -0,0 +1,110 @@ + +/** + * 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, ref, computed, inject } from 'vue'; +import { FButtonEdit } from '@farris/ui-vue/components/button-edit'; +import { collectionPropertyEditorProps, CollectionPropertyEditorProps } from './collection-property-editor.props'; +import CollectionPropertyContainer from './components/collection-property-container.component'; +import { cloneDeep } from 'lodash-es'; + +export default defineComponent({ + name: 'FCollectionPropertyEditor', + props: collectionPropertyEditorProps, + emits: ['valueChange', 'selectionChange'] as (string[] & ThisType) | undefined, + setup(props: CollectionPropertyEditorProps, context: SetupContext) { + const collectionPropertyContainerRef = ref(); + const useFormCommand = inject('useFormCommand') as any; + const useFormSchema = inject('useFormSchema') as any; + + const propertyData = ref(cloneDeep(props.modelValue) || []); + /** 编辑器输入框的显示内容 */ + const displayText = computed(() => { + return `共 ${propertyData.value?.length || 0} 项`; + }); + + /** + * 确定事件 + */ + function onSubmit() { + context.emit('valueChange', propertyData.value); + return true; + } + + /** + * 取消事件 + */ + function onCancel() { + return true; + } + + /** + * 行选择事件 + */ + function onSelectionChange({ selectedData, propertyConfig }) { + context.emit('selectionChange', { selectedData, propertyConfig }); + } + + const modalOptions = { + title: props.modalTitle, + width: 650, + height: 700, + fitContent: false, + showMaxButton: true, + resizeable: true, + draggable: true, + enableEsc: true, + buttons: [ + { + name: 'cancel', + text: '取消', + class: 'btn btn-secondary', + handle: onCancel + }, + { + name: 'accept', + text: '确定', + class: 'btn btn-primary', + handle: onSubmit + } + ] + }; + + return () => { + return +
    + +
    +
    ; + }; + + + } +}); diff --git a/packages/ui-vue/components/collection-property-editor/src/collection-property-editor.props.ts b/packages/ui-vue/components/collection-property-editor/src/collection-property-editor.props.ts new file mode 100644 index 00000000000..e54fbac2f83 --- /dev/null +++ b/packages/ui-vue/components/collection-property-editor/src/collection-property-editor.props.ts @@ -0,0 +1,16 @@ +import { ExtractPropTypes } from "vue"; +import { createPropsResolver } from '../../dynamic-resolver'; +import schema from './schema/collection-property-editor.schema.json'; +import { collectionPropertyContainerProps } from "./components/collection-property-container.props"; + +export const collectionPropertyEditorProps = { + ...collectionPropertyContainerProps, + modalTitle: { + type: String, + default: '编辑器' + }, +} as Record; + + +export type CollectionPropertyEditorProps = ExtractPropTypes; +export const propsResolver = createPropsResolver(collectionPropertyEditorProps, schema); diff --git a/packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.component.tsx b/packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.component.tsx new file mode 100644 index 00000000000..2110939d913 --- /dev/null +++ b/packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.component.tsx @@ -0,0 +1,206 @@ + +/** + * 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, ref, computed, onMounted, provide } from 'vue'; +import { FPropertyPanel } from '@farris/ui-vue/components/property-panel'; +import { FTreeView } from '@farris/ui-vue/components/tree-view'; +import { DataColumn } from '@farris/ui-vue/components/data-view'; +import { cloneDeep } from 'lodash-es'; +import { CollectionPropertyContainerProps, collectionPropertyContainerProps } from './collection-property-container.props'; + +export default defineComponent({ + name: 'CollectionPropertyContainer', + props: collectionPropertyContainerProps, + emits: ['valueChange', 'selectionChange'] as (string[] & ThisType) | undefined, + setup(props: CollectionPropertyContainerProps, context: SetupContext) { + const treeViewRef = ref(); + const propertyPanelRef = ref(); + const { idField, textField, defaultComponentSchema, isToolbarHidden } = props; + + /** 属性数据 */ + const propertyData = ref(props.modelValue); + /** 属性配置 */ + const propertyConfig: any = ref(); + const propertyName = ref('collection-property-editor'); + provide('useFormCommand', props.useFormCommand); + provide('useFormSchema', props.useFormSchema); + + /** 当前选中的数据 */ + const selectedData = ref(); + /** 数据是否为空 */ + const isEmptyData = computed(() => { + return !propertyData.value || propertyData.value.length === 0; + }); + + const columns: DataColumn[] = [ + { field: textField, title: '名称', width: 340, resizable: true, dataType: 'string' }, + ]; + + /** + * 获取新的Schema + * @returns + */ + function getNewSchema() { + const newSchema = cloneDeep(defaultComponentSchema); + + const radomNumber = Math.random().toString().slice(2, 6); + newSchema[idField] = newSchema[idField] + '_' + radomNumber; + newSchema[textField] = newSchema[textField] + '_' + radomNumber; + + return newSchema; + } + + /** + * 新增节点 + * @returns + */ + function addItem() { + // 1、添加新节点 + const newSchema = getNewSchema(); + propertyData.value.push(newSchema); + treeViewRef.value.updateDataSource(propertyData.value); + + // 2、选中新节点 + treeViewRef.value.selectItemById(newSchema[idField]); + } + + /** + * 选中第一个节点 + */ + function selectFirstNode() { + const firstNode = propertyData.value && propertyData.value.length > 0 ? propertyData.value[0] : null; + if (!firstNode) { + return; + } + treeViewRef.value.selectItemById(firstNode[idField]) + } + + /** + * 删除节点 + * @returns + */ + function removeItem() { + // 1、删除节点 + const indexToDelete = propertyData.value.indexOf(selectedData.value); + propertyData.value.splice(indexToDelete, 1); + treeViewRef.value.updateDataSource(propertyData.value); + + // 2、选中第一个节点 + selectFirstNode(); + } + + /** + * 下移节点 + * @returns + */ + function moveDownItem() { + if (!selectedData.value) { + return; + } + + const indexToMove = propertyData.value.indexOf(selectedData.value); + // 1、如果选择了最后一个节点,则不进行操作 + if (indexToMove === propertyData.value.length - 1) { + return; + } + + // 2、下移节点 + propertyData.value[indexToMove] = propertyData.value[indexToMove + 1]; + propertyData.value[indexToMove + 1] = selectedData.value; + treeViewRef.value.updateDataSource(propertyData.value); + } + + /** + * 上移节点 + * @returns + */ + function moveUpItem() { + if (!selectedData.value) { + return; + } + // 1、如果选择了第一个节点,则不进行操作 + const indexToMove = propertyData.value.indexOf(selectedData.value); + if (indexToMove === 0) { + return; + } + + // 2、上移节点 + propertyData.value[indexToMove] = propertyData.value[indexToMove - 1]; + propertyData.value[indexToMove - 1] = selectedData.value; + treeViewRef.value.updateDataSource(propertyData.value); + } + + /** + * 左侧树列表选中事件 + * @param selectedDatas + */ + function onSelectionChange(selectedDatas: any) { + selectedData.value = selectedDatas[0]; + context.emit('selectionChange', { selectedData, propertyConfig }); + + propertyPanelRef.value.updatePropertyConfig(propertyConfig.value, selectedData.value, true); + } + + /** + * 属性变更事件 + * @param propertyData + */ + function onPropertyChanged() { + treeViewRef.value.updateDataSource(propertyData.value); + + } + + onMounted(() => { + selectFirstNode(); + }); + + return () => { + return ( +
    + +
    +
    + +
    + + +
    +
    + + ); + }; + } +}); diff --git a/packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.props.ts b/packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.props.ts new file mode 100644 index 00000000000..59a6e3c9dfe --- /dev/null +++ b/packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.props.ts @@ -0,0 +1,35 @@ +import { ExtractPropTypes } from "vue"; + +export const collectionPropertyContainerProps = { + modelValue: { + type: Array, + default: [] + }, + idField: { + type: String, + default: 'id' + }, + textField: { + type: String, + default: '' + }, + defaultComponentSchema: { + type: Object, + default: {} + }, + isToolbarHidden: { + type: Boolean, + default: false + }, + useFormCommand: { + type: Object, + default: {} + }, + useFormSchema: { + type: Object, + default: {} + }, +} as Record; + + +export type CollectionPropertyContainerProps = ExtractPropTypes; diff --git a/packages/ui-vue/components/collection-property-editor/src/schema/collection-property-editor.schema.json b/packages/ui-vue/components/collection-property-editor/src/schema/collection-property-editor.schema.json new file mode 100644 index 00000000000..cc54c526e69 --- /dev/null +++ b/packages/ui-vue/components/collection-property-editor/src/schema/collection-property-editor.schema.json @@ -0,0 +1,57 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/collection-property-editor.schema.json", + "title": "collection-property-editor", + "description": "A Farris Component", + "type": "object", + "properties": { + "id": { + "description": "The unique identifier for collection-property-editor", + "type": "string" + }, + "type": { + "description": "The type string of collection-property-editor", + "type": "string", + "default": "collection-property-editor" + }, + "appearance": { + "description": "", + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "style": { + "type": "string" + } + }, + "default": {} + }, + "modelValue": { + "type": "array", + "default": [] + }, + "idField": { + "type": "string", + "default": "id" + }, + "textField": { + "type": "string", + "default": "" + }, + "defaultComponentSchema": { + "type": "object", + "default": {} + }, + "modalTitle": { + "type": "string", + "default": "编辑器" + } + }, + "required": [ + "type" + ], + "ignore": [ + "id" + ] +} \ No newline at end of file diff --git a/packages/ui-vue/components/collection-property-editor/src/schema/schema-mapper.ts b/packages/ui-vue/components/collection-property-editor/src/schema/schema-mapper.ts new file mode 100644 index 00000000000..97964aee23b --- /dev/null +++ b/packages/ui-vue/components/collection-property-editor/src/schema/schema-mapper.ts @@ -0,0 +1,5 @@ +import { MapperFunction, resolveAppearance } from '../../../dynamic-resolver'; + +export const schemaMapper = new Map([ + ['appearance', resolveAppearance] +]); diff --git a/packages/ui-vue/components/collection-property-editor/src/schema/schema-resolver.ts b/packages/ui-vue/components/collection-property-editor/src/schema/schema-resolver.ts new file mode 100644 index 00000000000..b02bdf93eec --- /dev/null +++ b/packages/ui-vue/components/collection-property-editor/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/ui-vue/components/dynamic-form/src/component/dynamic-form-group/dynamic-form-group.component.tsx b/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-group/dynamic-form-group.component.tsx index 3d2b26b7d50..049e2c1ac38 100644 --- a/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-group/dynamic-form-group.component.tsx +++ b/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-group/dynamic-form-group.component.tsx @@ -67,6 +67,8 @@ export default defineComponent({ } } else if (editorType === 'lookup' && editor.value['onUpdate:idValue'] && typeof editor.value['onUpdate:idValue'] === 'function') { editorProps['onUpdate:idValue'] = editor.value['onUpdate:idValue']; + } else if (editorType === 'collection-property-editor' && editor.value['onSelectionChange'] && typeof editor.value['onSelectionChange'] === 'function') { + editorProps['onSelectionChange'] = editor.value['onSelectionChange']; } return () => ; }); diff --git a/packages/ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts b/packages/ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts index 786c8b71072..20d4235bfa6 100644 --- a/packages/ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts +++ b/packages/ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts @@ -91,6 +91,8 @@ export function useTypeResolver(): UseTypeResolver { return 'onValueChange'; case 'expression-editor': return 'onExpressionChanged'; + case 'collection-property-editor': + return 'onValueChange'; } } diff --git a/packages/ui-vue/components/dynamic-form/src/types.ts b/packages/ui-vue/components/dynamic-form/src/types.ts index d10c2663b28..0f7839782fc 100644 --- a/packages/ui-vue/components/dynamic-form/src/types.ts +++ b/packages/ui-vue/components/dynamic-form/src/types.ts @@ -4,7 +4,7 @@ export type EditorType = 'button-edit' | 'check-box' | 'check-group' | 'combo-li 'response-layout-editor-setting' | 'switch' | 'grid-field-editor' | 'field-selector' | 'schema-selector' | 'mapping-editor' | 'textarea' | 'response-form-layout-setting' | 'binding-selector' | 'query-solution-config' | 'solution-preset' | 'item-collection-editor' | 'menu-lookup' | 'response-layout-splitter' | 'configuration-parameter-editor' | 'property-editor' | 'sort-condition-editor' | - 'filter-condition-editor' | 'expression-editor' | 'code-editor'; + 'filter-condition-editor' | 'expression-editor' | 'code-editor' | 'collection-property-editor'; export interface EditorConfig { /** 编辑器类型 */ diff --git a/packages/ui-vue/components/dynamic-view/src/components/maps.ts b/packages/ui-vue/components/dynamic-view/src/components/maps.ts index 5286eb9dfb8..a32ec6e6867 100644 --- a/packages/ui-vue/components/dynamic-view/src/components/maps.ts +++ b/packages/ui-vue/components/dynamic-view/src/components/maps.ts @@ -69,6 +69,7 @@ import FPropertyEditor from '@farris/ui-vue/components/property-editor'; import FExpressionEditor from '@farris/ui-vue/components/expression-editor'; import FCodeEditor from '@farris/ui-vue/components/code-editor'; import FHtmlTemplate from '@farris/ui-vue/components/html-template'; +import FCollectionPropertyEditor from '@farris/ui-vue/components/collection-property-editor'; const componentMap: Record = {}; const componentPropsConverter: Record = {}; @@ -154,6 +155,7 @@ function loadRegister() { FPropertyEditor.register(componentMap, componentPropsConverter, componentPropertyConfigConverter, resolverMap); FCodeEditor.register(componentMap, componentPropsConverter, componentPropertyConfigConverter, resolverMap); FHtmlTemplate.register(componentMap, componentPropsConverter, componentPropertyConfigConverter, resolverMap); + FCollectionPropertyEditor.register(componentMap, componentPropsConverter, componentPropertyConfigConverter, resolverMap); } } -- Gitee From 2239061adc724054c0d6d4a955973936b82feb6e Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Thu, 17 Apr 2025 11:15:31 +0800 Subject: [PATCH 246/287] =?UTF-8?q?chore:=20=E8=A1=A5=E5=85=85navbar?= =?UTF-8?q?=E7=9A=84rightToolbar=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form-designer/form-designer.component.tsx | 2 +- .../components/common/src/properties/index.ts | 3 +- .../src/properties/toolbar-item.property.ts | 101 ++++++++++++++++++ .../src/converter/right-toolbar.converter.ts | 14 +++ .../property-config/navbar.property-config.ts | 29 ++++- .../navbar/src/schema/navbar.schema.json | 3 + 6 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 packages/mobile-ui-vue/components/common/src/properties/toolbar-item.property.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/converter/right-toolbar.converter.ts diff --git a/packages/designer/src/components/components/form-designer/form-designer.component.tsx b/packages/designer/src/components/components/form-designer/form-designer.component.tsx index 5c41dced2d6..96f444f8839 100644 --- a/packages/designer/src/components/components/form-designer/form-designer.component.tsx +++ b/packages/designer/src/components/components/form-designer/form-designer.component.tsx @@ -21,7 +21,7 @@ export default defineComponent({ const propertyPanelInstance = ref(); const schema = ref(props.schema); const componentSchema = schema.value.module ? ref(schema.value.module.components[0]) : ref(schema.value); - const componentId = ref(componentSchema['id'] || 'root-component'); + const componentId = ref(componentSchema.value['id'] || 'root-component'); const dragulaCompostion = ref(); const fillTabs = ref(true); const controlTreeRef = ref(); diff --git a/packages/mobile-ui-vue/components/common/src/properties/index.ts b/packages/mobile-ui-vue/components/common/src/properties/index.ts index 45e1b856918..0e938d51c5d 100644 --- a/packages/mobile-ui-vue/components/common/src/properties/index.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/index.ts @@ -1,4 +1,5 @@ export * from './dg-control'; export { SchemaDOMMapping } from './schema-dom-mapping'; export { BaseControlProperty } from './base-property'; -export { InputBaseProperty } from './input-base-property'; \ No newline at end of file +export { InputBaseProperty } from './input-base-property'; +export { ToolbarItemProperty } from './toolbar-item.property'; \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/common/src/properties/toolbar-item.property.ts b/packages/mobile-ui-vue/components/common/src/properties/toolbar-item.property.ts new file mode 100644 index 00000000000..17e8eb82234 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/src/properties/toolbar-item.property.ts @@ -0,0 +1,101 @@ +import { BaseControlProperty } from "./base-property"; + +export class ToolbarItemProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + public getPropertyConfig(propertyData: any) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 行为 + this.propertyConfig.categories['behavior'] = this.getNavBarBehaviorConfig(propertyData); + // 事件 + this.getEventPropConfig(propertyData); + + return this.propertyConfig; + } + + getBasicPropConfig(propertyData: any): any { + return { + description: 'Basic Information', + title: '基本信息', + properties: { + id: { + description: '工具栏按钮的标识', + title: '标识', + type: 'string', + readonly: true + }, + text: { + description: '工具栏按钮的标签', + title: '标签', + type: 'string', + readonly: false + } + } + }; + + } + + private getNavBarBehaviorConfig(propertyData) { + const visibleProperty = this.getVisibleProperty(propertyData) + const self = this; + return { + description: "基本信息", + title: "行为", + properties: { + ...visibleProperty, + disabled: { + title: "是否禁用", + type: "boolean", + } + }, + setPropertyRelates(changeObject: any, data: any) { + if (!changeObject) { + return; + } + switch (changeObject.propertyID) { + case 'visible': + self.afterMutilEditorChanged(propertyData, changeObject); + break; + } + } + }; + } + + private getEventPropConfig(propertyData: any) { + const events = [ + { + label: "onClick", + name: "点击事件", + } + ]; + const self = this; + const initialData = self.eventsEditorUtils['formProperties'](propertyData, self.viewModelId, events); + const properties = {}; + properties[self.viewModelId] = { + type: 'events-editor', + editor: { + initialData + } + }; + this.propertyConfig.categories['eventsEditor'] = { + title: '事件', + hideTitle: true, + properties, + refreshPanelAfterChanged: true, + tabId: 'commands', + tabName: '交互', + setPropertyRelates(changeObject: any, data: any) { + const parameters = changeObject.propertyValue; + delete propertyData[self.viewModelId]; + if (parameters) { + parameters.setPropertyRelates = this.setPropertyRelates; + self.eventsEditorUtils.saveRelatedParameters(propertyData, self.viewModelId, parameters['events'], parameters); + } + } + }; + } + +} diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/right-toolbar.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/right-toolbar.converter.ts new file mode 100644 index 00000000000..c8047af63d4 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/right-toolbar.converter.ts @@ -0,0 +1,14 @@ +import { ComponentSchema } from "@farris/mobile-ui-vue/common"; +import { PropertyConverter, SchemaService } from "../types"; + +export default { + convertTo: (schema: ComponentSchema, propertyKey: string, propertyValue: any, schemaService: SchemaService) => { + if (!schema.rightToolbar) { + schema.rightToolbar = []; + } + schema.rightToolbar[propertyKey] = propertyValue; + }, + convertFrom: (schema: ComponentSchema, propertyKey: string, schemaService: SchemaService) => { + return schema.rightToolbar ? schema.rightToolbar[propertyKey] : schema[propertyKey]; + } +} as PropertyConverter; diff --git a/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts b/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts index 0cabd550539..dc9f2031620 100644 --- a/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts +++ b/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts @@ -1,8 +1,12 @@ -import { BaseControlProperty } from "@farris/mobile-ui-vue/common"; +import { BaseControlProperty, ToolbarItemProperty } from "@farris/mobile-ui-vue/common"; +import ToolbarConverter from "@farris/mobile-ui-vue/dynamic-resolver/src/converter/right-toolbar.converter"; export class NavBarProperty extends BaseControlProperty { + private toolbarItemProperty: ToolbarItemProperty; constructor(componentId: string, designerHostService: any) { super(componentId, designerHostService); + this.toolbarItemProperty = new ToolbarItemProperty(componentId, designerHostService) + } public getPropertyConfig(propertyData: any) { // 基本信息 @@ -12,6 +16,29 @@ export class NavBarProperty extends BaseControlProperty { // 行为 this.propertyConfig.categories['behavior'] = this.getNavBarBehaviorConfig(propertyData); + this.propertyConfig.categories['rightToolbar'] = { + title: '工具栏', + $converter: ToolbarConverter, + properties: { + items: { + title: '右侧工具栏', + editor: { + type: "collection-property-editor", + textField: 'text', + modalTitle: '右侧工具栏编辑器', + onSelectionChange: ({ selectedData, propertyConfig }) => { + propertyConfig.value = this.toolbarItemProperty.getPropertyConfig(selectedData.value); + }, + defaultComponentSchema: { + id: 'button', + text: '按钮', + visible: true, + disabled: false + } + } + } + } + } return this.propertyConfig; } 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 index f61ca3117df..d933a637939 100644 --- a/packages/mobile-ui-vue/components/navbar/src/schema/navbar.schema.json +++ b/packages/mobile-ui-vue/components/navbar/src/schema/navbar.schema.json @@ -44,6 +44,9 @@ }, "onClickLeft": { "type": "string" + }, + "rightToolbar": { + "type": "object" } }, "events": [ -- Gitee From 816e4762fba9b52beba5fca547289df84dd53d92 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Thu, 17 Apr 2025 11:33:43 +0800 Subject: [PATCH 247/287] =?UTF-8?q?chore:=20=E5=AE=8C=E5=96=84collection-p?= =?UTF-8?q?roperty-editor=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../collection-property-editor.component.tsx | 6 ++-- ...ollection-property-container.component.tsx | 28 ++++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/ui-vue/components/collection-property-editor/src/collection-property-editor.component.tsx b/packages/ui-vue/components/collection-property-editor/src/collection-property-editor.component.tsx index ee7c906dee2..48f3339ee0b 100644 --- a/packages/ui-vue/components/collection-property-editor/src/collection-property-editor.component.tsx +++ b/packages/ui-vue/components/collection-property-editor/src/collection-property-editor.component.tsx @@ -26,8 +26,8 @@ export default defineComponent({ emits: ['valueChange', 'selectionChange'] as (string[] & ThisType) | undefined, setup(props: CollectionPropertyEditorProps, context: SetupContext) { const collectionPropertyContainerRef = ref(); - const useFormCommand = inject('useFormCommand') as any; - const useFormSchema = inject('useFormSchema') as any; + const useFormCommand = inject('useFormCommand'); + const useFormSchema = inject('useFormSchema'); const propertyData = ref(cloneDeep(props.modelValue) || []); /** 编辑器输入框的显示内容 */ @@ -58,7 +58,7 @@ export default defineComponent({ } const modalOptions = { - title: props.modalTitle, + title: props.modalTitle || '编辑器', width: 650, height: 700, fitContent: false, diff --git a/packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.component.tsx b/packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.component.tsx index 2110939d913..1268030f8f7 100644 --- a/packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.component.tsx +++ b/packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.component.tsx @@ -33,7 +33,7 @@ export default defineComponent({ /** 属性数据 */ const propertyData = ref(props.modelValue); /** 属性配置 */ - const propertyConfig: any = ref(); + const propertyConfig = ref(); const propertyName = ref('collection-property-editor'); provide('useFormCommand', props.useFormCommand); provide('useFormSchema', props.useFormSchema); @@ -67,7 +67,7 @@ export default defineComponent({ * 新增节点 * @returns */ - function addItem() { + function onAddItem() { // 1、添加新节点 const newSchema = getNewSchema(); propertyData.value.push(newSchema); @@ -92,7 +92,7 @@ export default defineComponent({ * 删除节点 * @returns */ - function removeItem() { + function onRemoveItem() { // 1、删除节点 const indexToDelete = propertyData.value.indexOf(selectedData.value); propertyData.value.splice(indexToDelete, 1); @@ -106,14 +106,15 @@ export default defineComponent({ * 下移节点 * @returns */ - function moveDownItem() { + function onMoveDownItem() { if (!selectedData.value) { return; } const indexToMove = propertyData.value.indexOf(selectedData.value); - // 1、如果选择了最后一个节点,则不进行操作 - if (indexToMove === propertyData.value.length - 1) { + // 1、如果选择了最后一个节点,则不进行移动 + const shouldNotMove = indexToMove === propertyData.value.length - 1; + if (shouldNotMove) { return; } @@ -127,13 +128,14 @@ export default defineComponent({ * 上移节点 * @returns */ - function moveUpItem() { + function onMoveUpItem() { if (!selectedData.value) { return; } // 1、如果选择了第一个节点,则不进行操作 const indexToMove = propertyData.value.indexOf(selectedData.value); - if (indexToMove === 0) { + const shouldNotMove = indexToMove === 0; + if (shouldNotMove) { return; } @@ -147,7 +149,7 @@ export default defineComponent({ * 左侧树列表选中事件 * @param selectedDatas */ - function onSelectionChange(selectedDatas: any) { + function onSelectionChange(selectedDatas: any[]) { selectedData.value = selectedDatas[0]; context.emit('selectionChange', { selectedData, propertyConfig }); @@ -171,10 +173,10 @@ export default defineComponent({ return (
    -- Gitee From 6940aebf4a2085258a2cd0ff1a7698acc3893d3b Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Thu, 17 Apr 2025 11:35:37 +0800 Subject: [PATCH 248/287] =?UTF-8?q?chore:=20=E5=AE=8C=E5=96=84collection-p?= =?UTF-8?q?roperty-editor=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../collection-property-editor.component.tsx | 6 ++-- ...ollection-property-container.component.tsx | 28 ++++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/ui-vue/components/collection-property-editor/src/collection-property-editor.component.tsx b/packages/ui-vue/components/collection-property-editor/src/collection-property-editor.component.tsx index ee7c906dee2..48f3339ee0b 100644 --- a/packages/ui-vue/components/collection-property-editor/src/collection-property-editor.component.tsx +++ b/packages/ui-vue/components/collection-property-editor/src/collection-property-editor.component.tsx @@ -26,8 +26,8 @@ export default defineComponent({ emits: ['valueChange', 'selectionChange'] as (string[] & ThisType) | undefined, setup(props: CollectionPropertyEditorProps, context: SetupContext) { const collectionPropertyContainerRef = ref(); - const useFormCommand = inject('useFormCommand') as any; - const useFormSchema = inject('useFormSchema') as any; + const useFormCommand = inject('useFormCommand'); + const useFormSchema = inject('useFormSchema'); const propertyData = ref(cloneDeep(props.modelValue) || []); /** 编辑器输入框的显示内容 */ @@ -58,7 +58,7 @@ export default defineComponent({ } const modalOptions = { - title: props.modalTitle, + title: props.modalTitle || '编辑器', width: 650, height: 700, fitContent: false, diff --git a/packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.component.tsx b/packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.component.tsx index 2110939d913..1268030f8f7 100644 --- a/packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.component.tsx +++ b/packages/ui-vue/components/collection-property-editor/src/components/collection-property-container.component.tsx @@ -33,7 +33,7 @@ export default defineComponent({ /** 属性数据 */ const propertyData = ref(props.modelValue); /** 属性配置 */ - const propertyConfig: any = ref(); + const propertyConfig = ref(); const propertyName = ref('collection-property-editor'); provide('useFormCommand', props.useFormCommand); provide('useFormSchema', props.useFormSchema); @@ -67,7 +67,7 @@ export default defineComponent({ * 新增节点 * @returns */ - function addItem() { + function onAddItem() { // 1、添加新节点 const newSchema = getNewSchema(); propertyData.value.push(newSchema); @@ -92,7 +92,7 @@ export default defineComponent({ * 删除节点 * @returns */ - function removeItem() { + function onRemoveItem() { // 1、删除节点 const indexToDelete = propertyData.value.indexOf(selectedData.value); propertyData.value.splice(indexToDelete, 1); @@ -106,14 +106,15 @@ export default defineComponent({ * 下移节点 * @returns */ - function moveDownItem() { + function onMoveDownItem() { if (!selectedData.value) { return; } const indexToMove = propertyData.value.indexOf(selectedData.value); - // 1、如果选择了最后一个节点,则不进行操作 - if (indexToMove === propertyData.value.length - 1) { + // 1、如果选择了最后一个节点,则不进行移动 + const shouldNotMove = indexToMove === propertyData.value.length - 1; + if (shouldNotMove) { return; } @@ -127,13 +128,14 @@ export default defineComponent({ * 上移节点 * @returns */ - function moveUpItem() { + function onMoveUpItem() { if (!selectedData.value) { return; } // 1、如果选择了第一个节点,则不进行操作 const indexToMove = propertyData.value.indexOf(selectedData.value); - if (indexToMove === 0) { + const shouldNotMove = indexToMove === 0; + if (shouldNotMove) { return; } @@ -147,7 +149,7 @@ export default defineComponent({ * 左侧树列表选中事件 * @param selectedDatas */ - function onSelectionChange(selectedDatas: any) { + function onSelectionChange(selectedDatas: any[]) { selectedData.value = selectedDatas[0]; context.emit('selectionChange', { selectedData, propertyConfig }); @@ -171,10 +173,10 @@ export default defineComponent({ return (
    -- Gitee From ee557d90eb015f2bdc03e4eef2487e707f225ac6 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Thu, 17 Apr 2025 14:01:51 +0800 Subject: [PATCH 249/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=A8=A1=E6=9D=BF=E6=A0=B7=E5=BC=8F=E5=8F=8A=E6=89=93?= =?UTF-8?q?=E5=8C=85=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/mobile-ui-vue/.gitignore | 1 + packages/mobile-ui-vue/components/register.ts | 3 +- packages/mobile-ui-vue/index.html | 2 +- packages/mobile-ui-vue/package.json | 1 + .../src/assets/styles/page/basic.scss | 195 ++++++++++++++++++ .../src/assets/styles/page/index.scss | 2 + .../src/assets/styles/page/listview-tmpl.scss | 108 ++++++++++ packages/mobile-ui-vue/src/main.ts | 1 + 8 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 packages/mobile-ui-vue/src/assets/styles/page/basic.scss create mode 100644 packages/mobile-ui-vue/src/assets/styles/page/index.scss create mode 100644 packages/mobile-ui-vue/src/assets/styles/page/listview-tmpl.scss diff --git a/packages/mobile-ui-vue/.gitignore b/packages/mobile-ui-vue/.gitignore index bef97693ba6..1c11aea63f5 100644 --- a/packages/mobile-ui-vue/.gitignore +++ b/packages/mobile-ui-vue/.gitignore @@ -9,6 +9,7 @@ lerna-debug.log* node_modules dist +lib package dist-ssr *.local diff --git a/packages/mobile-ui-vue/components/register.ts b/packages/mobile-ui-vue/components/register.ts index 02f0fe96957..788a7789af2 100644 --- a/packages/mobile-ui-vue/components/register.ts +++ b/packages/mobile-ui-vue/components/register.ts @@ -20,6 +20,7 @@ import Switch from './switch'; import DatePicker from './date-picker'; import DateTimePicker from './date-time-picker'; import Picker from './picker'; +import Lookup from './lookup'; const componentMap: Record = {}; const propsConverterMap: Record = {}; @@ -41,7 +42,7 @@ function registerComponents() { Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, ContentContainer, FloatContainer, Navbar, Button, ButtonGroup, Listview, - Form, FormItem, InputGroup, Textarea, NumberInput, Switch, DatePicker, DateTimePicker, Picker + Form, FormItem, InputGroup, Textarea, NumberInput, Switch, DatePicker, DateTimePicker, Picker,Lookup ]; componentsToRegister.forEach((componentToRegister) => { componentToRegister.register(componentMap, propsConverterMap, propConfigsConverterMap, resolverMap); diff --git a/packages/mobile-ui-vue/index.html b/packages/mobile-ui-vue/index.html index 23f687958c7..e8b75dbc3b8 100644 --- a/packages/mobile-ui-vue/index.html +++ b/packages/mobile-ui-vue/index.html @@ -5,7 +5,7 @@ - + Farris Mobile + +
    + + + diff --git a/packages/mobile-render/package.json b/packages/mobile-render/package.json index 2f167a8cdc7..0b9186b866e 100644 --- a/packages/mobile-render/package.json +++ b/packages/mobile-render/package.json @@ -14,9 +14,9 @@ "url": "git@gitee.com:ubml/farris-vue.git" }, "scripts": { - "dev": "vite", - "build": "vue-tsc --noEmit && vite build", - "preview": "vite preview", + "dev": "farris-cli dev", + "build": "farris-cli build", + "preview": "farris-cli preview", "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", "format": "prettier --write src/" }, @@ -30,45 +30,26 @@ "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", "shelljs": "^0.8.4", "typescript": "^4.6.4", - "vite": "^4.1.4", - "vite-plugin-banner": "^0.8.0", - "vite-svg-loader": "^4.0.0", "vitest": "^0.29.2", "vue-tsc": "^1.2.0" } diff --git a/packages/mobile-render/scripts/publish.sh b/packages/mobile-render/scripts/publish.sh index 024391d4f69..b6888d76a93 100644 --- a/packages/mobile-render/scripts/publish.sh +++ b/packages/mobile-render/scripts/publish.sh @@ -14,7 +14,7 @@ mkdir -p $RENDER_DIR # 拷贝文件 cp -r -p ../mobile-ui-vue/package/index.css "${STYLE_DIR}/farris-mobile-ui-vue.css" -cp -r -p ../mobile-ui-vue/public/assets/farris-mobile-page.css "${STYLE_DIR}/farris-mobile-page-vue.css" +cp -r -p ../mobile-ui-vue/lib/page.css "${STYLE_DIR}/farris-mobile-page-vue.css" cp -r -p ../mobile-ui-vue/package/index.systemjs.js "${SCRIPT_DIR}/mobile-ui-vue.js" cp -r -p ../devkit/dist-rollup/@farris/devkit-vue.js "${SCRIPT_DIR}/devkit-vue.js" diff --git a/packages/mobile-render/tsconfig.node.json b/packages/mobile-render/tsconfig.node.json index d8915f131ad..7fed214121a 100644 --- a/packages/mobile-render/tsconfig.node.json +++ b/packages/mobile-render/tsconfig.node.json @@ -7,8 +7,5 @@ "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 deleted file mode 100644 index 4c68bb48c60..00000000000 --- a/packages/mobile-render/vite.config.ts +++ /dev/null @@ -1,52 +0,0 @@ -// / -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/button-group/index.ts b/packages/mobile-ui-vue/components/button-group/index.ts index 4bb2569a6cc..4e36f328dc9 100644 --- a/packages/mobile-ui-vue/components/button-group/index.ts +++ b/packages/mobile-ui-vue/components/button-group/index.ts @@ -11,4 +11,4 @@ withRegister(ButtonGroup, { name: BUTTON_GROUP_REGISTERED_NAME, propsResolverGen export * from './src/button-group.props'; export { ButtonGroup }; -export default ButtonGroup as typeof ButtonGroup & Plugin; +export default ButtonGroup; diff --git a/packages/mobile-ui-vue/components/button/index.ts b/packages/mobile-ui-vue/components/button/index.ts index 15c9d8e848b..8fec33b0b6b 100644 --- a/packages/mobile-ui-vue/components/button/index.ts +++ b/packages/mobile-ui-vue/components/button/index.ts @@ -12,4 +12,4 @@ withRegister(Button, { name: BUTTON_REGISTERED_NAME, propsResolverGenerator }); withRegisterDesigner(Button, { name: BUTTON_REGISTERED_NAME, propsResolverGenerator, designerComponent: ButtonDesign }); export { Button }; -export default Button as typeof Button & Plugin; +export default Button; diff --git a/packages/mobile-ui-vue/components/button/src/button.component.tsx b/packages/mobile-ui-vue/components/button/src/button.component.tsx index 0cd0c47273e..5854499fdef 100644 --- a/packages/mobile-ui-vue/components/button/src/button.component.tsx +++ b/packages/mobile-ui-vue/components/button/src/button.component.tsx @@ -24,7 +24,7 @@ export default defineComponent({ return classList; }); - const applyGradientBorderBehavior = (style: CSSProperties, color: string) =>{ + const applyGradientBorderBehavior = (style: CSSProperties, color: string) => { const isGradientColor = color.includes('gradient'); if (isGradientColor) { style.border = 0; @@ -47,7 +47,7 @@ export default defineComponent({ return style; }); - const onClickButton = (event: Event) =>{ + const onClickButton = (event: Event) => { if (props.disabled) { stopPropagation(event); } else { @@ -74,8 +74,8 @@ export default defineComponent({ ); }; - const renderText = ()=> { - return slots.default && {slots.default()}; + const renderText = () => { + return (slots.default || props.text) && {slots.default ? slots.default() : props.text}; }; return () => ( 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 25a3ebf90ef..e5a1224d244 100644 --- a/packages/mobile-ui-vue/components/button/src/button.props.ts +++ b/packages/mobile-ui-vue/components/button/src/button.props.ts @@ -42,6 +42,8 @@ export const buttonProps = { loading: { type: Boolean, default: false }, + text: { type: String, default: '' }, + loadingText: { type: String, default: '' } }; diff --git a/packages/mobile-ui-vue/components/component/index.ts b/packages/mobile-ui-vue/components/component/index.ts index ba722ade21f..bf0f9d3a345 100644 --- a/packages/mobile-ui-vue/components/component/index.ts +++ b/packages/mobile-ui-vue/components/component/index.ts @@ -42,4 +42,4 @@ Component.registerDesigner = ( export * from './src/component.props'; export { Component }; -export default Component as typeof Component & Plugin; +export default Component; diff --git a/packages/mobile-ui-vue/components/content-container/index.ts b/packages/mobile-ui-vue/components/content-container/index.ts index d6c256518cf..3b5995969ea 100644 --- a/packages/mobile-ui-vue/components/content-container/index.ts +++ b/packages/mobile-ui-vue/components/content-container/index.ts @@ -1,32 +1,14 @@ -import { App, Plugin } from 'vue'; -import FContentContainer from './src/content-container.component'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; +import ContentContainerInstallless from './src/content-container.component'; import { propsResolverGenerator } from './src/content-container.props'; import ContentContainerDesign from './src/designer/content-container.design.component'; -import { RegisterContext } from '../common'; -const CONTENT_CONTAINER_REGISTERED_NAME = 'content-container'; - -FContentContainer.install = (app: App) => { - app.component(FContentContainer.name as string, FContentContainer); -}; +const ContentContainer = withInstall(ContentContainerInstallless); -FContentContainer.register = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record, resolverMap: Record,registerContext: RegisterContext -) => { - componentMap[CONTENT_CONTAINER_REGISTERED_NAME] = FContentContainer; - propsResolverMap[CONTENT_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; - -FContentContainer.registerDesigner = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record,registerContext: RegisterContext -) => { - componentMap[CONTENT_CONTAINER_REGISTERED_NAME] = ContentContainerDesign; - propsResolverMap[CONTENT_CONTAINER_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; +const CONTENT_CONTAINER_REGISTERED_NAME = 'content-container'; +withRegister(ContentContainer, { name: CONTENT_CONTAINER_REGISTERED_NAME, propsResolverGenerator }); +withRegisterDesigner(ContentContainer, { name: CONTENT_CONTAINER_REGISTERED_NAME, propsResolverGenerator, designerComponent: ContentContainerDesign }); -export * from './src/content-container.props'; -export { FContentContainer }; -export default FContentContainer as typeof FContentContainer & Plugin; +export { ContentContainer }; +export default ContentContainer; diff --git a/packages/mobile-ui-vue/components/float-container/index.ts b/packages/mobile-ui-vue/components/float-container/index.ts index 0a6b3139a45..0c1d2ef206f 100644 --- a/packages/mobile-ui-vue/components/float-container/index.ts +++ b/packages/mobile-ui-vue/components/float-container/index.ts @@ -27,4 +27,4 @@ FloatContainer.registerDesigner = ( export * from './src/float-container.props'; export { FloatContainer }; -export default FloatContainer as typeof FloatContainer & Plugin; +export default FloatContainer; diff --git a/packages/mobile-ui-vue/components/form/index.ts b/packages/mobile-ui-vue/components/form/index.ts index b91f4f8ab50..8df9ae7b199 100644 --- a/packages/mobile-ui-vue/components/form/index.ts +++ b/packages/mobile-ui-vue/components/form/index.ts @@ -29,4 +29,4 @@ withRegisterDesigner(Form, { name: FORM_REGISTERED_NAME, propsResolverGenerator, export * from '@farris/mobile-ui-vue/form-item/src/form.props'; export { Form }; -export default Form as typeof Form & Plugin; +export default Form; diff --git a/packages/mobile-ui-vue/components/register.ts b/packages/mobile-ui-vue/components/register.ts index 788a7789af2..fee88e812a7 100644 --- a/packages/mobile-ui-vue/components/register.ts +++ b/packages/mobile-ui-vue/components/register.ts @@ -21,6 +21,8 @@ import DatePicker from './date-picker'; import DateTimePicker from './date-time-picker'; import Picker from './picker'; import Lookup from './lookup'; +import RadioGroup from './radio-group'; +import CheckboxGroup from './checkbox-group'; const componentMap: Record = {}; const propsConverterMap: Record = {}; @@ -33,20 +35,50 @@ let componentsRegistered = false; * 注册组件 */ function registerComponents() { - if (componentsRegistered) { - return; - } - componentsRegistered = true; + if (componentsRegistered) { + return; + } + componentsRegistered = true; - const componentsToRegister = [ - Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, - ContentContainer, FloatContainer, - Navbar, Button, ButtonGroup, Listview, - Form, FormItem, InputGroup, Textarea, NumberInput, Switch, DatePicker, DateTimePicker, Picker,Lookup - ]; - componentsToRegister.forEach((componentToRegister) => { - componentToRegister.register(componentMap, propsConverterMap, propConfigsConverterMap, resolverMap); - }); + const componentsToRegister = [ + Component, + PageContainer, + PageHeaderContainer, + PageBodyContainer, + PageFooterContainer, + ContentContainer, + FloatContainer, + Navbar, + Button, + ButtonGroup, + Listview, + Form, + FormItem, + InputGroup, + Textarea, + NumberInput, + Switch, + DatePicker, + DateTimePicker, + Picker, + Lookup, + RadioGroup, + CheckboxGroup + ]; + componentsToRegister.forEach((componentToRegister) => { + componentToRegister.register( + componentMap, + propsConverterMap, + propConfigsConverterMap, + resolverMap + ); + }); } -export { componentMap, propsConverterMap, propConfigsConverterMap, resolverMap, registerComponents }; +export { + componentMap, + propsConverterMap, + propConfigsConverterMap, + resolverMap, + registerComponents +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index af8a1ded56c..6b6cf708bb8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1571,24 +1571,15 @@ importers: 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 @@ -1600,73 +1591,37 @@ importers: 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) + version: 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) '@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) + version: 7.18.0(eslint@9.19.0(jiti@1.21.6))(typescript@4.9.5) '@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) + version: 9.0.0(eslint@9.19.0(jiti@1.21.6))(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) + version: 13.0.0(eslint-plugin-vue@9.29.1(eslint@9.19.0(jiti@1.21.6)))(eslint@9.19.0(jiti@1.21.6))(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 + version: 9.29.1(eslint@9.19.0(jiti@1.21.6)) 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 @@ -1676,30 +1631,9 @@ importers: 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(jsdom@20.0.3)(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) + version: 0.29.8(happy-dom@14.12.3)(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) @@ -3661,18 +3595,10 @@ 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} @@ -3714,19 +3640,10 @@ 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'} @@ -4573,9 +4490,6 @@ 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} @@ -6265,10 +6179,6 @@ 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==} @@ -6826,12 +6736,6 @@ 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} @@ -7017,10 +6921,6 @@ 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'} @@ -7103,10 +7003,6 @@ 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'} @@ -7907,10 +7803,6 @@ 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'} @@ -10675,9 +10567,6 @@ 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==} @@ -13291,11 +13180,6 @@ 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) @@ -13317,20 +13201,6 @@ 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 @@ -13345,8 +13215,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@8.57.1': {} - '@eslint/js@9.19.0': {} '@eslint/object-schema@2.1.6': {} @@ -13386,18 +13254,8 @@ 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': {} @@ -14478,24 +14336,6 @@ 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 @@ -14549,19 +14389,6 @@ 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 @@ -14610,18 +14437,6 @@ 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) @@ -14705,17 +14520,6 @@ 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)) @@ -14759,8 +14563,6 @@ 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 @@ -15032,22 +14834,22 @@ snapshots: '@vue/devtools-api@6.6.4': {} - '@vue/eslint-config-prettier@9.0.0(eslint@8.57.1)(prettier@3.5.3)': + '@vue/eslint-config-prettier@9.0.0(eslint@9.19.0(jiti@1.21.6))(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) + eslint: 9.19.0(jiti@1.21.6) + eslint-config-prettier: 9.1.0(eslint@9.19.0(jiti@1.21.6)) + eslint-plugin-prettier: 5.2.3(eslint-config-prettier@9.1.0(eslint@9.19.0(jiti@1.21.6)))(eslint@9.19.0(jiti@1.21.6))(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)': + '@vue/eslint-config-typescript@13.0.0(eslint-plugin-vue@9.29.1(eslint@9.19.0(jiti@1.21.6)))(eslint@9.19.0(jiti@1.21.6))(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) + '@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) + '@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) + eslint-plugin-vue: 9.29.1(eslint@9.19.0(jiti@1.21.6)) + vue-eslint-parser: 9.4.3(eslint@9.19.0(jiti@1.21.6)) optionalDependencies: typescript: 4.9.5 transitivePeerDependencies: @@ -17208,10 +17010,6 @@ 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: @@ -17733,9 +17531,9 @@ snapshots: dependencies: eslint: 9.19.0(jiti@1.21.6) - eslint-config-prettier@9.1.0(eslint@8.57.1): + eslint-config-prettier@9.1.0(eslint@9.19.0(jiti@1.21.6)): dependencies: - eslint: 8.57.1 + eslint: 9.19.0(jiti@1.21.6) eslint-import-resolver-node@0.3.9: dependencies: @@ -17823,28 +17621,14 @@ 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): + eslint-plugin-prettier@5.2.3(eslint-config-prettier@9.1.0(eslint@9.19.0(jiti@1.21.6)))(eslint@9.19.0(jiti@1.21.6))(prettier@3.5.3): dependencies: - eslint: 8.57.1 + eslint: 9.19.0(jiti@1.21.6) 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-config-prettier: 9.1.0(eslint@9.19.0(jiti@1.21.6)) eslint-plugin-vue@9.29.1(eslint@9.19.0(jiti@1.21.6)): dependencies: @@ -17874,49 +17658,6 @@ 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)) @@ -18209,10 +17950,6 @@ 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 @@ -18331,12 +18068,6 @@ 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 @@ -19239,8 +18970,6 @@ 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: {} @@ -22548,8 +22277,6 @@ snapshots: text-extensions@2.4.0: {} - text-table@0.2.0: {} - through2-filter@3.0.0: dependencies: through2: 2.0.5 @@ -23271,7 +22998,7 @@ snapshots: '@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@20.5.1)(sass-embedded@1.80.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' - '@vitest/browser' @@ -23289,8 +23016,7 @@ snapshots: vite-plugin-md@0.21.5(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@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) - '@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)) + '@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@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 @@ -23893,19 +23619,6 @@ 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 5e5388d263b4d577a054b37108ab0b8563b93c00 Mon Sep 17 00:00:00 2001 From: LuPing Zou <“zouluping@inspur.com”> Date: Thu, 17 Apr 2025 16:48:07 +0800 Subject: [PATCH 254/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E7=AB=AFC?= =?UTF-8?q?ard=E6=8E=A7=E4=BB=B6=E6=94=AF=E6=8C=81=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=BB=91=E5=8A=A8=E5=B7=A5=E5=85=B7=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../property-config/card.property-config.ts | 39 ++++++++++++++++- .../card/src/schema/card.schema.json | 11 +++++ .../card/src/schema/schema-mapper.ts | 3 +- .../src/properties/toolbar-item.property.ts | 24 +++++++---- .../src/common/toolbar-resolver.ts | 42 +++++++++++++------ .../list-view.property-config.ts | 3 +- .../list-view/src/schema/schema-mapper.ts | 31 +------------- 7 files changed, 100 insertions(+), 53 deletions(-) diff --git a/packages/mobile-ui-vue/components/card/src/property-config/card.property-config.ts b/packages/mobile-ui-vue/components/card/src/property-config/card.property-config.ts index 89e883bca74..8dcb6e8a87b 100644 --- a/packages/mobile-ui-vue/components/card/src/property-config/card.property-config.ts +++ b/packages/mobile-ui-vue/components/card/src/property-config/card.property-config.ts @@ -1,9 +1,13 @@ -import { ContainerBaseProperty } from "@farris/mobile-ui-vue/common"; +import { ContainerBaseProperty, ToolbarItemProperty } from "@farris/mobile-ui-vue/common"; +import { toolbarConverter } from "@farris/mobile-ui-vue/dynamic-resolver/src/converter"; export class CardProperty extends ContainerBaseProperty { + private toolbarItemProperty: ToolbarItemProperty; + constructor(componentId: string, designerHostService: any) { super(componentId, designerHostService); + this.toolbarItemProperty = new ToolbarItemProperty(componentId, designerHostService); } public getPropertyConfig(propertyData: any) { @@ -13,6 +17,8 @@ export class CardProperty extends ContainerBaseProperty { this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); // 行为 this.propertyConfig.categories['behavior'] = this.getBehaviorConfig(propertyData); + // 滑动工具栏 + this.propertyConfig.categories['toolbar'] = this.getToolbarConfig(propertyData); return this.propertyConfig; } @@ -25,4 +31,35 @@ export class CardProperty extends ContainerBaseProperty { }; } + protected getToolbarConfig(propertyData: any) { + return { + title: '底部工具栏', + $converter: toolbarConverter, + properties: { + items: { + title: '底部工具栏', + editor: { + type: "collection-property-editor", + textField: 'text', + modalTitle: '工具栏编辑器', + onSelectionChange: ({ selectedData, propertyConfig }) => { + propertyConfig.value = this.toolbarItemProperty.getPropertyConfig(selectedData.value, { + showAppearance: true, + showButtonType: true, + showIcon: true, + }); + }, + defaultComponentSchema: { + id: 'button', + text: '按钮', + visible: true, + disabled: false, + buttonType: 'primary', + } + } + } + } + }; + } + } diff --git a/packages/mobile-ui-vue/components/card/src/schema/card.schema.json b/packages/mobile-ui-vue/components/card/src/schema/card.schema.json index 6c6a9aaf197..15bafa49fa7 100644 --- a/packages/mobile-ui-vue/components/card/src/schema/card.schema.json +++ b/packages/mobile-ui-vue/components/card/src/schema/card.schema.json @@ -56,6 +56,17 @@ "description": "是否显示尾部区域", "type": "boolean", "default": true + }, + "toolbar": { + "description": "底部工具栏", + "type": "object", + "properties": { + "items": { + "type": "array", + "default": [] + } + }, + "default": {} } }, "required": [ diff --git a/packages/mobile-ui-vue/components/card/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/card/src/schema/schema-mapper.ts index de0117f8568..97c101bfe1a 100644 --- a/packages/mobile-ui-vue/components/card/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/card/src/schema/schema-mapper.ts @@ -1,7 +1,8 @@ -import { resolveAppearance, resolvePadding, resolveMargin, MapperFunction } from '../../../dynamic-resolver'; +import { resolveAppearance, resolvePadding, resolveMargin, resolveToolbar, MapperFunction } from '../../../dynamic-resolver'; export const schemaMapper = new Map([ ['appearance', resolveAppearance], ['padding', resolvePadding], ['margin', resolveMargin], + ['toolbar', resolveToolbar], ]); diff --git a/packages/mobile-ui-vue/components/common/src/properties/toolbar-item.property.ts b/packages/mobile-ui-vue/components/common/src/properties/toolbar-item.property.ts index e70a07fed3c..ea857a333ff 100644 --- a/packages/mobile-ui-vue/components/common/src/properties/toolbar-item.property.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/toolbar-item.property.ts @@ -3,6 +3,7 @@ import { BaseControlProperty } from "./base-property"; export interface ToolbarItemPropOptions { showAppearance?: boolean; showButtonType?: boolean; + showIcon?: boolean; } export class ToolbarItemProperty extends BaseControlProperty { @@ -35,18 +36,18 @@ export class ToolbarItemProperty extends BaseControlProperty { protected getAppearanceConfig(propertyData: any) { const buttonTypeData = [ - { text: 'Primary', value: 'primary' }, - { text: 'Danger', value: 'danger' }, - { text: 'Warning', value: 'warning' }, - { text: 'Success', value: 'success' }, - { text: 'Secondary', value: 'secondary' }, - { text: 'Info', value: 'info' }, + { text: 'Primary 主要', value: 'primary' }, + { text: 'Danger 危险', value: 'danger' }, + { text: 'Warning 警告', value: 'warning' }, + { text: 'Success 成功', value: 'success' }, + { text: 'Secondary 次要', value: 'secondary' }, + { text: 'Info 提示', value: 'info' }, ]; const additionalProperties: any = {}; if (this.options?.showButtonType) { additionalProperties.buttonType = { - description: '按钮的颜色主题', - title: '按钮样式', + description: '按钮的主题风格', + title: '按钮类型', editor: { type: 'combo-tree', textField: 'text', @@ -55,6 +56,13 @@ export class ToolbarItemProperty extends BaseControlProperty { }, }; } + if (this.options?.showIcon) { + additionalProperties.icon = { + description: '显示在按钮文本左侧的图标', + title: '按钮图标', + type: 'string', + }; + } return super.getAppearanceConfig(propertyData, additionalProperties); } diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts index 08ebea5f43f..5c114f65d73 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts @@ -1,15 +1,33 @@ -export function resolveToolbar(key: string, toolbarObject: { buttons: any[],appearance:any }) { - const result = [] as any; - toolbarObject?.buttons.map(button => { - const newButton = {}; - Object.keys(button).map(key => { - if (key === 'appearance') { - newButton['class']=button[key]?.class||''; - }else{ - newButton[key] = button[key]; +function generateResolveToolbarFunction(toolbarPropertyName = "toolbarItems", options?: { defaultButtonType: string }) { + return (key: string, toolbarObject: { items: any[] }) => { + const toolbarItems: any[] = []; + const result = { [toolbarPropertyName]: toolbarItems }; + if (typeof toolbarObject !== 'object' || !toolbarObject) { + return result; + } + const items: any[] = toolbarObject?.items || []; + if (!Array.isArray(items)) { + return result; + } + items.filter(item => typeof item === 'object' && !!item).forEach(item => { + const newItem: any = {}; + Object.keys(item).forEach(key => { + if (key === 'buttonType') { + newItem.type = item[key]; + } else if (key === 'type') { + return; + } else { + newItem[key] = item[key]; + } + }); + if (!newItem.type && !newItem.customClass && !newItem.customStyle && options?.defaultButtonType) { + newItem.type = options.defaultButtonType; } + toolbarItems.push(newItem); }); - result.push(newButton); - }); - return { buttons: result }; + return result; + }; } + +export const resolveToolbar = generateResolveToolbarFunction("toolbarItems", { defaultButtonType: "primary" }); +export const resolveSwipeToolbar = generateResolveToolbarFunction("swipeToolbar", { defaultButtonType: "danger" }); diff --git a/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.ts b/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.ts index 700b5cacce8..3fd5bbe9298 100644 --- a/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.ts +++ b/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.ts @@ -107,7 +107,8 @@ export class ListViewProperty extends ContainerBaseProperty { id: 'button', text: '按钮', visible: true, - disabled: false + disabled: false, + buttonType: 'danger', } } } 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 e28d9aff5fd..c8d356c6c06 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,4 +1,4 @@ -import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; +import { resolveAppearance, resolveSwipeToolbar, MapperFunction } from '../../../dynamic-resolver'; function createTemplatePropResolver(name: string): MapperFunction { return (key: string, content: string) => { @@ -10,35 +10,6 @@ function createTemplatePropResolver(name: string): MapperFunction { }; } -function resolveSwipeToolbar(propKey: string, swipeToolbar: any) { - const swipeToolbarItems: any[] = []; - const result = { swipeToolbar: swipeToolbarItems }; - if (typeof swipeToolbar !== 'object' || !swipeToolbar) { - return result; - } - const items: any[] = swipeToolbar?.items || []; - if (!Array.isArray(items)) { - return result; - } - items.filter(item => typeof item === 'object' && !!item).forEach(item => { - const newItem: any = {}; - Object.keys(item).forEach(key => { - if (key === 'buttonType') { - newItem.type = item[key]; - } else if (key === 'type') { - return; - } else { - newItem[key] = item[key]; - } - }); - if (!newItem.type && !newItem.customClass && !newItem.customStyle) { - newItem.type = 'danger'; - } - swipeToolbarItems.push(newItem); - }); - return result; -} - export const schemaMapper = new Map([ ['appearance', resolveAppearance], ['dataSource', 'data'], -- Gitee From 64365ae787e53688cacb19b8c73bb5e36f13a487 Mon Sep 17 00:00:00 2001 From: LuPing Zou <“zouluping@inspur.com”> Date: Thu, 17 Apr 2025 16:48:07 +0800 Subject: [PATCH 255/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E7=AB=AFN?= =?UTF-8?q?avbar=E6=8E=A7=E4=BB=B6=E8=AE=BE=E8=AE=A1=E6=97=B6=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/designer/card.design.component.tsx | 22 ++++++++--------- .../src/common/toolbar-resolver.ts | 3 +++ .../mobile-ui-vue/components/navbar/index.ts | 20 ++++------------ .../src/designer/nav.design.component.tsx | 18 ++++++++------ .../navbar/src/navbar.component.tsx | 14 ++++++++--- .../components/navbar/src/navbar.props.ts | 14 +++++++---- .../property-config/navbar.property-config.ts | 4 +++- .../navbar/src/schema/navbar.schema.json | 24 ++++++++++++++++--- .../navbar/src/schema/schema-mapper.ts | 5 ++-- 9 files changed, 77 insertions(+), 47 deletions(-) diff --git a/packages/mobile-ui-vue/components/card/src/designer/card.design.component.tsx b/packages/mobile-ui-vue/components/card/src/designer/card.design.component.tsx index babedc37e2d..17122cf19c9 100644 --- a/packages/mobile-ui-vue/components/card/src/designer/card.design.component.tsx +++ b/packages/mobile-ui-vue/components/card/src/designer/card.design.component.tsx @@ -24,17 +24,15 @@ export default defineComponent({ }); context.expose(componentInstance.value); - return () => { - return ( - - {context.slots.default && context.slots.default()} - - ); - }; + return () => ( + + {context.slots.default && context.slots.default()} + + ); } }); diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts index 5c114f65d73..2a701e5c463 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts @@ -14,6 +14,9 @@ function generateResolveToolbarFunction(toolbarPropertyName = "toolbarItems", op Object.keys(item).forEach(key => { if (key === 'buttonType') { newItem.type = item[key]; + } else if (key === 'appearance') { + newItem.customClass = item[key]?.class || ''; + newItem.customStyle = item[key]?.style || ''; } else if (key === 'type') { return; } else { diff --git a/packages/mobile-ui-vue/components/navbar/index.ts b/packages/mobile-ui-vue/components/navbar/index.ts index 87285570d1b..41cc8f5bd6d 100644 --- a/packages/mobile-ui-vue/components/navbar/index.ts +++ b/packages/mobile-ui-vue/components/navbar/index.ts @@ -1,25 +1,15 @@ -import { withInstall, RegisterContext } from '@farris/mobile-ui-vue/common'; -import { propsResolverGenerator } from './src/navbar.props'; +import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import NavbarInstallless from './src/navbar.component'; +import { propsResolverGenerator } from './src/navbar.props'; import NavbarDesign from './src/designer/nav.design.component'; const NAVBAR_REGISTERED_NAME = 'navbar'; const Navbar = withInstall(NavbarInstallless); -Navbar.register = ( - componentMap: Record, propsResolverMap: Record, - configresolverMap: Record, resolverMap: Record, registerContext: RegisterContext -) => { - componentMap[NAVBAR_REGISTERED_NAME] = Navbar; - propsResolverMap[NAVBAR_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; - -Navbar.registerDesigner = (componentMap: Record, propsResolverMap: Record, - configresolverMap: Record, registerContext: RegisterContext) => { - componentMap[NAVBAR_REGISTERED_NAME] = NavbarDesign; - propsResolverMap[NAVBAR_REGISTERED_NAME] = propsResolverGenerator(registerContext); -}; +withRegister(Navbar, { name: NAVBAR_REGISTERED_NAME, propsResolverGenerator }); +withRegisterDesigner(Navbar, { name: NAVBAR_REGISTERED_NAME, propsResolverGenerator, designerComponent: NavbarDesign }); +export * from './src/navbar.props'; export { Navbar }; export default Navbar; diff --git a/packages/mobile-ui-vue/components/navbar/src/designer/nav.design.component.tsx b/packages/mobile-ui-vue/components/navbar/src/designer/nav.design.component.tsx index 3d72b36708a..ea72d34d8c7 100644 --- a/packages/mobile-ui-vue/components/navbar/src/designer/nav.design.component.tsx +++ b/packages/mobile-ui-vue/components/navbar/src/designer/nav.design.component.tsx @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { computed, defineComponent, inject, onMounted, ref, SetupContext } from 'vue'; +import { computed, defineComponent, inject, onMounted, ref } from 'vue'; -import Navbar from '../..'; +import { Navbar } from '@farris/mobile-ui-vue/navbar'; import { navbarProps, NavbarProps } from '../navbar.props'; import { useDesignerRules } from './use-designer-rules'; import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common'; @@ -23,9 +23,13 @@ import { DesignerHostService, DesignerItemContext, useDesignerComponent } from ' export default defineComponent({ name: 'FNavDesign', props: navbarProps, - emits: ['nav'] as (string[] & ThisType) | undefined, - setup(props: NavbarProps, context: SetupContext) { - const elementRef = ref(); + emits: [], + setup(props: NavbarProps, context) { + const navbarRef = ref(); + const elementRef = computed(() => { + return navbarRef.value?.elementRef; + }); + const designItemContext = inject('design-item-context') as DesignerItemContext; const designerHostService = inject('designer-host-service'); const designerRulesComposition = useDesignerRules(designItemContext, designerHostService); @@ -34,16 +38,16 @@ export default defineComponent({ onMounted(() => { elementRef.value.componentInstance = componentInstance; }); - context.expose(componentInstance.value); const navbarProps = computed(() => ({ ...props, + showToolbarOverlay: false, })); return () => { return ( - + ); }; } 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 529f01fcae9..821048ba3f6 100644 --- a/packages/mobile-ui-vue/components/navbar/src/navbar.component.tsx +++ b/packages/mobile-ui-vue/components/navbar/src/navbar.component.tsx @@ -27,6 +27,7 @@ export default defineComponent({ setup(props: NavbarProps, context) { const { bem } = useBem(NAVBAR_NAME); const { emit, slots } = context; + const elementRef = ref(); const showToolbarPopover = ref(false); function onLeftClick(event: MouseEvent): void { @@ -89,7 +90,7 @@ export default defineComponent({ v-model:show={showToolbarPopover.value} placement="bottom-right" contentClass={bem('toolbar')} - overlay={true} + overlay={props.showToolbarOverlay} >{{ triggerElement: () => ( @@ -99,7 +100,8 @@ export default defineComponent({ }).map((item) => (
    onToolbarItemClick(item)}> {item.text}
    @@ -123,8 +125,14 @@ export default defineComponent({ ); } + context.expose({ elementRef }); + return () => ( -
    +
    {shouldRenderLeft.value && renderLeftContent()}
    {slots.title ? slots.title() : props.title}
    {shouldRenderRight.value && renderRightContent()} 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 d4983176a38..30fe551e60f 100644 --- a/packages/mobile-ui-vue/components/navbar/src/navbar.props.ts +++ b/packages/mobile-ui-vue/components/navbar/src/navbar.props.ts @@ -44,12 +44,18 @@ export const navbarProps = { /** 右侧的下拉按钮工具栏 */ toolbarItems: { type: Array, default: [] }, + + /** 是否为工具栏的弹出气泡启用遮罩 */ + showToolbarOverlay: { type: Boolean, default: true }, + + customClass: { type: String, default: '' }, + customStyle: { type: String, default: '' }, }; export const propsResolverGenerator = getPropsResolverGenerator( - navbarProps, - navbarSchema, - schemaMapper, - schemaResolver + navbarProps, + navbarSchema, + schemaMapper, + schemaResolver ); export type NavbarProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts b/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts index 7f00dbc2427..a410ba19365 100644 --- a/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts +++ b/packages/mobile-ui-vue/components/navbar/src/property-config/navbar.property-config.ts @@ -29,7 +29,9 @@ export class NavBarProperty extends BaseControlProperty { textField: 'text', modalTitle: '右侧工具栏编辑器', onSelectionChange: ({ selectedData, propertyConfig }) => { - propertyConfig.value = this.toolbarItemProperty.getPropertyConfig(selectedData.value); + propertyConfig.value = this.toolbarItemProperty.getPropertyConfig(selectedData.value, { + showAppearance: true, + }); }, defaultComponentSchema: { id: 'button', 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 index d933a637939..3efd0d846f2 100644 --- a/packages/mobile-ui-vue/components/navbar/src/schema/navbar.schema.json +++ b/packages/mobile-ui-vue/components/navbar/src/schema/navbar.schema.json @@ -6,13 +6,13 @@ "type": "object", "properties": { "id": { - "description": "标志", + "description": "标识", "type": "string" }, "type": { "description": "组件类型", "type": "string", - "default": "button-group" + "default": "navbar" }, "appearance": { "description": "外观", @@ -46,7 +46,25 @@ "type": "string" }, "rightToolbar": { - "type": "object" + "description": "右侧工具栏", + "type": "object", + "properties": { + "items": { + "type": "array", + "default": [] + } + }, + "default": {} + }, + "showBottomBorder": { + "description": "是否在下方显示分隔线", + "type": "boolean", + "default": true + }, + "showToolbarOverlay": { + "description": "是否为工具栏的弹出气泡启用遮罩", + "type": "boolean", + "default": true } }, "events": [ 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 index 90dc1493e55..a37812cae58 100644 --- a/packages/mobile-ui-vue/components/navbar/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/navbar/src/schema/schema-mapper.ts @@ -1,5 +1,6 @@ -import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; +import { resolveAppearance, resolveToolbar, MapperFunction } from '../../../dynamic-resolver'; export const schemaMapper = new Map([ - ['appearance', resolveAppearance] + ['appearance', resolveAppearance], + ['rightToolbar', resolveToolbar], ]); -- Gitee From 1b7980c89968b446bb656e878059527d414df646 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Fri, 18 Apr 2025 15:34:14 +0800 Subject: [PATCH 256/287] =?UTF-8?q?fix:=20=E8=B0=83=E6=95=B4=E6=89=93?= =?UTF-8?q?=E5=8C=85=E5=90=8EMobile=E5=88=97=E8=A1=A8=E8=A1=8C=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E6=97=A0=E6=B3=95=E6=98=BE=E7=A4=BA=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/mobile-render/farris.config.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/mobile-render/farris.config.mjs b/packages/mobile-render/farris.config.mjs index 3939bebd141..6a1d3210954 100644 --- a/packages/mobile-render/farris.config.mjs +++ b/packages/mobile-render/farris.config.mjs @@ -30,6 +30,8 @@ export default { } }, alias: [ + + { find: "vue", replacement: 'vue/dist/vue.esm-bundler.js' }, { find: "@farris/devkit-vue", replacement: fileURLToPath(new URL('../devkit/lib', import.meta.url)) }, { find: "@farris/bef-vue", replacement: fileURLToPath(new URL('../bef/lib', import.meta.url)) }, { find: "@farris/mobile-command-services-vue", replacement: fileURLToPath(new URL('../mobile-command-services/lib', import.meta.url)) }, -- Gitee From 48f22e9975237338c1b9e5443969a6bef003c92f Mon Sep 17 00:00:00 2001 From: LuPing Zou <“zouluping@inspur.com”> Date: Fri, 18 Apr 2025 14:03:15 +0800 Subject: [PATCH 257/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8=E7=AB=AFB?= =?UTF-8?q?uttonGroup=E6=8E=A7=E4=BB=B6=E8=AE=BE=E8=AE=A1=E6=97=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../use-mobile-designer-context.ts | 3 +- .../components/button-group/index.ts | 6 +- .../src/button-group.component.tsx | 11 ++- .../button-group/src/button-group.props.ts | 3 + .../button-group/src/button-group.scss | 9 +- .../src/designer/card.design.component.tsx | 35 +++++++ .../src/designer/use-designer-rules.ts | 41 ++++++++ .../button-group.property-config.ts | 98 +++++++++++++++++++ .../src/schema/button-group.schema.json | 53 +++++----- .../button-group/src/schema/schema-mapper.ts | 25 +++-- .../property-config/card.property-config.ts | 2 +- .../common/src/properties/dg-control.ts | 2 + .../src/properties/toolbar-item.property.ts | 46 +++++++-- .../src/common/appearance-resolver.ts | 2 +- .../src/common/toolbar-resolver.ts | 2 +- .../list-view.property-config.ts | 2 +- 16 files changed, 290 insertions(+), 50 deletions(-) create mode 100644 packages/mobile-ui-vue/components/button-group/src/designer/card.design.component.tsx create mode 100644 packages/mobile-ui-vue/components/button-group/src/designer/use-designer-rules.ts create mode 100644 packages/mobile-ui-vue/components/button-group/src/property-config/button-group.property-config.ts diff --git a/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts b/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts index 9b7b3bc8a30..43c7531f920 100644 --- a/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts +++ b/packages/designer/src/components/composition/designer-context/use-mobile-designer-context.ts @@ -5,6 +5,7 @@ import SupportedControllers from '../../composition/command/supported-controller import { Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, Picker, NumberInput, Textarea, DatePicker, DateTimePicker, ContentContainer, Card, FloatContainer, Navbar, ListView, Form, FormItem, InputGroup, Button, registerDesignerComponents, Switch, CheckboxGroup, RadioGroup, + ButtonGroup, } from '@farris/mobile-ui-vue'; import { useMobileControlCreator } from "../control-creator/use-mobile-control-creator"; import { FormComponent, UseFormSchema } from "../../../components/types"; @@ -24,7 +25,7 @@ export function useMobileDesignerContext(): UseDesignerContext { ContentContainer, Card, FloatContainer,Textarea,DatePicker,DateTimePicker, Navbar, ListView,Picker,NumberInput,Switch,CheckboxGroup,RadioGroup, Form, FormItem, InputGroup, - Button + Button, ButtonGroup, ]; registerDesignerComponents(componentsToRegister); diff --git a/packages/mobile-ui-vue/components/button-group/index.ts b/packages/mobile-ui-vue/components/button-group/index.ts index 4bb2569a6cc..f825aa66e68 100644 --- a/packages/mobile-ui-vue/components/button-group/index.ts +++ b/packages/mobile-ui-vue/components/button-group/index.ts @@ -1,14 +1,14 @@ -import { Plugin } from 'vue'; import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import ButtonGroupInstallless from './src/button-group.component'; import { propsResolverGenerator } from './src/button-group.props'; +import ButtonGroupDesign from './src/designer/card.design.component'; const BUTTON_GROUP_REGISTERED_NAME = 'button-group'; const ButtonGroup = withInstall(ButtonGroupInstallless); withRegister(ButtonGroup, { name: BUTTON_GROUP_REGISTERED_NAME, propsResolverGenerator }); -// withRegisterDesigner(ButtonGroup, { name: BUTTON_GROUP_REGISTERED_NAME, propsResolverGenerator, designerComponent: InputGroupDesign }); +withRegisterDesigner(ButtonGroup, { name: BUTTON_GROUP_REGISTERED_NAME, propsResolverGenerator, designerComponent: ButtonGroupDesign }); export * from './src/button-group.props'; export { ButtonGroup }; -export default ButtonGroup as typeof ButtonGroup & Plugin; +export default ButtonGroup; 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 index 5d1949fee95..d059f45e876 100644 --- 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 @@ -1,4 +1,4 @@ -import { computed, defineComponent } from 'vue'; +import { defineComponent, computed, ref } from 'vue'; import { useBem } from '@farris/mobile-ui-vue/common'; import FButton from '@farris/mobile-ui-vue/button'; import { Icon } from '@farris/mobile-ui-vue/icon'; @@ -10,6 +10,7 @@ export default defineComponent({ emits: ['click'], setup(props: ButtonGroupProps, context) { const { bem } = useBem(BUTTON_GROUP_NAME); + const elementRef = ref(); const buttonItems = computed(() => { return props.items || []; @@ -120,8 +121,14 @@ export default defineComponent({ return buttonItem.variant === 'bare-vertical' ? renderBareVerticalButton(buttonItem) : renderDefaultButton(buttonItem); } + context.expose({ elementRef }); + return () => ( -
    +
    {buttonItems.value.map((buttonItem) => renderButtonItem(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 index 8919ad0dd81..ec5f39d8c95 100644 --- 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 @@ -44,6 +44,9 @@ export const buttonGroupProps = { /** 是否垂直排列 */ vertical: { type: Boolean, default: false }, + + customClass: { type: String, default: '' }, + customStyle: { type: String, default: '' }, }; /** 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 index dc524668874..5660c571295 100644 --- a/packages/mobile-ui-vue/components/button-group/src/button-group.scss +++ b/packages/mobile-ui-vue/components/button-group/src/button-group.scss @@ -18,6 +18,7 @@ white-space: nowrap; flex: 0 1 auto; user-select: none; + outline: none !important; &--bare-vertical { display: inline-flex; @@ -68,22 +69,22 @@ border-radius: 0; } - &--horizontal:not(&--mode-default) &__item:first-child { + &--horizontal:not(&--mode-default) &__item:first-child:not(:last-child) { border-top-right-radius: 0; border-bottom-right-radius: 0; } - &--vertical:not(&--mode-default) &__item:first-child { + &--vertical:not(&--mode-default) &__item:first-child:not(:last-child) { border-bottom-left-radius: 0; border-bottom-right-radius: 0; } - &--horizontal:not(&--mode-default) &__item:last-child { + &--horizontal:not(&--mode-default) &__item:last-child:not(:first-child) { border-top-left-radius: 0; border-bottom-left-radius: 0; } - &--vertical:not(&--mode-default) &__item:last-child { + &--vertical:not(&--mode-default) &__item:last-child:not(:first-child) { border-top-left-radius: 0; border-top-right-radius: 0; } diff --git a/packages/mobile-ui-vue/components/button-group/src/designer/card.design.component.tsx b/packages/mobile-ui-vue/components/button-group/src/designer/card.design.component.tsx new file mode 100644 index 00000000000..145466524ca --- /dev/null +++ b/packages/mobile-ui-vue/components/button-group/src/designer/card.design.component.tsx @@ -0,0 +1,35 @@ +import { computed, defineComponent, inject, onMounted, ref } from 'vue'; +import { buttonGroupProps, ButtonGroupProps } from '../button-group.props'; +import { useDesignerRulesForButtonGroup } from './use-designer-rules'; +import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common'; +import { ButtonGroup } from '@farris/mobile-ui-vue/button-group'; + +export default defineComponent({ + name: 'FButtonGroupDesign', + props: buttonGroupProps, + emits: [], + setup(props: ButtonGroupProps, context) { + const buttonGroupRef = ref(); + const elementRef = computed(() => { + return buttonGroupRef.value?.elementRef; + }); + + const designerHostService = inject('designer-host-service'); + const designItemContext = inject('design-item-context') as DesignerItemContext; + const designerRulesComposition = useDesignerRulesForButtonGroup(designItemContext, designerHostService); + const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); + + onMounted(() => { + elementRef.value.componentInstance = componentInstance; + }); + context.expose(componentInstance.value); + + function onClick(): void { + elementRef.value?.click?.(); + } + + return () => ( + + ); + } +}); diff --git a/packages/mobile-ui-vue/components/button-group/src/designer/use-designer-rules.ts b/packages/mobile-ui-vue/components/button-group/src/designer/use-designer-rules.ts new file mode 100644 index 00000000000..e5c930c80df --- /dev/null +++ b/packages/mobile-ui-vue/components/button-group/src/designer/use-designer-rules.ts @@ -0,0 +1,41 @@ +import { DesignerItemContext } from "@farris/mobile-ui-vue/common"; +import { ButtonGroupProperty } from "../property-config/button-group.property-config"; +import { DesignerHostService, DraggingResolveContext, UseDesignerRules } from "@farris/mobile-ui-vue/common"; + +export function useDesignerRulesForButtonGroup(designItemContext: DesignerItemContext, designerHostService?: DesignerHostService): UseDesignerRules { + + function canAccepts(draggingContext: DraggingResolveContext): boolean { + return false; + } + + function getStyles() { + return ''; + } + + function checkCanMoveComponent() { + return true; + } + + function checkCanDeleteComponent() { + return true; + } + + function hideNestedPaddingInDesginerView() { + return true; + } + + function getPropsConfig(componentId: string) { + const buttonGroupProp = new ButtonGroupProperty(componentId, designerHostService); + const { schema } = designItemContext; + return buttonGroupProp.getPropertyConfig(schema); + } + + return { + canAccepts, + getStyles, + checkCanMoveComponent, + checkCanDeleteComponent, + hideNestedPaddingInDesginerView, + getPropsConfig + }; +} diff --git a/packages/mobile-ui-vue/components/button-group/src/property-config/button-group.property-config.ts b/packages/mobile-ui-vue/components/button-group/src/property-config/button-group.property-config.ts new file mode 100644 index 00000000000..bfa8c6387fa --- /dev/null +++ b/packages/mobile-ui-vue/components/button-group/src/property-config/button-group.property-config.ts @@ -0,0 +1,98 @@ +import { BaseControlProperty, ToolbarItemProperty } from "@farris/mobile-ui-vue/common"; + +export class ButtonGroupProperty extends BaseControlProperty { + + private toolbarItemProperty: ToolbarItemProperty; + + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + this.toolbarItemProperty = new ToolbarItemProperty(componentId, designerHostService); + } + + public getPropertyConfig(propertyData: any) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicPropConfig(propertyData); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceConfig(propertyData); + // 行为 + this.propertyConfig.categories['behavior'] = this.getBehaviorConfig(propertyData); + + return this.propertyConfig; + } + + private isDefaultMode(propertyData: any): boolean { + const mode = propertyData?.mode; + return mode !== 'group' && mode !== 'outline' && mode !== 'text'; + } + + public getBehaviorConfig(propertyData: any) { + return super.getBehaviorConfig(propertyData, '', { + items: { + title: '按钮栏', + editor: { + type: "collection-property-editor", + textField: 'text', + modalTitle: '按钮栏编辑器', + onSelectionChange: ({ selectedData, propertyConfig }) => { + propertyConfig.value = this.toolbarItemProperty.getPropertyConfig(selectedData.value, { + showAppearance: true, + showButtonType: true, + showIcon: true, + showPlain: true, + showRound: this.isDefaultMode(propertyData), + showVariant: this.isDefaultMode(propertyData), + }); + }, + defaultComponentSchema: { + id: 'button-group-item', + text: '按钮', + visible: true, + disabled: false, + displayType: 'primary', + } + } + }, + mode: { + title: "显示模式", + description: "按钮组的显示模式", + editor: { + type: 'combo-tree', + textField: 'text', + valueField: 'value', + data: [ + { value: 'default', text: '独立按钮' }, + { value: 'group', text: '组合按钮' }, + { value: 'outline', text: '边框组合' }, + { value: 'text', text: '文本分隔' }, + ], + }, + }, + block: { + title: '是否占满整行', + description: '是否占满整行的宽度', + type: 'boolean', + }, + round: { + title: '是否圆角', + description: '是否为按钮启用圆角', + type: 'boolean', + }, + size: { + title: '按钮大小', + description: '按钮的大小', + editor: { + type: 'combo-tree', + textField: 'text', + valueField: 'value', + data: [ + { value: 'large', text: '大号按钮' }, + { value: 'normal', text: '普通按钮' }, + { value: 'small', text: '小号按钮' }, + { value: 'mini', text: '迷你按钮' }, + ], + }, + } + }); + } + +} 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 index 5688518ead4..f9f7c17b46d 100644 --- 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 @@ -6,7 +6,7 @@ "type": "object", "properties": { "id": { - "description": "唯一标志", + "description": "唯一标识", "type": "string" }, "type": { @@ -52,20 +52,34 @@ "type": "string", "default": "group" }, + "size": { + "description": "按钮大小", + "type": "string", + "default": "normal" + }, "items": { "description": "按钮项集合", "type": "array", + "default": [ + { + "id": "button-group-item", + "visible": true, + "disabled": false, + "text": "按钮", + "displayType": "primary" + } + ], "items": { "type": "object", "properties": { "id": { - "description": "唯一标志", + "description": "唯一标识", "type": "string" }, "type": { "description": "组件类型", "type": "string", - "default": "button-group" + "default": "button-group-item" }, "visible": { "description": "是否可见", @@ -78,23 +92,19 @@ "default": false }, "displayType": { - "description": "显示类型", + "description": "按钮类型", "type": "string", - "default": "default" + "default": "primary" }, "text": { "description": "文本", - "type": "string" - }, - "block": { - "description": "沾满整行", - "type": "boolean", - "default": false + "type": "string", + "default": "按钮" }, "round": { "description": "圆角按钮", "type": "boolean", - "default": false + "default": true }, "plain": { "description": "朴素按钮", @@ -105,6 +115,10 @@ "description": "图标", "type": "string" }, + "variant": { + "description": "变体", + "type": "string" + }, "onClick": { "description": "点击事件", "type": "string" @@ -116,22 +130,17 @@ "required": [ "id", "type" - ], - "ignore": [ - "id", - "type", - "appearance" ] } } }, "required": [ - "id", - "type" - ], - "ignore": [ "id", "type", - "appearance" + "items", + "round", + "block", + "mode", + "size" ] } \ 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 index 05f8ba178f9..b09130b3613 100644 --- 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 @@ -1,17 +1,28 @@ import { resolveAppearance, MapperFunction } from '../../../dynamic-resolver'; export function resolveItems(key: string, items: any[]) { - const newItems = items.map((item: any) => { - const newItem = { ...item }; - newItem.type = item.displayType; - + const buttonItems = items.filter(item => { + return !!item && typeof item === 'object'; + }).map(item => { + const newItem: any = {}; + Object.keys(item).forEach(key => { + if (key === 'displayType') { + newItem.type = item[key]; + } else if (key === 'appearance') { + newItem.customClass = item[key]?.class || ''; + newItem.customStyle = item[key]?.style || ''; + } else if (key === 'type') { + return; + } else { + newItem[key] = item[key]; + } + }); return newItem; }); - - return { items: newItems }; + return { items: buttonItems }; } export const schemaMapper = new Map([ ['appearance', resolveAppearance], - ['items', resolveItems] + ['items', resolveItems], ]); diff --git a/packages/mobile-ui-vue/components/card/src/property-config/card.property-config.ts b/packages/mobile-ui-vue/components/card/src/property-config/card.property-config.ts index 8dcb6e8a87b..4eb35897c39 100644 --- a/packages/mobile-ui-vue/components/card/src/property-config/card.property-config.ts +++ b/packages/mobile-ui-vue/components/card/src/property-config/card.property-config.ts @@ -54,7 +54,7 @@ export class CardProperty extends ContainerBaseProperty { text: '按钮', visible: true, disabled: false, - buttonType: 'primary', + displayType: 'primary', } } } diff --git a/packages/mobile-ui-vue/components/common/src/properties/dg-control.ts b/packages/mobile-ui-vue/components/common/src/properties/dg-control.ts index ad7cb877589..7686b232834 100644 --- a/packages/mobile-ui-vue/components/common/src/properties/dg-control.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/dg-control.ts @@ -22,6 +22,8 @@ export const DgControl = { 'button': { type: 'button', name: '按钮', icon: 'Button' }, + 'button-group': { type: 'button-group', name: '按钮组', icon: 'ButtonGroup' }, + 'input-group': { type: 'input-group', name: '文本', icon: 'TextBox' }, 'textarea': { type: 'textarea', name: '多行文本', icon: 'MultiTextBox' }, diff --git a/packages/mobile-ui-vue/components/common/src/properties/toolbar-item.property.ts b/packages/mobile-ui-vue/components/common/src/properties/toolbar-item.property.ts index ea857a333ff..16d97a2ee1c 100644 --- a/packages/mobile-ui-vue/components/common/src/properties/toolbar-item.property.ts +++ b/packages/mobile-ui-vue/components/common/src/properties/toolbar-item.property.ts @@ -4,6 +4,9 @@ export interface ToolbarItemPropOptions { showAppearance?: boolean; showButtonType?: boolean; showIcon?: boolean; + showRound?: boolean; + showPlain?: boolean; + showVariant?: boolean; } export class ToolbarItemProperty extends BaseControlProperty { @@ -36,16 +39,16 @@ export class ToolbarItemProperty extends BaseControlProperty { protected getAppearanceConfig(propertyData: any) { const buttonTypeData = [ - { text: 'Primary 主要', value: 'primary' }, - { text: 'Danger 危险', value: 'danger' }, - { text: 'Warning 警告', value: 'warning' }, - { text: 'Success 成功', value: 'success' }, - { text: 'Secondary 次要', value: 'secondary' }, - { text: 'Info 提示', value: 'info' }, + { text: '主要按钮', value: 'primary' }, + { text: '危险按钮', value: 'danger' }, + { text: '警告按钮', value: 'warning' }, + { text: '成功按钮', value: 'success' }, + { text: '次要按钮', value: 'secondary' }, + { text: '提示按钮', value: 'info' }, ]; const additionalProperties: any = {}; if (this.options?.showButtonType) { - additionalProperties.buttonType = { + additionalProperties.displayType = { description: '按钮的主题风格', title: '按钮类型', editor: { @@ -63,6 +66,35 @@ export class ToolbarItemProperty extends BaseControlProperty { type: 'string', }; } + if (this.options?.showRound) { + additionalProperties.round = { + description: '是否为按钮启用圆角', + title: '是否圆角', + type: 'boolean', + }; + } + if (this.options?.showPlain) { + additionalProperties.plain = { + description: '是否朴素按钮', + title: '是否朴素按钮', + type: 'boolean', + }; + } + if (this.options?.showVariant) { + additionalProperties.variant = { + description: '按钮的变体', + title: '变体', + editor: { + type: 'combo-tree', + textField: 'text', + valueField: 'value', + data: [ + { text: '无', value: 'default' }, + { text: '图标在上', value: 'bare-vertical' }, + ], + }, + }; + } return super.getAppearanceConfig(propertyData, additionalProperties); } diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/appearance-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/appearance-resolver.ts index 5d603ec4dec..4392ca2d6cc 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/appearance-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/appearance-resolver.ts @@ -1,3 +1,3 @@ export function resolveAppearance(key: string, appearanceObject: { class: string; style: string }) { - return { customClass: appearanceObject.class, customStyle: appearanceObject.style }; + return { customClass: appearanceObject?.class, customStyle: appearanceObject?.style }; } diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts index 2a701e5c463..0a3221cdf4f 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts @@ -12,7 +12,7 @@ function generateResolveToolbarFunction(toolbarPropertyName = "toolbarItems", op items.filter(item => typeof item === 'object' && !!item).forEach(item => { const newItem: any = {}; Object.keys(item).forEach(key => { - if (key === 'buttonType') { + if (key === 'displayType') { newItem.type = item[key]; } else if (key === 'appearance') { newItem.customClass = item[key]?.class || ''; diff --git a/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.ts b/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.ts index 3fd5bbe9298..12c220b375b 100644 --- a/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.ts +++ b/packages/mobile-ui-vue/components/list-view/src/property-config/list-view.property-config.ts @@ -108,7 +108,7 @@ export class ListViewProperty extends ContainerBaseProperty { text: '按钮', visible: true, disabled: false, - buttonType: 'danger', + displayType: 'danger', } } } -- Gitee From 443b60d643886db11c16f8994717063ec3ecd1fb Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Fri, 18 Apr 2025 17:47:43 +0800 Subject: [PATCH 258/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8loading?= =?UTF-8?q?=E3=80=81dialog=E3=80=81notify=E7=BB=84=E4=BB=B6=E5=AE=8C?= =?UTF-8?q?=E5=96=84;mobile-command-services=E6=96=B0=E5=A2=9Eui-services?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/ui-services/dialog.service.ts | 43 +++++++++ .../lib/ui-services/index.ts | 5 +- .../lib/ui-services/loading.service.ts | 28 ++++++ .../lib/ui-services/notify.service.ts | 42 +++++++++ packages/mobile-command-services/package.json | 4 +- .../mobile-ui-vue/components/button/index.ts | 3 +- .../mobile-ui-vue/components/dialog/index.ts | 1 + .../dialog/src/dialog.component.tsx | 33 +++---- .../components/dialog/src/dialog.props.ts | 31 +++++-- .../components/dialog/src/index.tsx | 80 ++++++++-------- packages/mobile-ui-vue/components/index.ts | 14 ++- .../components/list/src/list.component.tsx | 2 +- .../mobile-ui-vue/components/loading/index.ts | 5 +- .../loading/src/composition/types.ts | 5 - .../components/loading/src/index.tsx | 91 +++++++++++++++++++ .../components/loading/src/loading.props.ts | 20 +++- .../components/loading/src/loading.scss | 8 ++ .../components/notify/src/index.tsx | 43 +++++---- .../notify/src/notify.component.tsx | 29 ++---- .../components/notify/src/notify.props.ts | 62 +++++-------- .../src/pull-refresh.component.tsx | 2 +- .../switch/src/switch.component.tsx | 2 +- packages/mobile-ui-vue/demos/dialog/base.vue | 2 +- .../mobile-ui-vue/demos/loading/index.vue | 4 + .../mobile-ui-vue/demos/loading/service.vue | 13 +++ pnpm-lock.yaml | 15 +-- 26 files changed, 404 insertions(+), 183 deletions(-) create mode 100644 packages/mobile-command-services/lib/ui-services/dialog.service.ts create mode 100644 packages/mobile-command-services/lib/ui-services/loading.service.ts create mode 100644 packages/mobile-command-services/lib/ui-services/notify.service.ts delete mode 100644 packages/mobile-ui-vue/components/loading/src/composition/types.ts create mode 100644 packages/mobile-ui-vue/components/loading/src/index.tsx create mode 100644 packages/mobile-ui-vue/demos/loading/service.vue diff --git a/packages/mobile-command-services/lib/ui-services/dialog.service.ts b/packages/mobile-command-services/lib/ui-services/dialog.service.ts new file mode 100644 index 00000000000..17d65e5e00d --- /dev/null +++ b/packages/mobile-command-services/lib/ui-services/dialog.service.ts @@ -0,0 +1,43 @@ +import { Dialog } from '@farris/mobile-ui-vue'; + +/** + * 轻提示服务 + */ +class DialogService { + + /** + * 构造函数 + */ + constructor() { + } + + /** + * 确认弹窗 + */ + public confirm(options: any): void { + Dialog.confirm(options); + } + + /** + * 输入弹窗 + */ + public prompt(options: any): void { + Dialog.prompt(options); + } + + /** + * 提示弹窗 + */ + public alert(options: any): void { + Dialog.alert(options); + } + + /** + * 清除 + */ + public clear(): void { + Dialog.clear(); + } + +} +export { DialogService }; diff --git a/packages/mobile-command-services/lib/ui-services/index.ts b/packages/mobile-command-services/lib/ui-services/index.ts index cf513ecdf9e..60dd4735a27 100644 --- a/packages/mobile-command-services/lib/ui-services/index.ts +++ b/packages/mobile-command-services/lib/ui-services/index.ts @@ -1 +1,4 @@ -export * from './toast.service'; \ No newline at end of file +export * from './toast.service'; +export * from './dialog.service'; +export * from './loading.service'; +export * from './notify.service'; \ No newline at end of file diff --git a/packages/mobile-command-services/lib/ui-services/loading.service.ts b/packages/mobile-command-services/lib/ui-services/loading.service.ts new file mode 100644 index 00000000000..0d70378fcd7 --- /dev/null +++ b/packages/mobile-command-services/lib/ui-services/loading.service.ts @@ -0,0 +1,28 @@ +import { Loading } from '@farris/mobile-ui-vue'; + +/** + * 加载中服务 + */ +class LoadingService { + + /** + * 构造函数 + */ + constructor() { + } + + /** + * 显示加载中 + */ + public show(options: any): void { + Loading.show(options); + } + + /** + * 隐藏加载中 + */ + public hidden(): void { + Loading.hidden(); + } +} +export { LoadingService }; diff --git a/packages/mobile-command-services/lib/ui-services/notify.service.ts b/packages/mobile-command-services/lib/ui-services/notify.service.ts new file mode 100644 index 00000000000..85a7be05c1f --- /dev/null +++ b/packages/mobile-command-services/lib/ui-services/notify.service.ts @@ -0,0 +1,42 @@ +import { Notify } from '@farris/mobile-ui-vue'; + +/** + * 通知服务 + */ +class NotifyService { + + /** + * 构造函数 + */ + constructor() { + } + + /** + * 消息通知 + */ + public info(message: string): void { + Notify.info(message); + } + + /** + * 成功通知 + */ + public success(message: string): void { + Notify.success(message); + } + + /** + * 警告通知 + */ + public warning(message: string): void { + Notify.warning(message); + } + + /** + * 失败通知 + */ + public error(message: string): void { + Notify.error(message); + } +} +export { NotifyService }; diff --git a/packages/mobile-command-services/package.json b/packages/mobile-command-services/package.json index d2ac3449ed3..87af8f80e0e 100644 --- a/packages/mobile-command-services/package.json +++ b/packages/mobile-command-services/package.json @@ -26,7 +26,8 @@ "vue": "^3.2.37", "vue-router": "^4.3.0", "@farris/bef-vue": "workspace:^", - "@farris/devkit-vue": "workspace:^" + "@farris/devkit-vue": "workspace:^", + "@farris/mobile-ui-vue": "workspace:*" }, "devDependencies": { "@babel/parser": "^7.19.0", @@ -69,7 +70,6 @@ "vitest": "^0.29.2", "vue-tsc": "^1.2.0", "tslib": "^2.7.0", - "@farris/mobile-ui-vue": "latest", "axios": "^1.7.2", "rollup-plugin-typescript2": "^0.36.0", "rollup-plugin-visualizer": "^5.12.0", diff --git a/packages/mobile-ui-vue/components/button/index.ts b/packages/mobile-ui-vue/components/button/index.ts index 8fec33b0b6b..8084a9042c0 100644 --- a/packages/mobile-ui-vue/components/button/index.ts +++ b/packages/mobile-ui-vue/components/button/index.ts @@ -1,9 +1,10 @@ -import { Plugin } from 'vue'; import { withInstall, withRegister, withRegisterDesigner } from '@farris/mobile-ui-vue/common'; import ButtonInstallless from './src/button.component'; import { propsResolverGenerator } from './src/button.props'; import ButtonDesign from './src/designer/button.design.component'; +export * from './src/button.props'; + const BUTTON_REGISTERED_NAME = 'button'; const Button = withInstall(ButtonInstallless); diff --git a/packages/mobile-ui-vue/components/dialog/index.ts b/packages/mobile-ui-vue/components/dialog/index.ts index 311ad77e787..75acd2c292f 100644 --- a/packages/mobile-ui-vue/components/dialog/index.ts +++ b/packages/mobile-ui-vue/components/dialog/index.ts @@ -1,4 +1,5 @@ import Dialog from './src/index'; +export type { DialogAlertOptions, DialogConfirmOptions, DialogPromptOptions } from './src'; export { Dialog }; export default Dialog; diff --git a/packages/mobile-ui-vue/components/dialog/src/dialog.component.tsx b/packages/mobile-ui-vue/components/dialog/src/dialog.component.tsx index d36a898da38..e6982dfeb1c 100644 --- a/packages/mobile-ui-vue/components/dialog/src/dialog.component.tsx +++ b/packages/mobile-ui-vue/components/dialog/src/dialog.component.tsx @@ -14,20 +14,19 @@ * limitations under the License. */ import { SetupContext, computed, defineComponent, ref, toRef, watch } from 'vue'; -import { DialogProps, dialogProps } from './dialog.props'; import { preventDefault, useBem } from '@farris/mobile-ui-vue/common'; import Popup from '@farris/mobile-ui-vue/popup'; -import FmButton from '@farris/mobile-ui-vue/button'; +import Button from '@farris/mobile-ui-vue/button'; +import { DIALOG_NAME, DialogButton, DialogProps, dialogProps } from './dialog.props'; -const name = 'fm-dialog'; export default defineComponent({ - name, + name: DIALOG_NAME, props: dialogProps, emits: ['update:show', 'open', 'close'], setup(props: DialogProps, context: SetupContext) { const { attrs, emit, slots } = context; - const { bem } = useBem(name); + const { bem } = useBem(DIALOG_NAME); const hasShown = ref(props.show); watch( @@ -86,13 +85,13 @@ export default defineComponent({ return
    {getContent()}
    ; }; - const onButtonClick = (event: MouseEvent, button: any) => { + const onButtonClick = (event: MouseEvent, button: DialogButton) => { preventDefault(event, true); if (button.disabled || button.loading) { return; } - if (typeof button.handler === 'function') { - button.handler.call(null, button); + if (typeof button.onClick === 'function') { + button.onClick.call(null, button); } else { hasShown.value = false; emit('update:show', false); @@ -112,18 +111,16 @@ export default defineComponent({
    {slots.footer ? slots.footer() - : props.buttons?.map((button: any) => ( - ( + ))}
    ); diff --git a/packages/mobile-ui-vue/components/dialog/src/dialog.props.ts b/packages/mobile-ui-vue/components/dialog/src/dialog.props.ts index d9c1e0a97c9..90585a5a7ab 100644 --- a/packages/mobile-ui-vue/components/dialog/src/dialog.props.ts +++ b/packages/mobile-ui-vue/components/dialog/src/dialog.props.ts @@ -13,16 +13,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ExtractPropTypes, PropType } from 'vue'; +import { ButtonType } from '@farris/mobile-ui-vue/button/src/button.props'; +import { ExtractPropTypes, PropType, TeleportProps } from 'vue'; -export type alignType = 'start' | 'end' | 'left' | 'center' | 'right' | 'justify' | 'match-parent'; +export enum MessageAlign { + start= 'start', + end= 'end', + left= 'left', + center= 'center', + right= 'right', + justify= 'justify', + matchParent= 'match-parent', +}; + +export type DialogButton = { + type?: ButtonType, + disabled?: boolean, + loading?: boolean, + text: string, + onClick: (button: DialogButton) => void +}; + +export const DIALOG_NAME = 'FmDialog'; export const dialogProps = { title: { type: String, default: '' }, message: { type: String, default: '' }, - messageAlign: { type: String as PropType, default: 'center' }, + messageAlign: { type: String as PropType, default: MessageAlign.center }, show: { type: Boolean, default: false }, @@ -30,13 +49,13 @@ export const dialogProps = { lockScroll: { type: Boolean, default: true }, - teleport: { type: String, default: '' }, + teleport: { type: [String, Object] as PropType, default: '' }, buttonLayout: { type: String, default: 'row' }, - buttons: { type: Array, default: [] }, + buttons: { type: Array as PropType, default: [] }, - className: { type: String, default: '' }, + className: { type: String, default: undefined }, showClose: { type: Boolean, default: false }, diff --git a/packages/mobile-ui-vue/components/dialog/src/index.tsx b/packages/mobile-ui-vue/components/dialog/src/index.tsx index 0c884b16e7a..06b6a5cfd85 100644 --- a/packages/mobile-ui-vue/components/dialog/src/index.tsx +++ b/packages/mobile-ui-vue/components/dialog/src/index.tsx @@ -1,31 +1,19 @@ -/** - * 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, ref } from 'vue'; import { mountComponent, usePopupState, isObject, inBrowser } from '@farris/mobile-ui-vue/common'; +import { InputProps, InputGroup } from '@farris/mobile-ui-vue/input-group'; +import { DialogProps, MessageAlign } from './dialog.props'; import FMDialog from './dialog.component'; -import FMInput from '@farris/mobile-ui-vue/input-group'; let instance; -function defaultOptions() { + +function defaultOptions(): DialogProps { return { title: '', message: '', - messageAlign: 'center', + messageAlign: MessageAlign.center, overlay: true, lockScroll: true, + show: false, teleport: 'body', buttonLayout: 'row', buttons: [], @@ -47,7 +35,7 @@ const initInstance = () => { })); }; -function Dialog(options) { +function Dialog(options: Partial) { if (!inBrowser) { return; } @@ -68,11 +56,18 @@ function Dialog(options) { Dialog.clear = () => { if (instance) { - instance.toggle(false); + instance.close(); } }; -Dialog.confirm = (options) => { +export type DialogConfirmOptions = Partial & { + cancelText: string, + confirmText: string, + onConfirm: () => void, + onCancel: () => void, +}> + +Dialog.confirm = (options: DialogConfirmOptions) => { const CancelText = '取消'; const ConfirmText = '确定'; @@ -87,15 +82,14 @@ Dialog.confirm = (options) => { buttons: [ { text: cancelText, - type: 'info', - handler: () => { + onClick: () => { onCancel(); instance.close(); } }, { text: confirmText, - handler: () => { + onClick: () => { onConfirm(); instance.close(); } @@ -106,13 +100,16 @@ Dialog.confirm = (options) => { Dialog(_options); }; -Dialog.prompt = (options) => { - const CancelText = '取消'; - const ConfirmText = '确定'; +export type DialogPromptOptions = Partial, + onConfirm: (value: string)=> void +}> +Dialog.prompt = (options: DialogPromptOptions) => { const { - confirmText = ConfirmText, - cancelText = CancelText, + confirmText = '取消', + cancelText = '确定', onConfirm = () => {}, onCancel = () => {}, defaultText = '', @@ -127,14 +124,14 @@ Dialog.prompt = (options) => { buttons: [ { text: cancelText, - handler: () => { + onClick: () => { onCancel(); instance.close(); } }, { text: confirmText, - handler: () => { + onClick: () => { onConfirm(inputValue.value); instance.close(); } @@ -142,24 +139,29 @@ Dialog.prompt = (options) => { ], content: () => { return ( - + withBorder={true}> ); }, ...others }; Dialog(_options); }; -Dialog.alert = (options) => { - const ConfirmText = '确定'; - const { confirmText = ConfirmText, onConfirm = () => {}, ...others } = options; + +export type DialogAlertOptions = Partial & { + confirmText: string, + onConfirm: () => void +}> + +Dialog.alert = (options: DialogAlertOptions) => { + const { confirmText = '确定', onConfirm = () => {}, ...others } = options; const _options = { buttons: [ { text: confirmText, - handler: () => { + onClick: () => { onConfirm(); instance.close(); } @@ -172,7 +174,7 @@ Dialog.alert = (options) => { Dialog.currentOptions = defaultOptions(); -Dialog.setDefaultOptions = (options) => { +Dialog.setDefaultOptions = (options: DialogProps) => { Object.assign(Dialog.currentOptions, options); }; @@ -181,7 +183,7 @@ Dialog.resetDefaultOptions = () => { }; Dialog.install = (app: App) => { - app.component(FMDialog.name, FMDialog); + app.component((FMDialog.name as string), FMDialog); app.config.globalProperties.$dialog = Dialog; }; diff --git a/packages/mobile-ui-vue/components/index.ts b/packages/mobile-ui-vue/components/index.ts index 8078076ff25..a665c1ef0e0 100644 --- a/packages/mobile-ui-vue/components/index.ts +++ b/packages/mobile-ui-vue/components/index.ts @@ -49,6 +49,8 @@ import FloatContainer from './float-container'; import Filter from './filter'; import * as Utils from './common/src/utils'; +export type { LoadingOptions } from './loading'; + import DynamicView from './dynamic-view'; export * from './register'; export * from './designer'; @@ -72,9 +74,6 @@ const components = [ Textarea, Navbar, Switch, - Toast, - Notify, - Dialog, Radio, RadioGroup, Rate, @@ -89,7 +88,6 @@ const components = [ TimePicker, TimePickerPanel, TabBar, - Loading, PullRefresh, List, ListView, @@ -100,7 +98,7 @@ const components = [ Tab, Tag, Overlay, - + PageContainer, PageBodyContainer, PageHeaderContainer, @@ -108,6 +106,12 @@ const components = [ Component, ContentContainer, FloatContainer, + + Toast, + Notify, + Loading, + Dialog, + DynamicView ]; diff --git a/packages/mobile-ui-vue/components/list/src/list.component.tsx b/packages/mobile-ui-vue/components/list/src/list.component.tsx index 530cd7a44ed..580b39745d8 100644 --- a/packages/mobile-ui-vue/components/list/src/list.component.tsx +++ b/packages/mobile-ui-vue/components/list/src/list.component.tsx @@ -123,7 +123,7 @@ export default defineComponent({ const renderLoading = () => { const loading = slots.loading ? slots.loading() : (
    - +
    ); return ( diff --git a/packages/mobile-ui-vue/components/loading/index.ts b/packages/mobile-ui-vue/components/loading/index.ts index 9f039c347e7..8df7ccc5ac8 100644 --- a/packages/mobile-ui-vue/components/loading/index.ts +++ b/packages/mobile-ui-vue/components/loading/index.ts @@ -1,9 +1,8 @@ -import { withInstall } from '@farris/mobile-ui-vue/common'; -import LoadingInstallless from './src/loading.component'; +import Loading from './src'; export * from './src/loading.props'; -const Loading = withInstall(LoadingInstallless); +export type { LoadingOptions } from './src/index'; export { Loading }; export default Loading; diff --git a/packages/mobile-ui-vue/components/loading/src/composition/types.ts b/packages/mobile-ui-vue/components/loading/src/composition/types.ts deleted file mode 100644 index d33d910dc1f..00000000000 --- a/packages/mobile-ui-vue/components/loading/src/composition/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -/** 加载图标的类型 */ -export type LoadingType = 'default' | 'spinner' | 'ring'; - -/** 加载图标与文本的对齐方向 */ -export type LoadingDirection = 'horizontal' | 'vertical'; diff --git a/packages/mobile-ui-vue/components/loading/src/index.tsx b/packages/mobile-ui-vue/components/loading/src/index.tsx new file mode 100644 index 00000000000..7e8b9be2c12 --- /dev/null +++ b/packages/mobile-ui-vue/components/loading/src/index.tsx @@ -0,0 +1,91 @@ +import { App } from 'vue'; +import { isObject, inBrowser, mountComponent, usePopupState } from '@farris/mobile-ui-vue/common'; +import Popup from '@farris/mobile-ui-vue/popup'; +import { LoadingDirection, LoadingProps, LoadingType } from './loading.props'; +import FMLoading from './loading.component'; + +let instance; + +export type LoadingOptions = string | Partial + +function defaultOptions(): Partial { + return { + type: LoadingType.default, + direction: LoadingDirection.horizontal, + text: '', + size: '24px', + duration: undefined, + color: undefined, + textColor: undefined + }; +} + +function parseOptions(options: LoadingOptions) { + return isObject(options) ? options : { text: options }; +} + +const initInstance = () => { + ({ instance } = mountComponent({ + setup() { + const { state } = usePopupState(); + + return () => + + ; + } + })); +}; + +function Loading(options: LoadingOptions) { + if (!inBrowser) { + return; + } + + if (!instance) { + initInstance(); + } + + options = { + ...Loading.currentOptions, + ...parseOptions(options) + }; + + instance.open(options); + + return instance; +} + +Loading.hidden = () => { + if (instance) { + instance.toggle(false); + } +}; + +Loading.show = (options: LoadingOptions = {}) => { + Loading.resetDefaultOptions(); + return Loading(parseOptions(options)); +}; + +Loading.currentOptions = defaultOptions(); + +Loading.setDefaultOptions = (options: Partial) => { + Object.assign(Loading.currentOptions, options); +}; + +Loading.resetDefaultOptions = () => { + Loading.currentOptions = defaultOptions(); +}; + +Loading.install = (app: App) => { + app.component((FMLoading.name as string), FMLoading); + app.config.globalProperties.$loading = Loading; +}; + +Loading.Component = FMLoading; + +export default Loading; diff --git a/packages/mobile-ui-vue/components/loading/src/loading.props.ts b/packages/mobile-ui-vue/components/loading/src/loading.props.ts index 5f02a704b16..2d955e99545 100644 --- a/packages/mobile-ui-vue/components/loading/src/loading.props.ts +++ b/packages/mobile-ui-vue/components/loading/src/loading.props.ts @@ -14,20 +14,32 @@ * limitations under the License. */ import { ExtractPropTypes, PropType } from 'vue'; -import { LoadingType, LoadingDirection } from './composition/types'; + +/** 加载图标的类型 */ +export enum LoadingType { + default = 'default', + spinner = 'spinner', + ring = 'ring', +}; + +/** 加载图标与文本的对齐方向 */ +export enum LoadingDirection { + horizontal = 'horizontal', + vertical = 'vertical', +}; export const LOADING_NAME = 'fm-loading'; export const loadingProps = { /** 加载图标的类型,可选值:`default`(默认)、`spinner`、`ring` */ - type: { type: String as PropType, default: 'default' }, + type: { type: String as PropType, default: LoadingType.default }, /** 文本内容 */ text: { type: String, default: '' }, /** 图标与文本的对齐方向,默认水平对齐,可选垂直对齐 */ - direction: { type: String as PropType, default: 'horizontal' }, + direction: { type: String as PropType, default: LoadingDirection.horizontal }, /** 图标的大小 */ size: { type: String, default: '24px' }, @@ -47,6 +59,6 @@ export const loadingProps = { /** 加载动画播放一个周期的时长,单位:ms */ duration: { type: Number, default: undefined }, -} as Record; +}; export type LoadingProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/loading/src/loading.scss b/packages/mobile-ui-vue/components/loading/src/loading.scss index 3de6637e9ce..27c9f972e30 100644 --- a/packages/mobile-ui-vue/components/loading/src/loading.scss +++ b/packages/mobile-ui-vue/components/loading/src/loading.scss @@ -71,6 +71,14 @@ border-radius: 50%; } } +.fm-loading-popup { + display: flex; + align-items: center; + justify-content: center; + width: 100px; + height: 100px; + background-color: inherit; +} @keyframes fm-circular { 0% { diff --git a/packages/mobile-ui-vue/components/notify/src/index.tsx b/packages/mobile-ui-vue/components/notify/src/index.tsx index 26c7dcd03f9..0aa07a2eb54 100644 --- a/packages/mobile-ui-vue/components/notify/src/index.tsx +++ b/packages/mobile-ui-vue/components/notify/src/index.tsx @@ -1,12 +1,17 @@ -import FMNotify from './notify.component'; -import { isObject, inBrowser } from '@farris/mobile-ui-vue/common'; -import { mountComponent, usePopupState } from '@farris/mobile-ui-vue/common'; import { App } from 'vue'; +import { isObject, inBrowser, mountComponent, usePopupState } from '@farris/mobile-ui-vue/common'; +import FMNotify from './notify.component'; +import { NotifyProps, NotifyType } from './notify.props'; + let instance; let timer; -function defaultOptions() { + +type NotifyOptions = string | Partial + +function defaultOptions(): NotifyProps { return { - type: 'info', + type: NotifyType.info, + show: false, message: '', duration: 3000, color: '#fff', @@ -14,8 +19,8 @@ function defaultOptions() { }; } -function parseOptions(message) { - return isObject(message) ? message : { message }; +function parseOptions(options: NotifyOptions) { + return isObject(options) ? options : { message: options }; } const initInstance = () => { @@ -27,7 +32,7 @@ const initInstance = () => { })); }; -function Notify(options) { +function Notify(options: NotifyOptions) { if (!inBrowser) { return; } @@ -44,7 +49,7 @@ function Notify(options) { instance.open(options); clearTimeout(timer); - if (options.duration > 0) { + if (options.duration && options.duration > 0) { timer = setTimeout(Notify.clear, options.duration); } @@ -57,29 +62,29 @@ Notify.clear = () => { } }; -Notify.info = (options) => { +Notify.info = (options: NotifyOptions) => { Notify.resetDefaultOptions(); - return Notify({ ...parseOptions(options), type: 'info' }); + return Notify({ ...parseOptions(options), type: NotifyType.info }); }; -Notify.success = (options) => { +Notify.success = (options: NotifyOptions) => { Notify.resetDefaultOptions(); - return Notify({ ...parseOptions(options), type: 'success' }); + return Notify({ ...parseOptions(options), type: NotifyType.success }); }; -Notify.error = (options) => { +Notify.error = (options: NotifyOptions) => { Notify.resetDefaultOptions(); - return Notify({ ...parseOptions(options), type: 'error' }); + return Notify({ ...parseOptions(options), type: NotifyType.error }); }; -Notify.warning = (options) => { +Notify.warning = (options: NotifyOptions) => { Notify.resetDefaultOptions(); - return Notify({ ...parseOptions(options), type: 'warning' }); + return Notify({ ...parseOptions(options), type: NotifyType.warning }); }; Notify.currentOptions = defaultOptions(); -Notify.setDefaultOptions = (options) => { +Notify.setDefaultOptions = (options: Partial) => { Object.assign(Notify.currentOptions, options); }; @@ -88,7 +93,7 @@ Notify.resetDefaultOptions = () => { }; Notify.install = (app: App) => { - app.component(FMNotify.name, FMNotify); + app.component((FMNotify.name as string), FMNotify); app.config.globalProperties.$notify = Notify; }; diff --git a/packages/mobile-ui-vue/components/notify/src/notify.component.tsx b/packages/mobile-ui-vue/components/notify/src/notify.component.tsx index 3be1b9f3634..ce049268cd6 100644 --- a/packages/mobile-ui-vue/components/notify/src/notify.component.tsx +++ b/packages/mobile-ui-vue/components/notify/src/notify.component.tsx @@ -1,33 +1,16 @@ -/** - * 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 { NotifyProps, notifyProps } from './notify.props'; +import { computed, defineComponent } from 'vue'; import { useBem } from '@farris/mobile-ui-vue/common'; - -const name = 'fm-notify'; +import { NOTIFY_NAME, NotifyProps, notifyProps } from './notify.props'; export default defineComponent({ - name, + name: NOTIFY_NAME, props: notifyProps, emits: ['click'], - setup(props: NotifyProps, context: SetupContext) { - const { bem } = useBem(name); + setup(props: NotifyProps) { + const { bem } = useBem(NOTIFY_NAME); const notifyClass = computed(() => ({ - [name]: true, + [bem()]: true, [bem('', props.type)]: true, [`${props.className}`]: true })); diff --git a/packages/mobile-ui-vue/components/notify/src/notify.props.ts b/packages/mobile-ui-vue/components/notify/src/notify.props.ts index 110dc36af29..9180fee9102 100644 --- a/packages/mobile-ui-vue/components/notify/src/notify.props.ts +++ b/packages/mobile-ui-vue/components/notify/src/notify.props.ts @@ -1,48 +1,28 @@ -/** - * 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 { ExtractPropTypes, PropType } from 'vue'; -type NotifyType = 'info' | 'success' | 'danger' | 'warning'; +export enum NotifyType { + info= 'info', + success= 'success', + error= 'error', + warning= 'warning' +}; + +export const NOTIFY_NAME = 'FmNotify'; export const notifyProps = { - show: { - type: Boolean, - default: false, - }, - type: { - type: String as PropType, - default: 'info', - }, - color: { - type: String, - default: '#fff', - }, - message: { - type: String, - }, - duration: { - type: Number, - default: 3000, - }, - className: { - type: String, - }, - background: { - type: String, - }, + show: { type: Boolean, default: false }, + + type: { type: String as PropType, default: NotifyType.info }, + + color: { type: String, default: '#fff' }, + + message: { type: String, default: '' }, + + duration: { type: Number, default: 3000 }, + + className: { type: String, default: undefined }, + + background: { type: String, default: undefined } }; export type NotifyProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/pull-refresh/src/pull-refresh.component.tsx b/packages/mobile-ui-vue/components/pull-refresh/src/pull-refresh.component.tsx index be589115acb..1201f7899be 100644 --- a/packages/mobile-ui-vue/components/pull-refresh/src/pull-refresh.component.tsx +++ b/packages/mobile-ui-vue/components/pull-refresh/src/pull-refresh.component.tsx @@ -176,7 +176,7 @@ export default defineComponent({ } if (status.value === 'loading') { - return ; + return ; } if (['pulling', 'loosing', 'complete'].includes(status.value)) { return
    {getStatusText()}
    ; diff --git a/packages/mobile-ui-vue/components/switch/src/switch.component.tsx b/packages/mobile-ui-vue/components/switch/src/switch.component.tsx index 5035a7c20f6..404d342baad 100644 --- a/packages/mobile-ui-vue/components/switch/src/switch.component.tsx +++ b/packages/mobile-ui-vue/components/switch/src/switch.component.tsx @@ -54,7 +54,7 @@ export default defineComponent({ }; const renderLoading = () => { - return ; + return ; }; const switchClass = computed(() => ({ diff --git a/packages/mobile-ui-vue/demos/dialog/base.vue b/packages/mobile-ui-vue/demos/dialog/base.vue index 860847345ce..de704010889 100644 --- a/packages/mobile-ui-vue/demos/dialog/base.vue +++ b/packages/mobile-ui-vue/demos/dialog/base.vue @@ -12,7 +12,7 @@ import { Dialog } from '@farris/mobile-ui-vue/dialog'; const onClickAlert = () => { Dialog.alert({ title: '标题', - message: '代码是写出来给人看的,附带能在机器上运行' + message: '代码是写出来给人看的,附带能在机器上运行', }); }; const onClickAlertWithOutTitle = () => { diff --git a/packages/mobile-ui-vue/demos/loading/index.vue b/packages/mobile-ui-vue/demos/loading/index.vue index 1257fd20ca4..4ad8eda3e55 100644 --- a/packages/mobile-ui-vue/demos/loading/index.vue +++ b/packages/mobile-ui-vue/demos/loading/index.vue @@ -17,6 +17,9 @@ + + + diff --git a/packages/mobile-ui-vue/demos/loading/service.vue b/packages/mobile-ui-vue/demos/loading/service.vue new file mode 100644 index 00000000000..1293e20fbaa --- /dev/null +++ b/packages/mobile-ui-vue/demos/loading/service.vue @@ -0,0 +1,13 @@ + + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6b6cf708bb8..c6b2af45118 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1389,6 +1389,9 @@ importers: '@farris/devkit-vue': specifier: workspace:^ version: link:../devkit + '@farris/mobile-ui-vue': + specifier: workspace:* + version: link:../mobile-ui-vue vue: specifier: ^3.2.37 version: 3.5.12(typescript@4.9.5) @@ -1417,9 +1420,6 @@ importers: '@commitlint/config-conventional': specifier: ^17.1.0 version: 17.8.1 - '@farris/mobile-ui-vue': - specifier: latest - version: 0.0.1-beta.3(typescript@4.9.5) '@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) @@ -3614,9 +3614,6 @@ packages: '@farris/designer-dragula@0.0.5': resolution: {integrity: sha512-Y9lUkoXO0EFc5kJXEr5q2BcU6XKeJLJc00cSoeZOFSiup5j+UeFaJz+GSgwGu46ZegGbR8wjZ20OMSNTDEGKFA==} - '@farris/mobile-ui-vue@0.0.1-beta.3': - resolution: {integrity: sha512-499FnKEf5OwEX+5w++AEi7KqpCASNJ0aVoLO6TOW82Rin9UKh8u36+4GdDwLjQiqW/qjoYXFItP21dZXcA/kCA==} - '@floating-ui/core@1.6.9': resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} @@ -13226,12 +13223,6 @@ snapshots: '@farris/designer-dragula@0.0.5': {} - '@farris/mobile-ui-vue@0.0.1-beta.3(typescript@4.9.5)': - dependencies: - vue: 3.5.12(typescript@4.9.5) - transitivePeerDependencies: - - typescript - '@floating-ui/core@1.6.9': dependencies: '@floating-ui/utils': 0.2.9 -- Gitee From cd5d68dc60b2c6dd09e8b881a739fdcb0f3a03d5 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Sat, 19 Apr 2025 11:57:42 +0800 Subject: [PATCH 259/287] =?UTF-8?q?chore:=20=E4=BF=AE=E5=A4=8D=E5=BC=95?= =?UTF-8?q?=E5=85=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/composition/control-property-changed.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/designer/src/components/composition/control-property-changed.service.ts b/packages/designer/src/components/composition/control-property-changed.service.ts index b6dd93b59bc..f642a2cdfd2 100644 --- a/packages/designer/src/components/composition/control-property-changed.service.ts +++ b/packages/designer/src/components/composition/control-property-changed.service.ts @@ -1,4 +1,4 @@ -import { FormPropertyChangeObject, SchemaDOMMapping } from "@farris/ui-vue"; +import { FormPropertyChangeObject, SchemaDOMMapping } from "@farris/ui-vue/components"; import { get, set } from "lodash-es"; import { FormBindingType, FormVariableCategory, UseDesignViewModel, UseFormSchema, UseSchemaService } from "../types"; import { DesignViewModelField } from "../types/design-viewmodel"; -- Gitee From 94e289665a855dd5cacd3db290b12fe6e30d1bb3 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Sat, 19 Apr 2025 16:34:44 +0800 Subject: [PATCH 260/287] =?UTF-8?q?feature:=20cli=E4=B8=AD=E7=9A=84build-c?= =?UTF-8?q?omponents=E5=91=BD=E4=BB=A4=E6=94=AF=E6=8C=81=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=8A=A8=E6=80=81packageName?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/cli/src/common/constant.ts | 6 ++++++ packages/cli/src/common/get-vite-config.ts | 7 ++++++- packages/cli/src/config/vite-component.ts | 3 ++- packages/cli/src/config/vite-lib.ts | 4 ++-- packages/cli/src/plugins/create-component-style.ts | 4 +++- packages/cli/src/plugins/replace.ts | 11 +++++++++-- packages/mobile-ui-vue/farris.config.mjs | 1 + 7 files changed, 29 insertions(+), 7 deletions(-) diff --git a/packages/cli/src/common/constant.ts b/packages/cli/src/common/constant.ts index 89044f1aaaa..e2ef25edff8 100644 --- a/packages/cli/src/common/constant.ts +++ b/packages/cli/src/common/constant.ts @@ -21,3 +21,9 @@ export const getDirname = (url: string)=> fileURLToPath(new URL('.', url)); export const CWD = process.cwd(); export const ROOT = findRootDir(CWD); export const FAARIS_CONFIG_FILE = join(CWD, 'farris.config.mjs'); + +export const getPackageName = ()=>{ + const { PackageName = '@components' } = process.env; + return PackageName; +}; + diff --git a/packages/cli/src/common/get-vite-config.ts b/packages/cli/src/common/get-vite-config.ts index 752eba06b6c..688b4da1529 100644 --- a/packages/cli/src/common/get-vite-config.ts +++ b/packages/cli/src/common/get-vite-config.ts @@ -15,6 +15,7 @@ type FarrisConfig = { target: string | string[]; server: ServerOptions; cssInjected?: boolean + packageName: string; }; const formatFarrisConfig = (farrisConfig: FarrisConfig, type: string) => { @@ -29,7 +30,8 @@ const formatFarrisConfig = (farrisConfig: FarrisConfig, type: string) => { plugins = [], alias, server, - cssInjected + cssInjected, + packageName = '@farris/mobile-ui-vue' } = farrisConfig; const dependencies = externalDependencies ? getDependencies() : []; @@ -43,6 +45,9 @@ const formatFarrisConfig = (farrisConfig: FarrisConfig, type: string) => { if(cssInjected){ plugins.push(cssInjectedByJsPlugin()); } + if(packageName) { + process.env.PackageName = packageName; + } const viteConfig = { build: { diff --git a/packages/cli/src/config/vite-component.ts b/packages/cli/src/config/vite-component.ts index c4af3f37929..18f6820b2fe 100644 --- a/packages/cli/src/config/vite-component.ts +++ b/packages/cli/src/config/vite-component.ts @@ -2,6 +2,7 @@ import { mergeConfig } from 'vite'; import CommonConfig from "./vite-common.js"; import { replace } from "../plugins/replace.js"; import { createComponentStyle } from "../plugins/create-component-style.js"; +import { getPackageName } from '../common/constant.js'; export default mergeConfig(CommonConfig, { logLevel: 'silent', @@ -15,7 +16,7 @@ export default mergeConfig(CommonConfig, { output: { exports: "named", globals: (id: string)=>{ - if(id.includes('@farris/mobile-ui-vue')) { + if(id.includes(getPackageName())) { const name = id.split('/').pop() || ''; return name.slice(0,1).toUpperCase() + name.slice(1); } diff --git a/packages/cli/src/config/vite-lib.ts b/packages/cli/src/config/vite-lib.ts index ada437c7edb..6b5b50d6c8c 100644 --- a/packages/cli/src/config/vite-lib.ts +++ b/packages/cli/src/config/vite-lib.ts @@ -1,6 +1,6 @@ import { mergeConfig } from 'vite'; import { resolve } from "node:path"; -import { CWD } from '../common/constant.js'; +import { CWD, getPackageName } from '../common/constant.js'; import { systemjsBundle } from '../plugins/systemjs-bundle.js'; import CommonConfig from "./vite-common.js"; @@ -19,7 +19,7 @@ export default mergeConfig(CommonConfig, { exports: "named", globals: { vue: "Vue", - '@farris/mobile-ui-vue': 'FarrisVue' + [getPackageName()]: getPackageName() } } }, diff --git a/packages/cli/src/plugins/create-component-style.ts b/packages/cli/src/plugins/create-component-style.ts index 0839337bc56..8222d5442c2 100644 --- a/packages/cli/src/plugins/create-component-style.ts +++ b/packages/cli/src/plugins/create-component-style.ts @@ -1,10 +1,12 @@ +import { getPackageName } from "../common/constant.js"; + const NotStyleComponents = ['designer-canvas', 'dynamic-view', 'dynamic-resolver', 'common']; const getComponentStyle = (imports: string[]) => { const components = imports .filter(path => { - return path.startsWith('@farris/mobile-ui-vue/') && !NotStyleComponents.find(notStylecomponent => path.includes(notStylecomponent)); + return path.startsWith(`${getPackageName()}/`) && !NotStyleComponents.find(notStylecomponent => path.includes(notStylecomponent)); }) .filter((item, index, array) => { const targetIndex = array.filter(e=> e!==item).findIndex(e => item.includes(e)); diff --git a/packages/cli/src/plugins/replace.ts b/packages/cli/src/plugins/replace.ts index 6aea2950c5a..7aba2585585 100644 --- a/packages/cli/src/plugins/replace.ts +++ b/packages/cli/src/plugins/replace.ts @@ -1,10 +1,17 @@ +import { getPackageName } from '../common/constant.js'; + export function replace(path: (format: string, args: string[]) => string){ return { - name: 'farris-replace', + name: 'farris-replace-path', renderChunk(code: string, chunk: any) { const fileNames = chunk.fileName.split('.'); const format = fileNames[fileNames.length-2]; - return code.replace(/@farris\/mobile-ui-vue\/([\w-]+)/g, (match, captureGroup)=>{ + // const regExpress = new RegExp(/@farris\/mobile-ui-vue\/([\w-]+)/g); + const dynamicRegExp = new RegExp( + `${getPackageName().replace(/\//g, '\\/')}\\/([\\w-]+)`, // 自动转义斜杠 + 'g' + ); + return code.replace(dynamicRegExp, (match, captureGroup)=>{ return path(format, [captureGroup]); }); } diff --git a/packages/mobile-ui-vue/farris.config.mjs b/packages/mobile-ui-vue/farris.config.mjs index 64fd25fb984..cf03a371ed0 100644 --- a/packages/mobile-ui-vue/farris.config.mjs +++ b/packages/mobile-ui-vue/farris.config.mjs @@ -6,6 +6,7 @@ const externals = [BUILD_TYPE === 'components' ? "@farris/mobile-ui-vue" : '']; const externalDependencies = BUILD_TYPE !== 'app'; export default { + packageName: '@farris/mobile-ui-vue', lib: { entry: fileURLToPath(new URL('./components/index.ts', import.meta.url)), name: "farris-mobile-ui-vue", -- Gitee From b36b57b77315f32d73abc086d602195b304af48a Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Sat, 19 Apr 2025 17:17:22 +0800 Subject: [PATCH 261/287] =?UTF-8?q?feature:=20=E5=AE=9E=E7=8E=B0=E5=B8=AE?= =?UTF-8?q?=E5=8A=A9=E5=92=8C=E5=88=97=E8=A1=A8=E5=86=85=E7=BD=AE=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E6=89=A9=E5=B1=95=E6=8F=92=E4=BB=B6=EF=BC=8C=E8=B0=83?= =?UTF-8?q?=E9=80=9A=E4=B8=BB=E6=B5=81=E7=A8=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/mobile-render/src/main.ts | 1 - .../converters/component-converters/index.ts | 1 + .../lookup-edit-converter.ts | 33 ++++ .../form/converters/converter-factory.ts | 4 +- .../metadata/form/form-metadata-converter.ts | 3 - .../form/form-metadata-data-service.ts | 4 - .../module-config/module-config-builder.ts | 2 - .../page-config/bindings/binding-context.ts | 7 + .../bindings/entity-field-binding.ts | 2 + .../services/page-config/bindings/index.ts | 1 + .../page-config/page-config-binder.ts | 85 +++++---- .../src/services/plugin/index.ts | 1 + .../src/services/plugin/plugin-creators.ts | 3 +- .../src/services/plugin/plugin-manager.ts | 2 +- .../services/plugin/{plugins => }/plugin.ts | 3 +- .../src/services/plugin/plugins/index.ts | 5 +- .../plugin/plugins/listview-plugin.ts | 18 -- .../plugin/plugins/listview-plugin/index.ts | 1 + .../listview-plugin/listview-plugin.ts | 31 ++++ .../services/plugin/plugins/lookup-plugin.ts | 18 -- .../plugin/plugins/lookup-plugin/index.ts | 1 + .../lookup-plugin/lookup-data-service.ts | 82 +++++++++ .../lookup-plugin/lookup-mapping-service.ts | 169 ++++++++++++++++++ .../plugins/lookup-plugin/lookup-plugin.ts | 58 ++++++ .../src/services/plugin/types.ts | 73 +++++--- .../src/views/page/page-runner.ts | 10 +- .../mobile-render/src/views/page/page.vue | 14 +- .../src/composition/use-render-component.ts | 1 - packages/mobile-ui-vue/components/index.ts | 2 +- .../lookup/src/schema/lookup.schema.json | 11 +- .../lookup/src/schema/schema-mapper.ts | 3 + 31 files changed, 519 insertions(+), 130 deletions(-) create mode 100644 packages/mobile-render/src/services/metadata/form/converters/component-converters/lookup-edit-converter.ts rename packages/mobile-render/src/services/plugin/{plugins => }/plugin.ts (85%) delete mode 100644 packages/mobile-render/src/services/plugin/plugins/listview-plugin.ts create mode 100644 packages/mobile-render/src/services/plugin/plugins/listview-plugin/index.ts create mode 100644 packages/mobile-render/src/services/plugin/plugins/listview-plugin/listview-plugin.ts delete mode 100644 packages/mobile-render/src/services/plugin/plugins/lookup-plugin.ts create mode 100644 packages/mobile-render/src/services/plugin/plugins/lookup-plugin/index.ts create mode 100644 packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-data-service.ts create mode 100644 packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-mapping-service.ts create mode 100644 packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-plugin.ts diff --git a/packages/mobile-render/src/main.ts b/packages/mobile-render/src/main.ts index e824e1097d3..c50637e2bb6 100644 --- a/packages/mobile-render/src/main.ts +++ b/packages/mobile-render/src/main.ts @@ -12,7 +12,6 @@ import router from './router'; import { checkFormRoute, addFormRoute } from './router/use-form-routes'; import { PluginContext, PluginManager, createBuildInPlugins } from './services/plugin/index'; - // devkit export const devkitProviders: StaticProvider[] = [ ...befRootProviders, 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 dbaf49bf72a..b86d4ca7942 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 @@ -12,3 +12,4 @@ export * from './numeric-box-converter'; export * from './switch-field-converter'; export * from './datebox-converter'; export * from './enum-field-converter'; +export * from './lookup-edit-converter'; diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/lookup-edit-converter.ts b/packages/mobile-render/src/services/metadata/form/converters/component-converters/lookup-edit-converter.ts new file mode 100644 index 00000000000..eacac091890 --- /dev/null +++ b/packages/mobile-render/src/services/metadata/form/converters/component-converters/lookup-edit-converter.ts @@ -0,0 +1,33 @@ +import { JsonUtil } from '../../../../../utils/index'; +import { InputConverter } from "./input-converter"; + +/** + * 帮助转换器 + */ +class LookupEditConverter extends InputConverter { + + /** + * 执行转换 + */ + public convert(lookup: any): void { + const oldLookup = JsonUtil.cloneJsonObj(lookup); + super.convert(lookup); + + const { dataSource, helpId, displayType, idField, textField, valueField, pageSize } = oldLookup; + const type = 'lookup'; + const pagination = { + enable: pageSize > 0 ? true : false, + size: pageSize + }; + + const mappingFields = oldLookup.mapFields.replace(/'/g, '"'); + + lookup.editor = Object.assign(lookup.editor, { + type, dataSource, helpId, displayType, mappingFields, + idField, textField, valueField, pagination + }); + + } +} + +export { LookupEditConverter }; 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 5b56d4bd1ab..220339dc126 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 @@ -5,7 +5,8 @@ import { ViewModelsConverter } from './viewodels-converter'; import { ComponentConverter, PageContentContainerConverter, NavigationBarConverter, ButtonConverter, ButtonGroupConverter, ListViewConverter, - TextBoxConverter, MultiTextBoxConverter, NumericBoxConverter, SwitchFieldConverter, DateBoxConverter, EnumFieldConverter + TextBoxConverter, MultiTextBoxConverter, NumericBoxConverter, SwitchFieldConverter, + DateBoxConverter, EnumFieldConverter, LookupEditConverter } from './component-converters'; type ComponentConverterConstructor = new (context: ConverterContext) => ComponentConverter; @@ -77,6 +78,7 @@ class ConverterFactory { this.cmpConverterCtors.set('SwitchField', SwitchFieldConverter); this.cmpConverterCtors.set('DateBox', DateBoxConverter); this.cmpConverterCtors.set('EnumField', EnumFieldConverter); + this.cmpConverterCtors.set('LookupEdit', LookupEditConverter); } } 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 a42fd77acb5..fc9da3bbab0 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 @@ -97,12 +97,10 @@ class FormMetadataConverter { * 移除不受支持的组件 */ private removeUnSupportedComponents(): void { - console.group('----------unSupported components----------'); const vmComponents = this.context.getVmComponents(); vmComponents.forEach((vmComponent) => { this.removeUnSupportComponent(vmComponent, null); }); - console.groupEnd(); } /** @@ -113,7 +111,6 @@ class FormMetadataConverter { if (parentComponent && !componentSchema) { const componentIndex = parentComponent.contents.indexOf(component); parentComponent.contents.splice(componentIndex, 1); - console.log('unsupported component: ' + component.type); return; } 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 347642594ad..0ce90a8a833 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 @@ -43,13 +43,9 @@ export class FormMetadataDataService { 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/module-config/module-config-builder.ts b/packages/mobile-render/src/services/module-config/module-config-builder.ts index 3ba92dd77e8..e426342c5ef 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 @@ -87,8 +87,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; } 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 index 91df5d2ef0a..766d609b8dd 100644 --- a/packages/mobile-render/src/services/page-config/bindings/binding-context.ts +++ b/packages/mobile-render/src/services/page-config/bindings/binding-context.ts @@ -32,6 +32,13 @@ class BindingContext { return this.module.getViewModel(id); } + /** + * 获取绑定监听器 + */ + public getBindingWatcher(): BindingWatcher { + return this.watcher; + } + /** * 注册状态变更依赖 */ 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 index 8e595c99f96..bb1764f8abb 100644 --- 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 @@ -1,5 +1,7 @@ import { Binding } from './binding'; import { BindingContext } from './binding-context'; +import { LookupMappingService } from '../../../services/lookup-mapping-service'; +import { Lookup } from '@farris/mobile-ui-vue'; /** * 实体字段绑定 diff --git a/packages/mobile-render/src/services/page-config/bindings/index.ts b/packages/mobile-render/src/services/page-config/bindings/index.ts index 655068e8281..175ac2e4fb0 100644 --- a/packages/mobile-render/src/services/page-config/bindings/index.ts +++ b/packages/mobile-render/src/services/page-config/bindings/index.ts @@ -6,4 +6,5 @@ export * from './state-machine-binding'; export * from './binding-util'; export * from './binding-context'; +export * from './binding-watcher'; export * from './binding-factory'; 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 index bc18b7a775b..96c42829d79 100644 --- a/packages/mobile-render/src/services/page-config/page-config-binder.ts +++ b/packages/mobile-render/src/services/page-config/page-config-binder.ts @@ -1,8 +1,9 @@ import { reactive, Reactive } from 'vue'; -import { Module } from '@farris/devkit-vue'; +import { Module, ViewModel, ViewModelState } from '@farris/devkit-vue'; import { schemaMap } from '@farris/mobile-ui-vue'; import { TypeUtil, JsonUtil } from '../../utils/index'; import { BindingUtil, BindingContext, BindingFactory } from './bindings/index'; +import { AfterComponentBindingHookContext, Plugin, PluginManager } from '../plugin/index'; /** * 页面配置绑定器 @@ -14,6 +15,16 @@ class PageConfigBinder { */ private module: Module; + /** + * 视图模型 + */ + private viewModel: ViewModel; + + /** + * 插件管理器 + */ + private pluginManager: PluginManager; + /** * 原始的页面配置 */ @@ -25,23 +36,26 @@ class PageConfigBinder { private pageConfig: Reactive; /** - * 绑定上下文 + * 绑定工厂 */ - private bindingContext: BindingContext; + private bindingFactory: BindingFactory; /** - * 绑定工厂 + * 绑定上下文 */ - private bindingFactory: BindingFactory; + private bindingContext: BindingContext; + /** * 构造函数 */ - constructor(module: Module, pageConfig: any) { + constructor(module: Module, viewModel: ViewModel, pageConfig: any) { this.module = module; + this.viewModel = viewModel; + this.pluginManager = PluginManager.getInstance(); + this.bindingContext = new BindingContext(module); this.bindingFactory = new BindingFactory(); - this.originPageConfig = pageConfig; } @@ -58,10 +72,7 @@ class PageConfigBinder { public bind(): Reactive { const pageConfig = reactive(JsonUtil.cloneJsonObj(this.originPageConfig)); const pageSchema = schemaMap['component']; - - this.bindComponentConfig(pageConfig, pageSchema); - this.pageConfig = pageConfig; return this.pageConfig; } @@ -70,29 +81,43 @@ class PageConfigBinder { * 为组件绑定属性值 */ private bindComponentConfig(componentConfig: any, componentSchema: any) { + const orignComponentConfig = JsonUtil.cloneJsonObj(componentConfig); Object.keys(componentConfig).forEach((propName) => { - const propConfig = componentConfig[propName]; - - // 属性值是一个绑定 - const isBinding = BindingUtil.isBinding(propConfig); - if (isBinding) { - this.bindBindingProp(propName, propConfig, componentConfig, componentSchema); - return; - } - - // 属性值是一个数组 - if (TypeUtil.isArray(propConfig)) { - this.bindArrayProp(propName, propConfig, componentConfig, componentSchema); - return; - } - - // 属性值是个对象 - if (TypeUtil.isObject(propConfig)) { - this.bindObjectProp(propName, propConfig, componentConfig, componentSchema); - return; - } + this.bindProp(propName, propConfig, componentConfig, componentSchema); }); + + const hookContext: AfterComponentBindingHookContext = { + viewModel: this.viewModel, + componentSchema, + componentConfig: orignComponentConfig, + bindedComponentConfig: componentConfig + }; + this.pluginManager.runHooks('afterComponentBinding', hookContext); + } + + /** + * 绑定组件属性 + */ + public bindProp(propName: string, propConfig: any, componentConfig: any, componentSchema: any) { + // 属性值是一个绑定 + const isBinding = BindingUtil.isBinding(propConfig); + if (isBinding) { + this.bindBindingProp(propName, propConfig, componentConfig, componentSchema); + return; + } + + // 属性值是一个数组 + if (TypeUtil.isArray(propConfig)) { + this.bindArrayProp(propName, propConfig, componentConfig, componentSchema); + return; + } + + // 属性值是个对象 + if (TypeUtil.isObject(propConfig)) { + this.bindObjectProp(propName, propConfig, componentConfig, componentSchema); + return; + } } /** diff --git a/packages/mobile-render/src/services/plugin/index.ts b/packages/mobile-render/src/services/plugin/index.ts index e02123389cf..5a70f28f915 100644 --- a/packages/mobile-render/src/services/plugin/index.ts +++ b/packages/mobile-render/src/services/plugin/index.ts @@ -1,4 +1,5 @@ export * from './types'; +export * from './plugin'; export * from './plugins/index'; export * from './plugin-creators'; export * from './plugin-manager'; diff --git a/packages/mobile-render/src/services/plugin/plugin-creators.ts b/packages/mobile-render/src/services/plugin/plugin-creators.ts index 12a0adec70e..a8b71950e91 100644 --- a/packages/mobile-render/src/services/plugin/plugin-creators.ts +++ b/packages/mobile-render/src/services/plugin/plugin-creators.ts @@ -1,5 +1,6 @@ import { PluginContext } from './types'; -import { Plugin, ListViewPlugin, LookupPlugin } from './plugins'; +import { Plugin } from './plugin'; +import { ListViewPlugin, LookupPlugin } from './plugins'; /** * 内置构件构造函数 diff --git a/packages/mobile-render/src/services/plugin/plugin-manager.ts b/packages/mobile-render/src/services/plugin/plugin-manager.ts index 15ce3b9aa3e..3f578f93976 100644 --- a/packages/mobile-render/src/services/plugin/plugin-manager.ts +++ b/packages/mobile-render/src/services/plugin/plugin-manager.ts @@ -1,6 +1,6 @@ /* eslint-disable no-use-before-define */ import { Hook, HookName, HOOK_NAMES } from './types'; -import { Plugin } from './plugins/index'; +import { Plugin } from './plugin'; /** * 插件管理器 diff --git a/packages/mobile-render/src/services/plugin/plugins/plugin.ts b/packages/mobile-render/src/services/plugin/plugin.ts similarity index 85% rename from packages/mobile-render/src/services/plugin/plugins/plugin.ts rename to packages/mobile-render/src/services/plugin/plugin.ts index 5f1f3801c9e..d37dd2c32d5 100644 --- a/packages/mobile-render/src/services/plugin/plugins/plugin.ts +++ b/packages/mobile-render/src/services/plugin/plugin.ts @@ -1,5 +1,4 @@ - -import { PluginContext } from "../types"; +import { PluginContext } from './types'; /** * 插件基类 diff --git a/packages/mobile-render/src/services/plugin/plugins/index.ts b/packages/mobile-render/src/services/plugin/plugins/index.ts index c53ca12dd5c..48ffbb3ce3e 100644 --- a/packages/mobile-render/src/services/plugin/plugins/index.ts +++ b/packages/mobile-render/src/services/plugin/plugins/index.ts @@ -1,3 +1,2 @@ -export * from './plugin'; -export * from './listview-plugin'; -export * from './lookup-plugin'; +export * from './listview-plugin/index'; +export * from './lookup-plugin/index'; diff --git a/packages/mobile-render/src/services/plugin/plugins/listview-plugin.ts b/packages/mobile-render/src/services/plugin/plugins/listview-plugin.ts deleted file mode 100644 index 5d453f205f7..00000000000 --- a/packages/mobile-render/src/services/plugin/plugins/listview-plugin.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { PluginHooks } from '../types'; -import { Plugin } from './plugin'; - -/** - * 帮助插件 - */ -class ListViewPlugin extends Plugin implements PluginHooks { - - /** - * 页面配置绑定后扩展 - */ - public afterPageConfigBinding(context: any): void { - console.log('--------------------ListViewPlugin--------------------'); - console.log(context); - } -} - -export { ListViewPlugin }; diff --git a/packages/mobile-render/src/services/plugin/plugins/listview-plugin/index.ts b/packages/mobile-render/src/services/plugin/plugins/listview-plugin/index.ts new file mode 100644 index 00000000000..e615416c968 --- /dev/null +++ b/packages/mobile-render/src/services/plugin/plugins/listview-plugin/index.ts @@ -0,0 +1 @@ +export * from './listview-plugin'; diff --git a/packages/mobile-render/src/services/plugin/plugins/listview-plugin/listview-plugin.ts b/packages/mobile-render/src/services/plugin/plugins/listview-plugin/listview-plugin.ts new file mode 100644 index 00000000000..f4903be2906 --- /dev/null +++ b/packages/mobile-render/src/services/plugin/plugins/listview-plugin/listview-plugin.ts @@ -0,0 +1,31 @@ +import { PluginHooks, AfterPageInitHookContext, AfterComponentBindingHookContext } from '../../types'; +import { Plugin } from '../../plugin'; + +/** + * 帮助插件 + */ +class ListViewPlugin extends Plugin implements PluginHooks { + + /** + * 页面配置绑定后扩展 + */ + public afterComponentBinding(context: AfterComponentBindingHookContext): void { + if (context.componentConfig.type !== 'list-view') { + return; + } + + const { viewModel, componentConfig, bindedComponentConfig } = context; + const originItemClickHandler = bindedComponentConfig['onItemClick']; + bindedComponentConfig['onItemClick'] = (event: any) => { + const { id } = event.data; + const { path } = componentConfig.dataSource; + viewModel.entityStore.changeCurrentEntityByPath(path, id); + + if (originItemClickHandler) { + originItemClickHandler(event); + } + }; + } +} + +export { ListViewPlugin }; diff --git a/packages/mobile-render/src/services/plugin/plugins/lookup-plugin.ts b/packages/mobile-render/src/services/plugin/plugins/lookup-plugin.ts deleted file mode 100644 index 2aa318fea22..00000000000 --- a/packages/mobile-render/src/services/plugin/plugins/lookup-plugin.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { PluginHooks } from '../types'; -import { Plugin } from './plugin'; - -/** - * 帮助插件 - */ -class LookupPlugin extends Plugin implements PluginHooks { - - /** - * 页面配置绑定后扩展 - */ - public afterPageConfigBinding(context: any): void { - console.log('--------------------LookupPlugin--------------------'); - console.log(context); - } -} - -export { LookupPlugin }; diff --git a/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/index.ts b/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/index.ts new file mode 100644 index 00000000000..5f31c967d05 --- /dev/null +++ b/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/index.ts @@ -0,0 +1 @@ +export * from './lookup-plugin'; diff --git a/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-data-service.ts b/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-data-service.ts new file mode 100644 index 00000000000..4d8bcb3e8fb --- /dev/null +++ b/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-data-service.ts @@ -0,0 +1,82 @@ +import { Entity, HttpClient, HttpMethod, HttpMethods, HttpRequestConfig, ViewModel, ViewModelState } from '@farris/devkit-vue'; +import { BefRepository, RequestInfoUtil } from '@farris/bef-vue'; + +/** + * 帮助取数服务 + */ +class LookupDataService { + + /** + * 视图模型上下文 + */ + private viewModel: ViewModel; + + /** + * 实体仓库 + */ + private befRepository: BefRepository; + + /** + * Http客户端 + */ + private httpClient: HttpClient; + + /** + * 帮助上下文 + */ + public context: any; + + /** + * 构造函数 + */ + constructor(viewModel: ViewModel) { + this.viewModel = viewModel; + this.befRepository = this.viewModel.repository as BefRepository; + this.httpClient = this.befRepository.apiProxy.httpClient; + } + + /** + * 帮助取数 + */ + public getData(helpMetadataId: string, queryParam?: any): Promise { + const tableName = helpMetadataId.split('.')[0]; + const labelId = helpMetadataId.split('.')[1]; + queryParam = queryParam || {}; + return this.extendGetHelpData(labelId, tableName, queryParam); + } + + /** + * 自定义请求 + */ + public request(method: HttpMethod, url: string, requestConfig: HttpRequestConfig): Promise { + return this.httpClient.request(method, url, requestConfig); + } + + /** + * 扩展的帮助取数 + */ + private extendGetHelpData(labelId: string, tableName: string, queryParam: any): Promise { + const url = `${this.befRepository.apiProxy.baseUrl}/extension/elementhelps`; + const requestInfo = RequestInfoUtil.buildRequestInfo(this.befRepository); + + const currentEntity = this.viewModel.state.entityState.currentEntity as any; + const currentForm = { id: currentEntity.id }; + + const body = { + labelId: labelId, + nodeCode: tableName, + queryParam: { ...queryParam, currentForm }, + requestInfo: requestInfo + }; + + const requestConfig: HttpRequestConfig = { + body: body + }; + + return this.befRepository.apiProxy.request(HttpMethods.PUT, url, requestConfig); + } + +} + +export { LookupDataService }; + diff --git a/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-mapping-service.ts b/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-mapping-service.ts new file mode 100644 index 00000000000..e0f39580aa2 --- /dev/null +++ b/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-mapping-service.ts @@ -0,0 +1,169 @@ +import { ViewModel, ViewModelState } from '@farris/devkit-vue'; + +/** + * 帮助映射服务 + * @summary + * SrcField:帮助实体字段 + * TargetField:表单实体字段 + */ +export class LookupMappingService { + + /** + * 视图模型 + */ + private viewModel: ViewModel; + + /** + * 构造函数 + */ + constructor(viewModelContext: ViewModel) { + this.viewModel = viewModelContext; + } + + /** + * 获取主键值 + */ + public getIdValue(mappingFields: any, srcIdField: string): any { + const targetIdFieldPaths = this.getTargetFieldPaths(srcIdField, mappingFields); + if (!Array.isArray(targetIdFieldPaths) || targetIdFieldPaths.length === 0) { + return; + } + const idValue = this.viewModel.entityStore.getValueByPath(targetIdFieldPaths[0]); + + return idValue; + } + + /** + * 映射字段(帮助控件会直接调用) + * @summary + * mapFields格式形如: + * { + * id: "assoField.assoField", + * code: "assoField.assoField_Code", + * name: "assoField.assoField_Name" + * } + */ + public mapFields(srcDataArray: any[], mappingFields: any, options: any = {}) { + if (!mappingFields) { + return; + } + + const isMultiSelect = options.multiSelect || false; + const isSrcDataArrayEmpty = !Array.isArray(srcDataArray) || srcDataArray.length === 0; + const srcFieldPathArray = this.getSrcFieldPaths(mappingFields, !isSrcDataArrayEmpty); + + if (isSrcDataArrayEmpty === true) { + + // 清空时忽略第一次的主键映射 + const isPrimaryKeyMapping = options.isPrimaryKeyMapping || false; + if (isPrimaryKeyMapping === true) { + return; + } + srcFieldPathArray.forEach((srcFieldPath: string) => { + this.clearTargetFieldValue(srcFieldPath, mappingFields, isMultiSelect); + }); + } else { + + // 设置字段值 + srcFieldPathArray.forEach((srcFieldPath: string) => { + this.setTargetFieldValue(srcFieldPath, mappingFields, srcDataArray, isMultiSelect); + }); + } + } + + /** + * 向目标字段赋值 + */ + private setTargetFieldValue(srcFieldPath: string, mappingFields: any, srcDataArray: any[], isMultiSelect: boolean): void { + + // 获取字段值 + let targetFieldVal: any = ''; + if (isMultiSelect === true) { + targetFieldVal = srcDataArray.map((selectedHelpRow: any) => { + return this.getSrcFieldValue(srcFieldPath, selectedHelpRow); + }).join(','); + } else { + targetFieldVal = this.getSrcFieldValue(srcFieldPath, srcDataArray[0]); + } + + // 更新目标字段值 + const targetFieldBindingPath = this.getTargetFieldPaths(srcFieldPath, mappingFields); + const targetEntityStore = this.viewModel.entityStore; + targetFieldBindingPath.forEach((targetFieldPathArray: any) => { + targetEntityStore.setValueByPath(targetFieldPathArray, targetFieldVal); + }); + } + + /** + * 清空目标字段的值 + */ + private clearTargetFieldValue(srcFieldPath: string, mappingFields: any, isMultiSelect: boolean): void { + const targetFieldBindingPaths = this.getTargetFieldPaths(srcFieldPath, mappingFields); + targetFieldBindingPaths.forEach((targetFieldPathArray: any) => { + if (isMultiSelect === true) { + this.viewModel.entityStore.setValueByPath(targetFieldPathArray, ''); + } else { + // Not Supported + } + }); + } + + /** + * 获取源实体的字段绑定路径 + * @summary + * 1、设置值:需要先设置ID的值 + * 2、清空值:需要最后清空ID的值 + */ + private getSrcFieldPaths(mappingFields: any, isSetValue: boolean): string[] { + let srcFieldPathArray = Object.keys(mappingFields); + + // 交换ID字段顺序 + const idIndex = srcFieldPathArray.findIndex((item) => item === 'id'); + if (srcFieldPathArray.includes('id')) { + srcFieldPathArray.splice(idIndex, 1); + srcFieldPathArray = isSetValue ? ['id', ...srcFieldPathArray] : [...srcFieldPathArray, 'id']; + } + + return srcFieldPathArray; + } + + /** + * 获取目标实体的字段绑定路径 + */ + private getTargetFieldPaths(srcFieldPath: string, mappingFields: any): string[] { + const viewModelBindingPath = this.getViewModelBindingPath(); + const targetFieldPaths = []; + mappingFields[srcFieldPath].split(',').forEach((targetFieldPath: string) => { + if (!targetFieldPath) { + return; + } + targetFieldPath = '/' + targetFieldPath.replace('.', '/'); + targetFieldPath = `${viewModelBindingPath}${targetFieldPath}`; + targetFieldPaths.push(targetFieldPath); + }); + return targetFieldPaths; + } + + /** + * 获取源实体数据中的字段值 + */ + private getSrcFieldValue(srcFieldPath: string, srcData: any): any { + let srcFieldValue = ''; + if (srcFieldPath.indexOf('.') === -1) { + srcFieldValue = srcData[srcFieldPath]; + } else { + srcFieldValue = srcFieldPath.split('.').reduce((data, key) => { + return data[key]; + }, srcData); + } + return srcFieldValue; + } + + /** + * 获取视图模型的绑定路径 + */ + private getViewModelBindingPath(): string { + const { bindingPath } = this.viewModel; + return bindingPath === '/' ? '' : bindingPath; + } +} diff --git a/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-plugin.ts b/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-plugin.ts new file mode 100644 index 00000000000..0cc40d5c934 --- /dev/null +++ b/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-plugin.ts @@ -0,0 +1,58 @@ +import { provide } from 'vue'; +import { LOOKUP_HTTP_SERVICE_TOKEN } from '@farris/mobile-ui-vue'; +import { PluginHooks, AfterPageInitHookContext, AfterComponentBindingHookContext } from '../../types'; +import { Plugin } from '../../plugin'; +import { LookupDataService } from './lookup-data-service'; +import { LookupMappingService } from './lookup-mapping-service'; + +/** + * 帮助插件 + */ +class LookupPlugin extends Plugin implements PluginHooks { + + /** + * 页面初始化后 + */ + public afterPageInit(context: AfterPageInitHookContext): void { + const { viewModel } = context; + const lookupDataServce = new LookupDataService(viewModel); + provide(LOOKUP_HTTP_SERVICE_TOKEN, lookupDataServce); + } + + /** + * 页面配置绑定后扩展 + */ + public afterComponentBinding(context: AfterComponentBindingHookContext): void { + if (context.componentConfig.type !== 'lookup') { + return; + } + + const { viewModel, componentConfig, bindedComponentConfig } = context; + const mappingService = new LookupMappingService(viewModel); + const mappingFields = JSON.parse(componentConfig.mappingFields); + + // 注册变化事件,实现字段映射 + const originChangeHandler = bindedComponentConfig['onChange']; + bindedComponentConfig['onChange'] = (event: any) => { + mappingService.mapFields([event], mappingFields); + this.updateIdValue(componentConfig, bindedComponentConfig, mappingFields, mappingService); + + originChangeHandler(event); + }; + + this.updateIdValue(componentConfig, bindedComponentConfig, mappingFields, mappingService); + } + + /** + * 更新idValue属性 + */ + private updateIdValue(componentConfig: any, bindedComponentConfig: any, mappingFields: any, mappingService: any): void { + const idFieldPath = componentConfig.dataSource.idField; + const idValue = mappingService.getIdValue(mappingFields, idFieldPath); + + // 更新idValue属性 + bindedComponentConfig['idValue'] = idValue; + } +} + +export { LookupPlugin }; diff --git a/packages/mobile-render/src/services/plugin/types.ts b/packages/mobile-render/src/services/plugin/types.ts index 03b2fc8bf05..2bd63756910 100644 --- a/packages/mobile-render/src/services/plugin/types.ts +++ b/packages/mobile-render/src/services/plugin/types.ts @@ -1,17 +1,17 @@ import { App } from 'vue'; import { Router } from 'vue-router'; -import { Devkit } from '@farris/devkit-vue'; +import { Devkit, Module, ViewModel, ViewModelState } from '@farris/devkit-vue'; /** * 钩子名称 */ -type HookName = 'afterAppInit' | 'afterModuleInit' | 'afterPageInit' | 'beforePageConfigBinding' | 'afterPageConfigBinding'; +type HookName = 'afterAppInit' | 'afterModuleInit' | 'afterPageInit' | 'afterComponentBinding'; /** * 构造名称集合 */ const HOOK_NAMES: HookName[] = [ - 'afterAppInit', 'afterModuleInit', 'afterPageInit', 'beforePageConfigBinding', 'afterPageConfigBinding' + 'afterAppInit', 'afterModuleInit', 'afterPageInit', 'afterComponentBinding' ]; /** @@ -35,40 +35,67 @@ interface PluginHooks { afterModuleInit?: Hook; /** - * 页面初始化后 + * 视图上下文初始化后 */ afterPageInit?: Hook; /** - * 页面配置绑定前 + * 组件绑定后 */ - beforePageConfigBinding?: Hook; + afterComponentBinding?: Hook; +} - /** - * 页面配置绑定后 - */ - afterPageConfigBinding?: Hook; +/** + * 构造上下文 + */ +interface HookContext { + hookName: string; +} + +/** + * 应用初始化后上下文 + */ +interface AfterAppInitHookContext extends HookContext { + app: App; + router: Router; + devkit: Devkit; +} + +/** + * 模块初始化后上下文 + */ +interface AfterModuleInitHookContext extends HookContext { + module: Module; +} + +/** + * 组件初始化后上下文 + */ +interface AfterPageInitHookContext extends HookContext { + viewModel: ViewModel; +} + +/** + * 组件绑定后上下文 + */ +interface AfterComponentBindingHookContext { + viewModel: ViewModel; + componentSchema: any; + componentConfig: any; + bindedComponentConfig: any; } /** * 插件上下文 */ interface PluginContext { - - /** - * 应用实例 - */ app: App; - - /** - * 路由实例 - */ router: Router; - - /** - * 开发框架实例 - */ devkit: Devkit; } -export { HookName, HOOK_NAMES, Hook, PluginHooks, PluginContext }; +export { + HookName, HOOK_NAMES, Hook, + AfterAppInitHookContext, AfterModuleInitHookContext, AfterPageInitHookContext, AfterComponentBindingHookContext, + PluginHooks, PluginContext +}; diff --git a/packages/mobile-render/src/views/page/page-runner.ts b/packages/mobile-render/src/views/page/page-runner.ts index b4fff7d3e1c..60e4693839e 100644 --- a/packages/mobile-render/src/views/page/page-runner.ts +++ b/packages/mobile-render/src/views/page/page-runner.ts @@ -55,6 +55,7 @@ class PageRunner { this.initViewModel(); this.initUIState(); this.initPageConfig(); + this.pluginManager.runHooks('afterPageInit', { viewModel: this.viewModel }); } /** @@ -121,16 +122,9 @@ class PageRunner { const pageConfigBuilder = new PageConfigBuilder(formMetadata, pageId); const pageConfig = pageConfigBuilder.build(); - console.log('----------pageConfig----------'); - console.log(pageConfig); - // 绑定页面配置 - const pageConfigBinder = new PageConfigBinder(this.module, pageConfig); + const pageConfigBinder = new PageConfigBinder(this.module, this.viewModel, pageConfig); this.pageConfig = pageConfigBinder.bind(); - this.pluginManager.runHooks('afterPageConfigBinding', { pageConfig: this.pageConfig }); - - console.log('----------binded pageConfig----------'); - console.log(this.pageConfig); } /** diff --git a/packages/mobile-render/src/views/page/page.vue b/packages/mobile-render/src/views/page/page.vue index 343955e7f97..569dcb20b3e 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/components/dynamic-view/src/composition/use-render-component.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-render-component.ts index 08134f1b9ea..18742c42428 100644 --- 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 @@ -80,7 +80,6 @@ export function useRenderComponent(context: DynamicViewContext) { throw new Error(`Component(type=${componentType}) not found`); } const componentSchema = schemaMap[componentType]; - const resolvedComponentConfig = resolveProps(componentConfig); const slots = resolveSlots(resolvedComponentConfig, componentSchema) || {}; const defaultSlot = slots.default ? slots.default : resolveChildren(resolvedComponentConfig); diff --git a/packages/mobile-ui-vue/components/index.ts b/packages/mobile-ui-vue/components/index.ts index a5ebd6f06e3..11d41bf124e 100644 --- a/packages/mobile-ui-vue/components/index.ts +++ b/packages/mobile-ui-vue/components/index.ts @@ -49,11 +49,11 @@ import ContentContainer from './content-container'; import FloatContainer from './float-container'; import Filter from './filter'; import * as Utils from './common/src/utils'; - import DynamicView from './dynamic-view'; export * from './register'; export * from './designer'; export { type DynamicViewContext, DYNAMIC_VIEW_CONTEXT, DefaultDynamicViewContext } from './dynamic-view'; +export { LOOKUP_HTTP_SERVICE_TOKEN } from './lookup'; const components = [ Button, diff --git a/packages/mobile-ui-vue/components/lookup/src/schema/lookup.schema.json b/packages/mobile-ui-vue/components/lookup/src/schema/lookup.schema.json index 853b9375ff1..3fb119a38a6 100644 --- a/packages/mobile-ui-vue/components/lookup/src/schema/lookup.schema.json +++ b/packages/mobile-ui-vue/components/lookup/src/schema/lookup.schema.json @@ -32,6 +32,10 @@ "type": "object", "default": {} }, + "idValue": { + "description": "ID值", + "type": "string" + }, "required": { "description": "必填", "type": "boolean", @@ -63,7 +67,7 @@ "title": { "description": "标题", "type": "string", - "default": "" + "default": "请选择" }, "idField": { "description": "值字段", @@ -103,6 +107,10 @@ "onUpdate:modelValue": { "description": "值更新事件", "type": "string" + }, + "onChange": { + "description": "选择项变化事件", + "type": "string" } }, "events": [ @@ -114,7 +122,6 @@ "ignore": [ "id", "appearance", - "binding", "visible" ] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/lookup/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/lookup/src/schema/schema-mapper.ts index cbdfe5f71e0..9710dae5f8c 100644 --- a/packages/mobile-ui-vue/components/lookup/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/lookup/src/schema/schema-mapper.ts @@ -12,6 +12,9 @@ function converMappingFieldsToObject(mappingFields: any) { export const schemaMapper = new Map([ ['appearance', resolveAppearance], ['binding', 'modelValue'], + ['displayType', (key: string, value: any, resolvedSchema) => { + return { displayType: 'LIST'}; + }], ['mappingFields', (key: string, value: any, resolvedSchema) => { if (value) { return converMappingFieldsToObject(value); -- Gitee From b3fd733b0d5087774b00fe10e4dbe73dce5546f2 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Sat, 19 Apr 2025 17:28:38 +0800 Subject: [PATCH 262/287] =?UTF-8?q?fix:=20=E8=B0=83=E6=95=B4=E5=B8=AE?= =?UTF-8?q?=E5=8A=A9=E6=98=BE=E7=A4=BA=E7=B1=BB=E5=9E=8B=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/lookup/src/schema/schema-mapper.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/mobile-ui-vue/components/lookup/src/schema/schema-mapper.ts b/packages/mobile-ui-vue/components/lookup/src/schema/schema-mapper.ts index 9710dae5f8c..c443b783015 100644 --- a/packages/mobile-ui-vue/components/lookup/src/schema/schema-mapper.ts +++ b/packages/mobile-ui-vue/components/lookup/src/schema/schema-mapper.ts @@ -1,4 +1,5 @@ import { MapperFunction, resolveAppearance } from '@farris/mobile-ui-vue/dynamic-resolver'; +import { LookupDisplayType } from '../composition/index'; function converMappingFieldsToObject(mappingFields: any) { if (typeof mappingFields == 'string' && mappingFields.startsWith('{') && mappingFields.endsWith('}')) { @@ -13,7 +14,12 @@ export const schemaMapper = new Map([ ['appearance', resolveAppearance], ['binding', 'modelValue'], ['displayType', (key: string, value: any, resolvedSchema) => { - return { displayType: 'LIST'}; + const mappings = { + 'List': LookupDisplayType.List, + 'TreeList': LookupDisplayType.Tree + }; + const displayType = mappings[value]; + return { displayType }; }], ['mappingFields', (key: string, value: any, resolvedSchema) => { if (value) { -- Gitee From 0bd06807ee1acd353988e03f046961082f48689d Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Mon, 21 Apr 2025 08:58:25 +0800 Subject: [PATCH 263/287] =?UTF-8?q?fix:=20=E8=B0=83=E6=95=B4designer?= =?UTF-8?q?=E4=B8=AD=E7=A7=BB=E5=8A=A8=E7=BB=84=E4=BB=B6=E5=88=AB=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/designer/farris.config.mjs | 2 +- packages/designer/vite.config.dev.ts | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/designer/farris.config.mjs b/packages/designer/farris.config.mjs index e987a543247..0a6a9141f95 100644 --- a/packages/designer/farris.config.mjs +++ b/packages/designer/farris.config.mjs @@ -39,7 +39,7 @@ export default { alias: [ { find: '@', replacement: fileURLToPath(new URL('./src', import.meta.url)) }, { find: '@farris/ui-vue/components', replacement: fileURLToPath(new URL('../ui-vue/components', import.meta.url)) }, - { find: '@farris/mobile-ui-vue/components', replacement: fileURLToPath(new URL('../mobile-ui-vue/components', import.meta.url)) }, + { find: '@farris/mobile-ui-vue', replacement: fileURLToPath(new URL('../mobile-ui-vue/components', import.meta.url)) }, { find: '@farris/code-editor-vue/components', replacement: fileURLToPath(new URL('../code-editor/components', import.meta.url)) } ], // 插件 默认值 [vue(), vueJsx()] 不要重复添加 diff --git a/packages/designer/vite.config.dev.ts b/packages/designer/vite.config.dev.ts index 84e85c8bdbc..faf13102d0d 100644 --- a/packages/designer/vite.config.dev.ts +++ b/packages/designer/vite.config.dev.ts @@ -19,10 +19,7 @@ export default defineConfig({ alias: { '@farris/ui-vue': resolve(__dirname, '../ui-vue'), '@farris/code-editor-vue': resolve(__dirname, '../code-editor'), - '@farris/mobile-ui-vue': resolve(__dirname, '../mobile-ui-vue'), - '@components': resolve(__dirname, '../mobile-ui-vue/components'), - '@/components': resolve(__dirname, '../mobile-ui-vue/components'), - '@': resolve(__dirname, '../') + '@farris/mobile-ui-vue': resolve(__dirname, '../mobile-ui-vue/components') } } }); -- Gitee From d0bce4b03c1cd9257fa330a24c38fe03d1a22004 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Mon, 21 Apr 2025 09:18:21 +0800 Subject: [PATCH 264/287] =?UTF-8?q?fix:=20=E8=B0=83=E6=95=B4designer?= =?UTF-8?q?=E4=B8=AD=E7=A7=BB=E5=8A=A8=E7=BB=84=E4=BB=B6=E5=88=AB=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/designer/vite.config.dev.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/designer/vite.config.dev.ts b/packages/designer/vite.config.dev.ts index faf13102d0d..37b7971cdf1 100644 --- a/packages/designer/vite.config.dev.ts +++ b/packages/designer/vite.config.dev.ts @@ -17,6 +17,7 @@ export default defineConfig({ }, resolve: { alias: { + '@': resolve(__dirname, '../'), '@farris/ui-vue': resolve(__dirname, '../ui-vue'), '@farris/code-editor-vue': resolve(__dirname, '../code-editor'), '@farris/mobile-ui-vue': resolve(__dirname, '../mobile-ui-vue/components') -- Gitee From edd74dec2d036c5958c34f1acc093e7e39169409 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Mon, 21 Apr 2025 10:23:46 +0800 Subject: [PATCH 265/287] =?UTF-8?q?fix:=20=E5=88=A0=E9=99=A4=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E4=BD=BF=E7=94=A8=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/src/entity/base-property.ts | 129 -------- .../common/src/entity/input-base-property.ts | 285 ------------------ .../mobile-ui-vue/components/modal/style.ts | 3 - 3 files changed, 417 deletions(-) delete mode 100644 packages/mobile-ui-vue/components/common/src/entity/base-property.ts delete mode 100644 packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts delete mode 100644 packages/mobile-ui-vue/components/modal/style.ts diff --git a/packages/mobile-ui-vue/components/common/src/entity/base-property.ts b/packages/mobile-ui-vue/components/common/src/entity/base-property.ts deleted file mode 100644 index fa1776ca76e..00000000000 --- a/packages/mobile-ui-vue/components/common/src/entity/base-property.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { DesignerComponentInstance, DgControl } from "@farris/mobile-ui-vue/designer-canvas"; -import { cloneDeep } from "lodash-es"; - -/** - * 控件属性基类 - */ -export class BaseControlProperty { - public componentId: string; - - public viewModelId: string; - - public eventsEditorUtils: any; - - public formSchemaUtils: any; - public formMetadataConverter: any; - public designViewModelUtils: any; - public designViewModelField: any; - public controlCreatorUtils: any; - public designerHostService: any; - - schemaService: any = null; - - metadataService: any = null; - - protected propertyConfig = { - type: 'object', - categories: {} - }; - - constructor(componentId: string, designerHostService: any) { - this.componentId = componentId; - this.designerHostService = designerHostService; - this.eventsEditorUtils = designerHostService['eventsEditorUtils']; - this.formSchemaUtils = designerHostService['formSchemaUtils']; - this.formMetadataConverter = designerHostService['formMetadataConverter']; - this.viewModelId = this.formSchemaUtils?.getViewModelIdByComponentId(componentId) || ''; - this.designViewModelUtils = designerHostService['designViewModelUtils']; - this.controlCreatorUtils = designerHostService['controlCreatorUtils']; - this.metadataService = designerHostService['metadataService']; - this.schemaService = designerHostService['schemaService']; - } - - getTableInfo() { - return this.schemaService?.getTableInfoByViewModelId(this.viewModelId); - } - - setDesignViewModelField(propertyData: any) { - const bindingFieldId = propertyData.binding && propertyData.binding.type === 'Form' && propertyData.binding.field; - // 视图模型中[字段更新时机]属性现在要在控件上维护,所以在控件上复制一份属性值 - if (bindingFieldId) { - if (!this.designViewModelField) { - const dgViewModel = this.designViewModelUtils.getDgViewModel(this.viewModelId); - this.designViewModelField = dgViewModel.fields.find(f => f.id === bindingFieldId); - } - propertyData.updateOn = this.designViewModelField?.updateOn; - } - } - - getBasicPropConfig(propertyData: any): any { - return { - description: 'Basic Information', - title: '基本信息', - properties: { - id: { - description: '组件标识', - title: '标识', - type: 'string', - readonly: true - }, - type: { - description: '组件类型', - title: '控件类型', - type: 'select', - editor: { - type: 'combo-list', - textField: 'name', - valueField: 'value', - editable: false, - data: [{ value: propertyData.type, name: DgControl[propertyData.type] && DgControl[propertyData.type].name }] - } - } - } - }; - - } - - - protected getAppearanceConfig(propertyData = null): any { - return { - title: "外观", - description: "Appearance", - properties: { - class: { - title: "class样式", - type: "string", - description: "组件的CSS样式", - $converter: "/converter/appearance.converter" - }, - style: { - title: "style样式", - type: "string", - description: "组件的样式", - $converter: "/converter/appearance.converter" - } - } - }; - } - - /** - * - * @param propertyId - * @param componentInstance - * @returns - */ - public updateElementByParentContainer(propertyId: string, componentInstance: DesignerComponentInstance) { - // 1、定位控件父容器 - const parentContainer = componentInstance && componentInstance.parent && componentInstance.parent['schema']; - if (!parentContainer) { - return; - } - const index = parentContainer.contents.findIndex(c => c.id === propertyId); - // 通过cloneDeep方式的触发更新 - const controlSchema = cloneDeep(parentContainer.contents[index]); - // 5、替换控件 - parentContainer.contents.splice(index, 1); - parentContainer.contents.splice(index, 0, controlSchema); - } - -} diff --git a/packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts b/packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts deleted file mode 100644 index ce092430945..00000000000 --- a/packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts +++ /dev/null @@ -1,285 +0,0 @@ -import { BaseControlProperty } from './base-property'; -import { DesignerComponentInstance } from "@farris/mobile-ui-vue/designer-canvas"; -import { SchemaDOMMapping } from "@farris/mobile-ui-vue/property-panel"; -import { canvasChanged } from "@farris/mobile-ui-vue/designer-canvas/src/composition/designer-canvas-changed"; -import { FormSchemaEntityFieldType$Type } from './entity-schema'; - -export class InputBaseProperty extends BaseControlProperty { - constructor(componentId: string, designerHostService: any) { - super(componentId, designerHostService); - } - - public getPropertyConfig(propertyData: any, componentInstance: DesignerComponentInstance) { - // 基本信息 - this.propertyConfig.categories['basic'] = this.getBasicProperties(propertyData, componentInstance); - // 外观 - this.propertyConfig.categories['appearance'] = this.getAppearanceProperties(propertyData, componentInstance); - // 编辑器 - this.propertyConfig.categories['editor'] = this.getEditorProperties(propertyData); - return this.propertyConfig; - } - - public getBasicProperties(propertyData, componentInstance): any { - const self = this; - this.setDesignViewModelField(propertyData); - return { - description: 'Basic Information', - title: '基本信息', - properties: { - id: { - description: '组件标识', - title: '标识', - type: 'string', - readonly: true - }, - type: { - description: '编辑器类型', - title: '编辑器类型', - type: 'string', - refreshPanelAfterChanged: true, - $converter: '/converter/change-editor.converter', - editor: { - type: 'combo-list', - textField: 'value', - valueField: 'key', - editable: false, - data: self.designViewModelField ? SchemaDOMMapping.getEditorTypesByMDataType(self.designViewModelField.type?.name) : SchemaDOMMapping.getAllInputTypes() - } - }, - label: { - title: "标签", - type: "string", - $converter: '/converter/form-group-label.converter' - }, - binding: { - description: "绑定的表单字段", - title: "绑定", - editor: { - type: "binding-selector", - bindingType: { "enable": false }, - editorParams: { - componentSchema: propertyData, - needSyncToViewModel: true, - viewModelId: this.viewModelId, - designerHostService: this.designerHostService, - disableOccupiedFields: true - }, - textField: 'bindingField' - } - } - }, - setPropertyRelates(changeObject, prop) { - if (!changeObject) { - return; - } - switch (changeObject && changeObject.propertyID) { - case 'type': { - self.changeControlType(propertyData, changeObject, componentInstance); - break; - } - case 'label': { - changeObject.needRefreshControlTree = true; - break; - } - } - } - }; - } - public getAppearanceProperties(propertyData, componentInstance): any { - - const self = this; - return { - title: "外观", - description: "Appearance", - properties: { - class: { - title: "class样式", - type: "string", - description: "组件的CSS样式", - $converter: "/converter/appearance.converter" - }, - style: { - title: "style样式", - type: "string", - description: "组件的样式", - $converter: "/converter/appearance.converter" - } - }, - setPropertyRelates(changeObject, prop) { - if (!changeObject) { - return; - } - switch (changeObject && changeObject.propertyID) { - case 'class': - self.updateElementByParentContainer(propertyData.id, componentInstance); - break; - } - - } - }; - }; - - public getEditorProperties(propertyData): any { - return this.getComponentConfig(propertyData); - } - - - /** - * 卡片控件:切换控件类型后事件 - * @param propertyData 控件DOM属性 - * @param newControlType 新控件类型 - */ - private changeControlType(propertyData, changeObject, componentInstance: DesignerComponentInstance) { - const newControlType = changeObject.propertyValue; - - // 1、定位控件父容器 - const parentContainer = componentInstance && componentInstance.parent && componentInstance.parent['schema']; - if (!parentContainer) { - return; - } - - const index = parentContainer.contents.findIndex(c => c.id === propertyData.id); - const oldControl = parentContainer.contents[index]; - - let newControl; - // 2、记录绑定字段viewModel的变更 - if (this.designViewModelField) { - const dgViewModel = this.designViewModelUtils.getDgViewModel(this.viewModelId); - dgViewModel.changeField(this.designViewModelField.id, { - editor: { - $type: newControlType - }, - name: this.designViewModelField.name, - require: this.designViewModelField.require, - readonly: this.designViewModelField.readonly - }, false); - // 3、创建新控件 - newControl = this.controlCreatorUtils.setFormFieldProperty(this.designViewModelField, newControlType); - } - if (!newControl) { - newControl = this.controlCreatorUtils.createFormGroupWithoutField(newControlType); - } - // 4、保留原id样式等属性 - Object.assign(newControl, { - id: oldControl.id, - appearance: oldControl.appearance, - size: oldControl.size, - label: oldControl.label, - binding: oldControl.binding, - visible: oldControl.visible - }); - Object.assign(newControl.editor, { - isTextArea: newControl.isTextArea && oldControl.isTextArea, - placeholder: oldControl.editor?.placeholder, - holdPlace: oldControl.editor?.holdPlace, - readonly: oldControl.editor?.readonly, - required: oldControl.editor?.required, - }); - - // 5、替换控件 - parentContainer.contents.splice(index, 1); - parentContainer.contents.splice(index, 0, newControl); - componentInstance.schema = Object.assign(oldControl, newControl); - - // 6、暂时移除旧控件的选中样式(后续考虑更好的方式) - Array.from(document.getElementsByClassName('dgComponentSelected') as HTMLCollectionOf).forEach( - (element: HTMLElement) => element.classList.remove('dgComponentSelected') - ); - - Array.from(document.getElementsByClassName('dgComponentFocused') as HTMLCollectionOf).forEach( - (element: HTMLElement) => element.classList.remove('dgComponentFocused') - ); - // 7、触发刷新 - canvasChanged.value++; - - } - - public getComponentConfig(propertyData, info = {}, properties = {}, setPropertyRelates?: any) { - const editorBasic = Object.assign({ - description: "编辑器", - title: "编辑器", - type: "input-group", - $converter: "/converter/property-editor.converter" - }, info); - - const editorProperties = Object.assign({ - readonly: { - description: "", - title: "只读", - type: "boolean", - editor: { - enableClear: true, - editable: true - } - }, - disabled: { - description: "", - title: "禁用", - type: "boolean", - visible: false - }, - required: { - description: "", - title: "必填", - type: "boolean", - visible: false - }, - placeholder: { - description: "空值时,输入控件内的占位文本", - title: "提示文本", - type: "string", - visible: false - - } - }, properties); - - return { ...editorBasic, properties: { ...editorProperties }, setPropertyRelates }; - - } - - - /** - * 枚举项编辑器 - * @param propertyData - * @param valueField - * @param textField - * @returns - */ - protected getItemCollectionEditor(propertyData, valueField, textField) { - valueField = valueField || 'value'; - textField = textField || 'name'; - return { - editor: { - columns: [ - { field: valueField, title: '值', dataType: 'string' }, - { field: textField, title: '名称', dataType: 'string' }, - { field: 'disabled', title: '禁用', visible: false, dataType: 'boolean', editor: { type: 'switch' } }, - ], - type: "item-collection-editor", - valueField: valueField, - nameField: textField, - requiredFields: [valueField, textField], - uniqueFields: [valueField, textField], - readonly: this.checkEnumDataReadonly(propertyData) - } - }; - } - /** - * 判断枚举数据是否只读 - * 1、没有绑定信息或者绑定变量,可以新增、删除、修改 - * 2、绑定类型为字段,且字段为枚举字段,则不可新增、删除、修改枚举值。只能从be修改然后同步到表单上。 - * @param propertyData 下拉框控件属性值 - */ - private checkEnumDataReadonly(propertyData: any): boolean { - // 没有绑定信息或者绑定变量 - if (!propertyData.binding || propertyData.binding.type !== 'Form') { - return false; - } - if (this.designViewModelField && this.designViewModelField.type && - this.designViewModelField.type.$type === FormSchemaEntityFieldType$Type.EnumType) { - // 低代码、零代码,枚举字段均不可以改 - return true; - } - return false; - } -} diff --git a/packages/mobile-ui-vue/components/modal/style.ts b/packages/mobile-ui-vue/components/modal/style.ts deleted file mode 100644 index 9fef5f8ed02..00000000000 --- a/packages/mobile-ui-vue/components/modal/style.ts +++ /dev/null @@ -1,3 +0,0 @@ -import "@farris/mobile-ui-vue/dependent-base/style"; -import "@farris/mobile-ui-vue/button/style"; -import "@theme-default/components/modal.css"; -- Gitee From e00c31536f25e34e8867132b8e9be58a845c0aac Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Mon, 21 Apr 2025 14:15:57 +0800 Subject: [PATCH 266/287] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4tsconfig?= =?UTF-8?q?=E4=B8=AD=E5=AF=B9=E7=A7=BB=E5=8A=A8=E7=BB=84=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E9=85=8D=E7=BD=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/designer/tsconfig.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/designer/tsconfig.json b/packages/designer/tsconfig.json index 54db16283f1..938120701ad 100644 --- a/packages/designer/tsconfig.json +++ b/packages/designer/tsconfig.json @@ -19,9 +19,7 @@ "forceConsistentCasingInFileNames": true, "types": ["vitest/globals", "@types/jest"], "baseUrl": "./", - "paths": { - "@farris/mobile-ui-vue": ["../mobile-ui-vue/components"] - } + "paths": { } }, "include": ["components/**/*", "src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "designer/**/*"], "references": [{ "path": "./tsconfig.node.json" }] -- Gitee From 215c03bc8f3b5b43171b6e1674116137c95ce24e Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Mon, 21 Apr 2025 14:17:28 +0800 Subject: [PATCH 267/287] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4tsconfig?= =?UTF-8?q?=E4=B8=AD=E5=AF=B9=E7=A7=BB=E5=8A=A8=E7=BB=84=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E9=85=8D=E7=BD=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/designer/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/designer/tsconfig.json b/packages/designer/tsconfig.json index 938120701ad..0b7f4ecc103 100644 --- a/packages/designer/tsconfig.json +++ b/packages/designer/tsconfig.json @@ -19,7 +19,7 @@ "forceConsistentCasingInFileNames": true, "types": ["vitest/globals", "@types/jest"], "baseUrl": "./", - "paths": { } + "paths": {} }, "include": ["components/**/*", "src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "designer/**/*"], "references": [{ "path": "./tsconfig.node.json" }] -- Gitee From 616659365e57e0e5f27aadb0e53ed95d3dd1af80 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Mon, 21 Apr 2025 15:29:23 +0800 Subject: [PATCH 268/287] =?UTF-8?q?chore:=20=E8=B0=83=E6=95=B4MobileRender?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile-render/src/common/event-emitter.ts | 39 ------------------- packages/mobile-render/src/common/index.ts | 10 ++++- .../form/converters/base-converter.ts | 0 .../component-converters/button-converter.ts | 0 .../button-group-converter.ts | 4 +- .../component-converter.ts | 2 +- .../component-converters/datebox-converter.ts | 2 +- .../enum-field-converter.ts | 2 +- .../converters/component-converters/index.ts | 0 .../component-converters/input-converter.ts | 2 +- .../listview-converter.ts | 0 .../lookup-edit-converter.ts | 2 +- .../multi-textbox-converter.ts | 2 +- .../component-converters/navigation-bar.ts | 2 +- .../numeric-box-converter.ts | 2 +- .../page-content-container-converter.ts | 0 .../switch-field-converter.ts | 2 +- .../component-converters/textbox-converter.ts | 2 +- .../form/converters/converter-context.ts | 0 .../form/converters/converter-factory.ts | 0 .../metadata/form/converters/index.ts | 0 .../form/converters/schemas-converter.ts | 0 .../metadata/form/converters/types.ts | 0 .../form/converters/viewodels-converter.ts | 2 +- .../metadata/form/entity-schema-query.ts | 0 .../metadata/form/form-metadata-converter.ts | 0 .../form/form-metadata-data-service.ts | 0 .../metadata/form/form-metadata-normalizer.ts | 0 .../metadata/form/form-metadata-query.ts | 0 .../metadata/form/index.ts | 0 .../normalizers/button-group-normalizer.ts | 0 .../component-normalizer-factory.ts | 0 .../form/normalizers/component-normalizer.ts | 2 +- .../form/normalizers/form-group-normalizer.ts | 0 .../metadata/form/normalizers/index.ts | 0 .../form/normalizers/listview-normalizer.ts | 0 .../form/normalizers/normalizer-util.ts | 2 +- .../metadata/form/normalizers/types.ts | 0 .../metadata/form/types.ts | 0 .../{services => common}/metadata/index.ts | 0 .../metadata/metadata-cahce-service.ts | 0 .../metadata/metadata-data-service.ts | 0 .../metadata/metadata-repository.ts | 0 .../metadata/statemachine/index.ts | 0 .../state-machine-metadata-data-service.ts | 0 .../{services => common}/metadata/types.ts | 0 ...ommon-web-command-metadata-data-service.ts | 0 ...ustom-web-command-metadata-data-service.ts | 0 .../metadata/webcmd/index.ts | 0 ...tom-web-component-metadata-data-service.ts | 0 .../metadata/webcmp/index.ts | 0 .../module-config/command-handler-builder.ts | 0 .../entity-store-config-builder.ts | 0 .../form/form-array-store-config-builder.ts | 0 .../form/form-control-config-builder.ts | 0 .../form/form-store-config-builder.ts | 0 .../module-config/form/index.ts | 0 .../form/validation-rule-creator.ts | 0 .../module-config/index.ts | 0 .../module-config/module-config-builder.ts | 0 .../repository-config-builder.ts | 0 .../state-machine-config-builder.ts | 0 .../module-config/ui-store-config-builder.ts | 0 .../module-config/viewmodel-config-builder.ts | 0 .../page-config/bindings/binding-context.ts | 0 .../page-config/bindings/binding-factory.ts | 0 .../page-config/bindings/binding-util.ts | 2 +- .../page-config/bindings/binding-watcher.ts | 0 .../page-config/bindings/binding.ts | 0 .../page-config/bindings/command-binding.ts | 0 .../bindings/entity-field-binding.ts | 0 .../bindings/entity-list-binding.ts | 0 .../page-config/bindings/index.ts | 0 .../bindings/state-machine-binding.ts | 0 .../page-config/bindings/types.ts | 0 .../{services => common}/page-config/index.ts | 0 .../page-config/page-config-binder.ts | 2 +- .../page-config/page-config-builder.ts | 0 .../src/{services => common}/plugin/index.ts | 0 .../plugin/plugin-creators.ts | 0 .../plugin/plugin-manager.ts | 0 .../src/{services => common}/plugin/plugin.ts | 0 .../plugin/plugins/index.ts | 0 .../plugin/plugins/listview-plugin/index.ts | 0 .../listview-plugin/listview-plugin.ts | 0 .../plugin/plugins/lookup-plugin/index.ts | 0 .../lookup-plugin/lookup-data-service.ts | 0 .../lookup-plugin/lookup-mapping-service.ts | 0 .../plugins/lookup-plugin/lookup-plugin.ts | 0 .../src/{services => common}/plugin/types.ts | 0 .../mobile-render/src/common/providers.ts | 28 +++++++++++-- .../services/dynamic-route-service.ts | 6 +-- .../src/common/services/index.ts | 1 + packages/mobile-render/src/common/types.ts | 1 - .../src/{ => common}/utils/format-utils.ts | 0 .../src/{ => common}/utils/index.ts | 0 .../src/{ => common}/utils/json-util.ts | 0 .../src/{ => common}/utils/string-util.ts | 0 .../src/{ => common}/utils/type-util.ts | 0 packages/mobile-render/src/main.ts | 7 ++-- .../src/router/use-form-routes.ts | 2 +- packages/mobile-render/src/services/index.ts | 7 ---- .../mobile-render/src/services/providers.ts | 26 ------------- packages/mobile-render/src/types.ts | 4 -- .../src/views/form/form-runner.ts | 4 +- .../src/views/page/page-runner.ts | 6 ++- 106 files changed, 64 insertions(+), 111 deletions(-) delete mode 100644 packages/mobile-render/src/common/event-emitter.ts rename packages/mobile-render/src/{services => common}/metadata/form/converters/base-converter.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/button-converter.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/button-group-converter.ts (93%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/component-converter.ts (92%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/datebox-converter.ts (95%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/enum-field-converter.ts (91%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/index.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/input-converter.ts (94%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/listview-converter.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/lookup-edit-converter.ts (93%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/multi-textbox-converter.ts (91%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/navigation-bar.ts (95%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/numeric-box-converter.ts (91%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/page-content-container-converter.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/switch-field-converter.ts (90%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/textbox-converter.ts (90%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/converter-context.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/converter-factory.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/index.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/schemas-converter.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/types.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/viewodels-converter.ts (96%) rename packages/mobile-render/src/{services => common}/metadata/form/entity-schema-query.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/form-metadata-converter.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/form-metadata-data-service.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/form-metadata-normalizer.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/form-metadata-query.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/index.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/button-group-normalizer.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/component-normalizer-factory.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/component-normalizer.ts (99%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/form-group-normalizer.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/index.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/listview-normalizer.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/normalizer-util.ts (98%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/types.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/types.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/index.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/metadata-cahce-service.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/metadata-data-service.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/metadata-repository.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/statemachine/index.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/statemachine/state-machine-metadata-data-service.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/types.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/webcmd/common-web-command-metadata-data-service.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/webcmd/custom-web-command-metadata-data-service.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/webcmd/index.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/webcmp/custom-web-component-metadata-data-service.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/webcmp/index.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/command-handler-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/entity-store-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/form/form-array-store-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/form/form-control-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/form/form-store-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/form/index.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/form/validation-rule-creator.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/index.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/module-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/repository-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/state-machine-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/ui-store-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/viewmodel-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/binding-context.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/binding-factory.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/binding-util.ts (97%) rename packages/mobile-render/src/{services => common}/page-config/bindings/binding-watcher.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/binding.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/command-binding.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/entity-field-binding.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/entity-list-binding.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/index.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/state-machine-binding.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/types.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/index.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/page-config-binder.ts (99%) rename packages/mobile-render/src/{services => common}/page-config/page-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/index.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugin-creators.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugin-manager.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugin.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugins/index.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugins/listview-plugin/index.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugins/listview-plugin/listview-plugin.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugins/lookup-plugin/index.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugins/lookup-plugin/lookup-data-service.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugins/lookup-plugin/lookup-mapping-service.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugins/lookup-plugin/lookup-plugin.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/types.ts (100%) rename packages/mobile-render/src/{ => common}/services/dynamic-route-service.ts (96%) create mode 100644 packages/mobile-render/src/common/services/index.ts delete mode 100644 packages/mobile-render/src/common/types.ts rename packages/mobile-render/src/{ => common}/utils/format-utils.ts (100%) rename packages/mobile-render/src/{ => common}/utils/index.ts (100%) rename packages/mobile-render/src/{ => common}/utils/json-util.ts (100%) rename packages/mobile-render/src/{ => common}/utils/string-util.ts (100%) rename packages/mobile-render/src/{ => common}/utils/type-util.ts (100%) delete mode 100644 packages/mobile-render/src/services/index.ts delete mode 100644 packages/mobile-render/src/services/providers.ts diff --git a/packages/mobile-render/src/common/event-emitter.ts b/packages/mobile-render/src/common/event-emitter.ts deleted file mode 100644 index ebb955d37aa..00000000000 --- a/packages/mobile-render/src/common/event-emitter.ts +++ /dev/null @@ -1,39 +0,0 @@ -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 index 6dce9a10036..e02247cede2 100644 --- a/packages/mobile-render/src/common/index.ts +++ b/packages/mobile-render/src/common/index.ts @@ -1,2 +1,8 @@ -export * from './types'; -export * from './event-emitter'; +export * from './utils/index'; +export * from './services/index'; +export * from './metadata/index'; +export * from './module-config/index'; +export * from './page-config/index'; +export * from './plugin/index'; +export * from './providers'; + diff --git a/packages/mobile-render/src/services/metadata/form/converters/base-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/base-converter.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/base-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/base-converter.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/button-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/button-converter.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/button-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/button-converter.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/button-group-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/button-group-converter.ts similarity index 93% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/button-group-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/button-group-converter.ts index 8a50ac68010..85b83632088 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/button-group-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/button-group-converter.ts @@ -1,5 +1,5 @@ -import { ComponentConverter } from "./component-converter"; -import { JsonUtil } from '../../../../../utils/index'; +import { ComponentConverter } from './component-converter'; +import { JsonUtil } from '../../../../utils/index'; /** * 基础组件转换器 diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/component-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/component-converter.ts similarity index 92% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/component-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/component-converter.ts index e90a818242b..3f5f7062384 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/component-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/component-converter.ts @@ -1,4 +1,4 @@ -import { StringUtil } from '../../../../../utils/index'; +import { StringUtil } from '../../../../utils/index'; import { BaseConverter } from "../base-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/datebox-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/datebox-converter.ts similarity index 95% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/datebox-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/datebox-converter.ts index 11952970fb3..33c13e48772 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/datebox-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/datebox-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { InputConverter } from "./input-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/enum-field-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/enum-field-converter.ts similarity index 91% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/enum-field-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/enum-field-converter.ts index d1bcac80906..4387a186a53 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/enum-field-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/enum-field-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { InputConverter } from "./input-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/index.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/index.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/index.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/input-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/input-converter.ts similarity index 94% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/input-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/input-converter.ts index 4a264d58c8c..f0af9420d58 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/input-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/input-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { ComponentConverter } from "./component-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/listview-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/listview-converter.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/listview-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/listview-converter.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/lookup-edit-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/lookup-edit-converter.ts similarity index 93% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/lookup-edit-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/lookup-edit-converter.ts index eacac091890..74868a9cbee 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/lookup-edit-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/lookup-edit-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { InputConverter } from "./input-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/multi-textbox-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/multi-textbox-converter.ts similarity index 91% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/multi-textbox-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/multi-textbox-converter.ts index 34e898537ca..520c94eafd2 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/multi-textbox-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/multi-textbox-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { InputConverter } from "./input-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/navigation-bar.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/navigation-bar.ts similarity index 95% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/navigation-bar.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/navigation-bar.ts index c0fc91f6fdd..6d2f50d3796 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/navigation-bar.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/navigation-bar.ts @@ -1,5 +1,5 @@ import { ComponentConverter } from "./component-converter"; -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; /** * 导航条组件转换器 diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/numeric-box-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/numeric-box-converter.ts similarity index 91% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/numeric-box-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/numeric-box-converter.ts index 6065875f5d8..97192078239 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/numeric-box-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/numeric-box-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { InputConverter } from "./input-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/page-content-container-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/page-content-container-converter.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/page-content-container-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/page-content-container-converter.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/switch-field-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/switch-field-converter.ts similarity index 90% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/switch-field-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/switch-field-converter.ts index a50e4167676..35d20fda114 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/switch-field-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/switch-field-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { InputConverter } from "./input-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/textbox-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/textbox-converter.ts similarity index 90% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/textbox-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/textbox-converter.ts index 9c060fca030..7b0c5c497c2 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/textbox-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/textbox-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { InputConverter } from "./input-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/converter-context.ts b/packages/mobile-render/src/common/metadata/form/converters/converter-context.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/converter-context.ts rename to packages/mobile-render/src/common/metadata/form/converters/converter-context.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts b/packages/mobile-render/src/common/metadata/form/converters/converter-factory.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts rename to packages/mobile-render/src/common/metadata/form/converters/converter-factory.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/index.ts b/packages/mobile-render/src/common/metadata/form/converters/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/index.ts rename to packages/mobile-render/src/common/metadata/form/converters/index.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/schemas-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/schemas-converter.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/schemas-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/schemas-converter.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/types.ts b/packages/mobile-render/src/common/metadata/form/converters/types.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/types.ts rename to packages/mobile-render/src/common/metadata/form/converters/types.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/viewodels-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/viewodels-converter.ts similarity index 96% rename from packages/mobile-render/src/services/metadata/form/converters/viewodels-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/viewodels-converter.ts index 36e66f2c2cb..eab0b6cc15e 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/viewodels-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/viewodels-converter.ts @@ -1,4 +1,4 @@ -import { TypeUtil } from '../../../../utils/index'; +import { TypeUtil } from '../../../utils/index'; import { BaseConverter } from './base-converter'; /** diff --git a/packages/mobile-render/src/services/metadata/form/entity-schema-query.ts b/packages/mobile-render/src/common/metadata/form/entity-schema-query.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/entity-schema-query.ts rename to packages/mobile-render/src/common/metadata/form/entity-schema-query.ts diff --git a/packages/mobile-render/src/services/metadata/form/form-metadata-converter.ts b/packages/mobile-render/src/common/metadata/form/form-metadata-converter.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/form-metadata-converter.ts rename to packages/mobile-render/src/common/metadata/form/form-metadata-converter.ts diff --git a/packages/mobile-render/src/services/metadata/form/form-metadata-data-service.ts b/packages/mobile-render/src/common/metadata/form/form-metadata-data-service.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/form-metadata-data-service.ts rename to packages/mobile-render/src/common/metadata/form/form-metadata-data-service.ts diff --git a/packages/mobile-render/src/services/metadata/form/form-metadata-normalizer.ts b/packages/mobile-render/src/common/metadata/form/form-metadata-normalizer.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/form-metadata-normalizer.ts rename to packages/mobile-render/src/common/metadata/form/form-metadata-normalizer.ts diff --git a/packages/mobile-render/src/services/metadata/form/form-metadata-query.ts b/packages/mobile-render/src/common/metadata/form/form-metadata-query.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/form-metadata-query.ts rename to packages/mobile-render/src/common/metadata/form/form-metadata-query.ts diff --git a/packages/mobile-render/src/services/metadata/form/index.ts b/packages/mobile-render/src/common/metadata/form/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/index.ts rename to packages/mobile-render/src/common/metadata/form/index.ts diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/button-group-normalizer.ts b/packages/mobile-render/src/common/metadata/form/normalizers/button-group-normalizer.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/normalizers/button-group-normalizer.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/button-group-normalizer.ts diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer-factory.ts b/packages/mobile-render/src/common/metadata/form/normalizers/component-normalizer-factory.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer-factory.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/component-normalizer-factory.ts diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts b/packages/mobile-render/src/common/metadata/form/normalizers/component-normalizer.ts similarity index 99% rename from packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/component-normalizer.ts index 6ea43f243d4..74105ae64d0 100644 --- a/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts +++ b/packages/mobile-render/src/common/metadata/form/normalizers/component-normalizer.ts @@ -1,4 +1,4 @@ -import { isObject, isArray } from '../../../../utils/index'; +import { isObject, isArray } from '../../../utils/index'; import { FormMetadataQuery } from '../form-metadata-query'; import { PropBindingType } from './types'; import { NormalizerUtil } from './normalizer-util'; diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/form-group-normalizer.ts b/packages/mobile-render/src/common/metadata/form/normalizers/form-group-normalizer.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/normalizers/form-group-normalizer.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/form-group-normalizer.ts diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/index.ts b/packages/mobile-render/src/common/metadata/form/normalizers/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/normalizers/index.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/index.ts diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/listview-normalizer.ts b/packages/mobile-render/src/common/metadata/form/normalizers/listview-normalizer.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/normalizers/listview-normalizer.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/listview-normalizer.ts diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/normalizer-util.ts b/packages/mobile-render/src/common/metadata/form/normalizers/normalizer-util.ts similarity index 98% rename from packages/mobile-render/src/services/metadata/form/normalizers/normalizer-util.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/normalizer-util.ts index edab3c7c1c7..1d52b89165b 100644 --- a/packages/mobile-render/src/services/metadata/form/normalizers/normalizer-util.ts +++ b/packages/mobile-render/src/common/metadata/form/normalizers/normalizer-util.ts @@ -1,4 +1,4 @@ -import { isObject } from '../../../../utils/index'; +import { isObject } from '../../../utils/index'; import { PropBindingType } from './types'; /** diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/types.ts b/packages/mobile-render/src/common/metadata/form/normalizers/types.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/normalizers/types.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/types.ts diff --git a/packages/mobile-render/src/services/metadata/form/types.ts b/packages/mobile-render/src/common/metadata/form/types.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/types.ts rename to packages/mobile-render/src/common/metadata/form/types.ts diff --git a/packages/mobile-render/src/services/metadata/index.ts b/packages/mobile-render/src/common/metadata/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/index.ts rename to packages/mobile-render/src/common/metadata/index.ts diff --git a/packages/mobile-render/src/services/metadata/metadata-cahce-service.ts b/packages/mobile-render/src/common/metadata/metadata-cahce-service.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/metadata-cahce-service.ts rename to packages/mobile-render/src/common/metadata/metadata-cahce-service.ts diff --git a/packages/mobile-render/src/services/metadata/metadata-data-service.ts b/packages/mobile-render/src/common/metadata/metadata-data-service.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/metadata-data-service.ts rename to packages/mobile-render/src/common/metadata/metadata-data-service.ts diff --git a/packages/mobile-render/src/services/metadata/metadata-repository.ts b/packages/mobile-render/src/common/metadata/metadata-repository.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/metadata-repository.ts rename to packages/mobile-render/src/common/metadata/metadata-repository.ts diff --git a/packages/mobile-render/src/services/metadata/statemachine/index.ts b/packages/mobile-render/src/common/metadata/statemachine/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/statemachine/index.ts rename to packages/mobile-render/src/common/metadata/statemachine/index.ts diff --git a/packages/mobile-render/src/services/metadata/statemachine/state-machine-metadata-data-service.ts b/packages/mobile-render/src/common/metadata/statemachine/state-machine-metadata-data-service.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/statemachine/state-machine-metadata-data-service.ts rename to packages/mobile-render/src/common/metadata/statemachine/state-machine-metadata-data-service.ts diff --git a/packages/mobile-render/src/services/metadata/types.ts b/packages/mobile-render/src/common/metadata/types.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/types.ts rename to packages/mobile-render/src/common/metadata/types.ts diff --git a/packages/mobile-render/src/services/metadata/webcmd/common-web-command-metadata-data-service.ts b/packages/mobile-render/src/common/metadata/webcmd/common-web-command-metadata-data-service.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/webcmd/common-web-command-metadata-data-service.ts rename to packages/mobile-render/src/common/metadata/webcmd/common-web-command-metadata-data-service.ts diff --git a/packages/mobile-render/src/services/metadata/webcmd/custom-web-command-metadata-data-service.ts b/packages/mobile-render/src/common/metadata/webcmd/custom-web-command-metadata-data-service.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/webcmd/custom-web-command-metadata-data-service.ts rename to packages/mobile-render/src/common/metadata/webcmd/custom-web-command-metadata-data-service.ts diff --git a/packages/mobile-render/src/services/metadata/webcmd/index.ts b/packages/mobile-render/src/common/metadata/webcmd/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/webcmd/index.ts rename to packages/mobile-render/src/common/metadata/webcmd/index.ts diff --git a/packages/mobile-render/src/services/metadata/webcmp/custom-web-component-metadata-data-service.ts b/packages/mobile-render/src/common/metadata/webcmp/custom-web-component-metadata-data-service.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/webcmp/custom-web-component-metadata-data-service.ts rename to packages/mobile-render/src/common/metadata/webcmp/custom-web-component-metadata-data-service.ts diff --git a/packages/mobile-render/src/services/metadata/webcmp/index.ts b/packages/mobile-render/src/common/metadata/webcmp/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/webcmp/index.ts rename to packages/mobile-render/src/common/metadata/webcmp/index.ts diff --git a/packages/mobile-render/src/services/module-config/command-handler-builder.ts b/packages/mobile-render/src/common/module-config/command-handler-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/command-handler-builder.ts rename to packages/mobile-render/src/common/module-config/command-handler-builder.ts diff --git a/packages/mobile-render/src/services/module-config/entity-store-config-builder.ts b/packages/mobile-render/src/common/module-config/entity-store-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/entity-store-config-builder.ts rename to packages/mobile-render/src/common/module-config/entity-store-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts b/packages/mobile-render/src/common/module-config/form/form-array-store-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts rename to packages/mobile-render/src/common/module-config/form/form-array-store-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/form/form-control-config-builder.ts b/packages/mobile-render/src/common/module-config/form/form-control-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/form/form-control-config-builder.ts rename to packages/mobile-render/src/common/module-config/form/form-control-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts b/packages/mobile-render/src/common/module-config/form/form-store-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts rename to packages/mobile-render/src/common/module-config/form/form-store-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/form/index.ts b/packages/mobile-render/src/common/module-config/form/index.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/form/index.ts rename to packages/mobile-render/src/common/module-config/form/index.ts diff --git a/packages/mobile-render/src/services/module-config/form/validation-rule-creator.ts b/packages/mobile-render/src/common/module-config/form/validation-rule-creator.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/form/validation-rule-creator.ts rename to packages/mobile-render/src/common/module-config/form/validation-rule-creator.ts diff --git a/packages/mobile-render/src/services/module-config/index.ts b/packages/mobile-render/src/common/module-config/index.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/index.ts rename to packages/mobile-render/src/common/module-config/index.ts diff --git a/packages/mobile-render/src/services/module-config/module-config-builder.ts b/packages/mobile-render/src/common/module-config/module-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/module-config-builder.ts rename to packages/mobile-render/src/common/module-config/module-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/repository-config-builder.ts b/packages/mobile-render/src/common/module-config/repository-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/repository-config-builder.ts rename to packages/mobile-render/src/common/module-config/repository-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/state-machine-config-builder.ts b/packages/mobile-render/src/common/module-config/state-machine-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/state-machine-config-builder.ts rename to packages/mobile-render/src/common/module-config/state-machine-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/ui-store-config-builder.ts b/packages/mobile-render/src/common/module-config/ui-store-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/ui-store-config-builder.ts rename to packages/mobile-render/src/common/module-config/ui-store-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/viewmodel-config-builder.ts b/packages/mobile-render/src/common/module-config/viewmodel-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/viewmodel-config-builder.ts rename to packages/mobile-render/src/common/module-config/viewmodel-config-builder.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/binding-context.ts b/packages/mobile-render/src/common/page-config/bindings/binding-context.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/binding-context.ts rename to packages/mobile-render/src/common/page-config/bindings/binding-context.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/binding-factory.ts b/packages/mobile-render/src/common/page-config/bindings/binding-factory.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/binding-factory.ts rename to packages/mobile-render/src/common/page-config/bindings/binding-factory.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/binding-util.ts b/packages/mobile-render/src/common/page-config/bindings/binding-util.ts similarity index 97% rename from packages/mobile-render/src/services/page-config/bindings/binding-util.ts rename to packages/mobile-render/src/common/page-config/bindings/binding-util.ts index ed71ff5bf45..63cf10435c7 100644 --- a/packages/mobile-render/src/services/page-config/bindings/binding-util.ts +++ b/packages/mobile-render/src/common/page-config/bindings/binding-util.ts @@ -1,4 +1,4 @@ -import { isObject, isString, TypeUtil } from '../../../utils/index'; +import { isObject, isString, TypeUtil } from '../../utils/index'; import { BindingType } from './types'; /** diff --git a/packages/mobile-render/src/services/page-config/bindings/binding-watcher.ts b/packages/mobile-render/src/common/page-config/bindings/binding-watcher.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/binding-watcher.ts rename to packages/mobile-render/src/common/page-config/bindings/binding-watcher.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/binding.ts b/packages/mobile-render/src/common/page-config/bindings/binding.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/binding.ts rename to packages/mobile-render/src/common/page-config/bindings/binding.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/command-binding.ts b/packages/mobile-render/src/common/page-config/bindings/command-binding.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/command-binding.ts rename to packages/mobile-render/src/common/page-config/bindings/command-binding.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/entity-field-binding.ts b/packages/mobile-render/src/common/page-config/bindings/entity-field-binding.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/entity-field-binding.ts rename to packages/mobile-render/src/common/page-config/bindings/entity-field-binding.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/entity-list-binding.ts b/packages/mobile-render/src/common/page-config/bindings/entity-list-binding.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/entity-list-binding.ts rename to packages/mobile-render/src/common/page-config/bindings/entity-list-binding.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/index.ts b/packages/mobile-render/src/common/page-config/bindings/index.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/index.ts rename to packages/mobile-render/src/common/page-config/bindings/index.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/state-machine-binding.ts b/packages/mobile-render/src/common/page-config/bindings/state-machine-binding.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/state-machine-binding.ts rename to packages/mobile-render/src/common/page-config/bindings/state-machine-binding.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/types.ts b/packages/mobile-render/src/common/page-config/bindings/types.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/types.ts rename to packages/mobile-render/src/common/page-config/bindings/types.ts diff --git a/packages/mobile-render/src/services/page-config/index.ts b/packages/mobile-render/src/common/page-config/index.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/index.ts rename to packages/mobile-render/src/common/page-config/index.ts diff --git a/packages/mobile-render/src/services/page-config/page-config-binder.ts b/packages/mobile-render/src/common/page-config/page-config-binder.ts similarity index 99% rename from packages/mobile-render/src/services/page-config/page-config-binder.ts rename to packages/mobile-render/src/common/page-config/page-config-binder.ts index 96c42829d79..fb15efa5853 100644 --- a/packages/mobile-render/src/services/page-config/page-config-binder.ts +++ b/packages/mobile-render/src/common/page-config/page-config-binder.ts @@ -1,7 +1,7 @@ import { reactive, Reactive } from 'vue'; import { Module, ViewModel, ViewModelState } from '@farris/devkit-vue'; import { schemaMap } from '@farris/mobile-ui-vue'; -import { TypeUtil, JsonUtil } from '../../utils/index'; +import { TypeUtil, JsonUtil } from '../utils/index'; import { BindingUtil, BindingContext, BindingFactory } from './bindings/index'; import { AfterComponentBindingHookContext, Plugin, PluginManager } from '../plugin/index'; diff --git a/packages/mobile-render/src/services/page-config/page-config-builder.ts b/packages/mobile-render/src/common/page-config/page-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/page-config-builder.ts rename to packages/mobile-render/src/common/page-config/page-config-builder.ts diff --git a/packages/mobile-render/src/services/plugin/index.ts b/packages/mobile-render/src/common/plugin/index.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/index.ts rename to packages/mobile-render/src/common/plugin/index.ts diff --git a/packages/mobile-render/src/services/plugin/plugin-creators.ts b/packages/mobile-render/src/common/plugin/plugin-creators.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugin-creators.ts rename to packages/mobile-render/src/common/plugin/plugin-creators.ts diff --git a/packages/mobile-render/src/services/plugin/plugin-manager.ts b/packages/mobile-render/src/common/plugin/plugin-manager.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugin-manager.ts rename to packages/mobile-render/src/common/plugin/plugin-manager.ts diff --git a/packages/mobile-render/src/services/plugin/plugin.ts b/packages/mobile-render/src/common/plugin/plugin.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugin.ts rename to packages/mobile-render/src/common/plugin/plugin.ts diff --git a/packages/mobile-render/src/services/plugin/plugins/index.ts b/packages/mobile-render/src/common/plugin/plugins/index.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugins/index.ts rename to packages/mobile-render/src/common/plugin/plugins/index.ts diff --git a/packages/mobile-render/src/services/plugin/plugins/listview-plugin/index.ts b/packages/mobile-render/src/common/plugin/plugins/listview-plugin/index.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugins/listview-plugin/index.ts rename to packages/mobile-render/src/common/plugin/plugins/listview-plugin/index.ts diff --git a/packages/mobile-render/src/services/plugin/plugins/listview-plugin/listview-plugin.ts b/packages/mobile-render/src/common/plugin/plugins/listview-plugin/listview-plugin.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugins/listview-plugin/listview-plugin.ts rename to packages/mobile-render/src/common/plugin/plugins/listview-plugin/listview-plugin.ts diff --git a/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/index.ts b/packages/mobile-render/src/common/plugin/plugins/lookup-plugin/index.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugins/lookup-plugin/index.ts rename to packages/mobile-render/src/common/plugin/plugins/lookup-plugin/index.ts diff --git a/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-data-service.ts b/packages/mobile-render/src/common/plugin/plugins/lookup-plugin/lookup-data-service.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-data-service.ts rename to packages/mobile-render/src/common/plugin/plugins/lookup-plugin/lookup-data-service.ts diff --git a/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-mapping-service.ts b/packages/mobile-render/src/common/plugin/plugins/lookup-plugin/lookup-mapping-service.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-mapping-service.ts rename to packages/mobile-render/src/common/plugin/plugins/lookup-plugin/lookup-mapping-service.ts diff --git a/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-plugin.ts b/packages/mobile-render/src/common/plugin/plugins/lookup-plugin/lookup-plugin.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-plugin.ts rename to packages/mobile-render/src/common/plugin/plugins/lookup-plugin/lookup-plugin.ts diff --git a/packages/mobile-render/src/services/plugin/types.ts b/packages/mobile-render/src/common/plugin/types.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/types.ts rename to packages/mobile-render/src/common/plugin/types.ts diff --git a/packages/mobile-render/src/common/providers.ts b/packages/mobile-render/src/common/providers.ts index 2761df9479c..8285a3d2990 100644 --- a/packages/mobile-render/src/common/providers.ts +++ b/packages/mobile-render/src/common/providers.ts @@ -1,6 +1,26 @@ -import { StaticProvider } from "@farris/devkit-vue"; -import { EventEmitter } from "./event-emitter"; -export const eventEmitterProviders: StaticProvider[] = [ - { provide: EventEmitter, useClass: EventEmitter, deps: [] } +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/services/dynamic-route-service.ts b/packages/mobile-render/src/common/services/dynamic-route-service.ts similarity index 96% rename from packages/mobile-render/src/services/dynamic-route-service.ts rename to packages/mobile-render/src/common/services/dynamic-route-service.ts index 22e872c0a09..1be921d5269 100644 --- a/packages/mobile-render/src/services/dynamic-route-service.ts +++ b/packages/mobile-render/src/common/services/dynamic-route-service.ts @@ -1,7 +1,7 @@ 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'; +import { MetadataDataService, MetadataCacheService } from '../metadata/index'; +import Form from '../../views/form/form.vue'; +import Page from '../../views/page/page.vue'; /** * 动态路由服务 diff --git a/packages/mobile-render/src/common/services/index.ts b/packages/mobile-render/src/common/services/index.ts new file mode 100644 index 00000000000..3acd21c28cb --- /dev/null +++ b/packages/mobile-render/src/common/services/index.ts @@ -0,0 +1 @@ +export * from './dynamic-route-service'; diff --git a/packages/mobile-render/src/common/types.ts b/packages/mobile-render/src/common/types.ts deleted file mode 100644 index 448a521dc41..00000000000 --- a/packages/mobile-render/src/common/types.ts +++ /dev/null @@ -1 +0,0 @@ -export type Callable = (...args: U) => T; diff --git a/packages/mobile-render/src/utils/format-utils.ts b/packages/mobile-render/src/common/utils/format-utils.ts similarity index 100% rename from packages/mobile-render/src/utils/format-utils.ts rename to packages/mobile-render/src/common/utils/format-utils.ts diff --git a/packages/mobile-render/src/utils/index.ts b/packages/mobile-render/src/common/utils/index.ts similarity index 100% rename from packages/mobile-render/src/utils/index.ts rename to packages/mobile-render/src/common/utils/index.ts diff --git a/packages/mobile-render/src/utils/json-util.ts b/packages/mobile-render/src/common/utils/json-util.ts similarity index 100% rename from packages/mobile-render/src/utils/json-util.ts rename to packages/mobile-render/src/common/utils/json-util.ts diff --git a/packages/mobile-render/src/utils/string-util.ts b/packages/mobile-render/src/common/utils/string-util.ts similarity index 100% rename from packages/mobile-render/src/utils/string-util.ts rename to packages/mobile-render/src/common/utils/string-util.ts diff --git a/packages/mobile-render/src/utils/type-util.ts b/packages/mobile-render/src/common/utils/type-util.ts similarity index 100% rename from packages/mobile-render/src/utils/type-util.ts rename to packages/mobile-render/src/common/utils/type-util.ts diff --git a/packages/mobile-render/src/main.ts b/packages/mobile-render/src/main.ts index c50637e2bb6..ba334a86c71 100644 --- a/packages/mobile-render/src/main.ts +++ b/packages/mobile-render/src/main.ts @@ -4,13 +4,14 @@ 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 { formatUtils } from './utils'; + +import { formatUtils } from './common/utils/index'; +import { renderServiceProviders } from './common/providers'; import App from './app.vue'; import router from './router'; import { checkFormRoute, addFormRoute } from './router/use-form-routes'; -import { PluginContext, PluginManager, createBuildInPlugins } from './services/plugin/index'; +import { PluginContext, PluginManager, createBuildInPlugins } from './common/plugin/index'; // devkit export const devkitProviders: StaticProvider[] = [ diff --git a/packages/mobile-render/src/router/use-form-routes.ts b/packages/mobile-render/src/router/use-form-routes.ts index de05d2e324d..9c3ed7b72f3 100644 --- a/packages/mobile-render/src/router/use-form-routes.ts +++ b/packages/mobile-render/src/router/use-form-routes.ts @@ -1,6 +1,6 @@ import { RouteRecordRaw, Router, RouteRecord } from 'vue-router'; import { Devkit } from '@farris/devkit-vue'; -import { MetadataDataService, MetadataCacheService } from '../services/index'; +import { MetadataDataService, MetadataCacheService } from '../common/index'; import Form from '../views/form/form.vue'; import Page from '../views/page/page.vue'; diff --git a/packages/mobile-render/src/services/index.ts b/packages/mobile-render/src/services/index.ts deleted file mode 100644 index f406cc625e9..00000000000 --- a/packages/mobile-render/src/services/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from './metadata/index'; -export * from './module-config/index'; -export * from './page-config/index'; -export * from './plugin/index'; -export * from './dynamic-route-service'; -export * from './providers'; - diff --git a/packages/mobile-render/src/services/providers.ts b/packages/mobile-render/src/services/providers.ts deleted file mode 100644 index 8285a3d2990..00000000000 --- a/packages/mobile-render/src/services/providers.ts +++ /dev/null @@ -1,26 +0,0 @@ - -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 index 816bd2caea9..b0d64e23332 100644 --- a/packages/mobile-render/src/types.ts +++ b/packages/mobile-render/src/types.ts @@ -1,4 +1,3 @@ -import { EventEmitter } from "./common"; /* eslint-disable no-use-before-define */ // #region form schema @@ -236,9 +235,6 @@ export interface UseFieldResolver { export interface UseParamPersistence { persist(): Promise; } -export interface UseEventEmitter { - emitter: EventEmitter; -} export interface UseEventHandler { bind(): void; diff --git a/packages/mobile-render/src/views/form/form-runner.ts b/packages/mobile-render/src/views/form/form-runner.ts index 31f70ea9e89..66dff6b8720 100644 --- a/packages/mobile-render/src/views/form/form-runner.ts +++ b/packages/mobile-render/src/views/form/form-runner.ts @@ -3,8 +3,8 @@ 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'; +import { ModuleConfigBuilder } from '../../common/module-config/index'; +import { MetadataCacheService } from '../../common/metadata/index'; /** * 运行表单 diff --git a/packages/mobile-render/src/views/page/page-runner.ts b/packages/mobile-render/src/views/page/page-runner.ts index 60e4693839e..48bdbc3db72 100644 --- a/packages/mobile-render/src/views/page/page-runner.ts +++ b/packages/mobile-render/src/views/page/page-runner.ts @@ -1,7 +1,9 @@ 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, PluginManager } from '../../services/index'; +import { Devkit, Module, ViewModel, ViewModelState, createViewModel, VIEWMODEL_INJECTION_TOKEN } from '@farris/devkit-vue'; +import { MetadataCacheService } from '../../common/metadata/index'; +import { PageConfigBuilder, PageConfigBinder, } from '../../common/page-config/index'; +import { PluginManager } from '../../common/plugin/index'; /** * 运行页面 -- Gitee From 573ba4691bc9b699eb8820b559d128f564e41ea0 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Mon, 21 Apr 2025 20:10:31 +0800 Subject: [PATCH 269/287] =?UTF-8?q?feature:=20=E6=94=AF=E6=8C=81=E6=A0=B9?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=B8=B2=E6=9F=93=EF=BC=8C=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=B8=BA=E5=B5=8C=E5=A5=97=E7=BB=84=E4=BB=B6=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E8=A7=86=E5=9B=BE=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/configs/module-config-manager.ts | 38 ++++++++ .../form/converters/converter-factory.ts | 3 + .../converters/root-component-converter.ts | 94 +++++++++++++++++++ .../metadata/form/form-metadata-converter.ts | 12 +++ .../common/page-config/page-config-binder.ts | 24 +++-- .../common/page-config/page-config-builder.ts | 15 +-- .../module-runner.ts} | 51 ++++++++-- .../{form/form.vue => module/module.vue} | 6 +- .../src/views/page/page-runner.ts | 28 +++++- 9 files changed, 235 insertions(+), 36 deletions(-) create mode 100644 packages/mobile-render/src/common/metadata/form/converters/root-component-converter.ts rename packages/mobile-render/src/views/{form/form-runner.ts => module/module-runner.ts} (68%) rename packages/mobile-render/src/views/{form/form.vue => module/module.vue} (68%) diff --git a/packages/devkit/lib/module/configs/module-config-manager.ts b/packages/devkit/lib/module/configs/module-config-manager.ts index c06c78436bb..cf513396711 100644 --- a/packages/devkit/lib/module/configs/module-config-manager.ts +++ b/packages/devkit/lib/module/configs/module-config-manager.ts @@ -23,6 +23,20 @@ class ModuleConfigManager { this.config = moduleConfig; } + /** + * 获取模块配置 + */ + public getModuleConfig(): ModuleConfig { + return this.config; + } + + /** + * 获取所有视图模型配置 + */ + public getViewModelConfigs(): ViewModelConfig[] { + return this.config.viewModels; + } + /** * 获取ViewModel配置 */ @@ -35,6 +49,30 @@ class ModuleConfigManager { return targetViewModelConfig; } + /** + * 获取根视图模型配置 + */ + public getRootViewModelConfig(): ViewModelConfig { + const viewModelConfigs = this.getViewModelConfigs(); + const rootViewModelConfig = viewModelConfigs.find((viewModelConfig) => { + return !viewModelConfig.parentId; + }); + + return rootViewModelConfig; + } + + /** + * 获取根视图模型配置 + */ + public getChildViewModelConfigs(parentId: string): ViewModelConfig[] { + const viewModelConfigs = this.getViewModelConfigs(); + const childViewModelConfigs = viewModelConfigs.filter((viewModelConfig) => { + return viewModelConfig.id = parentId; + }); + + return childViewModelConfigs; + } + /** * 获取实体仓库配置 */ diff --git a/packages/mobile-render/src/common/metadata/form/converters/converter-factory.ts b/packages/mobile-render/src/common/metadata/form/converters/converter-factory.ts index 220339dc126..6d7e50191f5 100644 --- a/packages/mobile-render/src/common/metadata/form/converters/converter-factory.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/converter-factory.ts @@ -1,5 +1,6 @@ import { BaseConverter } from './base-converter'; import { ConverterContext } from './converter-context'; +import { RootComponentConverter } from './root-component-converter'; import { SchemasConverter } from './schemas-converter'; import { ViewModelsConverter } from './viewodels-converter'; import { @@ -39,6 +40,8 @@ class ConverterFactory { */ public create(type: string): BaseConverter { switch (type) { + case 'root-component': + return new RootComponentConverter(this.context); case 'schemas': return new SchemasConverter(this.context); case 'viewmodels': diff --git a/packages/mobile-render/src/common/metadata/form/converters/root-component-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/root-component-converter.ts new file mode 100644 index 00000000000..aa11e000294 --- /dev/null +++ b/packages/mobile-render/src/common/metadata/form/converters/root-component-converter.ts @@ -0,0 +1,94 @@ +import { BaseConverter } from './base-converter'; + +/** + * 根组件转换器 + */ +class RootComponentConverter extends BaseConverter { + + /** + * 执行转换 + */ + public convert(formModule: any) { + const { components, viewmodels } = formModule; + const rootComponent = this.appendRootComponent(components); + const rootViewModel = this.appendRootViewModel(viewmodels); + this.convertChildComponents(rootComponent, components); + this.convertChildViewModels(rootViewModel, viewmodels); + } + + /** + * 创建根组件 + */ + private appendRootComponent(components: any[]): any { + const rootComponent = { + id: 'root-component', + type: 'component', + componentType: 'Root', + viewModel: 'root-viewmodel', + contents: [] + }; + components.unshift(rootComponent); + + return rootComponent; + } + + /** + * 创建根视图模型 + */ + private appendRootViewModel(viewModels: any[]): any { + const rootViewModel = { + id: 'root-viewmodel', + code: 'root-viewmodel', + name: '表单根组件', + fields: [], + stateMachine: '', + serviceRefs: [], + commands: [ + ], + states: [ + ], + bindTo: '/' + }; + viewModels.unshift(rootViewModel); + + return rootViewModel; + } + + + /** + * 转换子组件 + */ + private convertChildComponents(rootComponent, childComponents: any[]): void { + const childComponentRefs = []; + childComponents.forEach((childComponent: any) => { + if (childComponent.componentType !== 'Page') { + return; + } + const componentRef = { + id: `${childComponent.id}-ref`, + type: "ComponentRef", + component: childComponent.id, + visible: true, + }; + + childComponentRefs.push(componentRef); + }); + + rootComponent.contents = childComponentRefs; + } + + /** + * 转换子视图模型 + */ + private convertChildViewModels(rootViewModel: any, childViewModels: any[]): void { + childViewModels.forEach((childViewModel: any) => { + if (childViewModel.parent) { + return; + } + + childViewModel.parent = rootViewModel.id; + }); + } +} + +export { RootComponentConverter }; diff --git a/packages/mobile-render/src/common/metadata/form/form-metadata-converter.ts b/packages/mobile-render/src/common/metadata/form/form-metadata-converter.ts index fc9da3bbab0..6f16308672f 100644 --- a/packages/mobile-render/src/common/metadata/form/form-metadata-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/form-metadata-converter.ts @@ -36,6 +36,7 @@ class FormMetadataConverter { return; } + this.convertRootComponent(); this.convertSchemas(); this.convertViewModels(); this.convertComponents(); @@ -50,6 +51,17 @@ class FormMetadataConverter { return !!formModule.schemas; } + /** + * 包装根组件 + * @summary + * 老表单没有Root组件,渲染时补全 + */ + private convertRootComponent() { + const rootComponentConverter = this.converterFactory.create('root-component'); + const formModule = this.context.getFormModule(); + rootComponentConverter.convert(formModule); + } + /** * 转换Schema结构 */ diff --git a/packages/mobile-render/src/common/page-config/page-config-binder.ts b/packages/mobile-render/src/common/page-config/page-config-binder.ts index fb15efa5853..84a79a504fe 100644 --- a/packages/mobile-render/src/common/page-config/page-config-binder.ts +++ b/packages/mobile-render/src/common/page-config/page-config-binder.ts @@ -18,7 +18,7 @@ class PageConfigBinder { /** * 视图模型 */ - private viewModel: ViewModel; + private pageViewModel: ViewModel; /** * 插件管理器 @@ -51,7 +51,7 @@ class PageConfigBinder { */ constructor(module: Module, viewModel: ViewModel, pageConfig: any) { this.module = module; - this.viewModel = viewModel; + this.pageViewModel = viewModel; this.pluginManager = PluginManager.getInstance(); this.bindingContext = new BindingContext(module); @@ -72,7 +72,7 @@ class PageConfigBinder { public bind(): Reactive { const pageConfig = reactive(JsonUtil.cloneJsonObj(this.originPageConfig)); const pageSchema = schemaMap['component']; - this.bindComponentConfig(pageConfig, pageSchema); + this.bindComponentConfig(pageConfig, pageSchema, this.pageViewModel); this.pageConfig = pageConfig; return this.pageConfig; } @@ -80,15 +80,15 @@ class PageConfigBinder { /** * 为组件绑定属性值 */ - private bindComponentConfig(componentConfig: any, componentSchema: any) { + private bindComponentConfig(componentConfig: any, componentSchema: any, viewModel: ViewModel) { const orignComponentConfig = JsonUtil.cloneJsonObj(componentConfig); Object.keys(componentConfig).forEach((propName) => { const propConfig = componentConfig[propName]; - this.bindProp(propName, propConfig, componentConfig, componentSchema); + this.bindProp(propName, propConfig, componentConfig, componentSchema, viewModel); }); const hookContext: AfterComponentBindingHookContext = { - viewModel: this.viewModel, + viewModel: viewModel, componentSchema, componentConfig: orignComponentConfig, bindedComponentConfig: componentConfig @@ -99,7 +99,7 @@ class PageConfigBinder { /** * 绑定组件属性 */ - public bindProp(propName: string, propConfig: any, componentConfig: any, componentSchema: any) { + public bindProp(propName: string, propConfig: any, componentConfig: any, componentSchema: any, viewModel: ViewModel) { // 属性值是一个绑定 const isBinding = BindingUtil.isBinding(propConfig); if (isBinding) { @@ -109,7 +109,7 @@ class PageConfigBinder { // 属性值是一个数组 if (TypeUtil.isArray(propConfig)) { - this.bindArrayProp(propName, propConfig, componentConfig, componentSchema); + this.bindArrayProp(propName, propConfig, componentConfig, componentSchema, viewModel); return; } @@ -132,11 +132,15 @@ class PageConfigBinder { /** * 绑定值是数组的属性 */ - private bindArrayProp(arrayPropName: string, arrayPropConfig: any[], componentConfig: any, componentSchema: any): void { + private bindArrayProp(arrayPropName: string, arrayPropConfig: any[], componentConfig: any, componentSchema: any, viewModel: ViewModel): void { const arrayPropSchema = BindingUtil.getPropSchema(arrayPropName, componentSchema); arrayPropConfig.forEach((arrayItemConfig: any) => { const arrayItemSchema = this.getArrayItemSchema(arrayItemConfig, arrayPropSchema); - this.bindComponentConfig(arrayItemConfig, arrayItemSchema); + if (arrayItemConfig.type === 'Component') { + const viewModelId = arrayItemConfig.viewModel; + viewModel = this.module.getViewModel(viewModelId); + } + this.bindComponentConfig(arrayItemConfig, arrayItemSchema, viewModel); }); } diff --git a/packages/mobile-render/src/common/page-config/page-config-builder.ts b/packages/mobile-render/src/common/page-config/page-config-builder.ts index 31a1072a847..ab4c1b5ccd3 100644 --- a/packages/mobile-render/src/common/page-config/page-config-builder.ts +++ b/packages/mobile-render/src/common/page-config/page-config-builder.ts @@ -1,3 +1,4 @@ +import { JsonUtil } from '../utils/json-util'; /** * 页面配置 * @summary @@ -36,7 +37,7 @@ class PageConfigBuilder { * 构造页面配置 */ public build() { - this.pageConfig = this.cloneJsonObj(this.pageViewModelComponentNode); + this.pageConfig = JsonUtil.cloneJsonObj(this.pageViewModelComponentNode); this.replaceComponentRef(this.pageConfig); return this.pageConfig; @@ -65,7 +66,7 @@ class PageConfigBuilder { throw new Error(`ViewModelComponent(id=${childViewModelComponentId}) does not exist`); } - const childViewModelComponentConfig = this.cloneJsonObj(childViewModelComponentNode); + const childViewModelComponentConfig = JsonUtil.cloneJsonObj(childViewModelComponentNode); Object.keys(childViewModelComponentConfig).forEach((propName: string) => { componentConfig[propName] = childViewModelComponentConfig[propName]; }); @@ -83,16 +84,6 @@ class PageConfigBuilder { 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/views/form/form-runner.ts b/packages/mobile-render/src/views/module/module-runner.ts similarity index 68% rename from packages/mobile-render/src/views/form/form-runner.ts rename to packages/mobile-render/src/views/module/module-runner.ts index 66dff6b8720..599d3cb19ff 100644 --- a/packages/mobile-render/src/views/form/form-runner.ts +++ b/packages/mobile-render/src/views/module/module-runner.ts @@ -1,15 +1,18 @@ import { provide } from 'vue'; import { Router } from 'vue-router'; -import { Devkit, Module, createDynamicModule, MODULE_INJECTION_TOKEN } from '@farris/devkit-vue'; +import { + Devkit, Module, createDynamicModule, MODULE_INJECTION_TOKEN, + ViewModel, ViewModelState, createViewModel, VIEWMODEL_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 '../../common/module-config/index'; +import { ModuleConfigBuilder } from '../../common/module-config/index'; import { MetadataCacheService } from '../../common/metadata/index'; /** - * 运行表单 + * 运行表单模块 */ -class FormRunner { +class ModuleRunner { /** * 路由实例 @@ -22,10 +25,15 @@ class FormRunner { private devkit!: Devkit; /** - * 模块 + * 表单模块 */ private module!: Module; + /** + * 表单根视图模型 + */ + private rootViewModel: ViewModel; + /** * 元数据缓存服务 */ @@ -44,13 +52,14 @@ class FormRunner { /** * 运行表单 */ - public runForm() { + public runModule() { this.initModule(); + this.initRootViewModel(); } /** - * 初始化模块 - */ + * 初始化模块 + */ private initModule() { const formCode = this.getFormCode(); let module = this.devkit.getModule(formCode); @@ -63,6 +72,30 @@ class FormRunner { provide(MODULE_INJECTION_TOKEN, module); } + /** + * 初始化根视图模型 + */ + private initRootViewModel() { + const rootViewModelId = this.getRootViewModelId(); + let rootViewModel = this.module.getViewModel(rootViewModelId); + if (!rootViewModel) { + rootViewModel = createViewModel(this.module, rootViewModelId); + } + + this.rootViewModel = rootViewModel; + provide(VIEWMODEL_INJECTION_TOKEN, rootViewModel); + } + + /** + * 获取根组件ID + */ + private getRootViewModelId(): string { + const moduleConfigManager = this.module.getConfigManager(); + const rootViewModelConfig = moduleConfigManager.getRootViewModelConfig(); + + return rootViewModelConfig.id; + } + /** * 创建模块 */ @@ -110,4 +143,4 @@ class FormRunner { } } -export { FormRunner }; +export { ModuleRunner }; diff --git a/packages/mobile-render/src/views/form/form.vue b/packages/mobile-render/src/views/module/module.vue similarity index 68% rename from packages/mobile-render/src/views/form/form.vue rename to packages/mobile-render/src/views/module/module.vue index 23e50dd2256..d529ccfb388 100644 --- a/packages/mobile-render/src/views/form/form.vue +++ b/packages/mobile-render/src/views/module/module.vue @@ -1,13 +1,13 @@ diff --git a/packages/mobile-render/src/views/page/page-runner.ts b/packages/mobile-render/src/views/page/page-runner.ts index 48bdbc3db72..b44fe550a72 100644 --- a/packages/mobile-render/src/views/page/page-runner.ts +++ b/packages/mobile-render/src/views/page/page-runner.ts @@ -1,6 +1,6 @@ import { provide, Reactive } from 'vue'; import { Router } from 'vue-router'; -import { Devkit, Module, ViewModel, ViewModelState, createViewModel, VIEWMODEL_INJECTION_TOKEN } from '@farris/devkit-vue'; +import { Devkit, Module, ViewModelConfig, ViewModel, ViewModelState, createViewModel, VIEWMODEL_INJECTION_TOKEN } from '@farris/devkit-vue'; import { MetadataCacheService } from '../../common/metadata/index'; import { PageConfigBuilder, PageConfigBinder, } from '../../common/page-config/index'; import { PluginManager } from '../../common/plugin/index'; @@ -30,6 +30,11 @@ class PageRunner { */ private viewModel!: ViewModel; + /** + * 子视图模型集合 + */ + private childViewModels: ViewModel[]; + /** * 页面配置响应式对象 */ @@ -55,6 +60,7 @@ class PageRunner { public runPage() { this.initModule(); this.initViewModel(); + this.initChildViewModels(); this.initUIState(); this.initPageConfig(); this.pluginManager.runHooks('afterPageInit', { viewModel: this.viewModel }); @@ -100,6 +106,24 @@ class PageRunner { provide(VIEWMODEL_INJECTION_TOKEN, viewModel); } + /** + * 初始化子组件视图模型 + */ + private initChildViewModels() { + this.childViewModels = []; + + const moduleConfigManager = this.module.getConfigManager(); + const childViewModelConfigs = moduleConfigManager.getChildViewModelConfigs(this.viewModel.id); + childViewModelConfigs.forEach((childViewModelConfig: ViewModelConfig) => { + const childViewModelId = childViewModelConfig.id; + let childViewModel = this.module.getViewModel(childViewModelId); + if (!childViewModel) { + childViewModel = createViewModel(this.module, childViewModelId); + } + this.childViewModels.push(childViewModel); + }); + } + /** * 初始化查询参数 */ @@ -135,7 +159,7 @@ class PageRunner { private getFormMetadata() { const devkitInjector = this.devkit.getInjector(); const metadataCacheService = devkitInjector.get(MetadataCacheService); - const { moduleId, pageId } = this.getModuleIdAndPageId(); + const { moduleId } = this.getModuleIdAndPageId(); const metadatas = metadataCacheService.getCache(moduleId); const formMetadata = metadatas.form; -- Gitee From 9edef882c86faa8edf6d81fbc7496fd3384bd1a4 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Mon, 21 Apr 2025 20:20:13 +0800 Subject: [PATCH 270/287] =?UTF-8?q?chore:=20=E8=B0=83=E6=95=B4=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E4=BB=A3=E7=A0=81=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile-render/src/common/event-emitter.ts | 39 ------------------- packages/mobile-render/src/common/index.ts | 10 ++++- .../form/converters/base-converter.ts | 0 .../component-converters/button-converter.ts | 0 .../button-group-converter.ts | 4 +- .../component-converter.ts | 2 +- .../component-converters/datebox-converter.ts | 2 +- .../enum-field-converter.ts | 2 +- .../converters/component-converters/index.ts | 0 .../component-converters/input-converter.ts | 2 +- .../listview-converter.ts | 0 .../lookup-edit-converter.ts | 2 +- .../multi-textbox-converter.ts | 2 +- .../component-converters/navigation-bar.ts | 2 +- .../numeric-box-converter.ts | 2 +- .../page-content-container-converter.ts | 0 .../switch-field-converter.ts | 2 +- .../component-converters/textbox-converter.ts | 2 +- .../form/converters/converter-context.ts | 0 .../form/converters/converter-factory.ts | 0 .../metadata/form/converters/index.ts | 0 .../form/converters/schemas-converter.ts | 0 .../metadata/form/converters/types.ts | 0 .../form/converters/viewodels-converter.ts | 2 +- .../metadata/form/entity-schema-query.ts | 0 .../metadata/form/form-metadata-converter.ts | 0 .../form/form-metadata-data-service.ts | 0 .../metadata/form/form-metadata-normalizer.ts | 0 .../metadata/form/form-metadata-query.ts | 0 .../metadata/form/index.ts | 0 .../normalizers/button-group-normalizer.ts | 0 .../component-normalizer-factory.ts | 0 .../form/normalizers/component-normalizer.ts | 2 +- .../form/normalizers/form-group-normalizer.ts | 0 .../metadata/form/normalizers/index.ts | 0 .../form/normalizers/listview-normalizer.ts | 0 .../form/normalizers/normalizer-util.ts | 2 +- .../metadata/form/normalizers/types.ts | 0 .../metadata/form/types.ts | 0 .../{services => common}/metadata/index.ts | 0 .../metadata/metadata-cahce-service.ts | 0 .../metadata/metadata-data-service.ts | 0 .../metadata/metadata-repository.ts | 0 .../metadata/statemachine/index.ts | 0 .../state-machine-metadata-data-service.ts | 0 .../{services => common}/metadata/types.ts | 0 ...ommon-web-command-metadata-data-service.ts | 0 ...ustom-web-command-metadata-data-service.ts | 0 .../metadata/webcmd/index.ts | 0 ...tom-web-component-metadata-data-service.ts | 0 .../metadata/webcmp/index.ts | 0 .../module-config/command-handler-builder.ts | 0 .../entity-store-config-builder.ts | 0 .../form/form-array-store-config-builder.ts | 0 .../form/form-control-config-builder.ts | 0 .../form/form-store-config-builder.ts | 0 .../module-config/form/index.ts | 0 .../form/validation-rule-creator.ts | 0 .../module-config/index.ts | 0 .../module-config/module-config-builder.ts | 0 .../repository-config-builder.ts | 0 .../state-machine-config-builder.ts | 0 .../module-config/ui-store-config-builder.ts | 0 .../module-config/viewmodel-config-builder.ts | 0 .../page-config/bindings/binding-context.ts | 0 .../page-config/bindings/binding-factory.ts | 0 .../page-config/bindings/binding-util.ts | 2 +- .../page-config/bindings/binding-watcher.ts | 0 .../page-config/bindings/binding.ts | 0 .../page-config/bindings/command-binding.ts | 0 .../bindings/entity-field-binding.ts | 0 .../bindings/entity-list-binding.ts | 0 .../page-config/bindings/index.ts | 0 .../bindings/state-machine-binding.ts | 0 .../page-config/bindings/types.ts | 0 .../{services => common}/page-config/index.ts | 0 .../page-config/page-config-binder.ts | 2 +- .../page-config/page-config-builder.ts | 0 .../src/{services => common}/plugin/index.ts | 0 .../plugin/plugin-creators.ts | 0 .../plugin/plugin-manager.ts | 0 .../src/{services => common}/plugin/plugin.ts | 0 .../plugin/plugins/index.ts | 0 .../plugin/plugins/listview-plugin/index.ts | 0 .../listview-plugin/listview-plugin.ts | 0 .../plugin/plugins/lookup-plugin/index.ts | 0 .../lookup-plugin/lookup-data-service.ts | 0 .../lookup-plugin/lookup-mapping-service.ts | 0 .../plugins/lookup-plugin/lookup-plugin.ts | 0 .../src/{services => common}/plugin/types.ts | 0 .../mobile-render/src/common/providers.ts | 28 +++++++++++-- .../services/dynamic-route-service.ts | 6 +-- .../src/common/services/index.ts | 1 + packages/mobile-render/src/common/types.ts | 1 - .../src/{ => common}/utils/format-utils.ts | 0 .../src/{ => common}/utils/index.ts | 0 .../src/{ => common}/utils/json-util.ts | 0 .../src/{ => common}/utils/string-util.ts | 0 .../src/{ => common}/utils/type-util.ts | 0 packages/mobile-render/src/main.ts | 7 ++-- .../src/router/use-form-routes.ts | 2 +- packages/mobile-render/src/services/index.ts | 7 ---- .../mobile-render/src/services/providers.ts | 26 ------------- packages/mobile-render/src/types.ts | 4 -- .../src/views/form/form-runner.ts | 4 +- .../src/views/page/page-runner.ts | 6 ++- 106 files changed, 64 insertions(+), 111 deletions(-) delete mode 100644 packages/mobile-render/src/common/event-emitter.ts rename packages/mobile-render/src/{services => common}/metadata/form/converters/base-converter.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/button-converter.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/button-group-converter.ts (93%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/component-converter.ts (92%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/datebox-converter.ts (95%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/enum-field-converter.ts (91%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/index.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/input-converter.ts (94%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/listview-converter.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/lookup-edit-converter.ts (93%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/multi-textbox-converter.ts (91%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/navigation-bar.ts (95%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/numeric-box-converter.ts (91%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/page-content-container-converter.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/switch-field-converter.ts (90%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/component-converters/textbox-converter.ts (90%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/converter-context.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/converter-factory.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/index.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/schemas-converter.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/types.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/converters/viewodels-converter.ts (96%) rename packages/mobile-render/src/{services => common}/metadata/form/entity-schema-query.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/form-metadata-converter.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/form-metadata-data-service.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/form-metadata-normalizer.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/form-metadata-query.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/index.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/button-group-normalizer.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/component-normalizer-factory.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/component-normalizer.ts (99%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/form-group-normalizer.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/index.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/listview-normalizer.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/normalizer-util.ts (98%) rename packages/mobile-render/src/{services => common}/metadata/form/normalizers/types.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/form/types.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/index.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/metadata-cahce-service.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/metadata-data-service.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/metadata-repository.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/statemachine/index.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/statemachine/state-machine-metadata-data-service.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/types.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/webcmd/common-web-command-metadata-data-service.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/webcmd/custom-web-command-metadata-data-service.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/webcmd/index.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/webcmp/custom-web-component-metadata-data-service.ts (100%) rename packages/mobile-render/src/{services => common}/metadata/webcmp/index.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/command-handler-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/entity-store-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/form/form-array-store-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/form/form-control-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/form/form-store-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/form/index.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/form/validation-rule-creator.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/index.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/module-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/repository-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/state-machine-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/ui-store-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/module-config/viewmodel-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/binding-context.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/binding-factory.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/binding-util.ts (97%) rename packages/mobile-render/src/{services => common}/page-config/bindings/binding-watcher.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/binding.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/command-binding.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/entity-field-binding.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/entity-list-binding.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/index.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/state-machine-binding.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/bindings/types.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/index.ts (100%) rename packages/mobile-render/src/{services => common}/page-config/page-config-binder.ts (99%) rename packages/mobile-render/src/{services => common}/page-config/page-config-builder.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/index.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugin-creators.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugin-manager.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugin.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugins/index.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugins/listview-plugin/index.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugins/listview-plugin/listview-plugin.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugins/lookup-plugin/index.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugins/lookup-plugin/lookup-data-service.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugins/lookup-plugin/lookup-mapping-service.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/plugins/lookup-plugin/lookup-plugin.ts (100%) rename packages/mobile-render/src/{services => common}/plugin/types.ts (100%) rename packages/mobile-render/src/{ => common}/services/dynamic-route-service.ts (96%) create mode 100644 packages/mobile-render/src/common/services/index.ts delete mode 100644 packages/mobile-render/src/common/types.ts rename packages/mobile-render/src/{ => common}/utils/format-utils.ts (100%) rename packages/mobile-render/src/{ => common}/utils/index.ts (100%) rename packages/mobile-render/src/{ => common}/utils/json-util.ts (100%) rename packages/mobile-render/src/{ => common}/utils/string-util.ts (100%) rename packages/mobile-render/src/{ => common}/utils/type-util.ts (100%) delete mode 100644 packages/mobile-render/src/services/index.ts delete mode 100644 packages/mobile-render/src/services/providers.ts diff --git a/packages/mobile-render/src/common/event-emitter.ts b/packages/mobile-render/src/common/event-emitter.ts deleted file mode 100644 index ebb955d37aa..00000000000 --- a/packages/mobile-render/src/common/event-emitter.ts +++ /dev/null @@ -1,39 +0,0 @@ -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 index 6dce9a10036..e02247cede2 100644 --- a/packages/mobile-render/src/common/index.ts +++ b/packages/mobile-render/src/common/index.ts @@ -1,2 +1,8 @@ -export * from './types'; -export * from './event-emitter'; +export * from './utils/index'; +export * from './services/index'; +export * from './metadata/index'; +export * from './module-config/index'; +export * from './page-config/index'; +export * from './plugin/index'; +export * from './providers'; + diff --git a/packages/mobile-render/src/services/metadata/form/converters/base-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/base-converter.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/base-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/base-converter.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/button-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/button-converter.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/button-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/button-converter.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/button-group-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/button-group-converter.ts similarity index 93% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/button-group-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/button-group-converter.ts index 8a50ac68010..85b83632088 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/button-group-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/button-group-converter.ts @@ -1,5 +1,5 @@ -import { ComponentConverter } from "./component-converter"; -import { JsonUtil } from '../../../../../utils/index'; +import { ComponentConverter } from './component-converter'; +import { JsonUtil } from '../../../../utils/index'; /** * 基础组件转换器 diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/component-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/component-converter.ts similarity index 92% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/component-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/component-converter.ts index e90a818242b..3f5f7062384 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/component-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/component-converter.ts @@ -1,4 +1,4 @@ -import { StringUtil } from '../../../../../utils/index'; +import { StringUtil } from '../../../../utils/index'; import { BaseConverter } from "../base-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/datebox-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/datebox-converter.ts similarity index 95% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/datebox-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/datebox-converter.ts index 11952970fb3..33c13e48772 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/datebox-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/datebox-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { InputConverter } from "./input-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/enum-field-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/enum-field-converter.ts similarity index 91% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/enum-field-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/enum-field-converter.ts index d1bcac80906..4387a186a53 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/enum-field-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/enum-field-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { InputConverter } from "./input-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/index.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/index.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/index.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/input-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/input-converter.ts similarity index 94% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/input-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/input-converter.ts index 4a264d58c8c..f0af9420d58 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/input-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/input-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { ComponentConverter } from "./component-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/listview-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/listview-converter.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/listview-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/listview-converter.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/lookup-edit-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/lookup-edit-converter.ts similarity index 93% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/lookup-edit-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/lookup-edit-converter.ts index eacac091890..74868a9cbee 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/lookup-edit-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/lookup-edit-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { InputConverter } from "./input-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/multi-textbox-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/multi-textbox-converter.ts similarity index 91% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/multi-textbox-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/multi-textbox-converter.ts index 34e898537ca..520c94eafd2 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/multi-textbox-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/multi-textbox-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { InputConverter } from "./input-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/navigation-bar.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/navigation-bar.ts similarity index 95% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/navigation-bar.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/navigation-bar.ts index c0fc91f6fdd..6d2f50d3796 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/navigation-bar.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/navigation-bar.ts @@ -1,5 +1,5 @@ import { ComponentConverter } from "./component-converter"; -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; /** * 导航条组件转换器 diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/numeric-box-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/numeric-box-converter.ts similarity index 91% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/numeric-box-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/numeric-box-converter.ts index 6065875f5d8..97192078239 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/numeric-box-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/numeric-box-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { InputConverter } from "./input-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/page-content-container-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/page-content-container-converter.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/page-content-container-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/page-content-container-converter.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/switch-field-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/switch-field-converter.ts similarity index 90% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/switch-field-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/switch-field-converter.ts index a50e4167676..35d20fda114 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/switch-field-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/switch-field-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { InputConverter } from "./input-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/component-converters/textbox-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/component-converters/textbox-converter.ts similarity index 90% rename from packages/mobile-render/src/services/metadata/form/converters/component-converters/textbox-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/component-converters/textbox-converter.ts index 9c060fca030..7b0c5c497c2 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/component-converters/textbox-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/component-converters/textbox-converter.ts @@ -1,4 +1,4 @@ -import { JsonUtil } from '../../../../../utils/index'; +import { JsonUtil } from '../../../../utils/index'; import { InputConverter } from "./input-converter"; /** diff --git a/packages/mobile-render/src/services/metadata/form/converters/converter-context.ts b/packages/mobile-render/src/common/metadata/form/converters/converter-context.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/converter-context.ts rename to packages/mobile-render/src/common/metadata/form/converters/converter-context.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts b/packages/mobile-render/src/common/metadata/form/converters/converter-factory.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/converter-factory.ts rename to packages/mobile-render/src/common/metadata/form/converters/converter-factory.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/index.ts b/packages/mobile-render/src/common/metadata/form/converters/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/index.ts rename to packages/mobile-render/src/common/metadata/form/converters/index.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/schemas-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/schemas-converter.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/schemas-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/schemas-converter.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/types.ts b/packages/mobile-render/src/common/metadata/form/converters/types.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/converters/types.ts rename to packages/mobile-render/src/common/metadata/form/converters/types.ts diff --git a/packages/mobile-render/src/services/metadata/form/converters/viewodels-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/viewodels-converter.ts similarity index 96% rename from packages/mobile-render/src/services/metadata/form/converters/viewodels-converter.ts rename to packages/mobile-render/src/common/metadata/form/converters/viewodels-converter.ts index 36e66f2c2cb..eab0b6cc15e 100644 --- a/packages/mobile-render/src/services/metadata/form/converters/viewodels-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/viewodels-converter.ts @@ -1,4 +1,4 @@ -import { TypeUtil } from '../../../../utils/index'; +import { TypeUtil } from '../../../utils/index'; import { BaseConverter } from './base-converter'; /** diff --git a/packages/mobile-render/src/services/metadata/form/entity-schema-query.ts b/packages/mobile-render/src/common/metadata/form/entity-schema-query.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/entity-schema-query.ts rename to packages/mobile-render/src/common/metadata/form/entity-schema-query.ts diff --git a/packages/mobile-render/src/services/metadata/form/form-metadata-converter.ts b/packages/mobile-render/src/common/metadata/form/form-metadata-converter.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/form-metadata-converter.ts rename to packages/mobile-render/src/common/metadata/form/form-metadata-converter.ts diff --git a/packages/mobile-render/src/services/metadata/form/form-metadata-data-service.ts b/packages/mobile-render/src/common/metadata/form/form-metadata-data-service.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/form-metadata-data-service.ts rename to packages/mobile-render/src/common/metadata/form/form-metadata-data-service.ts diff --git a/packages/mobile-render/src/services/metadata/form/form-metadata-normalizer.ts b/packages/mobile-render/src/common/metadata/form/form-metadata-normalizer.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/form-metadata-normalizer.ts rename to packages/mobile-render/src/common/metadata/form/form-metadata-normalizer.ts diff --git a/packages/mobile-render/src/services/metadata/form/form-metadata-query.ts b/packages/mobile-render/src/common/metadata/form/form-metadata-query.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/form-metadata-query.ts rename to packages/mobile-render/src/common/metadata/form/form-metadata-query.ts diff --git a/packages/mobile-render/src/services/metadata/form/index.ts b/packages/mobile-render/src/common/metadata/form/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/index.ts rename to packages/mobile-render/src/common/metadata/form/index.ts diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/button-group-normalizer.ts b/packages/mobile-render/src/common/metadata/form/normalizers/button-group-normalizer.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/normalizers/button-group-normalizer.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/button-group-normalizer.ts diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer-factory.ts b/packages/mobile-render/src/common/metadata/form/normalizers/component-normalizer-factory.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer-factory.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/component-normalizer-factory.ts diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts b/packages/mobile-render/src/common/metadata/form/normalizers/component-normalizer.ts similarity index 99% rename from packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/component-normalizer.ts index 6ea43f243d4..74105ae64d0 100644 --- a/packages/mobile-render/src/services/metadata/form/normalizers/component-normalizer.ts +++ b/packages/mobile-render/src/common/metadata/form/normalizers/component-normalizer.ts @@ -1,4 +1,4 @@ -import { isObject, isArray } from '../../../../utils/index'; +import { isObject, isArray } from '../../../utils/index'; import { FormMetadataQuery } from '../form-metadata-query'; import { PropBindingType } from './types'; import { NormalizerUtil } from './normalizer-util'; diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/form-group-normalizer.ts b/packages/mobile-render/src/common/metadata/form/normalizers/form-group-normalizer.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/normalizers/form-group-normalizer.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/form-group-normalizer.ts diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/index.ts b/packages/mobile-render/src/common/metadata/form/normalizers/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/normalizers/index.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/index.ts diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/listview-normalizer.ts b/packages/mobile-render/src/common/metadata/form/normalizers/listview-normalizer.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/normalizers/listview-normalizer.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/listview-normalizer.ts diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/normalizer-util.ts b/packages/mobile-render/src/common/metadata/form/normalizers/normalizer-util.ts similarity index 98% rename from packages/mobile-render/src/services/metadata/form/normalizers/normalizer-util.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/normalizer-util.ts index edab3c7c1c7..1d52b89165b 100644 --- a/packages/mobile-render/src/services/metadata/form/normalizers/normalizer-util.ts +++ b/packages/mobile-render/src/common/metadata/form/normalizers/normalizer-util.ts @@ -1,4 +1,4 @@ -import { isObject } from '../../../../utils/index'; +import { isObject } from '../../../utils/index'; import { PropBindingType } from './types'; /** diff --git a/packages/mobile-render/src/services/metadata/form/normalizers/types.ts b/packages/mobile-render/src/common/metadata/form/normalizers/types.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/normalizers/types.ts rename to packages/mobile-render/src/common/metadata/form/normalizers/types.ts diff --git a/packages/mobile-render/src/services/metadata/form/types.ts b/packages/mobile-render/src/common/metadata/form/types.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/form/types.ts rename to packages/mobile-render/src/common/metadata/form/types.ts diff --git a/packages/mobile-render/src/services/metadata/index.ts b/packages/mobile-render/src/common/metadata/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/index.ts rename to packages/mobile-render/src/common/metadata/index.ts diff --git a/packages/mobile-render/src/services/metadata/metadata-cahce-service.ts b/packages/mobile-render/src/common/metadata/metadata-cahce-service.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/metadata-cahce-service.ts rename to packages/mobile-render/src/common/metadata/metadata-cahce-service.ts diff --git a/packages/mobile-render/src/services/metadata/metadata-data-service.ts b/packages/mobile-render/src/common/metadata/metadata-data-service.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/metadata-data-service.ts rename to packages/mobile-render/src/common/metadata/metadata-data-service.ts diff --git a/packages/mobile-render/src/services/metadata/metadata-repository.ts b/packages/mobile-render/src/common/metadata/metadata-repository.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/metadata-repository.ts rename to packages/mobile-render/src/common/metadata/metadata-repository.ts diff --git a/packages/mobile-render/src/services/metadata/statemachine/index.ts b/packages/mobile-render/src/common/metadata/statemachine/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/statemachine/index.ts rename to packages/mobile-render/src/common/metadata/statemachine/index.ts diff --git a/packages/mobile-render/src/services/metadata/statemachine/state-machine-metadata-data-service.ts b/packages/mobile-render/src/common/metadata/statemachine/state-machine-metadata-data-service.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/statemachine/state-machine-metadata-data-service.ts rename to packages/mobile-render/src/common/metadata/statemachine/state-machine-metadata-data-service.ts diff --git a/packages/mobile-render/src/services/metadata/types.ts b/packages/mobile-render/src/common/metadata/types.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/types.ts rename to packages/mobile-render/src/common/metadata/types.ts diff --git a/packages/mobile-render/src/services/metadata/webcmd/common-web-command-metadata-data-service.ts b/packages/mobile-render/src/common/metadata/webcmd/common-web-command-metadata-data-service.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/webcmd/common-web-command-metadata-data-service.ts rename to packages/mobile-render/src/common/metadata/webcmd/common-web-command-metadata-data-service.ts diff --git a/packages/mobile-render/src/services/metadata/webcmd/custom-web-command-metadata-data-service.ts b/packages/mobile-render/src/common/metadata/webcmd/custom-web-command-metadata-data-service.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/webcmd/custom-web-command-metadata-data-service.ts rename to packages/mobile-render/src/common/metadata/webcmd/custom-web-command-metadata-data-service.ts diff --git a/packages/mobile-render/src/services/metadata/webcmd/index.ts b/packages/mobile-render/src/common/metadata/webcmd/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/webcmd/index.ts rename to packages/mobile-render/src/common/metadata/webcmd/index.ts diff --git a/packages/mobile-render/src/services/metadata/webcmp/custom-web-component-metadata-data-service.ts b/packages/mobile-render/src/common/metadata/webcmp/custom-web-component-metadata-data-service.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/webcmp/custom-web-component-metadata-data-service.ts rename to packages/mobile-render/src/common/metadata/webcmp/custom-web-component-metadata-data-service.ts diff --git a/packages/mobile-render/src/services/metadata/webcmp/index.ts b/packages/mobile-render/src/common/metadata/webcmp/index.ts similarity index 100% rename from packages/mobile-render/src/services/metadata/webcmp/index.ts rename to packages/mobile-render/src/common/metadata/webcmp/index.ts diff --git a/packages/mobile-render/src/services/module-config/command-handler-builder.ts b/packages/mobile-render/src/common/module-config/command-handler-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/command-handler-builder.ts rename to packages/mobile-render/src/common/module-config/command-handler-builder.ts diff --git a/packages/mobile-render/src/services/module-config/entity-store-config-builder.ts b/packages/mobile-render/src/common/module-config/entity-store-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/entity-store-config-builder.ts rename to packages/mobile-render/src/common/module-config/entity-store-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts b/packages/mobile-render/src/common/module-config/form/form-array-store-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/form/form-array-store-config-builder.ts rename to packages/mobile-render/src/common/module-config/form/form-array-store-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/form/form-control-config-builder.ts b/packages/mobile-render/src/common/module-config/form/form-control-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/form/form-control-config-builder.ts rename to packages/mobile-render/src/common/module-config/form/form-control-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts b/packages/mobile-render/src/common/module-config/form/form-store-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/form/form-store-config-builder.ts rename to packages/mobile-render/src/common/module-config/form/form-store-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/form/index.ts b/packages/mobile-render/src/common/module-config/form/index.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/form/index.ts rename to packages/mobile-render/src/common/module-config/form/index.ts diff --git a/packages/mobile-render/src/services/module-config/form/validation-rule-creator.ts b/packages/mobile-render/src/common/module-config/form/validation-rule-creator.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/form/validation-rule-creator.ts rename to packages/mobile-render/src/common/module-config/form/validation-rule-creator.ts diff --git a/packages/mobile-render/src/services/module-config/index.ts b/packages/mobile-render/src/common/module-config/index.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/index.ts rename to packages/mobile-render/src/common/module-config/index.ts diff --git a/packages/mobile-render/src/services/module-config/module-config-builder.ts b/packages/mobile-render/src/common/module-config/module-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/module-config-builder.ts rename to packages/mobile-render/src/common/module-config/module-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/repository-config-builder.ts b/packages/mobile-render/src/common/module-config/repository-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/repository-config-builder.ts rename to packages/mobile-render/src/common/module-config/repository-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/state-machine-config-builder.ts b/packages/mobile-render/src/common/module-config/state-machine-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/state-machine-config-builder.ts rename to packages/mobile-render/src/common/module-config/state-machine-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/ui-store-config-builder.ts b/packages/mobile-render/src/common/module-config/ui-store-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/ui-store-config-builder.ts rename to packages/mobile-render/src/common/module-config/ui-store-config-builder.ts diff --git a/packages/mobile-render/src/services/module-config/viewmodel-config-builder.ts b/packages/mobile-render/src/common/module-config/viewmodel-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/module-config/viewmodel-config-builder.ts rename to packages/mobile-render/src/common/module-config/viewmodel-config-builder.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/binding-context.ts b/packages/mobile-render/src/common/page-config/bindings/binding-context.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/binding-context.ts rename to packages/mobile-render/src/common/page-config/bindings/binding-context.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/binding-factory.ts b/packages/mobile-render/src/common/page-config/bindings/binding-factory.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/binding-factory.ts rename to packages/mobile-render/src/common/page-config/bindings/binding-factory.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/binding-util.ts b/packages/mobile-render/src/common/page-config/bindings/binding-util.ts similarity index 97% rename from packages/mobile-render/src/services/page-config/bindings/binding-util.ts rename to packages/mobile-render/src/common/page-config/bindings/binding-util.ts index ed71ff5bf45..63cf10435c7 100644 --- a/packages/mobile-render/src/services/page-config/bindings/binding-util.ts +++ b/packages/mobile-render/src/common/page-config/bindings/binding-util.ts @@ -1,4 +1,4 @@ -import { isObject, isString, TypeUtil } from '../../../utils/index'; +import { isObject, isString, TypeUtil } from '../../utils/index'; import { BindingType } from './types'; /** diff --git a/packages/mobile-render/src/services/page-config/bindings/binding-watcher.ts b/packages/mobile-render/src/common/page-config/bindings/binding-watcher.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/binding-watcher.ts rename to packages/mobile-render/src/common/page-config/bindings/binding-watcher.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/binding.ts b/packages/mobile-render/src/common/page-config/bindings/binding.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/binding.ts rename to packages/mobile-render/src/common/page-config/bindings/binding.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/command-binding.ts b/packages/mobile-render/src/common/page-config/bindings/command-binding.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/command-binding.ts rename to packages/mobile-render/src/common/page-config/bindings/command-binding.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/entity-field-binding.ts b/packages/mobile-render/src/common/page-config/bindings/entity-field-binding.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/entity-field-binding.ts rename to packages/mobile-render/src/common/page-config/bindings/entity-field-binding.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/entity-list-binding.ts b/packages/mobile-render/src/common/page-config/bindings/entity-list-binding.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/entity-list-binding.ts rename to packages/mobile-render/src/common/page-config/bindings/entity-list-binding.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/index.ts b/packages/mobile-render/src/common/page-config/bindings/index.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/index.ts rename to packages/mobile-render/src/common/page-config/bindings/index.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/state-machine-binding.ts b/packages/mobile-render/src/common/page-config/bindings/state-machine-binding.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/state-machine-binding.ts rename to packages/mobile-render/src/common/page-config/bindings/state-machine-binding.ts diff --git a/packages/mobile-render/src/services/page-config/bindings/types.ts b/packages/mobile-render/src/common/page-config/bindings/types.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/bindings/types.ts rename to packages/mobile-render/src/common/page-config/bindings/types.ts diff --git a/packages/mobile-render/src/services/page-config/index.ts b/packages/mobile-render/src/common/page-config/index.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/index.ts rename to packages/mobile-render/src/common/page-config/index.ts diff --git a/packages/mobile-render/src/services/page-config/page-config-binder.ts b/packages/mobile-render/src/common/page-config/page-config-binder.ts similarity index 99% rename from packages/mobile-render/src/services/page-config/page-config-binder.ts rename to packages/mobile-render/src/common/page-config/page-config-binder.ts index 96c42829d79..fb15efa5853 100644 --- a/packages/mobile-render/src/services/page-config/page-config-binder.ts +++ b/packages/mobile-render/src/common/page-config/page-config-binder.ts @@ -1,7 +1,7 @@ import { reactive, Reactive } from 'vue'; import { Module, ViewModel, ViewModelState } from '@farris/devkit-vue'; import { schemaMap } from '@farris/mobile-ui-vue'; -import { TypeUtil, JsonUtil } from '../../utils/index'; +import { TypeUtil, JsonUtil } from '../utils/index'; import { BindingUtil, BindingContext, BindingFactory } from './bindings/index'; import { AfterComponentBindingHookContext, Plugin, PluginManager } from '../plugin/index'; diff --git a/packages/mobile-render/src/services/page-config/page-config-builder.ts b/packages/mobile-render/src/common/page-config/page-config-builder.ts similarity index 100% rename from packages/mobile-render/src/services/page-config/page-config-builder.ts rename to packages/mobile-render/src/common/page-config/page-config-builder.ts diff --git a/packages/mobile-render/src/services/plugin/index.ts b/packages/mobile-render/src/common/plugin/index.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/index.ts rename to packages/mobile-render/src/common/plugin/index.ts diff --git a/packages/mobile-render/src/services/plugin/plugin-creators.ts b/packages/mobile-render/src/common/plugin/plugin-creators.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugin-creators.ts rename to packages/mobile-render/src/common/plugin/plugin-creators.ts diff --git a/packages/mobile-render/src/services/plugin/plugin-manager.ts b/packages/mobile-render/src/common/plugin/plugin-manager.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugin-manager.ts rename to packages/mobile-render/src/common/plugin/plugin-manager.ts diff --git a/packages/mobile-render/src/services/plugin/plugin.ts b/packages/mobile-render/src/common/plugin/plugin.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugin.ts rename to packages/mobile-render/src/common/plugin/plugin.ts diff --git a/packages/mobile-render/src/services/plugin/plugins/index.ts b/packages/mobile-render/src/common/plugin/plugins/index.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugins/index.ts rename to packages/mobile-render/src/common/plugin/plugins/index.ts diff --git a/packages/mobile-render/src/services/plugin/plugins/listview-plugin/index.ts b/packages/mobile-render/src/common/plugin/plugins/listview-plugin/index.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugins/listview-plugin/index.ts rename to packages/mobile-render/src/common/plugin/plugins/listview-plugin/index.ts diff --git a/packages/mobile-render/src/services/plugin/plugins/listview-plugin/listview-plugin.ts b/packages/mobile-render/src/common/plugin/plugins/listview-plugin/listview-plugin.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugins/listview-plugin/listview-plugin.ts rename to packages/mobile-render/src/common/plugin/plugins/listview-plugin/listview-plugin.ts diff --git a/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/index.ts b/packages/mobile-render/src/common/plugin/plugins/lookup-plugin/index.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugins/lookup-plugin/index.ts rename to packages/mobile-render/src/common/plugin/plugins/lookup-plugin/index.ts diff --git a/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-data-service.ts b/packages/mobile-render/src/common/plugin/plugins/lookup-plugin/lookup-data-service.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-data-service.ts rename to packages/mobile-render/src/common/plugin/plugins/lookup-plugin/lookup-data-service.ts diff --git a/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-mapping-service.ts b/packages/mobile-render/src/common/plugin/plugins/lookup-plugin/lookup-mapping-service.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-mapping-service.ts rename to packages/mobile-render/src/common/plugin/plugins/lookup-plugin/lookup-mapping-service.ts diff --git a/packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-plugin.ts b/packages/mobile-render/src/common/plugin/plugins/lookup-plugin/lookup-plugin.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/plugins/lookup-plugin/lookup-plugin.ts rename to packages/mobile-render/src/common/plugin/plugins/lookup-plugin/lookup-plugin.ts diff --git a/packages/mobile-render/src/services/plugin/types.ts b/packages/mobile-render/src/common/plugin/types.ts similarity index 100% rename from packages/mobile-render/src/services/plugin/types.ts rename to packages/mobile-render/src/common/plugin/types.ts diff --git a/packages/mobile-render/src/common/providers.ts b/packages/mobile-render/src/common/providers.ts index 2761df9479c..8285a3d2990 100644 --- a/packages/mobile-render/src/common/providers.ts +++ b/packages/mobile-render/src/common/providers.ts @@ -1,6 +1,26 @@ -import { StaticProvider } from "@farris/devkit-vue"; -import { EventEmitter } from "./event-emitter"; -export const eventEmitterProviders: StaticProvider[] = [ - { provide: EventEmitter, useClass: EventEmitter, deps: [] } +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/services/dynamic-route-service.ts b/packages/mobile-render/src/common/services/dynamic-route-service.ts similarity index 96% rename from packages/mobile-render/src/services/dynamic-route-service.ts rename to packages/mobile-render/src/common/services/dynamic-route-service.ts index 22e872c0a09..1be921d5269 100644 --- a/packages/mobile-render/src/services/dynamic-route-service.ts +++ b/packages/mobile-render/src/common/services/dynamic-route-service.ts @@ -1,7 +1,7 @@ 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'; +import { MetadataDataService, MetadataCacheService } from '../metadata/index'; +import Form from '../../views/form/form.vue'; +import Page from '../../views/page/page.vue'; /** * 动态路由服务 diff --git a/packages/mobile-render/src/common/services/index.ts b/packages/mobile-render/src/common/services/index.ts new file mode 100644 index 00000000000..3acd21c28cb --- /dev/null +++ b/packages/mobile-render/src/common/services/index.ts @@ -0,0 +1 @@ +export * from './dynamic-route-service'; diff --git a/packages/mobile-render/src/common/types.ts b/packages/mobile-render/src/common/types.ts deleted file mode 100644 index 448a521dc41..00000000000 --- a/packages/mobile-render/src/common/types.ts +++ /dev/null @@ -1 +0,0 @@ -export type Callable = (...args: U) => T; diff --git a/packages/mobile-render/src/utils/format-utils.ts b/packages/mobile-render/src/common/utils/format-utils.ts similarity index 100% rename from packages/mobile-render/src/utils/format-utils.ts rename to packages/mobile-render/src/common/utils/format-utils.ts diff --git a/packages/mobile-render/src/utils/index.ts b/packages/mobile-render/src/common/utils/index.ts similarity index 100% rename from packages/mobile-render/src/utils/index.ts rename to packages/mobile-render/src/common/utils/index.ts diff --git a/packages/mobile-render/src/utils/json-util.ts b/packages/mobile-render/src/common/utils/json-util.ts similarity index 100% rename from packages/mobile-render/src/utils/json-util.ts rename to packages/mobile-render/src/common/utils/json-util.ts diff --git a/packages/mobile-render/src/utils/string-util.ts b/packages/mobile-render/src/common/utils/string-util.ts similarity index 100% rename from packages/mobile-render/src/utils/string-util.ts rename to packages/mobile-render/src/common/utils/string-util.ts diff --git a/packages/mobile-render/src/utils/type-util.ts b/packages/mobile-render/src/common/utils/type-util.ts similarity index 100% rename from packages/mobile-render/src/utils/type-util.ts rename to packages/mobile-render/src/common/utils/type-util.ts diff --git a/packages/mobile-render/src/main.ts b/packages/mobile-render/src/main.ts index c50637e2bb6..ba334a86c71 100644 --- a/packages/mobile-render/src/main.ts +++ b/packages/mobile-render/src/main.ts @@ -4,13 +4,14 @@ 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 { formatUtils } from './utils'; + +import { formatUtils } from './common/utils/index'; +import { renderServiceProviders } from './common/providers'; import App from './app.vue'; import router from './router'; import { checkFormRoute, addFormRoute } from './router/use-form-routes'; -import { PluginContext, PluginManager, createBuildInPlugins } from './services/plugin/index'; +import { PluginContext, PluginManager, createBuildInPlugins } from './common/plugin/index'; // devkit export const devkitProviders: StaticProvider[] = [ diff --git a/packages/mobile-render/src/router/use-form-routes.ts b/packages/mobile-render/src/router/use-form-routes.ts index de05d2e324d..9c3ed7b72f3 100644 --- a/packages/mobile-render/src/router/use-form-routes.ts +++ b/packages/mobile-render/src/router/use-form-routes.ts @@ -1,6 +1,6 @@ import { RouteRecordRaw, Router, RouteRecord } from 'vue-router'; import { Devkit } from '@farris/devkit-vue'; -import { MetadataDataService, MetadataCacheService } from '../services/index'; +import { MetadataDataService, MetadataCacheService } from '../common/index'; import Form from '../views/form/form.vue'; import Page from '../views/page/page.vue'; diff --git a/packages/mobile-render/src/services/index.ts b/packages/mobile-render/src/services/index.ts deleted file mode 100644 index f406cc625e9..00000000000 --- a/packages/mobile-render/src/services/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from './metadata/index'; -export * from './module-config/index'; -export * from './page-config/index'; -export * from './plugin/index'; -export * from './dynamic-route-service'; -export * from './providers'; - diff --git a/packages/mobile-render/src/services/providers.ts b/packages/mobile-render/src/services/providers.ts deleted file mode 100644 index 8285a3d2990..00000000000 --- a/packages/mobile-render/src/services/providers.ts +++ /dev/null @@ -1,26 +0,0 @@ - -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 index 816bd2caea9..b0d64e23332 100644 --- a/packages/mobile-render/src/types.ts +++ b/packages/mobile-render/src/types.ts @@ -1,4 +1,3 @@ -import { EventEmitter } from "./common"; /* eslint-disable no-use-before-define */ // #region form schema @@ -236,9 +235,6 @@ export interface UseFieldResolver { export interface UseParamPersistence { persist(): Promise; } -export interface UseEventEmitter { - emitter: EventEmitter; -} export interface UseEventHandler { bind(): void; diff --git a/packages/mobile-render/src/views/form/form-runner.ts b/packages/mobile-render/src/views/form/form-runner.ts index 31f70ea9e89..66dff6b8720 100644 --- a/packages/mobile-render/src/views/form/form-runner.ts +++ b/packages/mobile-render/src/views/form/form-runner.ts @@ -3,8 +3,8 @@ 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'; +import { ModuleConfigBuilder } from '../../common/module-config/index'; +import { MetadataCacheService } from '../../common/metadata/index'; /** * 运行表单 diff --git a/packages/mobile-render/src/views/page/page-runner.ts b/packages/mobile-render/src/views/page/page-runner.ts index 60e4693839e..48bdbc3db72 100644 --- a/packages/mobile-render/src/views/page/page-runner.ts +++ b/packages/mobile-render/src/views/page/page-runner.ts @@ -1,7 +1,9 @@ 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, PluginManager } from '../../services/index'; +import { Devkit, Module, ViewModel, ViewModelState, createViewModel, VIEWMODEL_INJECTION_TOKEN } from '@farris/devkit-vue'; +import { MetadataCacheService } from '../../common/metadata/index'; +import { PageConfigBuilder, PageConfigBinder, } from '../../common/page-config/index'; +import { PluginManager } from '../../common/plugin/index'; /** * 运行页面 -- Gitee From ba0b30db28c0e1293b67d8a8300a84c128aa0627 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Mon, 21 Apr 2025 20:56:25 +0800 Subject: [PATCH 271/287] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=A0=B9=E7=BB=84=E4=BB=B6=E5=90=8E=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E6=8F=90=E5=8F=96=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/module/configs/module-config-manager.ts | 2 +- .../form/converters/root-component-converter.ts | 2 +- .../src/common/page-config/page-config-binder.ts | 14 ++++++++++---- .../src/common/services/dynamic-route-service.ts | 2 +- .../mobile-render/src/router/use-form-routes.ts | 5 ++++- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/packages/devkit/lib/module/configs/module-config-manager.ts b/packages/devkit/lib/module/configs/module-config-manager.ts index cf513396711..83ed51bc79e 100644 --- a/packages/devkit/lib/module/configs/module-config-manager.ts +++ b/packages/devkit/lib/module/configs/module-config-manager.ts @@ -67,7 +67,7 @@ class ModuleConfigManager { public getChildViewModelConfigs(parentId: string): ViewModelConfig[] { const viewModelConfigs = this.getViewModelConfigs(); const childViewModelConfigs = viewModelConfigs.filter((viewModelConfig) => { - return viewModelConfig.id = parentId; + return viewModelConfig.id === parentId; }); return childViewModelConfigs; diff --git a/packages/mobile-render/src/common/metadata/form/converters/root-component-converter.ts b/packages/mobile-render/src/common/metadata/form/converters/root-component-converter.ts index aa11e000294..5857c5a6148 100644 --- a/packages/mobile-render/src/common/metadata/form/converters/root-component-converter.ts +++ b/packages/mobile-render/src/common/metadata/form/converters/root-component-converter.ts @@ -82,7 +82,7 @@ class RootComponentConverter extends BaseConverter { */ private convertChildViewModels(rootViewModel: any, childViewModels: any[]): void { childViewModels.forEach((childViewModel: any) => { - if (childViewModel.parent) { + if (childViewModel.parent || childViewModel.id === rootViewModel.id) { return; } diff --git a/packages/mobile-render/src/common/page-config/page-config-binder.ts b/packages/mobile-render/src/common/page-config/page-config-binder.ts index 84a79a504fe..c98c64a5912 100644 --- a/packages/mobile-render/src/common/page-config/page-config-binder.ts +++ b/packages/mobile-render/src/common/page-config/page-config-binder.ts @@ -115,7 +115,7 @@ class PageConfigBinder { // 属性值是个对象 if (TypeUtil.isObject(propConfig)) { - this.bindObjectProp(propName, propConfig, componentConfig, componentSchema); + this.bindObjectProp(propName, propConfig, componentConfig, componentSchema, viewModel); return; } } @@ -132,7 +132,10 @@ class PageConfigBinder { /** * 绑定值是数组的属性 */ - private bindArrayProp(arrayPropName: string, arrayPropConfig: any[], componentConfig: any, componentSchema: any, viewModel: ViewModel): void { + private bindArrayProp( + arrayPropName: string, arrayPropConfig: any[], componentConfig: any, componentSchema: any, + viewModel: ViewModel + ): void { const arrayPropSchema = BindingUtil.getPropSchema(arrayPropName, componentSchema); arrayPropConfig.forEach((arrayItemConfig: any) => { const arrayItemSchema = this.getArrayItemSchema(arrayItemConfig, arrayPropSchema); @@ -168,10 +171,13 @@ class PageConfigBinder { /** * 获取对象的Schema */ - private bindObjectProp(objPropName: string, objPropConfig: any, componentConfig: any, componentSchema: any): void { + private bindObjectProp( + objPropName: string, objPropConfig: any, componentConfig: any, componentSchema: any, + viewModel: ViewModel + ): void { const objPropSchema = BindingUtil.getPropSchema(objPropName, componentSchema); const objSchema = this.getObjectSchema(objPropConfig, objPropSchema); - this.bindComponentConfig(objPropConfig, objSchema); + this.bindComponentConfig(objPropConfig, objSchema, viewModel); } /** diff --git a/packages/mobile-render/src/common/services/dynamic-route-service.ts b/packages/mobile-render/src/common/services/dynamic-route-service.ts index 1be921d5269..a821af52315 100644 --- a/packages/mobile-render/src/common/services/dynamic-route-service.ts +++ b/packages/mobile-render/src/common/services/dynamic-route-service.ts @@ -1,6 +1,6 @@ import { RouteRecordRaw, Router } from 'vue-router'; import { MetadataDataService, MetadataCacheService } from '../metadata/index'; -import Form from '../../views/form/form.vue'; +import Form from '../../views/module/module.vue'; import Page from '../../views/page/page.vue'; /** diff --git a/packages/mobile-render/src/router/use-form-routes.ts b/packages/mobile-render/src/router/use-form-routes.ts index 9c3ed7b72f3..8d4cbfee785 100644 --- a/packages/mobile-render/src/router/use-form-routes.ts +++ b/packages/mobile-render/src/router/use-form-routes.ts @@ -1,7 +1,7 @@ import { RouteRecordRaw, Router, RouteRecord } from 'vue-router'; import { Devkit } from '@farris/devkit-vue'; import { MetadataDataService, MetadataCacheService } from '../common/index'; -import Form from '../views/form/form.vue'; +import Form from '../views/module/module.vue'; import Page from '../views/page/page.vue'; /** @@ -96,6 +96,9 @@ function createFormRoute(formMetadata: any) { }; componentNodes.forEach((componentNode) => { + if (componentNode.componentType !== 'Page') { + return; + } const pageRoute: RouteRecordRaw = { path: componentNode.route.uri, component: Page -- Gitee From 6c1ef138260755c250bc94d36c816b8b5d09f912 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Tue, 22 Apr 2025 08:35:52 +0800 Subject: [PATCH 272/287] =?UTF-8?q?feature:=20=E7=A7=BB=E5=8A=A8button?= =?UTF-8?q?=E3=80=81checkboxgroup=E3=80=81datepicker=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E6=97=B6=E5=B1=9E=E6=80=A7=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/assets/farris-mobile-ui-vue.css | 2 +- .../public/assets/farris-mobile-page-vue.css | 2 +- .../public/assets/farris-mobile-ui-vue.css | 2 +- packages/mobile-render/src/main.ts | 2 +- .../button-edit/src/button-edit.props.ts | 6 +- .../src/designer/button.design.component.tsx | 23 +-- .../property-config/button.property-config.ts | 2 +- .../button/src/schema/button.schema.json | 5 +- .../button/src/schema/schema-mapper.ts | 2 +- .../checkbox-group.property-config.ts | 11 ++ .../compositions/use-event-listener/index.ts | 16 +- .../src/compositions/use-long-press/index.ts | 1 + .../date-picker/src/date-picker.component.tsx | 1 + .../date-picker.property-config.ts | 2 +- .../src/schema/date-picker.schema.json | 165 +++++++++--------- .../date-picker/src/schema/schema-mapper.ts | 3 +- .../src/date-time-picker.component.tsx | 1 + .../date-picker.property-config.ts | 2 +- .../src/schema/datetime-picker.schema.json | 5 + .../src/schema/schema-mapper.ts | 3 +- .../dynamic-resolver/src/props-resolver.ts | 5 +- .../src/composition/use-render-component.ts | 22 ++- packages/mobile-ui-vue/components/index.ts | 6 +- .../src/composition/use-load-list-data.ts | 2 +- .../lookup/src/lookup-panel.props.ts | 2 +- .../lookup/src/schema/schema-mapper.ts | 3 +- packages/mobile-ui-vue/farris.config.mjs | 2 +- 27 files changed, 152 insertions(+), 146 deletions(-) diff --git a/packages/designer/public/assets/farris-mobile-ui-vue.css b/packages/designer/public/assets/farris-mobile-ui-vue.css index 7f49e0efccb..16df0875d6a 100644 --- a/packages/designer/public/assets/farris-mobile-ui-vue.css +++ b/packages/designer/public/assets/farris-mobile-ui-vue.css @@ -1 +1 @@ -@charset "UTF-8";:root{--fm-black: #000;--fm-white: #fff;--fm-gray-1: #f2f3f5;--fm-gray-2: #eee;--fm-gray-3: #ddd;--fm-gray-4: #ccc;--fm-gray-5: #999;--fm-gray-6: #666;--fm-gray-7: #333;--fm-red: #F24645;--fm-red-light: #f9e8e8;--fm-blue: #3A90FF;--fm-blue-2: #65a7ff;--fm-blue-light: #ecf2fe;--fm-green: #5CC171;--fm-green-2: #5AC1C3;--fm-green-light: #e9f5ed;--fm-orange: #FF9800;--fm-orange-2: #FA6400;--fm-orange-3: #FFB400;--fm-orange-light: #faf0e1;--fm-primary-color: var(--fm-blue);--fm-success-color: var(--fm-green);--fm-danger-color: var(--fm-red);--fm-warning-color: var(--fm-orange);--fm-submit-color: var(--fm-green-2);--fm-primary-color-light: var(--fm-blue-light);--fm-success-color-light: var(--fm-green-light);--fm-danger-color-light: var(--fm-red-light);--fm-warning-color-light: var(--fm-orange-light);--fm-text-color: var(--fm-gray-7);--fm-text-color-light: var(--fm-gray-5);--fm-active-color: var(--fm-gray-1);--fm-disabled-color: var(--fm-gray-4);--fm-readonly-color: var(--fm-gray-6);--fm-active-opacity: .7;--fm-readonly-opacity: .6;--fm-disabled-opacity: .5;--fm-background: var(--fm-gray-1);--fm-background-white: var(--fm-white);--fm-box-shadow-color: var(--fm-gray-1);--fm-padding-base: 4px;--fm-padding-xs: 8px;--fm-padding-sm: 12px;--fm-padding-md: 16px;--fm-padding-lg: 24px;--fm-padding-xl: 32px;--fm-padding-horizontal-xs: 0 var(--fm-padding-xs);--fm-padding-horizontal-sm: 0 var(--fm-padding-sm);--fm-padding-horizontal-md: 0 var(--fm-padding-md);--fm-padding-horizontal-lg: 0 var(--fm-padding-lg);--fm-margin-base: 4px;--fm-margin-xs: 8px;--fm-margin-sm: 12px;--fm-margin-md: 16px;--fm-margin-lg: 24px;--fm-margin-xl: 32px;--fm-margin-horizontal-xs: 0 var(--fm-margin-xs);--fm-margin-horizontal-sm: 0 var(--fm-margin-sm);--fm-margin-horizontal-md: 0 var(--fm-margin-md);--fm-margin-horizontal-lg: 0 var(--fm-margin-lg);--fm-font-bold-light: 500;--fm-font-bold: 600;--fm-font-size: 16px;--fm-line-height: 1.2;--fm-font-size-xs: 10px;--fm-font-size-sm: 12px;--fm-font-size-md: 14px;--fm-font-size-lg: 16px;--fm-gradient-blue: linear-gradient(-45deg,var(--fm-blue-2) 0%, var(--fm-blue) 100%);--fm-gradient-orange: linear-gradient(-45deg,var(--fm-orange) 0%, var(--fm-orange-2) 100%);--fm-base-font: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Segoe UI, Arial, Roboto, "PingFang SC", "miui", "Hiragino Sans GB", "Microsoft Yahei", sans-serif;--fm-price-font: avenir-heavy, "PingFang SC", helvetica neue, arial, sans-serif;--fm-duration-base: .3s;--fm-duration-fast: .2s;--fm-ease-out: ease-out;--fm-ease-in: ease-in;--fm-noborder: none;--fm-radius-sm: 2px;--fm-radius-md: 4px;--fm-radius-lg: 8px;--fm-radius-max: 999px;--fm-zindex-1: 9;--fm-zindex-2: 10;--fm-zindex-3: 99;--fm-zindex-4: 100;--fm-zindex-5: 999;--fm-zindex-6: 1000}*,*:before,*:after{box-sizing:border-box}body,h1,h2,h3,h4,p,figure,blockquote,dl,dd{margin:0}ul[role=list],ol[role=list]{list-style:none}html:focus-within{scroll-behavior:smooth}body{min-height:100vh;text-rendering:optimizeSpeed;line-height:1.5;font-family:-apple-system,Noto Sans,Helvetica Neue,Helvetica,Nimbus Sans L,Arial,Liberation Sans,PingFang SC,Hiragino Sans GB,Noto Sans CJK SC,Source Han Sans SC,Source Han Sans CN,Microsoft YaHei,Wenquanyi Micro Hei,WenQuanYi Zen Hei,ST Heiti,SimHei,WenQuanYi Zen Hei Sharp,sans-serif}a:not([class]){text-decoration-skip-ink:auto}img,picture{max-width:100%;display:block}input,button,textarea,select{font:inherit}@font-face{font-family:farrisMobile;font-style:normal;font-weight:400;src:url(data:font/ttf;base64,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AADmFAAAACUAAOYVAADmFQAAACYAAOYWAADmFgAAACcAAOYXAADmFwAAACgAAOYYAADmGAAAACkAAOYZAADmGQAAAHYAAOYaAADmGgAAAHUAAOYbAADmGwAAAHQAAOYcAADmHAAAAHMAAOYdAADmHQAAACoAAOYeAADmHgAAACsAAOYfAADmHwAAAHAAAOYgAADmIAAAAHEAAOYhAADmIQAAAHIAAOYiAADmIgAAAG8AAOYjAADmIwAAACwAAOYkAADmJAAAAGUAAOYlAADmJQAAAGYAAOYmAADmJgAAAGcAAOYnAADmJwAAAGgAAOYoAADmKAAAAGkAAOYpAADmKQAAAGoAAOYqAADmKgAAAGsAAOYrAADmKwAAAGwAAOYsAADmLAAAAG0AAOYtAADmLQAAAG4AAOYuAADmLgAAAGMAAOYvAADmLwAAAGQAAOYwAADmMAAAAGIAAOYyAADmMgAAADQAAOYzAADmMwAAAC0AAOY0AADmNAAAAC4AAOY2AADmNgAAAC8AAOY3AADmNwAAADAAAOY5AADmOQAAADEAAOY6AADmOgAAADIAAOZVAADmVQAAADUAAOZWAADmVgAAADoAAOZXAADmVwAAADcAAOZYAADmWAAAADgAAOZZAADmWQAAAD0AAOZaAADmWgAAAF4AAOZbAADmWwAAAF8AAOZcAADmXAAAAGAAAOZdAADmXQAAAGEAAOZeAADmXgAAADYAAOZfAADmXwAAADsAAOZgAADmYAAAADwAAOZhAADmYQAAADkAAOZiAADmYgAAAD4AAOZjAADmYwAAAD8AAOZkAADmZAAAAEAAAOZlAADmZQAAAEEAAOZmAADmZgAAAEIAAOZnAADmZwAAAEMAAOZoAADmaAAAAEQAAOZpAADmaQAAAEUAAOZqAADmagAAAEYAAOZrAADmawAAAEcAAOZsAADmbAAAAEgAAOZtAADmbQAAAEkAAOZuAADmbgAAAEoAAOZvAADmbwAAAEsAAOZwAADmcAAAAEwAAOZxAADmcQAAAE0AAOZyAADmcgAAAE4AAOZzAADmcwAAAE8AAOZ0AADmdAAAAFAAAOZ1AADmdQAAAFEAAOZ2AADmdgAAAFIAAOZ3AADmdwAAAFMAAOZ4AADmeAAAAFQAAOZ5AADmeQAAAFUAAOZ6AADmegAAAFYAAOZ7AADmewAAAFcAAOZ8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AV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFzAXQBdQF2AXcBeAF5AXoBewF8AX0BfgF/AYABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+AAlzLW1vcmUtbzEIcy1kZWxldGUIcy1iYWNrLW8Gcy1zY2FuEHMtb3JnYW5pemF0aW9uLW8Jcy1ncm91cC1vCXMtZmlsdGVyMQlzLWNsZWFyLW8Ocy1pbGx1c3RyYXRlLW8Icy1tb21lbnQIcy1zaG9wLW8Kcy1tb21lbnQtbwZzLXNob3AKcy1yZXZva2UtbwpzLXN1Ym1pdC1vB3MtYXBwLW8Gcy1ib29rBXMtYXBwBHMtbXkJcy1jb21tZW50C3MtY29tbWVudC1vCHMtYm9vay1vBnMtbXktbwxzLWxvY2F0aW9uLW8Kcy1sb2NhdGlvbgZzLW5ld3MIcy1uZXdzLW8Jcy1TZW5kaW5nCnMtSW1wb3J0LW8Icy1FZGl0LW8Icy1RUmNvZGULcy1CcmllZmNhc2URcy1Ob3RpZmljYXRpb25vZmYIcy1QZW5jaWwIcy1TdGFyLW8Jcy1CYXJDb2RlD3MtU2FsZU1lc3NhZ2UtbwxzLUxpc3R2aWV3LW8Lcy1QaWN0dXJlLW8Ocy1TYXZlRmlsbGV0LW8Ocy1TaG9wcGluZ2NhcnQJcy1QZW5kaW5nDnMtRXhwYW5kdmlldy1vCHMtTG9jay1vCXMtU2VydmljZQpzLVdhbGxldC1vEHMtU2hvcHBpbmdjYXJ0LW8Lcy1TZXR0aW5nLW8Ncy1VbmZvbGRSZWMtbwlzLVByb2ZpbGUGTGluay1vDVVzZXJTZXR0aW5nLW8Jcy1hZ3JlZS1vDHMtYXJyb3ctZG93bgdzLWFkZC1vB3MtYW5uZXgMcy1hcnJvdy1sZWZ0CnMtYXJyb3ctdXAScy1jaGVja2JveC1jaGVja2VkCnMtY2hlY2tib3gHcy1hcnJvdwpzLWV4Y2hhbmdlB3MtY2xlYXIJcy1jaGVja2VkB3MtZXllLW8Lcy1jbG9zZS1leWUEcy1hdAxzLWZlZWRiYWNrLW8Pcy1mb2xkLWNpcmNsZS1vB3MtY3Jvc3MHcy1taW51cwZzLWZpbGUPcy1mb2xkLXRyaWFuZ2xlCHMtZmlsdGVyCXMtZm9yd29yZAZzLXBsdXMJcy1maWxlZGVsCHMtZm9sZC1vCXMtaW1hZ2UtbwhzLW1vcmUtbw5zLXJlZGlvLWNpcmNsZQpzLXJlamVjdC1vCXMtc3VjY2VzcwlzLXJlZnJlc2gGcy1zdGFyDXMtcHJvY2Vzc2Zsb3cRcy11bmZvbGQtY2lyY2xlLW8Icy1yZXdpbmQKcy11bmZvbGQtbwtzLXdhcm5pbmctbxFzLXVuZm9sZC10cmlhbmdsZQlzLXByaW50LW8Kcy1zZWFyY2gtbwhBaXJwbGFuZQVUcmFpbgNCdXMEVGF4aQxvdmVydGltZW1lYWwTZm0taS10cmFmZmljZGV0YWlscw9mbS1pLXRyYWZmaWNzdWITZm0taS1hY2NvbW1vZGF0aW9uMQ1mbS1pLWJ1c2luZXNzC2ZtLWktYnVkZ2V0CWZtLWktZ2lmdBFmbS1pLWNhbmNlbGxhdGlvbgxmbS1pLWludm9pY2UJZm0taS1saXN0CmZtLWktbWVhbHMIZm0taS1wYXkMZm0taS1zdWJzaWR5B3Nob3V6aGUTZm0taS1jb3N0YWxsb2NhdGlvbgxmbS1pLXBheW1lbnQOZm0taS1JdGluZXJhcnkOZm0taS1tb3JleGUwMmQPZm0taS1pbWFnZXhlMDJlEGZtLWktcmVqZWN0eGUwMmYPZm0taS1hZ3JlZXhlMDMxDWZtLWktY2FyZGZvbGQPZm0taS1jYXJkdW5mb2xkEWZtLWktdHJhZmZpY290aGVyD2ZtLWktYm90dG9tc2F2ZRBmbS1pLXRyYWZmaWNib2F0D2ZtLWktdHJhZmZpY2NhchFmbS1pLXRyYWZmaWNwbGFuZRFmbS1pLXRyYWZmaWN0cmFpbg9mbS1pLXRyYWZmaWNidXMMZm0taS1hZGRncmF5CmZtLWktY2xvc2UIZm0taS1hZGQJZm0taS1tb3JlCmZtLWktY2hlY2sPZm0taS1iYWNrY2lyY2xlCmZtLWktYWdyZWUMZm0taS1sb2FkaW5nDGZtLWktZmlsZWRlbAlmbS1pLWZpbGUQZm0taS1wcm9jZXNzZmxvdwxmbS1pLXJlZHN0YXIQZm0taS1yaWdodGNpcmNsZQ9mbS1pLXRpbWVjaXJjbGUOZm0taS1zY3JlZW5pbmcMZm0taS11bmNoZWNrDmZtLWktb3BlcmF0aW9uE2ZtLWktYXBwcm92YWxhbW91bnQLZm0taS1hZ3JlZWQOZm0taS1pbnByb2Nlc3MNZm0taS1mZWVkYmFjawpmbS1pLXByaW50DmZtLWktaW1wb3J0YW50GmZtLWktYW1vdW50b2ZyZWltYnVyc2VtZW50FGZtLWktc2FmZXR5YXNzaXN0YW50C2ZtLWktcmVtaW5kDWZtLWktZXllb3BwZW4NZm0taS1leWVjbG9zZRBmbS1pLVBob3RvZ3JhcGh5D2ZtLWktcGhvdG9ncmFwaA9mbS1pLWFkZHBpY3R1cmUTZm0taS10b3Bfb3RoZXItZmFjZQ5mbS1pLXRvcF9vdGhlcgtmbS1pLWRlbGV0ZQ1mbS1pLW5leHRwYWdlDmZtLWktYWRkYnV0dG9uFmZtLWktd2FpdGZvcnByb2Nlc3NpbmcTZm0taS13YXJuaW5nbWVzc2FnZRJmbS1pLWZhaWx1cmVwcm9tcHQUZm0taS1zdWNjZXNzZnVsaGludHMKZm0taS1vdGhlcgxmbS1pLXJldHJhY3QOZm0taS1kcm9wLWRvd24LZm0taS1jYW5jZWwLZm0taS1zZWFyY2gTZm0taS1tdWx0aXBsZWNob2ljZRFmbS1pLXNpbmdsZWNob2ljZQ9mbS1pLW1pY3JvcGhvbmUXZm0taS1hcnJvdy1jaGV2cm9uLWxlZnQPZm0taS1oZWxwY2VudGVyDmZtLWktc3dlZXBjb2RlDmZtLWktZ3JvdXBjaGF0DmZtLWktYWRkZnJpZW5kC2ZtLWktdG9wX215EGZtLWktdG9wX215LWZhY2UPZm0taS10b3BfZnJpZW5kFGZtLWktdG9wX2ZyaWVuZC1mYWNlFWZtLWktdG9wX3B1YmxpY3ByYWlzZRpmbS1pLXRvcF9wdWJsaWNwcmFpc2UtZmFjZQ1mbS1pLXRvcF9ob21lEmZtLWktdG9wX2hvbWUtZmFjZQAAAAA=) format("truetype")}@keyframes fm-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fm-fade-out{0%{opacity:1}to{opacity:0}}.fm-fade-enter-active{animation:.3s fm-fade-in both ease-out}.fm-fade-leave-active{animation:.3s fm-fade-out both ease-in}.fm-slide-up-enter-from,.fm-slide-up-leave-to{transform:translate3d(0,100%,0)}.fm-slide-down-enter-from,.fm-slide-down-leave-to{transform:translate3d(0,-100%,0)}.fm-slide-left-enter-from,.fm-slide-left-leave-to{transform:translate3d(-100%,0,0)}.fm-slide-right-enter-from,.fm-slide-right-leave-to{transform:translate3d(100%,0,0)}.fm-slide-up-enter-active,.fm-slide-down-enter-active,.fm-slide-left-enter-active,.fm-slide-right-enter-active{transition-timing-function:ease-out}.fm-slide-up-leave-active,.fm-slide-down-leave-active,.fm-slide-left-leave-active,.fm-slide-right-leave-active{transition-timing-function:ease-in}.fm-slide-in-enter-active,.fm-slide-in-leave-active,.fm-slide-out-enter-active,.fm-slide-out-leave-active{will-change:transform;transition:all .3s;height:100%;width:100%;top:0;position:absolute;backface-visibility:hidden;perspective:1000}.fm-slide-in-leave-to,.fm-slide-out-enter-from{transform:translate(-100%);opacity:0}.fm-slide-in-enter-from,.fm-slide-out-leave-to{transform:translate(100%);opacity:0}@keyframes fm-drop-down-in{0%{height:0;opacity:0}to{opacity:1}}@keyframes fm-drop-down-out{0%{opacity:1}to{height:0;opacity:0}}.fm-drop-down-enter-active{animation:.3s fm-drop-down-in both ease-out}.fm-drop-down-leave-active{animation:.3s fm-drop-down-out both ease-in}@keyframes fm-rotate{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}:root{--fm-button-height: 42px;--fm-button-padding: 0 14px;--fm-button-radius: 2px;--fm-button-border-width: 1px;--fm-button-color: var(--fm-white);--fm-button-line-height: var(--fm-line-height);--fm-button-font-size: var(--fm-font-size);--fm-button-plain-background: var(--fm-white);--fm-button-lg-height: 46px;--fm-button-lg-font-size: 18px;--fm-button-md-height: 38px;--fm-button-md-font-size: 14px;--fm-button-sm-height: 34px;--fm-button-sm-padding: 0 8px;--fm-button-sm-font-size: 12px;--fm-button-xs-height: 28px;--fm-button-xs-font-size: 10px;--fm-button-secondary-color: var(--fm-blue-light)}.fm-button{position:relative;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;text-align:center;margin:0;border:none;transition:opacity .2s;color:var(--fm-button-color);height:var(--fm-button-height);padding:var(--fm-button-padding);font-size:var(--fm-button-font-size);line-height:var(--fm-button-line-height);border-radius:var(--fm-button-radius)}.fm-button--primary,.fm-button--info{background:var(--fm-primary-color)}.fm-button--secondary{color:var(--fm-primary-color);background:var(--fm-button-secondary-color)}.fm-button--danger{background-color:var(--fm-danger-color)}.fm-button--warning{background-color:var(--fm-warning-color)}.fm-button--success{background-color:var(--fm-success-color)}.fm-button--plain{box-shadow:none;background:var(--fm-button-plain-background)}.fm-button--plain.fm-button--primary,.fm-button--plain.fm-button--info{color:var(--fm-primary-color);border:var(--fm-button-border-width) solid var(--fm-primary-color)}.fm-button--plain.fm-button--success{color:var(--fm-success-color);border:var(--fm-button-border-width) solid var(--fm-success-color)}.fm-button--plain.fm-button--danger{color:var(--fm-danger-color);border:var(--fm-button-border-width) solid var(--fm-danger-color)}.fm-button--plain.fm-button--warning{color:var(--fm-button-warning-color);border:var(--fm-button-border-width) solid var(--fm-button-warning-color)}.fm-button--noborder{border:none!important}.fm-button--large{height:var(--fm-button-lg-height);font-size:var(--fm-button-lg-font-size)}.fm-button--normal{height:var(--fm-button-md-height);font-size:var(--fm-button-md-font-size)}.fm-button--small{height:var(--fm-button-sm-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-sm-font-size)}.fm-button--mini{height:var(--fm-button-xs-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-xs-font-size)}.fm-button--block{display:flex;width:100%}.fm-button--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-button--loading:before,.fm-button--disabled:before{display:none}.fm-button--round{border-radius:var(--fm-radius-max)}.fm-button--square{border-radius:0}.fm-button__loading{display:inline-block;width:20px;max-width:100%;height:20px;max-height:100%;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-button__loading circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}.fm-button__loading-icon-circular{color:#fff}.fm-button__loading-text{margin-left:6px}.fm-button__icon:not(:last-child){margin-right:6px}.fm-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;background-color:#000;border:inherit;border-color:#000;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;content:" "}.fm-button:active:before{opacity:.1}.fm-button-edit__tags{min-height:24px;flex:1;display:flex;overflow:auto}.fm-button-edit__tag:not(:last-child){margin-right:6px}.fm-button-group{display:flex;padding:8px 16px}.fm-button-group__item{display:flex;flex:1}:root{--fm-cell-padding: 10px 16px;--fm-cell-margin: 5px;--fm-cell-line-height: 24px;--fm-cell-font-size: var(--fm-font-size);--fm-cell-background: var(--fm-background-white);--fm-cell-color: var(--fm-text-color);--fm-cell-label-font-size: 12px;--fm-cell-label-line-height: 18px;--fm-cell-label-color: var(--fm-text-color-light);--fm-cell-required-color: var(--fm-danger-color)}.fm-cell{width:100%;padding:var(--fm-cell-padding);background-color:var(--fm-cell-background);color:var(--fm-cell-color);font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);position:relative;display:flex;overflow:hidden}.fm-cell-bottom-border,.fm-cell:not(:last-child){border-bottom:1px solid #ddd;position:relative}@media (min-resolution: 1dppx){html:not([data-scale]) .fm-cell-bottom-border,html:not([data-scale]) .fm-cell:not(:last-child){border-bottom:none}html:not([data-scale]) .fm-cell-bottom-border:after,html:not([data-scale]) .fm-cell:not(:last-child):after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-cell-bottom-border:after,.fm-cell:not(:last-child):after{left:16px!important}.fm-cell.fm-cell-all-width:not(:last-child):after{left:0!important}.fm-cell--clickable{cursor:pointer}.fm-cell--clickable:active{background-color:var(--fm-active-color)}.fm-cell--required .fm-cell-title{position:relative}.fm-cell--required .fm-cell-title .fm-cell-title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-cell__title,.fm-cell__value{flex:1;font-size:inherit}.fm-cell__title{display:inline-block;overflow:hidden}.fm-cell__title-text{display:flex;word-break:break-all}.fm-cell__title-text span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-cell__right{display:flex;overflow:hidden;flex-direction:column}.fm-cell__right-content{display:flex;flex:1}.fm-cell__right--fill{flex:1}.fm-cell__value{position:relative;overflow:hidden;text-align:right;vertical-align:middle;word-wrap:break-word}.fm-cell__value--alone{text-align:left}.fm-cell__label{margin-top:var(--fm-cell-margin);color:var(--fm-cell-label-color);font-size:var(--fm-cell-label-font-size);line-height:var(--fm-cell-label-line-height)}.fm-cell--center{align-items:center}.fm-cell__extra,.fm-cell__left-icon,.fm-cell__right-icon{min-width:1em;font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);display:flex;align-items:center}.fm-cell__left-icon{margin-right:var(--fm-cell-margin)}.fm-cell__extra,.fm-cell__right-icon{margin-left:var(--fm-cell-margin)}.fm-cell--noborder .fm-cell:after{display:none!important}.fm-cell--card{padding-left:0;padding-right:0}.fm-checkbox-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-checkbox-group--vertical{flex-direction:column}.fm-checkbox-group--vertical .fm-checkbox:not(:last-child){margin-bottom:8px}.fm-checkbox{margin-top:4px;margin-bottom:4px}:root{--fm-checker-color: var(--fm-text-color);--fm-checker-font-size: var(--fm-font-size);--fm-checker-icon-color: var(--fm-text-color-light);--fm-checker-icon-background: var(--fm-background-white);--fm-checker-icon-radius: var(--fm-radius-md);--fm-checker-checked-icon-color: var(--fm-primary-color);--fm-checker-button-background: var(--fm-gray-2);--fm-checker-disabled-color: var(--fm-disabled-color);--fm-checker-disabled-icon-color: var(--fm-gray-1)}.fm-checker{display:flex;align-items:center;color:var(--fm-checker-color);font-size:var(--fm-checker-font-size)}.fm-checker__icon{display:inline-block;align-items:center}.fm-checker__icon .fm-icon{display:block;height:20px;width:20px;line-height:18px;font-size:14px;text-align:center;border-radius:var(--fm-checker-icon-radius);border:1px solid var(--fm-checker-icon-color);color:var(--fm-checker-icon-background);background-color:var(--fm-checker-icon-background)}.fm-checker__label{margin-left:8px;margin-right:8px;display:inline-block;line-height:20px}.fm-checker:first-child .fm-checker_button{margin-left:0}.fm-checker--round .fm-checker__icon .fm-icon{border-radius:100%}.fm-checker--button .fm-checker__label{font-size:13px;text-align:center;border-radius:14px;line-height:28px;padding:0 12px;min-width:60px;margin-right:0;color:var(--fm-checker-color);background:var(--fm-checker-button-background)}.fm-checker--checked .fm-checker__icon .fm-icon{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-checked-icon-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--checked.fm-checker--button .fm-checker__label{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--readonly{opacity:var(--fm-readonly-opacity)}.fm-checker--disabled{color:var(--fm-checker-disabled-color)}.fm-checker--disabled .fm-checker__icon .fm-icon{border-color:var(--fm-checker-disabled-color);background-color:var(--fm-checker-disabled-icon-color);color:var(--fm-checker-disabled-icon-color)}.fm-checker--disabled.fm-checker--checked .fm-checker__icon .fm-icon{background-color:var(--fm-checker-disabled-color);border-color:var(--fm-checker-disabled-color)}:root{--fm-icon-font-size: 14px;--fm-icon-color: inherit}.fm-icon{font-family:farrisMobile!important;font-size:var(--fm-icon-font-size);font-style:normal;color:var(--fm-icon-color);display:inline-block;width:1em;height:1em;font-weight:400;line-height:1;vertical-align:middle;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fm-icon:before{display:inline-block}.fm-icon-filter:before{content:"\e697"}.fm-icon-cardfold:before{content:"\e6b7"}.fm-icon-cardunfold:before{content:"\e6b8"}.fm-icon-trafficother:before{content:"\e6b9"}.fm-icon-bottomsave:before{content:"\e6ba"}.fm-icon-trafficboat:before{content:"\e6bb"}.fm-icon-trafficcar:before{content:"\e6bc"}.fm-icon-trafficplane:before{content:"\e6bd"}.fm-icon-traffictrain:before{content:"\e6be"}.fm-icon-trafficbus:before{content:"\e6bf"}.fm-icon-addgray:before{content:"\e6a7"}.fm-icon-close:before{content:"\e6a8"}.fm-icon-add-line:before{content:"\e6a9"}.fm-icon-more:before{content:"\e6aa"}.fm-icon-check:before{content:"\e6ab"}.fm-icon-backcircle:before{content:"\e6ac"}.fm-icon-agree:before{content:"\e6ad"}.fm-icon-loading:before{content:"\e6ae"}.fm-icon-filedel:before{content:"\e6af"}.fm-icon-file:before{content:"\e6b0"}.fm-icon-processflow:before{content:"\e6b1"}.fm-icon-redstar:before{content:"\e6b2"}.fm-icon-rightcircle:before{content:"\e6b3"}.fm-icon-timecircle:before{content:"\e6b4"}.fm-icon-screening:before{content:"\e6b5"}.fm-icon-uncheck:before{content:"\e6b6"}.fm-icon-operation:before{content:"\e02c"}.fm-icon-approvalamount:before{content:"\e02b"}.fm-icon-agreed:before{content:"\e02a"}.fm-icon-inprocess:before{content:"\e029"}.fm-icon-feedback:before{content:"\e028"}.fm-icon-print:before{content:"\e027"}.fm-icon-important:before{content:"\e026"}.fm-icon-amountofreimbursement:before{content:"\e025"}.fm-icon-safetyassistant:before{content:"\e024"}.fm-icon-remind:before{content:"\e023"}.fm-icon-eyeoppen:before{content:"\e022"}.fm-icon-eyeclose:before{content:"\e01e"}.fm-icon-photography:before{content:"\e021"}.fm-icon-photograph:before{content:"\e020"}.fm-icon-addpicture:before{content:"\e01f"}.fm-icon-top_other-face:before{content:"\e01d"}.fm-icon-top_other:before{content:"\e01c"}.fm-icon-delete:before{content:"\e01b"}.fm-icon-nextpage:before{content:"\e01a"}.fm-icon-addbutton:before{content:"\e019"}.fm-icon-waitforprocessing:before{content:"\e018"}.fm-icon-warningmessage:before{content:"\e017"}.fm-icon-failureprompt:before{content:"\e016"}.fm-icon-successfulhints:before{content:"\e015"}.fm-icon-other:before{content:"\e014"}.fm-icon-retract:before{content:"\e013"}.fm-icon-drop-down:before{content:"\e012"}.fm-icon-cancel:before{content:"\e011"}.fm-icon-search:before{content:"\e010"}.fm-icon-multiplechoice:before{content:"\e00f"}.fm-icon-singlechoice:before{content:"\e00e"}.fm-icon-microphone:before{content:"\e00d"}.fm-icon-arrow-chevron-left:before{content:"\e00c"}.fm-icon-helpcenter:before{content:"\e00b"}.fm-icon-sweepcode:before{content:"\e00a"}.fm-icon-groupchat:before{content:"\e009"}.fm-icon-addfriend:before{content:"\e008"}.fm-icon-top_my:before{content:"\e007"}.fm-icon-top_my-face:before{content:"\e006"}.fm-icon-top_friend:before{content:"\e005"}.fm-icon-top_friend-face:before{content:"\e004"}.fm-icon-top_publicpraise:before{content:"\e003"}.fm-icon-top_publicpraise-face:before{content:"\e002"}.fm-icon-top_home:before{content:"\e001"}.fm-icon-top_home-face:before{content:"\e000"}.fm-icon-s-agree-o:before{content:"\e655"}.fm-icon-s-arrow-down:before{content:"\e656"}.fm-icon-s-add-o:before{content:"\e657"}.fm-icon-s-annex:before{content:"\e658"}.fm-icon-s-arrow:before{content:"\e659"}.fm-icon-s-arrow-up:before{content:"\e65e"}.fm-icon-s-checkbox-checked:before{content:"\e65f"}.fm-icon-s-checkbox:before{content:"\e660"}.fm-icon-s-arrow-left:before{content:"\e661"}.fm-icon-s-exchange:before{content:"\e662"}.fm-icon-s-clear:before{content:"\e663"}.fm-icon-s-checked:before{content:"\e664"}.fm-icon-s-eye-o:before{content:"\e665"}.fm-icon-s-close-eye:before{content:"\e666"}.fm-icon-s-at:before{content:"\e667"}.fm-icon-s-feedback-o:before{content:"\e668"}.fm-icon-s-fold-circle-o:before{content:"\e669"}.fm-icon-s-cross:before{content:"\e66a"}.fm-icon-s-minus:before{content:"\e66b"}.fm-icon-s-file:before{content:"\e66c"}.fm-icon-s-fold-triangle:before{content:"\e66d"}.fm-icon-s-filter:before{content:"\e66e"}.fm-icon-s-forword:before{content:"\e66f"}.fm-icon-s-plus:before{content:"\e670"}.fm-icon-s-filedel:before{content:"\e671"}.fm-icon-s-fold-o:before{content:"\e672"}.fm-icon-s-image-o:before{content:"\e673"}.fm-icon-s-more-o:before{content:"\e674"}.fm-icon-s-redio-circle:before{content:"\e675"}.fm-icon-s-reject-o:before{content:"\e676"}.fm-icon-s-success:before{content:"\e677"}.fm-icon-s-refresh:before{content:"\e678"}.fm-icon-s-star:before{content:"\e679"}.fm-icon-s-processflow:before{content:"\e67a"}.fm-icon-s-unfold-circle-o:before{content:"\e67b"}.fm-icon-s-rewind:before{content:"\e67c"}.fm-icon-s-unfold-o:before{content:"\e67d"}.fm-icon-s-save-o:before{content:"\e67e"}.fm-icon-s-warning-o:before{content:"\e67f"}.fm-icon-s-unfold-triangle:before{content:"\e680"}.fm-icon-s-print-o:before{content:"\e681"}.fm-icon-s-search-o:before{content:"\e682"}.fm-icon-s-news:before{content:"\e683"}.fm-icon-s-news-o:before{content:"\e684"}.fm-icon-s-shop:before{content:"\e68c"}.fm-icon-s-sending:before{content:"\e60b"}.fm-icon-s-import-o:before{content:"\e60c"}.fm-icon-s-edit-o:before{content:"\e60d"}.fm-icon-s-qrcode:before{content:"\e60e"}.fm-icon-s-briefcase:before{content:"\e60f"}.fm-icon-s-notificationoff:before{content:"\e610"}.fm-icon-s-pencil:before{content:"\e611"}.fm-icon-s-star-o:before{content:"\e612"}.fm-icon-s-barcode:before{content:"\e613"}.fm-icon-s-salemessage-o:before{content:"\e614"}.fm-icon-s-listview-o:before{content:"\e615"}.fm-icon-s-picture-o:before{content:"\e616"}.fm-icon-s-savefillet-o:before{content:"\e617"}.fm-icon-s-shoppingcart:before{content:"\e618"}.fm-icon-s-pending:before{content:"\e61d"}.fm-icon-s-expandview-o:before{content:"\e61e"}.fm-icon-s-lock-o:before{content:"\e623"}.fm-icon-s-my:before{content:"\e692"}.fm-icon-s-service:before{content:"\e633"}.fm-icon-s-wallet-o:before{content:"\e634"}.fm-icon-s-shoppingcart-o:before{content:"\e636"}.fm-icon-s-setting-o:before{content:"\e637"}.fm-icon-s-my-o:before{content:"\e696"}.fm-icon-s-unfoldrec-o:before{content:"\e639"}.fm-icon-s-profile:before{content:"\e63a"}.fm-icon-s-link-o:before{content:"\e609"}.fm-icon-s-usersetting-o:before{content:"\e632"}.fm-icon-s-shop-o:before{content:"\e68a"}.fm-icon-s-list:before{content:"\e62a"}.fm-icon-s-location-o:before{content:"\e685"}.fm-icon-s-location:before{content:"\e686"}.fm-icon-s-moment:before{content:"\e689"}.fm-icon-s-moment-o:before{content:"\e68b"}.fm-icon-s-revoke-o:before{content:"\e687"}.fm-icon-s-submit-o:before{content:"\e688"}.fm-icon-s-app-o:before{content:"\e68f"}.fm-icon-s-app:before{content:"\e691"}.fm-icon-s-book-o:before{content:"\e695"}.fm-icon-s-book:before{content:"\e690"}.fm-icon-s-comment:before{content:"\e693"}.fm-icon-s-comment-o:before{content:"\e694"}.fm-icon-s-illustrate-o:before{content:"\e68d"}.fm-icon-s-clear-o:before{content:"\e68e"}.fm-icon-friend:before{content:"\e005"}.fm-icon-scan:before{content:"\e69a"}.fm-icon-back:before{content:"\e69b"}.fm-icon-menu:before{content:"\e69d"}:root{--fm-navbar-background: var(--fm-background-white);--fm-navbar-color: var(--fm-text-color);--fm-navbar-height: 44px;--fm-navbar-title-size: 17px;--fm-navbar-side-size: 16px;--fm-navbar-arrow-size: 18px}.fm-navbar{position:relative;z-index:9;display:flex;align-items:center;line-height:1.5;text-align:center;user-select:none;height:var(--fm-navbar-height);color:var(--fm-navbar-color);background-color:var(--fm-navbar-background)}.fm-navbar.fm-navbar-fixed{position:fixed;top:0;left:0;width:100%}.fm-navbar.fm-navbar-border-bottom{border-bottom:1px solid #eee;position:relative}@media (min-resolution: 1dppx){html:not([data-scale]) .fm-navbar.fm-navbar-border-bottom{border-bottom:none}html:not([data-scale]) .fm-navbar.fm-navbar-border-bottom:after{content:"";position:absolute;background-color:#eee;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-navbar-title{max-width:60%;margin:0 auto;font-weight:500;font-size:var(--fm-navbar-title-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-navbar-left,.fm-navbar-right{position:absolute;top:0;bottom:0;display:flex;align-items:center;max-width:30%;padding:0 16px;font-size:var(--fm-navbar-side-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;cursor:pointer}.fm-navbar-left{left:0}.fm-navbar-left:active{opacity:var(--fm-active-opacity)}.fm-navbar-left.fm-navbar-left-padding{padding-left:14px}.fm-navbar-right{right:0}.fm-navbar-right .fm-navbar-text:active{opacity:var(--fm-active-opacity)}.fm-navbar .fm-navbar-left-arrow{min-width:1em;margin-right:4px;font-size:var(--fm-navbar-arrow-size)}:root{--fm-input-group-size: var(--fm-font-size);--fm-input-group-color: var(--fm-text-color);--fm-input-group-sub-size: 13px;--fm-input-group-padding: 10px 16px;--fm-input-group-sub-color: var(--fm-text-color-light);--fm-input-group-border-color: var(--fm-gray-2)}.fm-input-group{display:flex;flex-direction:column;background-color:var(--fm-white)}.fm-input-group--padding{padding:var(--fm-input-group-padding)}.fm-input-group__body{flex:1;display:flex;align-items:center;min-height:24px}.fm-input-group__body--border{border:1px solid var(--fm-input-group-border-color);padding:4px 8px;border-radius:4px}.fm-input-group__control{display:flex;width:100%;min-width:0;margin:0;padding:0;border:0;resize:none;line-height:inherit;background-color:transparent;color:var(--fm-input-group-color);font-size:var(--fm-input-group-size);outline:none}.fm-input-group__control::placeholder{color:var(--fm-input-group-sub-color)}.fm-input-group__control:disabled{opacity:1;cursor:not-allowed;color:var(--fm-disabled-color);-webkit-text-fill-color:currentColor}.fm-input-group__control::-webkit-search-cancel-button{display:none}.fm-input-group__control--readonly{cursor:default;color:var(--fm-readonly-color)}.fm-input-group__control--left{justify-content:flex-start;text-align:left}.fm-input-group__control--center{justify-content:center;text-align:center}.fm-input-group__control--right{justify-content:flex-end;text-align:right}.fm-input-group__clear{cursor:pointer;margin-right:-8px;padding:4px 8px;color:var(--fm-input-group-sub-color);flex-shrink:0;box-sizing:content-box}.fm-input-group__left-icon{margin:auto 4px auto 0}.fm-input-group__right-icon{margin:auto 0 auto 4px}.fm-input-group__word-limit{margin-top:4px;line-height:18px;text-align:right;font-size:var(--fm-input-group-sub-size);color:var(--fm-input-group-sub-color)}.fm-radio-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-radio-group--vertical{flex-direction:column}.fm-radio-group--vertical .fm-radio:not(:last-child){margin-bottom:8px}.fm-radio{margin-top:4px;margin-bottom:4px}:root,:host{--fm-rate-icon-size: 20px;--fm-rate-icon-gutter: var(--fm-padding-base);--fm-rate-icon-void-color: var(--fm-gray-4);--fm-rate-icon-full-color: var(--fm-orange-3);--fm-rate-icon-disabled-color: var(--fm-gray-4)}.fm-rate{display:inline-flex;cursor:pointer;user-select:none;flex-wrap:wrap}.fm-rate__item{position:relative}.fm-rate__item:not(:last-child){padding-right:var(--fm-rate-icon-gutter)}.fm-rate__icon{display:block;width:1em;color:var(--fm-rate-icon-void-color);font-size:var(--fm-rate-icon-size)}.fm-rate__icon--half{position:absolute;top:0;left:0;overflow:hidden;pointer-events:none;color:var(--fm-rate-icon-full-color)}.fm-rate__icon--full{color:var(--fm-rate-icon-full-color)}.fm-rate__icon--disabled{color:var(--fm-rate-icon-disabled-color)}.fm-rate--disabled{cursor:not-allowed}.fm-rate--readonly{cursor:default}:root{--fm-form-item-size: var(--fm-font-size);--fm-form-item-color: var(--fm-text-color);--fm-form-item-label-width: 105px;--fm-form-item-sub-size: 13px}.fm-form-item{font-size:var(--fm-form-item-size);color:var(--fm-form-item-color)}.fm-form-item--vertical{flex-direction:column}.fm-form-item--vertical .fm-form-item__label{margin-bottom:4px}.fm-form-item__label{display:flex;flex:none;align-items:flex-start;text-align:left;width:var(--fm-form-item-label-width);margin-right:4px}.fm-form-item__label--left{justify-content:flex-start}.fm-form-item__label--center{justify-content:center}.fm-form-item__label--right{justify-content:flex-end}.fm-form-item__label--required{position:relative}.fm-form-item__label--required .fm-cell__title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-form-item__content{display:flex}.fm-form-item__content .fm-input-group{padding:0;flex:1}.fm-form-item__content--left{justify-content:flex-start}.fm-form-item__content--left input.fm-input-group__control{justify-content:flex-start;text-align:left}.fm-form-item__content--center{justify-content:center}.fm-form-item__content--center input.fm-input-group__control{justify-content:flex-center;text-align:center}.fm-form-item__content--right{justify-content:flex-end}.fm-form-item__content--right input.fm-input-group__control{justify-content:flex-end;text-align:right}.fm-form-item__error-message{color:var(--fm-danger-color);font-size:var(--fm-form-item-sub-size)}.fm-form-item__error-message--left{text-align:left}.fm-form-item__error-message--center{text-align:center}.fm-form-item__error-message--right{text-align:right}.fm-form{display:flex;flex-direction:column}.fm-form .farris-component.can-move{padding:0!important}.fm-input-wrapper:not(:last-child) .fm-cell:not(.fm-no-hairline):after,.fm-form-item-wrapper:not(:last-child):not(.fm-no-hairline):after,.fm-form-designer-item-wrapper:not(:last-child) .fm-form-item-wrapper:not(.fm-no-hairline):after{transform:scaleY(.5)}:root{--fm-overlay-background: rgba(0, 0, 0, .4);--fm-overlay-zindex: 98}.fm-overlay{width:100%;position:fixed;top:0;left:0;z-index:var(--fm-overlay-zindex);background-color:var(--fm-overlay-background);bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-overlay{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}:root{--fm-popup-background: var(--fm-white);--fm-popup-zindex: var(--fm-zindex-3);--fm-popup-radius: 16px}.fm-popup{position:fixed;max-height:100%;overflow-y:auto;background-color:var(--fm-popup-background);transition:all var(--fm-duration-base);z-index:var(--fm-popup-zindex)}.fm-popup--center{top:50%;left:50%;transform:translate(-50%,-50%)}.fm-popup--center.fm-popup--round{border-radius:var(--fm-popup-radius)}.fm-popup--top,.fm-popup--bottom{left:0;right:0}.fm-popup--top{top:0}.fm-popup--top.fm-popup--round{border-radius:0 0 var(--fm-popup-radius) var(--fm-popup-radius)}.fm-popup--bottom{bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--bottom{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--bottom.fm-popup--round{border-radius:var(--fm-popup-radius) var(--fm-popup-radius) 0 0}.fm-popup--left,.fm-popup--right{top:0;bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--left,.fm-popup--right{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--left{left:0}.fm-popup--left.fm-popup--round{border-radius:0 var(--fm-popup-radius) var(--fm-popup-radius) 0}.fm-popup--right{right:0}.fm-popup--right.fm-popup--round{border-radius:var(--fm-popup-radius) 0 0 var(--fm-popup-radius)}:root{--fm-switch-background: var(--fm-text-color-light);--fm-switch-on-color: var(--fm-primary-color)}.fm-switch{position:relative;cursor:pointer;display:inline-block;transition:background-color var(--fm-duration-base);background-color:var(--fm-switch-background)}.fm-switch--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-switch--readonly{cursor:default;opacity:var(--fm-readonly-opacity)}.fm-switch--loading{cursor:default}.fm-switch--on{background-color:var(--fm-switch-on-color)}.fm-switch--on .fm-switch__loadding{color:var(--fm-switch-on-color)}.fm-switch__node{display:flex;align-items:center;justify-content:center;position:absolute;top:1px;left:1px;z-index:1;width:28px;height:28px;border-radius:100%;background-color:var(--fm-white);transition:transform var(--fm-duration-base) cubic-bezier(.3,1.05,.4,1.05)}:root{--fm-toast-zindex: var(--fm-zindex-5);--fm-toast-color: var(--fm-white);--fm-toast-font-size: 16px;--fm-toast-background: var(--fm-gray-7);--fm-toast-icon-font-size: 48px}.fm-toast{position:fixed;top:50%;left:50%;display:-webkit-box;display:-webkit-flex;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:content-box;max-width:70%;padding:16px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;border-radius:7px;transform:translate(-50%,-50%);color:var(--fm-toast-color);z-index:var(--fm-toast-zindex);font-size:var(--fm-toast-font-size);background-color:var(--fm-toast-background)}.fm-toast--top{top:50px;transform:translate(-50%)}.fm-toast--bottom{top:auto;bottom:50px}.fm-toast--info,.fm-toast--success,.fm-toast--warning,.fm-toast--error{width:88px;min-height:88px}.fm-toast__icon-wrapper{margin-bottom:8px}.fm-toast--default{padding:8px 16px}.fm-toast--loading{min-width:84px;min-height:84px}.fm-toast--loading-icon{position:relative;display:inline-block;width:30px;height:30px;margin-bottom:8px;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-toast--loading-icon circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}:root{--fm-notify-color: var(--fm-white);--fm-notify-zindex: var(--fm-zindex-5);--fm-notify-info-background: var(--fm-primary-color);--fm-notify-success-background: var(--fm-success-color);--fm-notify-warning-background: var(--fm-warning-color);--fm-notify-error-background: var(--fm-danger-color)}.fm-notify{position:fixed;left:0;top:0;z-index:var(--fm-notify-zindex);display:flex;align-items:center;justify-content:center;width:100%;max-height:100%;padding:8px 16px;box-sizing:border-box;color:var(--fm-notify-color);font-size:14px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;overflow-y:auto}.fm-notify--info{background-color:var(--fm-notify-info-background)}.fm-notify--success{background-color:var(--fm-notify-success-background)}.fm-notify--warning{background-color:var(--fm-notify-warning-background)}.fm-notify--error{background-color:var(--fm-notify-error-background)}:root{--fm-dialog-background: var(--fm-background-2);--fm-dialog-padding-top: 24px;--fm-dialog-padding-left: 16px;--fm-dialog-header-font-size: 17px;--fm-dialog-header-line-height: 24px;--fm-dialog-content-font-size: 15px;--fm-dialog-content-line-height: 20px;--fm-dialog-footer-height: 50px;--fm-border-color: var(--fm-gray-4)}@media screen and (min-width: 375px){.fm-dialog{width:320px}}@media screen and (min-width: 280px) and (max-width: 375px){.fm-dialog{width:240px}}.fm-dialog{display:flex;flex-direction:column;background-color:var(--fm-dialog-background);overflow:hidden}.fm-dialog__header{padding-top:var(--fm-dialog-padding-top);padding-left:var(--fm-dialog-header-padding-left);padding-right:var(--fm-dialog-header-padding-left);font-weight:var(--fm-font-bold-light);font-size:var(--fm-dialog-header-font-size);color:var(--fm-text-color);line-height:var(--fm-dialog-header-line-height);text-align:center}.fm-dialog__content{max-height:70vh;overflow-y:auto}.fm-dialog__content__message{padding:var(--fm-dialog-padding-top) var(--fm-dialog-padding-left);font-size:var(--fm-dialog-content-font-size);line-height:var(--fm-dialog-content-line-height);white-space:pre-wrap;text-align:center;word-wrap:break-word}.fm-dialog__content__message--has-title{padding-top:11px;color:var(--fm-text-color-light)}.fm-dialog__content--prompt{padding:14px}.fm-dialog__content--prompt__input{display:block}.fm-dialog__footer{display:flex;flex-direction:row;align-items:center;border-top:1px solid var(--fm-border-color);position:relative}@media (min-resolution: 1dppx){html:not([data-scale]) .fm-dialog__footer{border-top:none}html:not([data-scale]) .fm-dialog__footer:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}}.fm-dialog__footer .fm-button{border:0;height:var(--fm-dialog-footer-height);border-right:1px solid var(--fm-border-color);position:relative}@media (min-resolution: 1dppx){html:not([data-scale]) .fm-dialog__footer .fm-button{border-right:none}html:not([data-scale]) .fm-dialog__footer .fm-button:after{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 0 auto auto;width:1px;height:100%;background:var(--fm-border-color);transform-origin:100% 50%;transform:scaleX(.5)}}.fm-dialog__footer .fm-button:last-child{border-right:0}.fm-dialog__footer .fm-button:last-child:after{display:none!important}.fm-dialog__footer .fm-button--default{color:var(--fm-text-color)}.fm-dialog__footer--is-column{flex-direction:column}.fm-dialog__footer--is-column__button{border-top:1px solid var(--fm-border-color);position:relative}@media (min-resolution: 1dppx){html:not([data-scale]) .fm-dialog__footer--is-column__button{border-top:none}html:not([data-scale]) .fm-dialog__footer--is-column__button:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}}.fm-dialog__footer--is-column__button:first-child{border-top:0}.fm-dialog__footer--is-column__button:first-child:before{display:none!important}.fm-dialog.fm-dialog--relative{position:relative}.fm-dialog.fm-dialog--relative__header{padding-right:40px}.fm-dialog__close{position:absolute;right:16px;top:16px;width:22px;height:22px;line-height:22px;text-align:center}.fm-dialog__close .fm-icon{font-size:15px;color:var(--fm-text-color-2)}:root,:host{--fm-loading-color: var(--fm-gray-5);--fm-loading-text-font-size: 14px;--fm-loading-text-line-height: 1.4}.fm-loading{display:flex;align-items:center;position:relative;color:var(--fm-loading-color)}.fm-loading__text{color:var(--fm-loading-color);font-size:var(--fm-loading-text-font-size);line-height:var(--fm-loading-text-line-height);margin-left:var(--fm-margin-xs)}.fm-loading--vertical{flex-direction:column}.fm-loading--vertical .fm-loading__text{margin-top:var(--fm-margin-xs);margin-left:0}.fm-loading__circular{display:block;animation:fm-rotate 2s linear infinite}.fm-loading__circular circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:3;stroke-linecap:round}.fm-loading__spinner{display:block;position:relative;animation:fm-rotate 1s linear infinite;animation-timing-function:steps(12)}.fm-loading__line{position:absolute;top:0;left:0;width:100%;height:100%}.fm-loading__line-inner{display:block;width:2px;height:25%;margin:0 auto;background-color:currentColor;border-radius:40%}.fm-loading__ring{display:block;animation:fm-rotate .75s linear infinite;border:4px solid;border-right-color:transparent;border-radius:50%}@keyframes fm-circular{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40}to{stroke-dasharray:90,150;stroke-dashoffset:-120}}.fm-loading__line--1{transform:rotate(30deg);opacity:1}.fm-loading__line--2{transform:rotate(60deg);opacity:.9375}.fm-loading__line--3{transform:rotate(90deg);opacity:.875}.fm-loading__line--4{transform:rotate(120deg);opacity:.8125}.fm-loading__line--5{transform:rotate(150deg);opacity:.75}.fm-loading__line--6{transform:rotate(180deg);opacity:.6875}.fm-loading__line--7{transform:rotate(210deg);opacity:.625}.fm-loading__line--8{transform:rotate(240deg);opacity:.5625}.fm-loading__line--9{transform:rotate(270deg);opacity:.5}.fm-loading__line--10{transform:rotate(300deg);opacity:.4375}.fm-loading__line--11{transform:rotate(330deg);opacity:.375}.fm-loading__line--12{transform:rotate(360deg);opacity:.3125}:root,:host{--fm-pull-refresh-head-height: 50px;--fm-pull-refresh-head-font-size: var(--fm-font-size-md);--fm-pull-refresh-head-text-color: var(--fm-text-color-light);--fm-pull-refresh-animation-duration: .3s}.fm-pull-refresh{overflow:hidden}.fm-pull-refresh__track{position:relative;height:100%}.fm-pull-refresh__track--not-pulling{transition:transform ease var(--fm-pull-refresh-animation-duration)}.fm-pull-refresh__head{position:absolute;left:0;width:100%;height:var(--fm-pull-refresh-head-height);color:var(--fm-pull-refresh-head-text-color);font-size:var(--fm-pull-refresh-head-font-size);line-height:var(--fm-pull-refresh-head-height);text-align:center;transform:translateY(-100%);display:flex;justify-content:center;align-items:center;flex-direction:column;overflow:hidden}:root,:host{--fm-list-text-color: var(--fm-gray-5);--fm-list-text-font-size: var(--fm-font-size-md, 14px);--fm-list-text-line-height: 50px;--fm-list-loading-icon-size: 16px}.fm-list__loading,.fm-list__error,.fm-list__load-more,.fm-list__finished-info{color:var(--fm-list-text-color);font-size:var(--fm-list-text-font-size);line-height:var(--fm-list-text-line-height);text-align:center}.fm-list__loading-container{display:flex;height:var(--fm-list-text-line-height);justify-content:center;align-items:center}:root,:host{--fm-listview-checkbox-container-width: 40px;--fm-listview-toolbar-height: 42px;--fm-listview-split-line-color: rgb(230, 235, 235);--fm-listview-empty-text-color: var(--fm-gray-5);--fm-listview-empty-text-font-size: var(--fm-font-size-md, 14px);--fm-listview-empty-text-line-height: 50px}.fm-list-view--fill{height:100%;flex-grow:1;flex-shrink:1;display:flex;flex-direction:column;overflow:hidden}.fm-list-view--fill .fm-list-view__track{flex:1 1 0;overflow:auto;-webkit-overflow-scrolling:touch}.fm-list-view--fill .fm-pull-refresh{min-height:100%}.fm-list-view .fm-list{user-select:none;-webkit-user-select:none}.fm-list-view__item{display:flex;position:relative;overflow:hidden}.fm-list-view__item-checker{display:flex;position:absolute;height:100%;width:var(--fm-listview-checkbox-container-width);justify-content:center;align-items:center}.fm-list-view__item-content{flex:1;transform:translate(0)}.fm-list-view__content--split .fm-list-view__item:not(:last-child):not(.fm-list-view__item--child){border-bottom:1px solid var(--fm-listview-split-line-color)}.fm-list-view--multi-select .fm-list-view__item-content{transform:translate(var(--fm-listview-checkbox-container-width))}.fm-list-view__item--group{display:block}.fm-list-view__item-group-header{padding:10px 16px;line-height:20px;font-size:var(--fm-font-size-md);color:var(--fm-gray-5)}.fm-list-view__empty-message{display:block;color:var(--fm-listview-empty-text-color);font-size:var(--fm-listview-empty-text-font-size);line-height:var(--fm-listview-empty-text-line-height);text-align:center}.fm-list-view__item-text{padding:13px 20px;color:var(--fm-gray-7);font-size:var(--fm-font-size)}.fm-list-view__toolbar{display:flex;align-items:center;height:var(--fm-listview-toolbar-height)}.fm-list-view__toolbar-item{flex:1}:root,:host{--fm-swipe-cell-button-text-color: var(--fm-white);--fm-swipe-cell-button-bg-color: var(--fm-gray-4);--fm-swipe-cell-button-font-size: var(--fm-font-size);--fm-swipe-cell-button-icon-size: var(--fm-font-size);--fm-swipe-cell-button-padding: var(--fm-padding-md)}.fm-swipe-cell{position:relative;overflow:hidden}.fm-swipe-cell__wrapper{transition-timing-function:cubic-bezier(.18,.89,.32,1);transition-property:transform}.fm-swipe-cell__left,.fm-swipe-cell__right{position:absolute;top:0;height:100%;display:flex}.fm-swipe-cell__left{left:0;transform:translate3d(-100%,0,0);flex-direction:row-reverse}.fm-swipe-cell__right{right:0;transform:translate3d(100%,0,0)}.fm-swipe-cell__button{display:inline-flex;justify-content:center;align-items:center;height:100%;padding:0 var(--fm-swipe-cell-button-padding);color:var(--fm-swipe-cell-button-text-color);background-color:var(--fm-swipe-cell-button-bg-color)}.fm-swipe-cell__icon{font-size:var(--fm-swipe-cell-button-icon-size)}.fm-swipe-cell__text{font-size:var(--fm-swipe-cell-button-font-size)}.fm-swipe-cell__icon+.fm-swipe-cell__text:not(:empty){margin-left:6px}:root,:host{--fm-action-sheet-max-height: 80%;--fm-action-sheet-border-radius: 12px;--fm-action-sheet-description-color: var(--fm-gray-5);--fm-action-sheet-description-line-height: 22px;--fm-action-sheet-description-font-size: var(--fm-font-size-md);--fm-action-sheet-description-padding: 12px 16px;--fm-action-sheet-item-default-background: var(--fm-background-white);--fm-action-sheet-item-active-background: #f2f3f5;--fm-action-sheet-item-padding: 13px 16px;--fm-action-sheet-item-text-color: #1a1a1a;--fm-action-sheet-item-disabled-text-color: #bdbdbd;--fm-action-sheet-item-subtitle-color: var(--fm-gray-5);--fm-action-sheet-item-icon-size: 18px;--fm-action-sheet-item-icon-margin-right: 8px;--fm-action-sheet-item-title-font-size: var(--fm-font-size-lg);--fm-action-sheet-item-title-line-height: 24px;--fm-action-sheet-item-subtitle-font-size: var(--fm-font-size-sm);--fm-action-sheet-item-subtitle-line-height: 18px;--fm-action-sheet-item-subtitle-margin-top: 2px;--fm-action-sheet-footer-gap-color: #f5f5f5;--fm-action-sheet-divider-color: #e7e7e7;--fm-action-sheet-cancel-height: 48px;--fm-action-sheet-cancel-color: #1a1a1a;--fm-action-sheet-cancel-font-size: var(--fm-font-size-lg);--fm-action-sheet-cancel-font-weight: 500}.fm-action-sheet{display:flex;flex-direction:column;max-height:var(--fm-action-sheet-max-height);overflow:hidden;user-select:none}.fm-action-sheet--round{border-top-left-radius:var(--fm-action-sheet-border-radius);border-top-right-radius:var(--fm-action-sheet-border-radius)}.fm-action-sheet__description{flex-shrink:0;color:var(--fm-action-sheet-description-color);line-height:var(--fm-action-sheet-description-line-height);font-size:var(--fm-action-sheet-description-font-size);text-align:center;padding:var(--fm-action-sheet-description-padding);position:relative}.fm-action-sheet__description--left{text-align:left}.fm-action-sheet__content{flex:1 auto;overflow-y:auto;-webkit-overflow-scrolling:touch}.fm-action-sheet__item,.fm-action-sheet__cancel{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__item:active,.fm-action-sheet__cancel:active{background-color:var(--fm-action-sheet-item-active-background)}.fm-action-sheet__item{display:flex;position:relative;flex-wrap:wrap;align-items:center;justify-content:center;text-align:center;padding:var(--fm-action-sheet-item-padding);color:var(--fm-action-sheet-item-text-color);cursor:pointer}.fm-action-sheet__item-icon{font-size:var(--fm-action-sheet-item-icon-size);margin-right:var(--fm-action-sheet-item-icon-margin-right)}.fm-action-sheet__item-title{font-size:var(--fm-action-sheet-item-title-font-size);line-height:var(--fm-action-sheet-item-title-line-height)}.fm-action-sheet__item-subtitle{font-size:var(--fm-action-sheet-item-subtitle-font-size);line-height:var(--fm-action-sheet-item-subtitle-line-height);width:100%;margin-top:var(--fm-action-sheet-item-subtitle-margin-top);color:var(--fm-action-sheet-item-subtitle-color);overflow-wrap:break-word}.fm-action-sheet__item--left{text-align:left;justify-content:flex-start}.fm-action-sheet__item--disabled{color:var(--fm-action-sheet-item-disabled-text-color);cursor:not-allowed}.fm-action-sheet__item--disabled:active{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__description:after,.fm-action-sheet__item:after{content:"";display:block;position:absolute;height:1px;bottom:0;left:0;right:0;transform:scaleY(.5);background-color:var(--fm-action-sheet-divider-color)}.fm-action-sheet__footer-gap{height:8px;background-color:var(--fm-action-sheet-footer-gap-color)}.fm-action-sheet__cancel{display:flex;flex-direction:column;justify-content:center;align-items:center;height:var(--fm-action-sheet-cancel-height);cursor:pointer;color:var(--fm-action-sheet-cancel-color);font-size:var(--fm-action-sheet-cancel-font-size);font-weight:var(--fm-action-sheet-cancel-font-weight)}:root{--fm-tab-bar-item-color: var(--fm-text-color);--fm-tab-bar-item-active-color: var(--fm-primary-color);--fm-tab-bar-item-font-size: 16px}.fm-tab-bar-item{flex:1 0 auto;position:relative;display:inline-flex;align-items:center;justify-content:center;margin:0 12px;line-height:44px}.fm-tab-bar-item--actived{color:var(--fm-tab-bar-item-active-color)}.fm-tab-bar-item--disabled{color:var(--fm-disabled-color)}.fm-tab-bar-item--dot .fm-tab-bar-item__text:after{content:"";position:absolute;top:0;right:0;width:8px;height:8px;background-color:var(--fm-danger-color);border-radius:100%;transform:translate(100%,100%)}.fm-tab-bar-item__text{position:relative;display:flex;justify-content:center;min-width:40px}.fm-tab-bar-item__ink{position:absolute;bottom:0;left:0;right:0;height:4px;background-color:var(--fm-tab-bar-item-active-color);border-radius:2px}.fm-tab-bar-item__badge{position:absolute;top:2px;right:0;padding:0 4px;max-width:28px;font-weight:500;font-size:12px;line-height:14px;border-radius:7px;color:var(--fm-background-white);background-color:var(--fm-danger-color);transform:translate(50%)}.fm-tab-bar-item__icon{position:relative;display:flex;align-items:center;justify-content:center;padding-right:4px}:root{--fm-tab-bar-height: 44px;--fm-tab-bar-background: var(--fm-background-white);--fm-tab-bar-color: var(--fm-text-color);--fm-tab-bar-active-color: var(--fm-primary-color);--fm-tab-bar-font-size: 16px}.fm-tab-bar{position:relative;background:var(--fm-tab-bar-background);color:var(--fm-tab-bar-color);font-size:var(--fm-tab-bar-font-size)}.fm-tab-bar--bottom-line{border-bottom:1px solid #ddd;position:relative}@media (min-resolution: 1dppx){html:not([data-scale]) .fm-tab-bar--bottom-line{border-bottom:none}html:not([data-scale]) .fm-tab-bar--bottom-line:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tab-bar__scroll-wrapper{position:relative;width:100%;overflow:hidden}.fm-tab-bar__list{display:flex;justify-content:space-between;min-width:100%;transition:all .3s cubic-bezier(.17,.89,.45,1)}.fm-tab-bar__ink{position:absolute;bottom:0;left:0;display:block;height:4px;background-color:var(--fm-tab-bar-active-color);transition:all var(--fm-duration-base);border-radius:2px}.fm-tab-bar__ink--disabled{background-color:var(--fm-disabled-color)}.fm-tabs{overflow:hidden}.fm-tabs__content{display:flex}.fm-tab{display:block;flex-shrink:0;width:100%;height:100%;overflow:auto;word-break:break-all}.fm-tab--collapse{height:0;overflow:visible}:root{--fm-tag-padding: 0 6px;--fm-tag-height: 18px;--fm-tag-font-size: 12px;--fm-tag-border-radius: 2px;--fm-tag-color: var(--fm-white)}.fm-tag{position:relative;display:inline-flex;align-items:center;white-space:nowrap;padding:0 4px;color:var(--fm-tag-color);font-size:var(--fm-tag-font-size);line-height:var(--fm-tag-height);border-radius:var(--fm-tag-border-radius)}.fm-tag--primary{background-color:var(--fm-primary-color)}.fm-tag--success{background-color:var(--fm-success-color)}.fm-tag--danger{background-color:var(--fm-danger-color)}.fm-tag--warning{background-color:var(--fm-warning-color)}.fm-tag--plain{background-color:var(--fm-white)}.fm-tag--plain.fm-tag--primary{border:1px solid var(--fm-primary-color);color:var(--fm-primary-color)}.fm-tag--plain.fm-tag--success{border:1px solid var(--fm-success-color);color:var(--fm-success-color)}.fm-tag--plain.fm-tag--warning{border:1px solid var(--fm-warning-color);color:var(--fm-warning-color)}.fm-tag--plain.fm-tag--danger{border:1px solid var(--fm-danger-color);color:var(--fm-danger-color)}.fm-tag--medium{padding:2px 6px}.fm-tag--large{padding:4px 8px;font-size:14px;border-radius:4px}.fm-tag--round{border-radius:100px}.fm-tag--mark{border-radius:0 100px 100px 0}.fm-tag__close{font-size:8px;margin-left:4px}.fm-tag--large .fm-tag__close{font-size:10px}: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}.fm-picker__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker__toolbar-left,.fm-picker__toolbar-right{padding:0 16px}.fm-picker__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker__content{position:relative;display:flex;cursor:grab}.fm-picker__columns{display:flex;flex:1;overflow:hidden}.fm-picker__column{flex:1}.fm-picker__column-item{display:flex;align-items:center;justify-content:center;height:44px}.fm-picker__mask{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;background-image:linear-gradient(180deg,#ffffffe6,#fff6),linear-gradient(0deg,#ffffffe6,#fff6);background-repeat:no-repeat;background-position:top,bottom;transform:translateZ(0);pointer-events:none}.fm-picker__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(.5)}.fm-picker-group__header{text-align:left}.fm-picker-group__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker-group__toolbar-left,.fm-picker-group__toolbar-right{padding:0 16px}.fm-picker-group__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker-group__tab-bar{display:inline-block}.fm-page-container{flex:1;display:flex;flex-direction:column;background:#f9fafb;overflow:hidden;-webkit-overflow-scrolling:auto;position:absolute;inset:0}.fm-page-container .drag-container{display:inherit;flex-direction:inherit;flex-shrink:1;flex-grow:1;flex-basis:0%;flex-wrap:inherit;justify-content:inherit;align-items:inherit;width:100%;overflow:inherit}.fm-page-body-container{flex-basis:0;flex-shrink:1;flex-grow:1;padding-bottom:12px;overflow:auto;display:flex;flex-direction:column}.fm-page-header-container{flex-shrink:0}.fm-page-footer-container{background-color:#fff}.fm-float-container{position:absolute!important;bottom:60px;right:30px} +@charset "UTF-8";:root{--fm-black: #000;--fm-white: #fff;--fm-gray-1: #f2f3f5;--fm-gray-2: #eee;--fm-gray-3: #ddd;--fm-gray-4: #ccc;--fm-gray-5: #999;--fm-gray-6: #666;--fm-gray-7: #333;--fm-red: #F24645;--fm-red-light: #f9e8e8;--fm-blue: #3A90FF;--fm-blue-2: #65a7ff;--fm-blue-light: #ecf2fe;--fm-green: #5CC171;--fm-green-2: #5AC1C3;--fm-green-light: #e9f5ed;--fm-orange: #FF9800;--fm-orange-2: #FA6400;--fm-orange-3: #FFB400;--fm-orange-light: #faf0e1;--fm-primary-color: var(--fm-blue);--fm-success-color: var(--fm-green);--fm-danger-color: var(--fm-red);--fm-warning-color: var(--fm-orange);--fm-submit-color: var(--fm-green-2);--fm-primary-color-light: var(--fm-blue-light);--fm-success-color-light: var(--fm-green-light);--fm-danger-color-light: var(--fm-red-light);--fm-warning-color-light: var(--fm-orange-light);--fm-text-color: var(--fm-gray-7);--fm-text-color-light: var(--fm-gray-5);--fm-active-color: var(--fm-gray-1);--fm-disabled-color: var(--fm-gray-4);--fm-readonly-color: var(--fm-gray-6);--fm-active-opacity: .7;--fm-readonly-opacity: .6;--fm-disabled-opacity: .5;--fm-background: var(--fm-gray-1);--fm-background-white: var(--fm-white);--fm-box-shadow-color: var(--fm-gray-1);--fm-padding-base: 4px;--fm-padding-xs: 8px;--fm-padding-sm: 12px;--fm-padding-md: 16px;--fm-padding-lg: 24px;--fm-padding-xl: 32px;--fm-padding-horizontal-xs: 0 var(--fm-padding-xs);--fm-padding-horizontal-sm: 0 var(--fm-padding-sm);--fm-padding-horizontal-md: 0 var(--fm-padding-md);--fm-padding-horizontal-lg: 0 var(--fm-padding-lg);--fm-margin-base: 4px;--fm-margin-xs: 8px;--fm-margin-sm: 12px;--fm-margin-md: 16px;--fm-margin-lg: 24px;--fm-margin-xl: 32px;--fm-margin-horizontal-xs: 0 var(--fm-margin-xs);--fm-margin-horizontal-sm: 0 var(--fm-margin-sm);--fm-margin-horizontal-md: 0 var(--fm-margin-md);--fm-margin-horizontal-lg: 0 var(--fm-margin-lg);--fm-font-bold-light: 500;--fm-font-bold: 600;--fm-font-size: 16px;--fm-line-height: 1.2;--fm-line-height-lg: 1.5;--fm-font-size-xs: 10px;--fm-font-size-sm: 12px;--fm-font-size-md: 14px;--fm-font-size-lg: 16px;--fm-gradient-blue: linear-gradient(-45deg,var(--fm-blue-2) 0%, var(--fm-blue) 100%);--fm-gradient-orange: linear-gradient(-45deg,var(--fm-orange) 0%, var(--fm-orange-2) 100%);--fm-base-font: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Segoe UI, Arial, Roboto, "PingFang SC", "miui", "Hiragino Sans GB", "Microsoft Yahei", sans-serif;--fm-price-font: avenir-heavy, "PingFang SC", helvetica neue, arial, sans-serif;--fm-duration-base: .3s;--fm-duration-fast: .2s;--fm-ease-out: ease-out;--fm-ease-in: ease-in;--fm-noborder: none;--fm-radius-sm: 2px;--fm-radius-md: 4px;--fm-radius-lg: 8px;--fm-radius-max: 999px;--fm-zindex-1: 9;--fm-zindex-2: 10;--fm-zindex-3: 99;--fm-zindex-4: 100;--fm-zindex-5: 999;--fm-zindex-6: 1000}*,*:before,*:after{box-sizing:border-box}body,h1,h2,h3,h4,p,figure,blockquote,dl,dd{margin:0}ul[role=list],ol[role=list]{list-style:none}html:focus-within{scroll-behavior:smooth}body{min-height:100vh;text-rendering:optimizeSpeed;line-height:1.5;font-family:-apple-system,Noto Sans,Helvetica Neue,Helvetica,Nimbus Sans L,Arial,Liberation Sans,PingFang SC,Hiragino Sans GB,Noto Sans CJK SC,Source Han Sans SC,Source Han Sans CN,Microsoft YaHei,Wenquanyi Micro Hei,WenQuanYi Zen Hei,ST Heiti,SimHei,WenQuanYi Zen Hei Sharp,sans-serif}a:not([class]){text-decoration-skip-ink:auto}img,picture{max-width:100%;display:block}input,button,textarea,select{font:inherit}@font-face{font-family:farrisMobile;font-style:normal;font-weight:400;src:url(data:font/ttf;base64,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AADmFAAAACUAAOYVAADmFQAAACYAAOYWAADmFgAAACcAAOYXAADmFwAAACgAAOYYAADmGAAAACkAAOYZAADmGQAAAHYAAOYaAADmGgAAAHUAAOYbAADmGwAAAHQAAOYcAADmHAAAAHMAAOYdAADmHQAAACoAAOYeAADmHgAAACsAAOYfAADmHwAAAHAAAOYgAADmIAAAAHEAAOYhAADmIQAAAHIAAOYiAADmIgAAAG8AAOYjAADmIwAAACwAAOYkAADmJAAAAGUAAOYlAADmJQAAAGYAAOYmAADmJgAAAGcAAOYnAADmJwAAAGgAAOYoAADmKAAAAGkAAOYpAADmKQAAAGoAAOYqAADmKgAAAGsAAOYrAADmKwAAAGwAAOYsAADmLAAAAG0AAOYtAADmLQAAAG4AAOYuAADmLgAAAGMAAOYvAADmLwAAAGQAAOYwAADmMAAAAGIAAOYyAADmMgAAADQAAOYzAADmMwAAAC0AAOY0AADmNAAAAC4AAOY2AADmNgAAAC8AAOY3AADmNwAAADAAAOY5AADmOQAAADEAAOY6AADmOgAAADIAAOZVAADmVQAAADUAAOZWAADmVgAAADoAAOZXAADmVwAAADcAAOZYAADmWAAAADgAAOZZAADmWQAAAD0AAOZaAADmWgAAAF4AAOZbAADmWwAAAF8AAOZcAADmXAAAAGAAAOZdAADmXQAAAGEAAOZeAADmXgAAADYAAOZfAADmXwAAADsAAOZgAADmYAAAADwAAOZhAADmYQAAADkAAOZiAADmYgAAAD4AAOZjAADmYwAAAD8AAOZkAADmZAAAAEAAAOZlAADmZQAAAEEAAOZmAADmZgAAAEIAAOZnAADmZwAAAEMAAOZoAADmaAAAAEQAAOZpAADmaQAAAEUAAOZqAADmagAAAEYAAOZrAADmawAAAEcAAOZsAADmbAAAAEgAAOZtAADmbQAAAEkAAOZuAADmbgAAAEoAAOZvAADmbwAAAEsAAOZwAADmcAAAAEwAAOZxAADmcQAAAE0AAOZyAADmcgAAAE4AAOZzAADmcwAAAE8AAOZ0AADmdAAAAFAAAOZ1AADmdQAAAFEAAOZ2AADmdgAAAFIAAOZ3AADmdwAAAFMAAOZ4AADmeAAAAFQAAOZ5AADmeQAAAFUAAOZ6AADmegAAAFYAAOZ7AADmewAAAFcAAOZ8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AV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFzAXQBdQF2AXcBeAF5AXoBewF8AX0BfgF/AYABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+AAlzLW1vcmUtbzEIcy1kZWxldGUIcy1iYWNrLW8Gcy1zY2FuEHMtb3JnYW5pemF0aW9uLW8Jcy1ncm91cC1vCXMtZmlsdGVyMQlzLWNsZWFyLW8Ocy1pbGx1c3RyYXRlLW8Icy1tb21lbnQIcy1zaG9wLW8Kcy1tb21lbnQtbwZzLXNob3AKcy1yZXZva2UtbwpzLXN1Ym1pdC1vB3MtYXBwLW8Gcy1ib29rBXMtYXBwBHMtbXkJcy1jb21tZW50C3MtY29tbWVudC1vCHMtYm9vay1vBnMtbXktbwxzLWxvY2F0aW9uLW8Kcy1sb2NhdGlvbgZzLW5ld3MIcy1uZXdzLW8Jcy1TZW5kaW5nCnMtSW1wb3J0LW8Icy1FZGl0LW8Icy1RUmNvZGULcy1CcmllZmNhc2URcy1Ob3RpZmljYXRpb25vZmYIcy1QZW5jaWwIcy1TdGFyLW8Jcy1CYXJDb2RlD3MtU2FsZU1lc3NhZ2UtbwxzLUxpc3R2aWV3LW8Lcy1QaWN0dXJlLW8Ocy1TYXZlRmlsbGV0LW8Ocy1TaG9wcGluZ2NhcnQJcy1QZW5kaW5nDnMtRXhwYW5kdmlldy1vCHMtTG9jay1vCXMtU2VydmljZQpzLVdhbGxldC1vEHMtU2hvcHBpbmdjYXJ0LW8Lcy1TZXR0aW5nLW8Ncy1VbmZvbGRSZWMtbwlzLVByb2ZpbGUGTGluay1vDVVzZXJTZXR0aW5nLW8Jcy1hZ3JlZS1vDHMtYXJyb3ctZG93bgdzLWFkZC1vB3MtYW5uZXgMcy1hcnJvdy1sZWZ0CnMtYXJyb3ctdXAScy1jaGVja2JveC1jaGVja2VkCnMtY2hlY2tib3gHcy1hcnJvdwpzLWV4Y2hhbmdlB3MtY2xlYXIJcy1jaGVja2VkB3MtZXllLW8Lcy1jbG9zZS1leWUEcy1hdAxzLWZlZWRiYWNrLW8Pcy1mb2xkLWNpcmNsZS1vB3MtY3Jvc3MHcy1taW51cwZzLWZpbGUPcy1mb2xkLXRyaWFuZ2xlCHMtZmlsdGVyCXMtZm9yd29yZAZzLXBsdXMJcy1maWxlZGVsCHMtZm9sZC1vCXMtaW1hZ2UtbwhzLW1vcmUtbw5zLXJlZGlvLWNpcmNsZQpzLXJlamVjdC1vCXMtc3VjY2VzcwlzLXJlZnJlc2gGcy1zdGFyDXMtcHJvY2Vzc2Zsb3cRcy11bmZvbGQtY2lyY2xlLW8Icy1yZXdpbmQKcy11bmZvbGQtbwtzLXdhcm5pbmctbxFzLXVuZm9sZC10cmlhbmdsZQlzLXByaW50LW8Kcy1zZWFyY2gtbwhBaXJwbGFuZQVUcmFpbgNCdXMEVGF4aQxvdmVydGltZW1lYWwTZm0taS10cmFmZmljZGV0YWlscw9mbS1pLXRyYWZmaWNzdWITZm0taS1hY2NvbW1vZGF0aW9uMQ1mbS1pLWJ1c2luZXNzC2ZtLWktYnVkZ2V0CWZtLWktZ2lmdBFmbS1pLWNhbmNlbGxhdGlvbgxmbS1pLWludm9pY2UJZm0taS1saXN0CmZtLWktbWVhbHMIZm0taS1wYXkMZm0taS1zdWJzaWR5B3Nob3V6aGUTZm0taS1jb3N0YWxsb2NhdGlvbgxmbS1pLXBheW1lbnQOZm0taS1JdGluZXJhcnkOZm0taS1tb3JleGUwMmQPZm0taS1pbWFnZXhlMDJlEGZtLWktcmVqZWN0eGUwMmYPZm0taS1hZ3JlZXhlMDMxDWZtLWktY2FyZGZvbGQPZm0taS1jYXJkdW5mb2xkEWZtLWktdHJhZmZpY290aGVyD2ZtLWktYm90dG9tc2F2ZRBmbS1pLXRyYWZmaWNib2F0D2ZtLWktdHJhZmZpY2NhchFmbS1pLXRyYWZmaWNwbGFuZRFmbS1pLXRyYWZmaWN0cmFpbg9mbS1pLXRyYWZmaWNidXMMZm0taS1hZGRncmF5CmZtLWktY2xvc2UIZm0taS1hZGQJZm0taS1tb3JlCmZtLWktY2hlY2sPZm0taS1iYWNrY2lyY2xlCmZtLWktYWdyZWUMZm0taS1sb2FkaW5nDGZtLWktZmlsZWRlbAlmbS1pLWZpbGUQZm0taS1wcm9jZXNzZmxvdwxmbS1pLXJlZHN0YXIQZm0taS1yaWdodGNpcmNsZQ9mbS1pLXRpbWVjaXJjbGUOZm0taS1zY3JlZW5pbmcMZm0taS11bmNoZWNrDmZtLWktb3BlcmF0aW9uE2ZtLWktYXBwcm92YWxhbW91bnQLZm0taS1hZ3JlZWQOZm0taS1pbnByb2Nlc3MNZm0taS1mZWVkYmFjawpmbS1pLXByaW50DmZtLWktaW1wb3J0YW50GmZtLWktYW1vdW50b2ZyZWltYnVyc2VtZW50FGZtLWktc2FmZXR5YXNzaXN0YW50C2ZtLWktcmVtaW5kDWZtLWktZXllb3BwZW4NZm0taS1leWVjbG9zZRBmbS1pLVBob3RvZ3JhcGh5D2ZtLWktcGhvdG9ncmFwaA9mbS1pLWFkZHBpY3R1cmUTZm0taS10b3Bfb3RoZXItZmFjZQ5mbS1pLXRvcF9vdGhlcgtmbS1pLWRlbGV0ZQ1mbS1pLW5leHRwYWdlDmZtLWktYWRkYnV0dG9uFmZtLWktd2FpdGZvcnByb2Nlc3NpbmcTZm0taS13YXJuaW5nbWVzc2FnZRJmbS1pLWZhaWx1cmVwcm9tcHQUZm0taS1zdWNjZXNzZnVsaGludHMKZm0taS1vdGhlcgxmbS1pLXJldHJhY3QOZm0taS1kcm9wLWRvd24LZm0taS1jYW5jZWwLZm0taS1zZWFyY2gTZm0taS1tdWx0aXBsZWNob2ljZRFmbS1pLXNpbmdsZWNob2ljZQ9mbS1pLW1pY3JvcGhvbmUXZm0taS1hcnJvdy1jaGV2cm9uLWxlZnQPZm0taS1oZWxwY2VudGVyDmZtLWktc3dlZXBjb2RlDmZtLWktZ3JvdXBjaGF0DmZtLWktYWRkZnJpZW5kC2ZtLWktdG9wX215EGZtLWktdG9wX215LWZhY2UPZm0taS10b3BfZnJpZW5kFGZtLWktdG9wX2ZyaWVuZC1mYWNlFWZtLWktdG9wX3B1YmxpY3ByYWlzZRpmbS1pLXRvcF9wdWJsaWNwcmFpc2UtZmFjZQ1mbS1pLXRvcF9ob21lEmZtLWktdG9wX2hvbWUtZmFjZQAAAAA=) format("truetype")}@keyframes fm-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fm-fade-out{0%{opacity:1}to{opacity:0}}.fm-fade-enter-active{animation:.3s fm-fade-in both ease-out}.fm-fade-leave-active{animation:.3s fm-fade-out both ease-in}.fm-slide-up-enter-from,.fm-slide-up-leave-to{transform:translate3d(0,100%,0)}.fm-slide-down-enter-from,.fm-slide-down-leave-to{transform:translate3d(0,-100%,0)}.fm-slide-left-enter-from,.fm-slide-left-leave-to{transform:translate3d(-100%,0,0)}.fm-slide-right-enter-from,.fm-slide-right-leave-to{transform:translate3d(100%,0,0)}.fm-slide-up-enter-active,.fm-slide-down-enter-active,.fm-slide-left-enter-active,.fm-slide-right-enter-active{transition-timing-function:ease-out}.fm-slide-up-leave-active,.fm-slide-down-leave-active,.fm-slide-left-leave-active,.fm-slide-right-leave-active{transition-timing-function:ease-in}.fm-slide-in-enter-active,.fm-slide-in-leave-active,.fm-slide-out-enter-active,.fm-slide-out-leave-active{will-change:transform;transition:all .3s;height:100%;width:100%;top:0;position:absolute;backface-visibility:hidden;perspective:1000}.fm-slide-in-leave-to,.fm-slide-out-enter-from{transform:translate(-100%);opacity:0}.fm-slide-in-enter-from,.fm-slide-out-leave-to{transform:translate(100%);opacity:0}@keyframes fm-drop-down-in{0%{height:0;opacity:0}to{opacity:1}}@keyframes fm-drop-down-out{0%{opacity:1}to{height:0;opacity:0}}.fm-drop-down-enter-active{animation:.3s fm-drop-down-in both ease-out}.fm-drop-down-leave-active{animation:.3s fm-drop-down-out both ease-in}@keyframes fm-rotate{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}:root{--fm-button-height: 42px;--fm-button-padding: 0 14px;--fm-button-radius: 2px;--fm-button-border-width: 1px;--fm-button-color: var(--fm-white);--fm-button-line-height: var(--fm-line-height);--fm-button-font-size: var(--fm-font-size);--fm-button-plain-background: var(--fm-white);--fm-button-lg-height: 46px;--fm-button-lg-font-size: 18px;--fm-button-md-height: 38px;--fm-button-md-font-size: 14px;--fm-button-sm-height: 34px;--fm-button-sm-padding: 0 8px;--fm-button-sm-font-size: 12px;--fm-button-xs-height: 28px;--fm-button-xs-font-size: 10px;--fm-button-secondary-color: var(--fm-blue-light)}.fm-button{position:relative;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;text-align:center;margin:0;border:none;transition:opacity .2s;color:var(--fm-button-color);height:var(--fm-button-height);padding:var(--fm-button-padding);font-size:var(--fm-button-font-size);line-height:var(--fm-button-line-height);border-radius:var(--fm-button-radius)}.fm-button--primary{background:var(--fm-primary-color)}.fm-button--secondary{color:var(--fm-primary-color);background:var(--fm-button-secondary-color)}.fm-button--danger{background-color:var(--fm-danger-color)}.fm-button--warning{background-color:var(--fm-warning-color)}.fm-button--success{background-color:var(--fm-success-color)}.fm-button--plain{box-shadow:none;background:var(--fm-button-plain-background)}.fm-button--plain.fm-button--primary{color:var(--fm-primary-color);border:var(--fm-button-border-width) solid var(--fm-primary-color)}.fm-button--plain.fm-button--success{color:var(--fm-success-color);border:var(--fm-button-border-width) solid var(--fm-success-color)}.fm-button--plain.fm-button--danger{color:var(--fm-danger-color);border:var(--fm-button-border-width) solid var(--fm-danger-color)}.fm-button--plain.fm-button--warning{color:var(--fm-button-warning-color);border:var(--fm-button-border-width) solid var(--fm-button-warning-color)}.fm-button--noborder{border:none!important}.fm-button--large{height:var(--fm-button-lg-height);font-size:var(--fm-button-lg-font-size)}.fm-button--middle{height:var(--fm-button-md-height);font-size:var(--fm-button-md-font-size)}.fm-button--small{height:var(--fm-button-sm-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-sm-font-size)}.fm-button--mini{height:var(--fm-button-xs-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-xs-font-size)}.fm-button--block{display:flex;width:100%}.fm-button--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-button--loading:before,.fm-button--disabled:before{display:none}.fm-button--round{border-radius:var(--fm-radius-max)}.fm-button--square{border-radius:0}.fm-button__loading{display:inline-block;width:20px;max-width:100%;height:20px;max-height:100%;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-button__loading circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}.fm-button__loading-icon-circular{color:#fff}.fm-button__loading-text{margin-left:6px}.fm-button__icon:not(:last-child){margin-right:6px}.fm-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;background-color:#000;border:inherit;border-color:#000;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;content:" "}.fm-button:active:before{opacity:.1}.fm-button-edit__tags{min-height:24px;flex:1;display:flex;overflow:auto}.fm-button-edit__tag:not(:last-child){margin-right:6px}:root{--fm-button-group-gap: 16px}.fm-button-group{display:inline-flex;flex-wrap:nowrap;max-width:100%}.fm-button-group+.fm-button-group{margin-left:var(--fm-button-group-gap)}.fm-button-group__item{margin:0;min-width:0;max-width:100%;white-space:nowrap;flex:0 1 auto;user-select:none;outline:none!important}.fm-button-group__item--bare-vertical{display:inline-flex;flex-direction:column;align-items:center;justify-content:space-between;color:#666}.fm-button-group__item--bare-vertical .fm-button-group__item-icon{font-size:20px}.fm-button-group__item--bare-vertical .fm-button-group__item-text{font-size:10px;line-height:16px}.fm-button-group__item--bare-vertical.fm-button-group__item--disabled{cursor:not-allowed;opacity:.5}.fm-button-group--block{display:flex}.fm-button-group--vertical{flex-direction:column}.fm-button-group--block .fm-button-group__item{width:auto;flex:10000 1 0%}.fm-button-group--horizontal.fm-button-group--mode-default .fm-button-group__item+.fm-button-group__item{margin-left:var(--fm-button-group-gap)}.fm-button-group--vertical.fm-button-group--mode-default .fm-button-group__item+.fm-button-group__item{margin-top:var(--fm-button-group-gap)}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:not(:first-child):not(:last-child),.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:not(:first-child):not(:last-child){border-radius:0}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:first-child:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:first-child:not(:last-child){border-bottom-left-radius:0;border-bottom-right-radius:0}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:last-child:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.fm-button-group--horizontal.fm-button-group--mode-outline .fm-button-group__item:not(:first-child){border-left:0}.fm-button-group--vertical.fm-button-group--mode-outline .fm-button-group__item:not(:first-child){border-top:0}.fm-button-group--horizontal.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after,.fm-button-group--vertical.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after{content:"";display:block;position:absolute;background-color:var(--fm-gray-3)}.fm-button-group--horizontal.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after{width:1px;right:0;top:var(--fm-padding-xs);bottom:var(--fm-padding-xs)}.fm-button-group--vertical.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after{height:1px;bottom:0;left:var(--fm-padding-xs);right:var(--fm-padding-xs)}.fm-button-group--fill{flex:1}:root{--fm-card-background: var(--fm-white);--fm-card-title-color: var(--fm-gray-7)}.fm-card{background-color:var(--fm-card-background)}.fm-card__header{display:flex;justify-content:space-between;align-items:center;padding:11px 16px 10px;border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-card__header:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-card__title{position:relative;padding-left:var(--fm-padding-md);color:var(--fm-card-title-color);font-size:var(--fm-font-size-lg);line-height:var(--fm-line-height-lg);font-weight:var(--fm-font-bold-light);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-card__title:before{content:"";position:absolute;left:0;top:50%;width:3px;height:14px;margin:-7px 0 0;background:var(--fm-primary-color)}.fm-card__footer{border-top:1px solid #ddd;position:relative;border-top:none}.fm-card__footer:before{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}:root{--fm-cell-padding: 10px 16px;--fm-cell-margin: 5px;--fm-cell-line-height: 24px;--fm-cell-font-size: var(--fm-font-size);--fm-cell-background: var(--fm-background-white);--fm-cell-color: var(--fm-text-color);--fm-cell-label-font-size: 12px;--fm-cell-label-line-height: 18px;--fm-cell-label-color: var(--fm-text-color-light);--fm-cell-required-color: var(--fm-danger-color)}.fm-cell{width:100%;padding:var(--fm-cell-padding);background-color:var(--fm-cell-background);color:var(--fm-cell-color);font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);position:relative;display:flex;overflow:hidden}.fm-cell--bottom-border,.fm-cell:not(:last-child){border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-cell--bottom-border:after,.fm-cell:not(:last-child):after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-cell--bottom-border:after,.fm-cell:not(:last-child):after{left:16px!important}.fm-cell.fm-cell-all-width:not(:last-child):after{left:0!important}.fm-cell--clickable{cursor:pointer}.fm-cell--clickable:active{background-color:var(--fm-active-color)}.fm-cell--required .fm-cell-title{position:relative}.fm-cell--required .fm-cell-title .fm-cell-title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-cell__title,.fm-cell__value{flex:1;font-size:inherit}.fm-cell__title{display:inline-block;overflow:hidden}.fm-cell__title-text{display:flex;word-break:break-all}.fm-cell__title-text span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-cell__right{display:flex;overflow:hidden;flex-direction:column}.fm-cell__right-content{display:flex;flex:1}.fm-cell__right--fill{flex:1}.fm-cell__value{position:relative;overflow:hidden;text-align:right;vertical-align:middle;word-wrap:break-word}.fm-cell__value--alone{text-align:left}.fm-cell__label{margin-top:var(--fm-cell-margin);color:var(--fm-cell-label-color);font-size:var(--fm-cell-label-font-size);line-height:var(--fm-cell-label-line-height)}.fm-cell--center{align-items:center}.fm-cell__extra,.fm-cell__left-icon,.fm-cell__right-icon{min-width:1em;font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);display:flex;align-items:center}.fm-cell__left-icon{margin-right:var(--fm-cell-margin)}.fm-cell__extra,.fm-cell__right-icon{margin-left:var(--fm-cell-margin)}.fm-cell--noborder .fm-cell:after{display:none!important}.fm-cell--card{padding-left:0;padding-right:0}.fm-checkbox-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-checkbox-group--vertical{flex-direction:column}.fm-checkbox-group--vertical .fm-checkbox:not(:last-child){margin-bottom:8px}.fm-checkbox{margin-top:4px;margin-bottom:4px}:root{--fm-checker-color: var(--fm-text-color);--fm-checker-font-size: var(--fm-font-size);--fm-checker-icon-color: var(--fm-text-color-light);--fm-checker-icon-background: var(--fm-background-white);--fm-checker-icon-radius: var(--fm-radius-md);--fm-checker-checked-icon-color: var(--fm-primary-color);--fm-checker-button-background: var(--fm-gray-2);--fm-checker-disabled-color: var(--fm-disabled-color);--fm-checker-disabled-icon-color: var(--fm-gray-1)}.fm-checker{display:flex;align-items:center;color:var(--fm-checker-color);font-size:var(--fm-checker-font-size)}.fm-checker__icon{display:inline-block;align-items:center}.fm-checker__icon .fm-icon{display:block;height:20px;width:20px;line-height:18px;font-size:14px;text-align:center;border-radius:var(--fm-checker-icon-radius);border:1px solid var(--fm-checker-icon-color);color:var(--fm-checker-icon-background);background-color:var(--fm-checker-icon-background)}.fm-checker__label{margin-left:8px;margin-right:8px;display:inline-block;line-height:20px}.fm-checker:first-child .fm-checker_button{margin-left:0}.fm-checker--round .fm-checker__icon .fm-icon{border-radius:100%}.fm-checker--button .fm-checker__label{font-size:13px;text-align:center;border-radius:14px;line-height:28px;padding:0 12px;min-width:60px;margin-right:0;color:var(--fm-checker-color);background:var(--fm-checker-button-background)}.fm-checker--checked .fm-checker__icon .fm-icon{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-checked-icon-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--checked.fm-checker--button .fm-checker__label{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--readonly{opacity:var(--fm-readonly-opacity)}.fm-checker--disabled{color:var(--fm-checker-disabled-color)}.fm-checker--disabled .fm-checker__icon .fm-icon{border-color:var(--fm-checker-disabled-color);background-color:var(--fm-checker-disabled-icon-color);color:var(--fm-checker-disabled-icon-color)}.fm-checker--disabled.fm-checker--checked .fm-checker__icon .fm-icon{background-color:var(--fm-checker-disabled-color);border-color:var(--fm-checker-disabled-color)}:root{--fm-icon-font-size: 14px;--fm-icon-color: inherit}.fm-icon{font-family:farrisMobile!important;font-size:var(--fm-icon-font-size);font-style:normal;color:var(--fm-icon-color);display:inline-block;width:1em;height:1em;font-weight:400;line-height:1;vertical-align:middle;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fm-icon:before{display:inline-block}.fm-icon-filter:before{content:"\e697"}.fm-icon-cardfold:before{content:"\e6b7"}.fm-icon-cardunfold:before{content:"\e6b8"}.fm-icon-trafficother:before{content:"\e6b9"}.fm-icon-bottomsave:before{content:"\e6ba"}.fm-icon-trafficboat:before{content:"\e6bb"}.fm-icon-trafficcar:before{content:"\e6bc"}.fm-icon-trafficplane:before{content:"\e6bd"}.fm-icon-traffictrain:before{content:"\e6be"}.fm-icon-trafficbus:before{content:"\e6bf"}.fm-icon-addgray:before{content:"\e6a7"}.fm-icon-close:before{content:"\e6a8"}.fm-icon-add-line:before{content:"\e6a9"}.fm-icon-more:before{content:"\e6aa"}.fm-icon-check:before{content:"\e6ab"}.fm-icon-backcircle:before{content:"\e6ac"}.fm-icon-agree:before{content:"\e6ad"}.fm-icon-loading:before{content:"\e6ae"}.fm-icon-filedel:before{content:"\e6af"}.fm-icon-file:before{content:"\e6b0"}.fm-icon-processflow:before{content:"\e6b1"}.fm-icon-redstar:before{content:"\e6b2"}.fm-icon-rightcircle:before{content:"\e6b3"}.fm-icon-timecircle:before{content:"\e6b4"}.fm-icon-screening:before{content:"\e6b5"}.fm-icon-uncheck:before{content:"\e6b6"}.fm-icon-operation:before{content:"\e02c"}.fm-icon-approvalamount:before{content:"\e02b"}.fm-icon-agreed:before{content:"\e02a"}.fm-icon-inprocess:before{content:"\e029"}.fm-icon-feedback:before{content:"\e028"}.fm-icon-print:before{content:"\e027"}.fm-icon-important:before{content:"\e026"}.fm-icon-amountofreimbursement:before{content:"\e025"}.fm-icon-safetyassistant:before{content:"\e024"}.fm-icon-remind:before{content:"\e023"}.fm-icon-eyeoppen:before{content:"\e022"}.fm-icon-eyeclose:before{content:"\e01e"}.fm-icon-photography:before{content:"\e021"}.fm-icon-photograph:before{content:"\e020"}.fm-icon-addpicture:before{content:"\e01f"}.fm-icon-top_other-face:before{content:"\e01d"}.fm-icon-top_other:before{content:"\e01c"}.fm-icon-delete:before{content:"\e01b"}.fm-icon-nextpage:before{content:"\e01a"}.fm-icon-addbutton:before{content:"\e019"}.fm-icon-waitforprocessing:before{content:"\e018"}.fm-icon-warningmessage:before{content:"\e017"}.fm-icon-failureprompt:before{content:"\e016"}.fm-icon-successfulhints:before{content:"\e015"}.fm-icon-other:before{content:"\e014"}.fm-icon-retract:before{content:"\e013"}.fm-icon-drop-down:before{content:"\e012"}.fm-icon-cancel:before{content:"\e011"}.fm-icon-search:before{content:"\e010"}.fm-icon-multiplechoice:before{content:"\e00f"}.fm-icon-singlechoice:before{content:"\e00e"}.fm-icon-microphone:before{content:"\e00d"}.fm-icon-arrow-chevron-left:before{content:"\e00c"}.fm-icon-helpcenter:before{content:"\e00b"}.fm-icon-sweepcode:before{content:"\e00a"}.fm-icon-groupchat:before{content:"\e009"}.fm-icon-addfriend:before{content:"\e008"}.fm-icon-top_my:before{content:"\e007"}.fm-icon-top_my-face:before{content:"\e006"}.fm-icon-top_friend:before{content:"\e005"}.fm-icon-top_friend-face:before{content:"\e004"}.fm-icon-top_publicpraise:before{content:"\e003"}.fm-icon-top_publicpraise-face:before{content:"\e002"}.fm-icon-top_home:before{content:"\e001"}.fm-icon-top_home-face:before{content:"\e000"}.fm-icon-s-agree-o:before{content:"\e655"}.fm-icon-s-arrow-down:before{content:"\e656"}.fm-icon-s-add-o:before{content:"\e657"}.fm-icon-s-annex:before{content:"\e658"}.fm-icon-s-arrow:before{content:"\e659"}.fm-icon-s-arrow-up:before{content:"\e65e"}.fm-icon-s-checkbox-checked:before{content:"\e65f"}.fm-icon-s-checkbox:before{content:"\e660"}.fm-icon-s-arrow-left:before{content:"\e661"}.fm-icon-s-exchange:before{content:"\e662"}.fm-icon-s-clear:before{content:"\e663"}.fm-icon-s-checked:before{content:"\e664"}.fm-icon-s-eye-o:before{content:"\e665"}.fm-icon-s-close-eye:before{content:"\e666"}.fm-icon-s-at:before{content:"\e667"}.fm-icon-s-feedback-o:before{content:"\e668"}.fm-icon-s-fold-circle-o:before{content:"\e669"}.fm-icon-s-cross:before{content:"\e66a"}.fm-icon-s-minus:before{content:"\e66b"}.fm-icon-s-file:before{content:"\e66c"}.fm-icon-s-fold-triangle:before{content:"\e66d"}.fm-icon-s-filter:before{content:"\e66e"}.fm-icon-s-forword:before{content:"\e66f"}.fm-icon-s-plus:before{content:"\e670"}.fm-icon-s-filedel:before{content:"\e671"}.fm-icon-s-fold-o:before{content:"\e672"}.fm-icon-s-image-o:before{content:"\e673"}.fm-icon-s-more-o:before{content:"\e674"}.fm-icon-s-redio-circle:before{content:"\e675"}.fm-icon-s-reject-o:before{content:"\e676"}.fm-icon-s-success:before{content:"\e677"}.fm-icon-s-refresh:before{content:"\e678"}.fm-icon-s-star:before{content:"\e679"}.fm-icon-s-processflow:before{content:"\e67a"}.fm-icon-s-unfold-circle-o:before{content:"\e67b"}.fm-icon-s-rewind:before{content:"\e67c"}.fm-icon-s-unfold-o:before{content:"\e67d"}.fm-icon-s-save-o:before{content:"\e67e"}.fm-icon-s-warning-o:before{content:"\e67f"}.fm-icon-s-unfold-triangle:before{content:"\e680"}.fm-icon-s-print-o:before{content:"\e681"}.fm-icon-s-search-o:before{content:"\e682"}.fm-icon-s-news:before{content:"\e683"}.fm-icon-s-news-o:before{content:"\e684"}.fm-icon-s-shop:before{content:"\e68c"}.fm-icon-s-sending:before{content:"\e60b"}.fm-icon-s-import-o:before{content:"\e60c"}.fm-icon-s-edit-o:before{content:"\e60d"}.fm-icon-s-qrcode:before{content:"\e60e"}.fm-icon-s-briefcase:before{content:"\e60f"}.fm-icon-s-notificationoff:before{content:"\e610"}.fm-icon-s-pencil:before{content:"\e611"}.fm-icon-s-star-o:before{content:"\e612"}.fm-icon-s-barcode:before{content:"\e613"}.fm-icon-s-salemessage-o:before{content:"\e614"}.fm-icon-s-listview-o:before{content:"\e615"}.fm-icon-s-picture-o:before{content:"\e616"}.fm-icon-s-savefillet-o:before{content:"\e617"}.fm-icon-s-shoppingcart:before{content:"\e618"}.fm-icon-s-pending:before{content:"\e61d"}.fm-icon-s-expandview-o:before{content:"\e61e"}.fm-icon-s-lock-o:before{content:"\e623"}.fm-icon-s-my:before{content:"\e692"}.fm-icon-s-service:before{content:"\e633"}.fm-icon-s-wallet-o:before{content:"\e634"}.fm-icon-s-shoppingcart-o:before{content:"\e636"}.fm-icon-s-setting-o:before{content:"\e637"}.fm-icon-s-my-o:before{content:"\e696"}.fm-icon-s-unfoldrec-o:before{content:"\e639"}.fm-icon-s-profile:before{content:"\e63a"}.fm-icon-s-link-o:before{content:"\e609"}.fm-icon-s-usersetting-o:before{content:"\e632"}.fm-icon-s-shop-o:before{content:"\e68a"}.fm-icon-s-list:before{content:"\e62a"}.fm-icon-s-location-o:before{content:"\e685"}.fm-icon-s-location:before{content:"\e686"}.fm-icon-s-moment:before{content:"\e689"}.fm-icon-s-moment-o:before{content:"\e68b"}.fm-icon-s-revoke-o:before{content:"\e687"}.fm-icon-s-submit-o:before{content:"\e688"}.fm-icon-s-app-o:before{content:"\e68f"}.fm-icon-s-app:before{content:"\e691"}.fm-icon-s-book-o:before{content:"\e695"}.fm-icon-s-book:before{content:"\e690"}.fm-icon-s-comment:before{content:"\e693"}.fm-icon-s-comment-o:before{content:"\e694"}.fm-icon-s-illustrate-o:before{content:"\e68d"}.fm-icon-s-clear-o:before{content:"\e68e"}.fm-icon-friend:before{content:"\e005"}.fm-icon-scan:before{content:"\e69a"}.fm-icon-back:before{content:"\e69b"}.fm-icon-menu:before{content:"\e69d"}:root{--fm-navbar-background: var(--fm-background-white);--fm-navbar-color: var(--fm-text-color);--fm-navbar-height: 44px;--fm-navbar-title-size: 17px;--fm-navbar-side-size: 16px;--fm-navbar-arrow-size: 16px;--fm-navbar-toolbar-item-height: 46px}.fm-navbar{position:relative;z-index:9;display:flex;align-items:center;line-height:1.5;text-align:center;user-select:none;height:var(--fm-navbar-height);color:var(--fm-navbar-color);background-color:var(--fm-navbar-background)}.fm-navbar--fixed{position:fixed;top:0;left:0;width:100%}.fm-navbar--bottom-border{border-bottom:1px solid #e6e6e6;position:relative;border-bottom:none}.fm-navbar--bottom-border:after{content:"";position:absolute;background-color:#e6e6e6;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-navbar__title{max-width:60%;margin:0 auto;font-weight:500;font-size:var(--fm-navbar-title-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-navbar__left,.fm-navbar__right{position:absolute;top:0;bottom:0;display:flex;align-items:center;max-width:30%;padding:0 16px;font-size:var(--fm-navbar-side-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;cursor:pointer}.fm-navbar__left{left:0}.fm-navbar__left:active{opacity:var(--fm-active-opacity)}.fm-navbar__left.fm-navbar-left-padding{padding-left:14px}.fm-navbar__right{right:0}.fm-navbar__right .fm-navbar-text:active{opacity:var(--fm-active-opacity)}.fm-navbar__left-arrow{min-width:1em;margin-right:4px;font-size:var(--fm-navbar-arrow-size)}.fm-navbar__toolbar{padding:0!important}.fm-navbar__toolbar-item{padding:0 var(--fm-padding-sm);height:var(--fm-navbar-toolbar-item-height);line-height:var(--fm-navbar-toolbar-item-height);user-select:none;cursor:pointer}.fm-navbar__toolbar-item:not(:last-child){border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-navbar__toolbar-item:not(:last-child):after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-navbar__toolbar-item--disabled{opacity:var(--fm-disabled-opacity);cursor:not-allowed}:root{--fm-input-group-size: var(--fm-font-size);--fm-input-group-color: var(--fm-text-color);--fm-input-group-sub-size: 13px;--fm-input-group-padding: 10px 16px;--fm-input-group-sub-color: var(--fm-text-color-light);--fm-input-group-border-color: var(--fm-gray-2)}.fm-input-group{display:flex;flex-direction:column;background-color:var(--fm-white)}.fm-input-group--padding{padding:var(--fm-input-group-padding)}.fm-input-group__body{flex:1;display:flex;align-items:center;min-height:24px;color:var(--fm-input-group-color);font-size:var(--fm-input-group-size)}.fm-input-group__body--border{border:1px solid var(--fm-input-group-border-color);padding:4px 8px;border-radius:4px}.fm-input-group__control{display:flex;width:100%;min-width:0;margin:0;padding:0;border:0;resize:none;color:inherit;font-size:inherit;outline:none;line-height:inherit;background-color:transparent}.fm-input-group__control::placeholder{color:var(--fm-input-group-sub-color)}.fm-input-group__control:disabled{opacity:1;cursor:not-allowed;color:var(--fm-disabled-color);-webkit-text-fill-color:currentColor}.fm-input-group__control::-webkit-search-cancel-button{display:none}.fm-input-group__control--readonly{cursor:default;color:var(--fm-readonly-color)}.fm-input-group__control--left{justify-content:flex-start;text-align:left}.fm-input-group__control--center{justify-content:center;text-align:center}.fm-input-group__control--right{justify-content:flex-end;text-align:right}.fm-input-group__clear{cursor:pointer;margin-right:-8px;padding:4px 8px;color:var(--fm-input-group-sub-color);flex-shrink:0;box-sizing:content-box}.fm-input-group__left-icon{margin:auto 4px auto 0}.fm-input-group__right-icon{margin:auto 0 auto 4px}.fm-input-group__word-limit{margin-top:4px;line-height:18px;text-align:right;font-size:var(--fm-input-group-sub-size);color:var(--fm-input-group-sub-color)}.fm-radio-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-radio-group--vertical{flex-direction:column}.fm-radio-group--vertical .fm-radio:not(:last-child){margin-bottom:8px}.fm-radio{margin-top:4px;margin-bottom:4px}:root,:host{--fm-rate-icon-size: 20px;--fm-rate-icon-gutter: var(--fm-padding-base);--fm-rate-icon-void-color: var(--fm-gray-4);--fm-rate-icon-full-color: var(--fm-orange-3);--fm-rate-icon-disabled-color: var(--fm-gray-4)}.fm-rate{display:inline-flex;cursor:pointer;user-select:none;flex-wrap:wrap}.fm-rate__item{position:relative}.fm-rate__item:not(:last-child){padding-right:var(--fm-rate-icon-gutter)}.fm-rate__icon{display:block;width:1em;color:var(--fm-rate-icon-void-color);font-size:var(--fm-rate-icon-size)}.fm-rate__icon--half{position:absolute;top:0;left:0;overflow:hidden;pointer-events:none;color:var(--fm-rate-icon-full-color)}.fm-rate__icon--full{color:var(--fm-rate-icon-full-color)}.fm-rate__icon--disabled{color:var(--fm-rate-icon-disabled-color)}.fm-rate--disabled{cursor:not-allowed}.fm-rate--readonly{cursor:default}:root{--fm-form-item-size: var(--fm-font-size);--fm-form-item-color: var(--fm-text-color);--fm-form-item-label-width: 105px;--fm-form-item-sub-size: 13px}.fm-form-item{font-size:var(--fm-form-item-size);color:var(--fm-form-item-color)}.fm-form-item--vertical{flex-direction:column}.fm-form-item--vertical .fm-form-item__label{margin-bottom:4px}.fm-form-item__label{display:flex;flex:none;align-items:flex-start;text-align:left;width:var(--fm-form-item-label-width);margin-right:4px}.fm-form-item__label--left{justify-content:flex-start}.fm-form-item__label--center{justify-content:center}.fm-form-item__label--right{justify-content:flex-end}.fm-form-item__label--required{position:relative}.fm-form-item__label--required .fm-cell__title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-form-item__content{display:flex}.fm-form-item__content .fm-input-group{padding:0;flex:1}.fm-form-item__content--left{justify-content:flex-start}.fm-form-item__content--left input.fm-input-group__control{justify-content:flex-start;text-align:left}.fm-form-item__content--center{justify-content:center}.fm-form-item__content--center input.fm-input-group__control{justify-content:flex-center;text-align:center}.fm-form-item__content--right{justify-content:flex-end}.fm-form-item__content--right input.fm-input-group__control{justify-content:flex-end;text-align:right}.fm-form-item__error-message{color:var(--fm-danger-color);font-size:var(--fm-form-item-sub-size)}.fm-form-item__error-message--left{text-align:left}.fm-form-item__error-message--center{text-align:center}.fm-form-item__error-message--right{text-align:right}:root{--fm-overlay-background: rgba(0, 0, 0, .4);--fm-overlay-zindex: 98}.fm-overlay{width:100%;position:fixed;top:0;left:0;z-index:var(--fm-overlay-zindex);background-color:var(--fm-overlay-background);bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-overlay{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}:root{--fm-popup-background: var(--fm-white);--fm-popup-zindex: var(--fm-zindex-3);--fm-popup-radius: 16px}.fm-popup{position:fixed;max-height:100%;overflow-y:auto;background-color:var(--fm-popup-background);transition:all var(--fm-duration-base);z-index:var(--fm-popup-zindex)}.fm-popup--center{top:50%;left:50%;transform:translate(-50%,-50%)}.fm-popup--center.fm-popup--round{border-radius:var(--fm-popup-radius)}.fm-popup--top,.fm-popup--bottom{left:0;right:0}.fm-popup--top{top:0}.fm-popup--top.fm-popup--round{border-radius:0 0 var(--fm-popup-radius) var(--fm-popup-radius)}.fm-popup--bottom{bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--bottom{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--bottom.fm-popup--round{border-radius:var(--fm-popup-radius) var(--fm-popup-radius) 0 0}.fm-popup--left,.fm-popup--right{top:0;bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--left,.fm-popup--right{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--left{left:0}.fm-popup--left.fm-popup--round{border-radius:0 var(--fm-popup-radius) var(--fm-popup-radius) 0}.fm-popup--right{right:0}.fm-popup--right.fm-popup--round{border-radius:var(--fm-popup-radius) 0 0 var(--fm-popup-radius)}:root{--fm-popover-zindex: var(--fm-zindex-5);--fm-popover-padding: var(--fm-padding-sm);--fm-popover-border-radius: var(--fm-radius-lg);--fm-popover-arrow-size: 8px;--fm-popover-content-font-size: var(--fm-font-size);--fm-popover-content-line-height: var(--fm-line-height);--fm-popover-light-theme-color: var(--fm-gray-7);--fm-popover-light-theme-background: var(--fm-white);--fm-popover-dark-theme-color: var(--fm-white);--fm-popover-dark-theme-background: var(--fm-gray-7);--fm-popover-shadow: 0 6px 30px 5px rgba(0, 0, 0, .05), 0 16px 24px 2px rgba(0, 0, 0, .04), 0 8px 10px -5px rgba(0, 0, 0, .08)}.fm-popover{position:absolute;overflow:visible;top:0;left:0;transition:opacity .15s;background-color:transparent;z-index:var(--fm-popover-zindex)}.fm-popover__wrapper{display:inline-block}.fm-popover__content{position:relative;padding:var(--fm-popover-padding);border-radius:var(--fm-popover-border-radius);font-size:var(--fm-popover-content-font-size);line-height:var(--fm-popover-content-line-height);word-break:break-all}.fm-popover__arrow{position:absolute;width:0;height:0;z-index:1;border-style:solid;border-color:transparent;border-width:var(--fm-popover-arrow-size, 8px)}.fm-popover__arrow--top{border-bottom-width:0;border-top-color:currentColor;margin-bottom:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--right{border-left-width:0;border-right-color:currentColor;margin-left:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--bottom{border-top-width:0;border-bottom-color:currentColor;margin-top:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--left{border-right-width:0;border-left-color:currentColor;margin-right:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover--light .fm-popover__content{background:var(--fm-popover-light-theme-background);color:var(--fm-popover-light-theme-color);box-shadow:var(--fm-popover-shadow)}.fm-popover--light .fm-popover__arrow{color:var(--fm-popover-light-theme-background)}.fm-popover--dark .fm-popover__content{background:var(--fm-popover-dark-theme-background);color:var(--fm-popover-dark-theme-color);box-shadow:var(--fm-popover-shadow)}.fm-popover--dark .fm-popover__arrow{color:var(--fm-popover-dark-theme-background)}:root{--fm-switch-background: var(--fm-text-color-light);--fm-switch-on-color: var(--fm-primary-color)}.fm-switch{position:relative;cursor:pointer;display:inline-block;transition:background-color var(--fm-duration-base);background-color:var(--fm-switch-background)}.fm-switch--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-switch--readonly{cursor:default;opacity:var(--fm-readonly-opacity)}.fm-switch--loading{cursor:default}.fm-switch--on{background-color:var(--fm-switch-on-color)}.fm-switch--on .fm-switch__loadding{color:var(--fm-switch-on-color)}.fm-switch__node{display:flex;align-items:center;justify-content:center;position:absolute;top:1px;left:1px;z-index:1;width:28px;height:28px;border-radius:100%;background-color:var(--fm-white);transition:transform var(--fm-duration-base) cubic-bezier(.3,1.05,.4,1.05)}:root{--fm-toast-zindex: var(--fm-zindex-5);--fm-toast-color: var(--fm-white);--fm-toast-font-size: 16px;--fm-toast-background: var(--fm-gray-7);--fm-toast-icon-font-size: 48px}.fm-toast{position:fixed;top:50%;left:50%;display:-webkit-box;display:-webkit-flex;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:content-box;max-width:70%;padding:16px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;border-radius:7px;transform:translate(-50%,-50%);color:var(--fm-toast-color);z-index:var(--fm-toast-zindex);font-size:var(--fm-toast-font-size);background-color:var(--fm-toast-background)}.fm-toast--top{top:50px;transform:translate(-50%)}.fm-toast--bottom{top:auto;bottom:50px}.fm-toast--info,.fm-toast--success,.fm-toast--warning,.fm-toast--error{width:88px;min-height:88px}.fm-toast__icon-wrapper{margin-bottom:8px}.fm-toast--default{padding:8px 16px}.fm-toast--loading{min-width:84px;min-height:84px}.fm-toast--loading-icon{position:relative;display:inline-block;width:30px;height:30px;margin-bottom:8px;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-toast--loading-icon circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}:root{--fm-notify-color: var(--fm-white);--fm-notify-zindex: var(--fm-zindex-5);--fm-notify-info-background: var(--fm-primary-color);--fm-notify-success-background: var(--fm-success-color);--fm-notify-warning-background: var(--fm-warning-color);--fm-notify-error-background: var(--fm-danger-color)}.fm-notify{position:fixed;left:0;top:0;z-index:var(--fm-notify-zindex);display:flex;align-items:center;justify-content:center;width:100%;max-height:100%;padding:8px 16px;box-sizing:border-box;color:var(--fm-notify-color);font-size:14px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;overflow-y:auto}.fm-notify--info{background-color:var(--fm-notify-info-background)}.fm-notify--success{background-color:var(--fm-notify-success-background)}.fm-notify--warning{background-color:var(--fm-notify-warning-background)}.fm-notify--error{background-color:var(--fm-notify-error-background)}:root{--fm-dialog-background: var(--fm-background-2);--fm-dialog-padding-top: 24px;--fm-dialog-padding-left: 16px;--fm-dialog-header-font-size: 17px;--fm-dialog-header-line-height: 24px;--fm-dialog-content-font-size: 15px;--fm-dialog-content-line-height: 20px;--fm-dialog-footer-height: 50px;--fm-border-color: var(--fm-gray-4)}@media screen and (min-width: 375px){.fm-dialog{width:320px}}@media screen and (min-width: 280px) and (max-width: 375px){.fm-dialog{width:240px}}.fm-dialog{display:flex;flex-direction:column;background-color:var(--fm-dialog-background);overflow:hidden}.fm-dialog__header{padding-top:var(--fm-dialog-padding-top);padding-left:var(--fm-dialog-header-padding-left);padding-right:var(--fm-dialog-header-padding-left);font-weight:var(--fm-font-bold-light);font-size:var(--fm-dialog-header-font-size);color:var(--fm-text-color);line-height:var(--fm-dialog-header-line-height);text-align:center}.fm-dialog__content{max-height:70vh;overflow-y:auto}.fm-dialog__content__message{padding:var(--fm-dialog-padding-top) var(--fm-dialog-padding-left);font-size:var(--fm-dialog-content-font-size);line-height:var(--fm-dialog-content-line-height);white-space:pre-wrap;text-align:center;word-wrap:break-word}.fm-dialog__content__message--has-title{padding-top:11px;color:var(--fm-text-color-light)}.fm-dialog__content--prompt{padding:14px}.fm-dialog__content--prompt__input{display:block}.fm-dialog__footer{display:flex;flex-direction:row;align-items:center;border-top:1px solid var(--fm-border-color);position:relative;border-top:none}.fm-dialog__footer:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}.fm-dialog__footer .fm-button{border:0;height:var(--fm-dialog-footer-height);border-right:1px solid var(--fm-border-color);position:relative;border-right:none}.fm-dialog__footer .fm-button:after{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 0 auto auto;width:1px;height:100%;background:var(--fm-border-color);transform-origin:100% 50%;transform:scaleX(.5)}.fm-dialog__footer .fm-button:last-child{border-right:0}.fm-dialog__footer .fm-button:last-child:after{display:none!important}.fm-dialog__footer .fm-button--default{color:var(--fm-text-color)}.fm-dialog__footer--is-column{flex-direction:column}.fm-dialog__footer--is-column__button{border-top:1px solid var(--fm-border-color);position:relative;border-top:none}.fm-dialog__footer--is-column__button:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}.fm-dialog__footer--is-column__button:first-child{border-top:0}.fm-dialog__footer--is-column__button:first-child:before{display:none!important}.fm-dialog.fm-dialog--relative{position:relative}.fm-dialog.fm-dialog--relative__header{padding-right:40px}.fm-dialog__close{position:absolute;right:16px;top:16px;width:22px;height:22px;line-height:22px;text-align:center}.fm-dialog__close .fm-icon{font-size:15px;color:var(--fm-text-color-2)}:root,:host{--fm-loading-color: var(--fm-gray-5);--fm-loading-text-font-size: 14px;--fm-loading-text-line-height: 1.4}.fm-loading{display:flex;align-items:center;position:relative;color:var(--fm-loading-color)}.fm-loading__text{color:var(--fm-loading-color);font-size:var(--fm-loading-text-font-size);line-height:var(--fm-loading-text-line-height);margin-left:var(--fm-margin-xs)}.fm-loading--vertical{flex-direction:column}.fm-loading--vertical .fm-loading__text{margin-top:var(--fm-margin-xs);margin-left:0}.fm-loading__circular{display:block;animation:fm-rotate 2s linear infinite}.fm-loading__circular circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:3;stroke-linecap:round}.fm-loading__spinner{display:block;position:relative;animation:fm-rotate 1s linear infinite;animation-timing-function:steps(12)}.fm-loading__line{position:absolute;top:0;left:0;width:100%;height:100%}.fm-loading__line-inner{display:block;width:2px;height:25%;margin:0 auto;background-color:currentColor;border-radius:40%}.fm-loading__ring{display:block;animation:fm-rotate .75s linear infinite;border:4px solid;border-right-color:transparent;border-radius:50%}.fm-loading-popup{display:flex;align-items:center;justify-content:center;width:100px;height:100px;background-color:inherit}@keyframes fm-circular{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40}to{stroke-dasharray:90,150;stroke-dashoffset:-120}}.fm-loading__line--1{transform:rotate(30deg);opacity:1}.fm-loading__line--2{transform:rotate(60deg);opacity:.9375}.fm-loading__line--3{transform:rotate(90deg);opacity:.875}.fm-loading__line--4{transform:rotate(120deg);opacity:.8125}.fm-loading__line--5{transform:rotate(150deg);opacity:.75}.fm-loading__line--6{transform:rotate(180deg);opacity:.6875}.fm-loading__line--7{transform:rotate(210deg);opacity:.625}.fm-loading__line--8{transform:rotate(240deg);opacity:.5625}.fm-loading__line--9{transform:rotate(270deg);opacity:.5}.fm-loading__line--10{transform:rotate(300deg);opacity:.4375}.fm-loading__line--11{transform:rotate(330deg);opacity:.375}.fm-loading__line--12{transform:rotate(360deg);opacity:.3125}:root,:host{--fm-pull-refresh-head-height: 50px;--fm-pull-refresh-head-font-size: var(--fm-font-size-md);--fm-pull-refresh-head-text-color: var(--fm-text-color-light);--fm-pull-refresh-animation-duration: .3s}.fm-pull-refresh{overflow:hidden}.fm-pull-refresh__track{position:relative;height:100%}.fm-pull-refresh__track--not-pulling{transition:transform ease var(--fm-pull-refresh-animation-duration)}.fm-pull-refresh__head{position:absolute;left:0;width:100%;height:var(--fm-pull-refresh-head-height);color:var(--fm-pull-refresh-head-text-color);font-size:var(--fm-pull-refresh-head-font-size);line-height:var(--fm-pull-refresh-head-height);text-align:center;transform:translateY(-100%);display:flex;justify-content:center;align-items:center;flex-direction:column;overflow:hidden}:root,:host{--fm-list-text-color: var(--fm-gray-5);--fm-list-text-font-size: var(--fm-font-size-md, 14px);--fm-list-text-line-height: 50px;--fm-list-loading-icon-size: 16px}.fm-list__loading,.fm-list__error,.fm-list__load-more,.fm-list__finished-info{color:var(--fm-list-text-color);font-size:var(--fm-list-text-font-size);line-height:var(--fm-list-text-line-height);text-align:center}.fm-list__loading-container{display:flex;height:var(--fm-list-text-line-height);justify-content:center;align-items:center}:root,:host{--fm-listview-checkbox-container-width: 40px;--fm-listview-toolbar-height: 42px;--fm-listview-split-line-color: rgb(230, 235, 235);--fm-listview-empty-text-color: var(--fm-gray-5);--fm-listview-empty-text-font-size: var(--fm-font-size-md, 14px);--fm-listview-empty-text-line-height: 50px}.fm-list-view--fill{height:100%;flex-grow:1;flex-shrink:1;display:flex;flex-direction:column;overflow:hidden}.fm-list-view--fill .fm-list-view__track{flex:1 1 0;overflow:auto;-webkit-overflow-scrolling:touch}.fm-list-view--fill .fm-pull-refresh{min-height:100%}.fm-list-view .fm-list{user-select:none;-webkit-user-select:none}.fm-list-view__item{display:flex;position:relative;overflow:hidden}.fm-list-view__item-checker{display:flex;position:absolute;height:100%;width:var(--fm-listview-checkbox-container-width);justify-content:center;align-items:center}.fm-list-view__item-content{flex:1;transform:translate(0)}.fm-list-view__content--split .fm-list-view__item:not(:last-child):not(.fm-list-view__item--child){border-bottom:1px solid var(--fm-listview-split-line-color)}.fm-list-view--multi-select .fm-list-view__item-content{transform:translate(var(--fm-listview-checkbox-container-width))}.fm-list-view__item--group{display:block}.fm-list-view__item-group-header{padding:10px 16px;line-height:20px;font-size:var(--fm-font-size-md);color:var(--fm-gray-5)}.fm-list-view__empty-message{display:block;color:var(--fm-listview-empty-text-color);font-size:var(--fm-listview-empty-text-font-size);line-height:var(--fm-listview-empty-text-line-height);text-align:center}.fm-list-view__item-text{padding:13px 20px;color:var(--fm-gray-7);font-size:var(--fm-font-size)}.fm-list-view__toolbar{display:flex;align-items:center;height:var(--fm-listview-toolbar-height)}.fm-list-view__toolbar-item{flex:1}:root,:host{--fm-swipe-cell-button-text-color: var(--fm-white);--fm-swipe-cell-button-bg-color: var(--fm-gray-4);--fm-swipe-cell-button-font-size: var(--fm-font-size);--fm-swipe-cell-button-icon-size: var(--fm-font-size);--fm-swipe-cell-button-padding: var(--fm-padding-md)}.fm-swipe-cell{position:relative;overflow:hidden}.fm-swipe-cell__wrapper{transition-timing-function:cubic-bezier(.18,.89,.32,1);transition-property:transform}.fm-swipe-cell__left,.fm-swipe-cell__right{position:absolute;top:0;height:100%;display:flex}.fm-swipe-cell__left{left:0;transform:translate3d(-100%,0,0);flex-direction:row-reverse}.fm-swipe-cell__right{right:0;transform:translate3d(100%,0,0)}.fm-swipe-cell__button{display:inline-flex;justify-content:center;align-items:center;height:100%;padding:0 var(--fm-swipe-cell-button-padding);color:var(--fm-swipe-cell-button-text-color);background-color:var(--fm-swipe-cell-button-bg-color)}.fm-swipe-cell__button--primary,.fm-swipe-cell__button--info{background:var(--fm-primary-color)}.fm-swipe-cell__button--secondary{color:var(--fm-primary-color);background:var(--fm-button-secondary-color)}.fm-swipe-cell__button--danger{background-color:var(--fm-danger-color)}.fm-swipe-cell__button--warning{background-color:var(--fm-warning-color)}.fm-swipe-cell__button--success{background-color:var(--fm-success-color)}.fm-swipe-cell__icon{font-size:var(--fm-swipe-cell-button-icon-size)}.fm-swipe-cell__text{font-size:var(--fm-swipe-cell-button-font-size)}.fm-swipe-cell__icon+.fm-swipe-cell__text:not(:empty){margin-left:6px}:root,:host{--fm-action-sheet-max-height: 80%;--fm-action-sheet-border-radius: 12px;--fm-action-sheet-description-color: var(--fm-gray-5);--fm-action-sheet-description-line-height: 22px;--fm-action-sheet-description-font-size: var(--fm-font-size-md);--fm-action-sheet-description-padding: 12px 16px;--fm-action-sheet-item-default-background: var(--fm-background-white);--fm-action-sheet-item-active-background: #f2f3f5;--fm-action-sheet-item-padding: 13px 16px;--fm-action-sheet-item-text-color: #1a1a1a;--fm-action-sheet-item-disabled-text-color: #bdbdbd;--fm-action-sheet-item-subtitle-color: var(--fm-gray-5);--fm-action-sheet-item-icon-size: 18px;--fm-action-sheet-item-icon-margin-right: 8px;--fm-action-sheet-item-title-font-size: var(--fm-font-size-lg);--fm-action-sheet-item-title-line-height: 24px;--fm-action-sheet-item-subtitle-font-size: var(--fm-font-size-sm);--fm-action-sheet-item-subtitle-line-height: 18px;--fm-action-sheet-item-subtitle-margin-top: 2px;--fm-action-sheet-footer-gap-color: #f5f5f5;--fm-action-sheet-divider-color: #e7e7e7;--fm-action-sheet-cancel-height: 48px;--fm-action-sheet-cancel-color: #1a1a1a;--fm-action-sheet-cancel-font-size: var(--fm-font-size-lg);--fm-action-sheet-cancel-font-weight: 500}.fm-action-sheet{display:flex;flex-direction:column;max-height:var(--fm-action-sheet-max-height);overflow:hidden;user-select:none}.fm-action-sheet--round{border-top-left-radius:var(--fm-action-sheet-border-radius);border-top-right-radius:var(--fm-action-sheet-border-radius)}.fm-action-sheet__description{flex-shrink:0;color:var(--fm-action-sheet-description-color);line-height:var(--fm-action-sheet-description-line-height);font-size:var(--fm-action-sheet-description-font-size);text-align:center;padding:var(--fm-action-sheet-description-padding);position:relative}.fm-action-sheet__description--left{text-align:left}.fm-action-sheet__content{flex:1 auto;overflow-y:auto;-webkit-overflow-scrolling:touch}.fm-action-sheet__item,.fm-action-sheet__cancel{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__item:active,.fm-action-sheet__cancel:active{background-color:var(--fm-action-sheet-item-active-background)}.fm-action-sheet__item{display:flex;position:relative;flex-wrap:wrap;align-items:center;justify-content:center;text-align:center;padding:var(--fm-action-sheet-item-padding);color:var(--fm-action-sheet-item-text-color);cursor:pointer}.fm-action-sheet__item-icon{font-size:var(--fm-action-sheet-item-icon-size);margin-right:var(--fm-action-sheet-item-icon-margin-right)}.fm-action-sheet__item-title{font-size:var(--fm-action-sheet-item-title-font-size);line-height:var(--fm-action-sheet-item-title-line-height)}.fm-action-sheet__item-subtitle{font-size:var(--fm-action-sheet-item-subtitle-font-size);line-height:var(--fm-action-sheet-item-subtitle-line-height);width:100%;margin-top:var(--fm-action-sheet-item-subtitle-margin-top);color:var(--fm-action-sheet-item-subtitle-color);overflow-wrap:break-word}.fm-action-sheet__item--left{text-align:left;justify-content:flex-start}.fm-action-sheet__item--disabled{color:var(--fm-action-sheet-item-disabled-text-color);cursor:not-allowed}.fm-action-sheet__item--disabled:active{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__description:after,.fm-action-sheet__item:after{content:"";display:block;position:absolute;height:1px;bottom:0;left:0;right:0;transform:scaleY(.5);background-color:var(--fm-action-sheet-divider-color)}.fm-action-sheet__footer-gap{height:8px;background-color:var(--fm-action-sheet-footer-gap-color)}.fm-action-sheet__cancel{display:flex;flex-direction:column;justify-content:center;align-items:center;height:var(--fm-action-sheet-cancel-height);cursor:pointer;color:var(--fm-action-sheet-cancel-color);font-size:var(--fm-action-sheet-cancel-font-size);font-weight:var(--fm-action-sheet-cancel-font-weight)}:root{--fm-tab-bar-item-color: var(--fm-text-color);--fm-tab-bar-item-active-color: var(--fm-primary-color);--fm-tab-bar-item-font-size: 16px}.fm-tab-bar-item{flex:1 0 auto;position:relative;display:inline-flex;align-items:center;justify-content:center;margin:0 12px;line-height:44px}.fm-tab-bar-item--actived{color:var(--fm-tab-bar-item-active-color)}.fm-tab-bar-item--disabled{color:var(--fm-disabled-color)}.fm-tab-bar-item--dot .fm-tab-bar-item__text:after{content:"";position:absolute;top:0;right:0;width:8px;height:8px;background-color:var(--fm-danger-color);border-radius:100%;transform:translate(100%,100%)}.fm-tab-bar-item__text{position:relative;display:flex;justify-content:center;min-width:40px}.fm-tab-bar-item__ink{position:absolute;bottom:0;left:0;right:0;height:4px;background-color:var(--fm-tab-bar-item-active-color);border-radius:2px}.fm-tab-bar-item__badge{position:absolute;top:2px;right:0;padding:0 4px;max-width:28px;font-weight:500;font-size:12px;line-height:14px;border-radius:7px;color:var(--fm-background-white);background-color:var(--fm-danger-color);transform:translate(50%)}.fm-tab-bar-item__icon{position:relative;display:flex;align-items:center;justify-content:center;padding-right:4px}:root{--fm-tab-bar-height: 44px;--fm-tab-bar-background: var(--fm-background-white);--fm-tab-bar-color: var(--fm-text-color);--fm-tab-bar-active-color: var(--fm-primary-color);--fm-tab-bar-font-size: 16px}.fm-tab-bar{position:relative;background:var(--fm-tab-bar-background);color:var(--fm-tab-bar-color);font-size:var(--fm-tab-bar-font-size)}.fm-tab-bar--bottom-line{border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-tab-bar--bottom-line:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-tab-bar__scroll-wrapper{position:relative;width:100%;overflow:hidden}.fm-tab-bar__list{display:flex;justify-content:space-between;min-width:100%;transition:all .3s cubic-bezier(.17,.89,.45,1)}.fm-tab-bar__ink{position:absolute;bottom:0;left:0;display:block;height:4px;background-color:var(--fm-tab-bar-active-color);transition:all var(--fm-duration-base);border-radius:2px}.fm-tab-bar__ink--disabled{background-color:var(--fm-disabled-color)}.fm-tabs{overflow:hidden}.fm-tabs__content{display:flex}.fm-tab{display:block;flex-shrink:0;width:100%;height:100%;overflow:auto;word-break:break-all}.fm-tab--collapse{height:0;overflow:visible}:root{--fm-tag-padding: 0 6px;--fm-tag-height: 18px;--fm-tag-font-size: 12px;--fm-tag-border-radius: 2px;--fm-tag-color: var(--fm-white)}.fm-tag{position:relative;display:inline-flex;align-items:center;white-space:nowrap;padding:0 4px;color:var(--fm-tag-color);font-size:var(--fm-tag-font-size);line-height:var(--fm-tag-height);border-radius:var(--fm-tag-border-radius)}.fm-tag--primary{background-color:var(--fm-primary-color)}.fm-tag--success{background-color:var(--fm-success-color)}.fm-tag--danger{background-color:var(--fm-danger-color)}.fm-tag--warning{background-color:var(--fm-warning-color)}.fm-tag--plain{background-color:var(--fm-white)}.fm-tag--plain.fm-tag--primary{border:1px solid var(--fm-primary-color);color:var(--fm-primary-color)}.fm-tag--plain.fm-tag--success{border:1px solid var(--fm-success-color);color:var(--fm-success-color)}.fm-tag--plain.fm-tag--warning{border:1px solid var(--fm-warning-color);color:var(--fm-warning-color)}.fm-tag--plain.fm-tag--danger{border:1px solid var(--fm-danger-color);color:var(--fm-danger-color)}.fm-tag--medium{padding:2px 6px}.fm-tag--large{padding:4px 8px;font-size:14px;border-radius:4px}.fm-tag--round{border-radius:100px}.fm-tag--mark{border-radius:0 100px 100px 0}.fm-tag__close{font-size:8px;margin-left:4px}.fm-tag--large .fm-tag__close{font-size:10px}: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}.fm-picker-panel__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker-panel__toolbar-left,.fm-picker-panel__toolbar-right{padding:0 16px}.fm-picker-panel__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker-panel__content{position:relative;display:flex;cursor:grab}.fm-picker-panel__columns{display:flex;flex:1;overflow:hidden}.fm-picker-panel__column{flex:1}.fm-picker-panel__column-item{display:flex;align-items:center;justify-content:center;height:44px}.fm-picker-panel__mask{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;background-image:linear-gradient(180deg,#ffffffe6,#fff6),linear-gradient(0deg,#ffffffe6,#fff6);background-repeat:no-repeat;background-position:top,bottom;transform:translateZ(0);pointer-events:none}.fm-picker-panel__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(.5)}.fm-picker-group__header{text-align:left}.fm-picker-group__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker-group__toolbar-left,.fm-picker-group__toolbar-right{padding:0 16px}.fm-picker-group__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker-group__tab-bar{display:inline-block}:root{--fm-lookup-panel-background: var(--fm-background);--fm-lookup-panel-search-list-zindex: var(--fm-zindex-3)}.fm-lookup-panel{height:100%;display:flex;flex-direction:column;overflow:hidden;background-color:var(--fm-lookup-panel-background)}.fm-lookup-panel__header{background-color:var(--fm-background-white)}.fm-lookup-panel__header__search{border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-lookup-panel__header__search:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-lookup-panel__header__selected-wrapper{display:flex;padding:6px 16px;overflow:auto}.fm-lookup-panel__header__selected-item{font-size:14px;line-height:20px;word-break:keep-all;white-space:nowrap;padding:4px 6px;color:var(--fm-primary-color);background-color:var(--fm-primary-color-light);border-radius:4px}.fm-lookup-panel__header__selected-item:not(:last-child){margin-right:8px}.fm-lookup-panel__footer{padding:0 16px;height:48px;display:flex;align-items:center;justify-content:space-between;box-shadow:0 0 7px 0 var(--fm-box-shadow-color);border-top:1px solid var(--fm-gray-1);background-color:var(--fm-background-white)}.fm-lookup-panel__content{flex:1;display:flex;overflow:hidden;margin-top:10px;position:relative}.fm-lookup-panel__list{flex:1;overflow-y:auto;background-color:var(--fm-background-white)}.fm-lookup-panel__list-item{display:flex;align-items:center;background-color:#fff}.fm-lookup-panel__list-checker{padding-left:16px}.fm-lookup-panel__search-list{position:absolute;inset:0;display:none;overflow-y:auto;z-index:var(--fm-lookup-panel-search-list-zindex);background-color:var(--fm-background-white)}.fm-lookup-panel__popup-selected{width:100%;display:flex;flex-direction:column}.fm-lookup-panel__popup-selected__footer-left{color:var(--fm-primary-color)}.fm-lookup-panel__selected-list{flex:1;overflow:auto}.fm-lookup-panel__empty{padding:12px 16px}.fm-lookup-panel__empty__text{text-align:center;color:var(--fm-text-color-light)}.fm-lookup-panel__breadcrumb{display:flex;align-items:center;height:42px;padding:0 16px;overflow:auto;border-bottom:1px solid var(--fm-border-color);position:relative;border-bottom:none}.fm-lookup-panel__breadcrumb:after{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-lookup-panel__breadcrumb__item{display:flex;align-items:center;color:var(--fm-primary-color);padding-right:8px;flex-shrink:0}.fm-lookup-panel__breadcrumb__item:last-child{color:var(--fm-text-color-light)}.fm-lookup-panel__breadcrumb__icon{font-size:10px;padding-left:4px}.fm-lookup-panel__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)}: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)}.fm-search{display:flex;align-items:center;padding:8px 12px;color:var(--fm-search-color);background-color:var(--fm-search-background)}.fm-search__input-wrapper{flex:1;padding:5px 8px;border-radius:17px;background-color:var(--fm-search-input-background)}.fm-search__input{background-color:var(--fm-search-input-background)}.fm-search__search-icon{margin-right:4px;color:var(--fm-text-color-light)}.fm-filter-panel{height:100%;display:flex;flex-direction:column;padding:8px 16px}.fm-filter-panel__content{flex:1}.fm-filter-panel__footer{padding:8px 16px}.fm-filter-panel__field:not(:first-child){margin-top:16px}.fm-filter-panel__field__title{display:flex;align-items:center;justify-content:space-between;line-height:22px}.fm-filter-panel__field__content{padding-top:12px}.fm-filter-panel__field__range{display:flex;align-items:center}.fm-filter-panel__field__range__splitter{width:8px;margin:0 8px;border:1px solid #999}.fm-filter-panel__field__list{display:flex;flex-wrap:wrap;margin:0 -5px}.fm-filter-panel__field__list__item{height:30px;width:89px;font-size:13px;text-align:center;overflow:hidden;padding:6px 8px;margin:0 5px 10px;background:var(--fm-background);border-radius:var(--fm-radius-md);color:var(--fm-primary-color)}.fm-filter-panel__field__list__item--selected{background:var(--fm-primary-color);color:var(--fm-background-white)}.fm-filter-panel__field .fm-input-group .fm-input-group__body{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}.fm-filter__portal{display:flex;align-items:center;padding:8px 16px}.fm-filter__portal__icon{font-size:20px}.fm-filter__portal__search{flex:1;padding:0 0 0 8px}.fm-page-container{flex:1;display:flex;flex-direction:column;background:#f9fafb;overflow:hidden;-webkit-overflow-scrolling:auto;position:absolute;inset:0}.fm-page-container .drag-container{display:inherit;flex-direction:inherit;flex-shrink:1;flex-grow:1;flex-basis:0%;flex-wrap:inherit;justify-content:inherit;align-items:inherit;width:100%;overflow:inherit}.fm-page-body-container{flex-basis:0;flex-shrink:1;flex-grow:1;padding-bottom:12px;overflow:auto;display:flex;flex-direction:column}.fm-page-header-container{flex-shrink:0}.fm-page-footer-container{background-color:#fff}.fm-float-container{position:absolute!important} diff --git a/packages/mobile-render/public/assets/farris-mobile-page-vue.css b/packages/mobile-render/public/assets/farris-mobile-page-vue.css index b8115616c75..9f77c8bbd16 100644 --- a/packages/mobile-render/public/assets/farris-mobile-page-vue.css +++ b/packages/mobile-render/public/assets/farris-mobile-page-vue.css @@ -1 +1 @@ -@charset "UTF-8";a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0}html{line-height:1;-webkit-tap-highlight-color:transparent}ol,ul{list-style:none}table{border-collapse:collapse;border-spacing:0}caption,td,th{font-weight:400;vertical-align:middle}blockquote,q{quotes:none}blockquote::after,blockquote::before,q::after,q::before{content:'';content:none}a img{border:none}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary{display:block}*,::after,::before{box-sizing:border-box}body{min-height:100vh;color:#333;background-color:#fff}@supports ((height:constant(safe-area-inset-top)) or (height:env(safe-area-inset-top))) and (-webkit-overflow-scrolling:touch){body{padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom)}}a{text-decoration:none;background:0 0}button,input[type=number],input[type=text],input[type=password],input[type=email],input[type=search],select,textarea{margin:0;font-family:inherit;-webkit-appearance:none}.fm-text-light{color:#888}.fm-text-lighter{color:#777}.fm-text-lightest{color:#666}.fm-text-emph{color:#333}.fm-text-primary{color:#3A90FF}.fm-utils-clearfix::after{content:'';clear:both;overflow:hidden}.fm-page{position:absolute;top:0;left:0;bottom:0;right:0;display:flex;flex-direction:column;background:#f9fafb;overflow:hidden}.fm-page-header{flex-shrink:0}.fm-page-main{flex-basis:0;flex-shrink:1;flex-grow:1;padding-bottom:12px;overflow:auto;display:flex;flex-direction:column}.fm-page-navbar{flex-shrink:0}.fm-page-footer{background-color:#fff}.fm-page-footer-btns{display:flex;flex-direction:row;align-items:center;height:100%}.fm-page-footer-btns-item{flex:1;display:flex;flex-direction:column;text-align:center;justify-content:center}.fm-page-footer-btns-item-icon{margin-bottom:4px;font-size:18px}.fm-page-footer-btns-item-text{font-size:12px;color:#999}.fm-page-footer-btns-item:hover .fm-page-footer-btns-item-icon{font-size:22px;color:#3a90ff}.fm-page-footer-btns-item:hover .fm-page-footer-btns-item-text{color:#3a90ff}.fm-form-control,.fm-textarea{width:100%;font-size:14px;color:#333}.fm-form-control{display:block;min-width:0;height:22px;margin:0;padding:0 4px;line-height:inherit;text-align:left;background-color:transparent;border:1px solid #ddd;border-radius:3px;resize:none}.fm-form-control:focus{border-color:#3499f6}.fm-textarea{border-radius:4px;padding:6px 16px;border:1px solid #ddd;outline:0;line-height:24px;display:inline-flex;vertical-align:middle}.fm-textarea:focus{border-color:#3499f6}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-info{background-color:#4D9AFF!important}.bg-submit{background-color:#5AC1C3!important}.bg-success{background-color:#5CC171!important}.bg-warning{background-color:#FF9800!important}.bg-danger{background-color:#F24645!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #DDD;border-radius:0}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border{position:relative;border:none}html:not([data-scale]) .border::before{content:'';position:absolute;left:0;top:0;width:200%;height:200%;border:1px solid #DDD;border-radius:0;transform-origin:0 0;transform:scale(.5);box-sizing:border-box;pointer-events:none}}.border-top{border-top:1px solid #DDD;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border-top{border-top:none}html:not([data-scale]) .border-top::before{content:'';position:absolute;background-color:#DDD;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:100%;height:1PX;transform-origin:50% 50%;transform:scaleY(.5)}}.border-right{border-right:1px solid #DDD;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border-right{border-right:none}html:not([data-scale]) .border-right::after{content:'';position:absolute;display:block;z-index:1;top:0;right:0;bottom:auto;left:auto;width:1PX;height:100%;background:#DDD;transform-origin:100% 50%;transform:scaleX(.5)}}.border-bottom{border-bottom:1px solid #DDD;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border-bottom{border-bottom:none}html:not([data-scale]) .border-bottom::after{content:'';position:absolute;background-color:#DDD;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.border-left{border-left:1px solid #DDD;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border-left{border-left:none}html:not([data-scale]) .border-left::before{content:'';position:absolute;background-color:#DDD;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:1PX;height:100%;transform-origin:100% 50%;transform:scaleX(.5)}}.border-0::before,.border-bottom-0::after,.border-left-0::before,.border-right-0::after,.border-top-0::before{display:none!important}.border-0{border:0}.border-top-0{border-top:0}.border-right-0{border-right:0}.border-bottom-0{border-bottom:0}.border-left-0{border-left:0}.clearfix::after{display:block;clear:both;content:""}.display-none{display:none!important}.display-inline{display:inline!important}.display-inline-block{display:inline-block!important}.display-block{display:block!important}.display-table{display:table!important}.display-table-row{display:table-row!important}.display-table-cell{display:table-cell!important}.display-flex,.fm-utils-flex-column{display:flex!important}.display-inline-flex{display:inline-flex!important}.flex-direction-row{flex-direction:row!important}.flex-direction-column{flex-direction:column!important}.flex-direction-row-reverse{flex-direction:row-reverse!important}.flex-direction-column-reverse{flex-direction:column-reverse!important}.flex-row,.fm-utils-flex-row{flex-direction:row!important}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-bottom,.fixed-top{position:fixed;z-index:1030;right:0;left:0}.fixed-top{top:0}.fixed-bottom{bottom:0}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.m-base{margin:4px!important}.mt-base,.my-base{margin-top:4px!important}.mr-base,.mx-base{margin-right:4px!important}.mb-base,.my-base{margin-bottom:4px!important}.ml-base,.mx-base{margin-left:4px!important}.p-base{padding:4px!important}.pt-base,.py-base{padding-top:4px!important}.pr-base,.px-base{padding-right:4px!important}.pb-base,.py-base{padding-bottom:4px!important}.pl-base,.px-base{padding-left:4px!important}.m-xs{margin:8px!important}.mt-xs,.my-xs{margin-top:8px!important}.mr-xs,.mx-xs{margin-right:8px!important}.mb-xs,.my-xs{margin-bottom:8px!important}.ml-xs,.mx-xs{margin-left:8px!important}.p-xs{padding:8px!important}.pt-xs,.py-xs{padding-top:8px!important}.pr-xs,.px-xs{padding-right:8px!important}.pb-xs,.py-xs{padding-bottom:8px!important}.pl-xs,.px-xs{padding-left:8px!important}.m-sm{margin:12px!important}.mt-sm,.my-sm{margin-top:12px!important}.mr-sm,.mx-sm{margin-right:12px!important}.mb-sm,.my-sm{margin-bottom:12px!important}.ml-sm,.mx-sm{margin-left:12px!important}.p-sm{padding:12px!important}.pt-sm,.py-sm{padding-top:12px!important}.pr-sm,.px-sm{padding-right:12px!important}.pb-sm,.py-sm{padding-bottom:12px!important}.pl-sm,.px-sm{padding-left:12px!important}.m-md{margin:16px!important}.mt-md,.my-md{margin-top:16px!important}.mr-md,.mx-md{margin-right:16px!important}.mb-md,.my-md{margin-bottom:16px!important}.ml-md,.mx-md{margin-left:16px!important}.p-md{padding:16px!important}.pt-md,.py-md{padding-top:16px!important}.pr-md,.px-md{padding-right:16px!important}.pb-md,.py-md{padding-bottom:16px!important}.pl-md,.px-md{padding-left:16px!important}.m-lg{margin:24px!important}.mt-lg,.my-lg{margin-top:24px!important}.mr-lg,.mx-lg{margin-right:24px!important}.mb-lg,.my-lg{margin-bottom:24px!important}.ml-lg,.mx-lg{margin-left:24px!important}.p-lg{padding:24px!important}.pt-lg,.py-lg{padding-top:24px!important}.pr-lg,.px-lg{padding-right:24px!important}.pb-lg,.py-lg{padding-bottom:24px!important}.pl-lg,.px-lg{padding-left:24px!important}.m-xl{margin:32px!important}.mt-xl,.my-xl{margin-top:32px!important}.mr-xl,.mx-xl{margin-right:32px!important}.mb-xl,.my-xl{margin-bottom:32px!important}.ml-xl,.mx-xl{margin-left:32px!important}.p-xl{padding:32px!important}.pt-xl,.py-xl{padding-top:32px!important}.pr-xl,.px-xl{padding-right:32px!important}.pb-xl,.py-xl{padding-bottom:32px!important}.pl-xl,.px-xl{padding-left:32px!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-align-left{text-align:left!important}.text-align-right{text-align:right!important}.text-align-center{text-align:center!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.visible{visibility:visible}.invisible{visibility:hidden}.d-flex{display:flex}.d-inline-flex{display:inline-flex}.d-block{display:block}.d-inline-block{display:inline-block}.d-inline{display:inline}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.fm-utils-absolute-all{top:0;bottom:0;position:absolute;right:0;left:0}.fm-utils-flex-column{flex-direction:column!important;overflow:hidden}.fm-utils-fill-flex-column,.fm-utils-fill-flex-row{flex-shrink:1;display:flex!important;overflow:hidden}.fm-utils-fill-flex-column{flex-grow:1;flex-basis:0;flex-direction:column!important}.fm-utils-flex-row{display:flex!important;overflow:hidden;flex-wrap:nowrap}.fm-utils-flex-row-wrap{display:flex!important;flex-direction:row!important;overflow:hidden;flex-wrap:wrap!important}.fm-utils-fill-flex-row{flex-grow:1;flex-basis:0;flex-direction:row!important;flex-wrap:nowrap!important}.fm-utils-fill-flex-row-wrap{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex!important;flex-direction:row!important;overflow:hidden;flex-wrap:wrap!important}.fm-utils-fill{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-utils-fill-auto{flex-shrink:1;flex-grow:1;flex-basis:0;overflow-x:hidden;overflow-y:auto}.fm-utils-overflow-xhya{overflow-x:hidden!important;overflow-y:auto!important}.fm-utils-overflow-xayh{overflow-y:hidden!important;overflow-x:auto!important}.fm-utils-overflow-xaya{overflow:auto!important}.fm-utils-overflow-hidden{overflow:hidden!important}.fm-utils-overflow-auto{overflow:auto!important}.fm-overflow-x-auto{overflow-x:auto!important}.fm-overflow-x-hidden,.fm-overflow-y-auto,.fm-overflow-y-hidden{overflow-x:hidden!important}.fm-overflow-y-auto{overflow-y:auto!important}.fm-overflow-y-hidden{overflow-y:hidden!important}.fm-overflow-hidden{overflow:hidden!important}.fm-utils-text-break{white-space:normal!important;word-break:break-all!important}.fm-utils-display-none{display:none!important}.fm-multi-ellipsis-l2,.fm-multi-ellipsis-l3{display:-webkit-box;-webkit-box-orient:vertical;text-overflow:ellipsis;overflow:hidden}.fm-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-multi-ellipsis-l2{-webkit-line-clamp:2}.fm-multi-ellipsis-l3{-webkit-line-clamp:3}.fm-float-button-wrapper{position:absolute;right:16px;bottom:50px}.fm-listview-error{background:#fff;box-shadow:0 2px 6px 0 rgba(0,0,0,.12)}.fm-error-cell{position:relative;display:flex;justify-content:space-between;align-items:center;padding:0 16px;height:32px}.fm-error-cell:not(:last-child)::after{content:'';height:1px;position:absolute;background-color:#f1f1f1;display:block;z-index:1;bottom:0;left:16px;right:0;transform:translateY(.5)}.fm-error-text{font-size:13px;color:#f24645;line-height:22px}.fm-error-icon{background:#F24645;color:#fff;border-radius:100%;margin-right:4px}.fm-tmpl-single-header{height:32px;display:flex;align-items:center;padding:0 0 0 16px;background:#F8F9FB}.fm-tmpl-single-header h6{color:#999;font-size:15px;font-weight:400;margin:0}.fm-tmpl-singlelist-with-iconarea{background:#fff;overflow:hidden}.fm-tmpl-singlelist-with-iconarea .singlelist--item{align-items:center;padding:0 0 0 16px;display:flex}.fm-tmpl-singlelist-with-iconarea .singlelist--item:last-child .singlelist--item-title-wrapper{border-bottom:none}.fm-tmpl-singlelist-with-iconarea .singlelist--item .item-img-round--wrapper .item-img-round--img{width:26px;height:26px;border-radius:13px}.fm-tmpl-singlelist-with-iconarea .singlelist--item .item-img-round--wrapper .item-img-round--img .fm-icon{line-height:26px}.fm-tmpl-singlelist-with-iconarea .singlelist--item-title-wrapper{flex-shrink:1;flex-grow:1;flex-basis:0;color:#333;font-size:16px;line-height:22px;padding:11px 0 10px;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-singlelist-with-iconarea .singlelist--item-title-wrapper{border-bottom:none}html:not([data-scale]) .fm-tmpl-singlelist-with-iconarea .singlelist--item-title-wrapper::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.item-img-round--wrapper{margin:0 10px 0 0}.item-img-round--wrapper .item-img-round--img{width:30px;height:30px;border-radius:15px;text-align:center;color:#fff}.item-img-round--wrapper .item-img-round--img .fm-icon{font-size:18px;line-height:30px}.item-img-round--wrapper .fm-bg-yellow{background:#FBB902}.item-img-round--wrapper .fm-bg-orange{background:#FF9800}.item-img-round--wrapper .fm-bg-blue{background:#4D9AFF}.item-img-round--wrapper .fm-bg-lightblue{background:#5ACBCD}.item-img-round--wrapper .fm-bg-purple{background:#817EFF}.item-img-round--wrapper .fm-bg-darkgreen{background:#51BD78}.fm-tmpl-header-with-img{display:flex;align-items:center}.fm-tmpl-header-with-img h5{font-size:16px;color:#333;margin:0;font-weight:400}.fm-tmpl-header-with-img .header-with-img--img-wrapper{margin:0 8px 0 0}.fm-tmpl-header-with-img .header-with-img--img-wrapper .header-with-img--img{width:20px;height:20px;border-radius:10px;line-height:20px;text-align:center;color:#fff;background-image:linear-gradient(180deg,#64CDFB 1%,#3A90FF 100%)}.fm-tmpl-header-with-img .header-with-img--img-wrapper .header-with-img--img .fm-icon{font-size:12px}.fm-tmpl-header-with-img .header-with-img--img-wrapper .fm-bg-blue{color:#fff;background-image:linear-gradient(180deg,#64CDFB 1%,#3A90FF 100%)}.fm-tmpl-header-with-img .header-with-img--img-wrapper .fm-bg-orange{color:#fff;background-image:linear-gradient(180deg,#FFB951 15%,#FF9800 100%)}.fm-tmpl-header-with-img .header-with-img--img-wrapper .fm-bg-green{color:#fff;background-image:linear-gradient(180deg,#7ACC8D 15%,#51BD78 100%)}.fm-cmp-collapse-style::after{display:none}.fm-cmp-collapse-style .van-collapse-item__title{align-items:center}.fm-cmp-collapse-style .van-collapse-item__content{padding:0}.fm-cmp-collapse-style.van-collapse{margin:0 0 12px}.fm-cmp-collapse-style.van-collapse:last-child{margin-bottom:0}.fm-tmpl-collapse-sub::after{border-bottom:0}.fm-tmpl-collapse-sub-header{display:flex;flex-direction:column-reverse}.fm-tmpl-collapse-sub-header .van-collapse-item__title .expand,.fm-tmpl-collapse-sub-header .van-collapse-item__title--expanded .collapse{display:none}.fm-tmpl-collapse-sub-header .van-collapse-item__title{color:#888;flex-direction:row-reverse;justify-content:center}.fm-tmpl-collapse-sub-header .van-collapse-item__title h6{color:#888;font-size:13px;font-weight:400}.fm-tmpl-collapse-sub-header .van-collapse-item__title .collapse-icon{margin:0 8px;transition:transform .3s}.fm-tmpl-collapse-sub-header .van-collapse-item__title--expanded .expand{display:inline-block}.fm-tmpl-collapse-sub-header .van-collapse-item__title--expanded .collapse-icon{transform:rotate(180deg)}.fm-btn-block-wrapper{height:42px;background:#fff;display:flex;align-items:center}.fm-btn-block-wrapper .fm-button{font-size:14px!important;height:100%}.fm-btn-with-icon .fm-btn-text{margin:0 8px}.fm-btn-with-icon .fm-btn-icon{font-size:14px}.fm-tmpl-list-with-img-detail.fm-tmpl-list-with-border{margin-bottom:12px}.fm-tmpl-list-with-img-detail.fm-tmpl-list-with-border .img-detail--item{margin-bottom:0;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-list-with-img-detail.fm-tmpl-list-with-border .img-detail--item{border-bottom:none}html:not([data-scale]) .fm-tmpl-list-with-img-detail.fm-tmpl-list-with-border .img-detail--item::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-round-bg{margin:4px auto 0;width:36px;height:36px;background:#3A90FF;border-radius:20px;line-height:36px;font-size:13px;text-align:center;overflow:hidden;white-space:nowrap}.fm-round-bg-text{color:#FFF}.fm-tmpl-list-with-img-detail .img-detail--item{padding:12px 16px;background:#fff;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-list-with-img-detail .img-detail--item{border-bottom:none}html:not([data-scale]) .fm-tmpl-list-with-img-detail .img-detail--item::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--item-content{display:flex;position:relative}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--status{position:absolute;right:0;top:23px}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--content{position:relative;flex-shrink:1;flex-grow:1;flex-basis:0}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--header{display:flex;align-items:center;justify-content:space-between;margin:0 0 6px}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--header .title{line-height:22px;font-weight:400;font-size:16px;color:#333}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--header .time{line-height:18px;color:#999;font-size:13px}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--info{line-height:18px;color:#999;font-size:13px;margin:0 0 4px}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--info>.gutter{margin:0 14px 0 0}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--actions{padding:18px 0 0;text-align:right}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--actions .fm-button{margin-left:13px}.fm-tmpl-list-with-img-detail .img-detail--item .img-detail--actions .fm-button:first-child{margin-left:0}.fm-tmpl-result{display:flex;flex-direction:column;padding-top:40px;align-items:center}.fm-tmpl-result-header .fm-result-title{display:flex;flex-direction:row;font-size:20px;color:#333}.fm-tmpl-result-header .fm-result-title .fm-result-title-number{color:#FF9800}.fm-tmpl-result-content{max-width:84%;padding-top:30px;padding-bottom:30px;text-align:center}.fm-tmpl-result-content .fm-result-img{width:140px;height:140px;margin:0 auto}.fm-tmpl-result-content .fm-result-img img{display:block;width:140px;height:140px}.fm-tmpl-result-content .fm-result-text{padding-top:30px;padding-bottom:10px;font-size:16px;color:#333;text-align:center}.fm-tmpl-result-content .fm-result-tip{line-height:22px;font-size:16px;color:#888;text-align:center}.fm-tmpl-result-footer{width:140px;margin:0 auto}.fm-tmpl-result-footer .fm-result-btn{margin-bottom:16px}.fm-tmpl-result-footer .fm-result-btn:last-child{margin-bottom:0}.fm-tabbar-style{border-top:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tabbar-style{border-top:none}html:not([data-scale]) .fm-tabbar-style::before{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:100%;height:1PX;transform-origin:50% 50%;transform:scaleY(.5)}}.fm-tabbar-style .show-fixed-width{padding:0 17px;flex-shrink:0;flex-grow:0;flex-basis:auto}.fm-tabbar-style .show-fixed-width+.show-left-width{padding:7px 16px 7px 0}.fm-tabbar-style .show-fixed-width .van-tabbar-item__icon .fm-icon{font-size:19px}.fm-tabbar-style .show-fixed-width .van-tabbar-item__text{font-size:12px;transform:scale(.8333)}.fm-tabbar-style .show-left-width{padding:7px 16px}.fm-tabbar-style .show-left-width .fm-button{height:100%}.fm-tmpl-detail-header{padding-left:16px;background-color:#fff}.fm-tmpl-detail-header-inner{display:flex;flex-direction:row;align-items:center;padding:16px 16px 16px 0;border-bottom:1px solid #DDD;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-detail-header-inner{border-bottom:none}html:not([data-scale]) .fm-tmpl-detail-header-inner::after{content:'';position:absolute;background-color:#DDD;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-approve-flow-wrapper .fm-approve-flow-item .fm-approve-flow-item-header-icon .header-icon::before,.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar .avatar-icon::before{content:"\e6b4"}.fm-tmpl-detail-header-inner .detail-header--avatar{width:40px;margin-right:10px;border-radius:50%;overflow:hidden}.fm-tmpl-detail-header-inner .detail-header--avatar img{display:block;width:40px;height:40px}.fm-tmpl-detail-header-inner .detail-header--content{flex:1}.fm-tmpl-detail-header-inner .detail-header--content-title{margin-bottom:3px;font-size:15px;color:#333}.fm-tmpl-detail-header-inner .detail-header--content-subtitle{font-size:13px;color:#888}.fm-static-input-list{padding:16px 0 16px 16px;background-color:#fff;margin:0 0 8px}.fm-static-input-list .fm-listview-item:last-child .fm-static-input-info{margin-bottom:0}.fm-static-input-info{display:flex;flex-direction:row;align-items:center;margin-bottom:8px;line-height:20px}.fm-static-input-info .input-info--label{width:92px;font-size:14px;color:#999;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fm-static-input-info .input-info--text{flex-shrink:1;flex-grow:1;flex-basis:0;padding-left:8px;font-size:14px;color:#333}.fm-static-input-info .input-info--accessory{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap}.fm-static-input-info .input-info--accessory-item{flex-shrink:0;width:28px;height:28px;margin-right:12px;border-radius:3px;overflow:hidden}.fm-static-input-info .input-info--accessory-item img{display:block;width:28px}.fm-static-input-info .input-info--accessory-item:last-child{margin-right:0}.fm-approve-flow-wrapper{padding:12px 16px;background-color:#fff}.fm-approve-flow-wrapper .fm-approve-flow-item{padding-left:7px}.fm-approve-flow-wrapper .fm-approve-flow-item-header{position:relative;border-left:1px dashed #D4D4D4}.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner{position:relative;display:flex;flex-direction:row;align-items:center;padding-left:28px}.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon{position:absolute;left:-8px;top:0;z-index:100}.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon .fm-icon{background-color:#fff;font-size:15px;color:#34AAFF;border-radius:50%}.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon img{background:#fff}.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-content{flex-shrink:1;flex-grow:1;flex-basis:0;line-height:21px;font-size:15px;color:#4C4C4C;font-weight:700}.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-right{flex-shrink:0;padding-left:6px}.fm-approve-flow-wrapper .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-right .fm-icon{color:#979797}.fm-approve-flow-wrapper .fm-approve-flow-item-header-state{margin-top:6px;padding-left:28px;font-size:13px;color:#FF9002}.fm-approve-flow-wrapper .fm-approve-flow-item-content{display:flex;flex-direction:row;align-items:flex-start;padding:12px 0 30px 28px;border-left:1px dashed #D4D4D4}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main{flex-shrink:1;flex-grow:1;flex-basis:0;display:flex;flex-direction:row;align-items:flex-start}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar{position:relative;display:flex;flex-direction:row;align-items:center;width:36px;height:36px}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar-img{display:block;width:36px;height:36px;border-radius:50%}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar-icon{position:absolute;right:4px;bottom:-4px;font-size:14px;color:#34AAFF;background-color:#fff;border-radius:50%}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-text{flex-shrink:1;flex-grow:1;flex-basis:0;padding:0 6px 0 9px}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-text-title{font-size:13px;color:rgba(51,51,51,.65)}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-main-text-subtitle{margin-top:2px;line-height:20px;font-size:14px;color:#333}.fm-approve-flow-wrapper .fm-approve-flow-item-content .fm-approve-flow-item-date{font-size:13px;color:rgba(51,51,51,.65)}.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar-icon,.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-header .fm-approve-flow-item-header-icon .fm-icon,.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-header .fm-approve-flow-item-header-state{color:#1AD0C8}.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-content .fm-approve-flow-item-main-avatar .avatar-icon::before,.fm-approve-flow-wrapper .fm-approve-flow-item.fm-approve-flow-item-approved .fm-approve-flow-item-header .fm-approve-flow-item-header-icon .header-icon::before{content:"\e6b3"}.fm-approve-flow-wrapper .fm-approve-flow-item:last-child .fm-approve-flow-item-header{border-left:0}.fm-approve-flow-wrapper .fm-approve-flow-item:last-child .fm-approve-flow-item-header::before{display:none!important}.fm-approve-flow-wrapper .fm-approve-flow-item:last-child .fm-approve-flow-item-content{padding-bottom:12px;border-left:none}.fm-approve-nopass,.fm-approve-pass{position:fixed;top:48px;right:14px;width:110px;height:110px;z-index:1000}.fm-approve--detail-header{padding-left:16px;background-color:#fff}.fm-approve--detail-header-inner{display:flex;flex-direction:row;align-items:center;padding:17px 16px 17px 0;border-bottom:1px solid #DDD;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-approve--detail-header-inner{border-bottom:none}html:not([data-scale]) .fm-approve--detail-header-inner::after{content:'';position:absolute;background-color:#DDD;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-approve--detail-header-inner .detail-header--avatar{width:40px;margin-right:10px;border-radius:50%;overflow:hidden}.fm-approve--detail-header-inner .detail-header--avatar img{display:block;width:40px;height:40px}.fm-approve--detail-header-inner .detail-header---info{flex:1}.fm-approve--detail-header-inner .detail-header---info-title{margin-bottom:3px;font-size:15px;color:#333}.fm-approve--detail-header-inner .detail-header---info-subtitle{font-size:13px;color:#888}.fm-apply-list-wrapper{padding:0 16px 16px;background-color:#fff;margin:0 0 12px}.fm-apply-list-item{display:flex;flex-direction:row;align-items:flex-start;margin-bottom:8px;line-height:20px}.fm-apply-list-item-label{width:92px;font-size:14px;color:#999;text-align:right;word-break:break-all}.fm-apply-list-item-text{flex-shrink:1;flex-grow:1;flex-basis:0;padding-left:14px;font-size:14px;color:#333;word-break:break-all}.fm-apply-list-item-accessory{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap}.fm-apply-list-item-accessory-item{flex-shrink:0;width:28px;height:28px;margin-right:12px;border-radius:3px;overflow:hidden}.fm-apply-list-item-accessory-item img{display:block;width:28px}.fm-apply-list-item-accessory-item:last-child{margin-right:0}.fm-apply-list-item:last-child{margin-bottom:0}.fm-apply-panel-title,.fm-apply-plate-title{height:28px;line-height:28px;padding-left:10px;margin-bottom:0;background:#F6F6F6;border-radius:2px}.fm-apply-panel-action,.fm-apply-plate-action{padding:0 6px;margin:0 0 0 auto;color:#D8D8D8}.fm-apply-panel-action:hover,.fm-apply-plate-action:hover{background:#3A90FF;color:#fff}.fm-apply-panel{padding-top:0}.fm-apply-panel .fm-apply-list{padding-top:10px;padding-bottom:14px}.fm-apply-panel .fm-apply-list+.fm-apply-list{border-top:1px solid #E8E8E8}.fm-apply-panel-list{padding:0 16px;background-color:#fff;margin:0;border-bottom:1px solid #E8E8E8}.fm-apply-panel-list:last-child{border-bottom:none}.fm-apply-panel-list .panel-list--header{height:42px;display:flex;align-items:center}.fm-apply-panel-list .panel-list--header .panel-list--header-title{font-size:15px;line-height:21px;color:#333;padding:0 0 0 10px;position:relative}.fm-apply-panel-list .panel-list--header .panel-list--header-title::before{content:'';position:absolute;left:0;top:50%;width:3px;height:14px;margin:-7px 0 0;background:#55BBF6}.fm-apply-details{margin:0 0 14px;background:#fff}.fm-apply-main{border-bottom:1px solid #E8E8E8}.fm-avatar-with-state{position:relative;display:flex;flex-direction:row;align-items:center;width:36px;height:36px}.fm-avatar-with-state--img{display:block;width:36px;height:36px;border-radius:50%}.fm-avatar-with-state--icon{position:absolute;right:4px;bottom:-4px;font-size:14px;color:#34AAFF;background-color:#fff;border-radius:50%}.fm-avatar-with-state .avatar-icon::before{content:"\e6b3"}.fm-avatar-with-state .fm-round-bg{background:rgba(77,154,255,.6)}.fm-avatar-with-state.fm-state-running .avatar-icon::before{content:"\e6b4"}.fm-feature-select-person{display:flex;flex-direction:row;flex-wrap:wrap;padding:0 0 14px}.fm-feature-select-person .select-person--item{position:relative;display:flex;align-items:center;margin:0 16px 0 0}.fm-feature-select-person .select-person--item .fm-avatar-with-state{width:48px;height:48px}.fm-feature-select-person .select-person--item .fm-avatar-with-state .fm-avatar-with-state--img{width:48px;height:48px;border-radius:24px}.fm-feature-select-person .select-person--item .fm-avatar-with-state .fm-avatar-with-state--icon{right:0;top:0;cursor:pointer}.fm-feature-select-person .select-person--item .fm-avatar-with-state .fm-avatar-with-state--icon::before{content:"\e016"}.fm-feature-select-person .select-person--item .fm-avatar-with-state .fm-avatar-with-state--icon:hover{background:#F24645;color:#fff}.fm-feature-select-person .select-person--item .fm-round-bg{width:48px;height:48px;border-radius:24px;line-height:48px}.fm-feature-select-person .select-person--icon{margin:0 0 0 3px;color:#A6A6A6}.fm-feature-select-person .select-person--icon::before{content:"→"}.fm-tmpl-search-container{position:relative;padding:7px 16px;display:flex;flex-direction:row;align-items:center;background:#fff}.fm-tmpl-search-container .fm-tmpl-search-type{flex-shrink:0;margin:0 10px 0 0}.fm-tmpl-search-container .fm-tmpl-search-type.fm-state-active{color:#3A90FF}.fm-tmpl-search-container .fm-tmpl-search-inner{flex:1 1 0}.fm-tmpl-search-container .fm-tmpl-search-inner .van-search{padding:0}.fm-tmpl-search-container .fm-tmpl-search-tree-select{position:absolute;left:0;right:0;top:100%;z-index:10}.fm-page-listview{display:flex;flex-direction:column}.fm-page-listview .fm-page-main{padding-bottom:0;flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-page-listview .fm-page-main .fm-tmpl-list-extend,.fm-page-listview .fm-page-main .fm-tmpl-search-container{flex-shrink:0}.fm-page-listview .fm-page-main .fm-tmpl-list-container{display:flex;flex-direction:column;flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-list-footer{display:flex;flex-direction:row;align-items:center;height:54px;padding:0 16px;background:#fff;box-shadow:0 -2px 8px 0 rgba(81,120,159,.12)}.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-list-footer .fm-tmpl-list-footer-btn{flex:1;text-align:center}.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-search-tree-overlay{position:absolute;left:0;bottom:0;right:0;top:0;z-index:9;background-color:rgba(0,0,0,.4)}.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-add-btn{position:absolute;right:16px;bottom:50px}.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-add-btn-inner{width:48px;height:48px;text-align:center;line-height:48px;border-radius:50%;background-image:linear-gradient(-45deg,#65A7FF 0,#3A90FF 100%);box-shadow:0 2px 5px 0 rgba(124,163,254,.57)}.fm-page-listview .fm-page-main .fm-tmpl-list-container .fm-tmpl-add-btn-inner .fm-icon{color:#fff;font-size:16px}.fm-page-listview .fm-page-main .fm-tmpl-list-container .van-pull-refresh{display:flex;flex-direction:column;flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-page-listview .fm-page-main .fm-tmpl-list-container .van-pull-refresh .van-pull-refresh__track{display:flex;flex-direction:column;flex-shrink:1;flex-grow:1;flex-basis:0}.fm-page-listview .fm-page-main .fm-tmpl-list-add .fm-tmpl-add-btn{bottom:16px}.fm-page-listview .fm-page-main .fm-tmpl-list-add .fm-listview-container.fm-listview-container-fill .fm-listview-main{padding-bottom:70px}.fm-page-listview .fm-page-main .fm-tmpl-tabs{flex:1;display:flex;flex-direction:column}.fm-page-listview .fm-page-main .fm-tmpl-tabs .fm-tab-bar,.fm-page-listview .fm-page-main .fm-tmpl-tabs .van-tabs__wrap{flex-shrink:0}.fm-page-listview .fm-page-main .fm-tmpl-tabs .fm-tabs-content,.fm-page-listview .fm-page-main .fm-tmpl-tabs .fm-tabs-content .fm-tab-pane,.fm-page-listview .fm-page-main .fm-tmpl-tabs .van-tabs__content{display:flex;flex-direction:column;flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-page-listview .fm-page-main .fm-tmpl-tabs .van-tabs__content .van-tab__pane{display:flex;flex-direction:column;flex:1}.fm-page-listview .fm-page-main .fm-tmpl-tabs .fm-tmpl-tabs-content{display:flex;flex-direction:column;flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-page-card .fm-page-footer,.fm-tmpl-list-extend{flex-shrink:0}.fm-btn-link{color:#3A90FF}.fm-page-card{display:flex;flex-direction:column}.fm-page-card .fm-page-main{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:auto}.fm-page-card .fm-page-main .fm-page-card-btns{padding:30px 16px 0}.fm-tmpl-struct-wrapper{flex-shrink:0;margin-top:12px}.fm-tmpl-struct-wrapper .fm-tmpl-section{margin-top:12px}.fm-tmpl-struct-wrapper .fm-tmpl-section:first-child{margin-top:0}.fm-tmpl-section{background-color:#fff}.fm-title::before,.fm-tmpl-section-header .fm-title::before{content:'';background:#3A90FF}.fm-tmpl-section-header{display:flex;align-items:center;justify-content:space-between;padding:11px 16px 10px}.fm-tmpl-section-header .fm-title{position:relative;padding-left:16px}.fm-tmpl-section-header .fm-title::before{position:absolute;left:0;top:50%;width:3px;height:14px;margin:-7px 0 0}.fm-tmpl-section-header .fm-title-text{font-size:15px;line-height:21px;color:#333}.fm-tmpl-section-header .fm-toolbar{display:flex;align-items:center}.fm-tmpl-section-header .fm-toolbar-item{display:flex;align-items:center;padding-left:16px;font-size:15px;color:#3A90FF}.fm-tmpl-section-header .fm-toolbar-item-text{margin-left:4px}.fm-tmpl-section-header .fm-toolbar-item-icon{font-size:16px}.fm-tmpl-section-content{padding:0 16px}.fm-tmpl-button-wrapper{padding:30px 16px 0;flex-shrink:0}.fm-tmpl-button-wrapper .fm-tmpl-btns{display:flex;align-items:center}.fm-tmpl-button-wrapper .fm-tmpl-btns .fm-button{flex:1;margin-right:11px}.fm-tmpl-button-wrapper .fm-tmpl-btns.fm-button:last-child{margin-right:0}.fm-tmpl-section-btn{display:flex;flex-direction:row;align-items:center;padding:0 16px;border-top:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-section-btn{border-top:none}html:not([data-scale]) .fm-tmpl-section-btn::before{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:100%;height:1PX;transform-origin:50% 50%;transform:scaleY(.5)}}.fm-tmpl-section-btn .fm-button{flex:1;position:relative}.fm-tmpl-section-btn .fm-button::after{position:absolute;right:0;top:50%;width:1px;height:16px;margin-top:-8px;background:#ddd;transform:scaleX(.5);content:''}.fm-tmpl-section-btn .fm-button:last-child::after{display:none}.fm-card-tmpl-header{height:36px;line-height:36px;background-color:#f9f9fb;padding-left:16px}.fm-edit-input-list{position:relative}.fm-banner-warpper{position:relative;background:url(imgs/questionnaire-header.png) center/cover no-repeat;display:flex;flex-direction:column;align-items:center;justify-content:center}.fm-banner-warpper .fm-banner-title,.fm-banner-warpper .fm-banner-title-sub{color:#fff;text-shadow:0 2px 8px rgba(0,26,123,.52)}.fm-banner-warpper .fm-banner-title{font-size:24px;line-height:33px}.fm-banner-warpper .fm-banner-title-sub{font-size:12px;line-height:17px;padding-top:4px}@media screen and (max-width:375px){.fm-banner-warpper{height:98px}}@media screen and (min-width:375px) and (max-width:414px){.fm-banner-warpper{height:116px}}@media screen and (min-width:414px){.fm-banner-warpper{height:128px}}.fm-stamp-wrapper{width:68px;height:68px;position:absolute;right:16px;top:12px;background:url(imgs/questionnaire-submitted.png) center/contain no-repeat;z-index:9}.fm-card-uploader-content{padding:10px 16px}.fm-page-header-staff{background:linear-gradient(90deg,#2899F6 0,#3E76F9 50%,#4384F8 100%)}.fm-page-header-staff .fm-navbar{background:0 0}.fm-page-header-staff .fm-navbar .fm-navbar-left-arrow,.fm-page-header-staff .fm-navbar .fm-navbar-title{color:#fff}.fm-navbar-right-text{color:#333;font-size:16px}.fm-input-wrapper:not(:last-child) .van-cell::after{display:block}.fm-inner-cell .van-checkbox__label::after,.fm-inner-cell .van-radio__label::after,.fm-input-wrapper:last-child .van-cell::after{display:none}.fm-radio-readonly .fm-inner-cell .van-radio .van-radio__icon .van-icon{background-color:#fff}.fm-radio-readonly .fm-inner-cell .van-radio .van-radio__icon--checked .van-icon{background-color:#1989fa;border-color:#1989fa}html:not([data-scale]) .fm-input-wrapper:not(:last-child) .fm-cell:not(.fm-no-hairline)::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1px;transform-origin:50% 100%}.fm-input-wrapper:not(:last-child) .fm-cell::after{left:16px!important}.fm-input-label-tips{display:flex;align-items:center;padding-left:4px}.fm-input-label-tips-content{font-size:14px;color:#333;line-height:20px;padding:6px 16px}.fm-tmpl-listview-timeline{margin-left:5px}.fm-tmpl-listview-timeline .fm-tmpl-timeline-text{position:relative;padding-left:22px;padding-bottom:2px;line-height:20px;font-size:14px;color:#666}.fm-tmpl-listview-timeline .fm-tmpl-timeline-text::after{position:absolute;left:-5px;top:5px;width:10px;height:10px;background-color:#ddd;border-radius:50%;content:''}.fm-tmpl-listview-timeline .fm-tmpl-timeline-text::before{position:absolute;left:0;top:0;bottom:0;width:1px;background-color:#ddd;content:''}.fm-tmpl-listview-timeline .fm-tmpl-timeline-date{padding-bottom:20px;padding-left:22px;font-size:12px;color:#999;border-left:1px solid #ddd}.fm-tmpl-listview-timeline.fm-tmpl-listview-timeline-first .fm-tmpl-timeline-text:before{top:5px}.fm-tmpl-listview-timeline.fm-tmpl-listview-timeline-last .fm-tmpl-timeline-text:before{height:5px}.fm-tmpl-listview-timeline.fm-tmpl-listview-timeline-last .fm-tmpl-timeline-date{border-color:transparent}.fm-tmpl-listview-goods{padding-left:16px;display:flex;padding-top:10px}.fm-tmpl-listview-goods .fm-tmpl-goods-img{flex-shrink:0;width:86px;height:86px;margin-right:10px;overflow:hidden}.fm-tmpl-listview-goods .fm-tmpl-goods-img img{display:block;width:86px;height:86px}.fm-tmpl-listview-goods .fm-tmpl-goods-content{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden;padding-right:16px;padding-bottom:10px;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-input-wrapper:not(:last-child) .fm-cell:not(.fm-no-hairline)::after{transform:scaleY(.5)}html:not([data-scale]) .fm-tmpl-listview-goods .fm-tmpl-goods-content{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-goods .fm-tmpl-goods-content::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-name{position:relative;min-height:40px;padding-right:28px;margin-bottom:4px;line-height:20px;font-size:16px;color:#666}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-name .fm-tmpl-goods-add{position:absolute;right:0;top:30px;width:24px;height:24px;line-height:24px;text-align:center;background-color:#ececec;border-radius:50%}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-name .fm-tmpl-goods-add .fm-icon{font-size:12px;color:#999}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-price{display:flex;align-items:flex-end;line-height:22px;margin-bottom:3px;color:#fa6400}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-price-prefix{font-size:12px}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-price-text{font-size:16px}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-shop{display:flex;align-items:center;line-height:16px;font-size:12px;color:#888}.fm-tmpl-listview-goods .fm-tmpl-goods-content .fm-tmpl-goods-shop .fm-icon{margin-right:3px;font-size:12px}.fm-tmpl-listview-order{padding-left:16px}.fm-tmpl-listview-order-inner{padding:12px 16px 12px 0;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-order-inner{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-order-inner::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-order .fm-tmpl-listview-order-name{margin-bottom:3px;line-height:21px;font-size:15px;color:#333}.fm-tmpl-listview-order .order-line-item{display:flex;flex-direction:row;align-items:center}.fm-tmpl-listview-order .order-line-item-left{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-tmpl-listview-order .order-line-item-right{flex-shrink:0}.fm-tmpl-listview-order .fm-tmpl-listview-order-number{line-height:20px;margin-bottom:10px}.fm-tmpl-listview-order .fm-tmpl-listview-order-number .order-number-text{font-size:14px;color:#888}.fm-tmpl-listview-order .fm-tmpl-listview-order-msg{line-height:18px;font-size:13px}.fm-tmpl-listview-order .fm-tmpl-listview-order-msg .order-msg-date{color:#888}.fm-tmpl-listview-order .fm-tmpl-listview-order-msg .order-msg-price{color:#ff7300}.fm-tmpl-listview-shop{padding:0 8px 10px;background:#f9fafb}.fm-tmpl-listview-shop-inner{background:#fff}.fm-tmpl-listview-shop-header{padding:10px 10px 18px;display:flex;flex-direction:row}.fm-tmpl-listview-shop-header .shop-header-img{flex-shrink:0;width:46px;height:46px;margin-right:10px}.fm-tmpl-listview-shop-header .shop-header-img img{display:block;width:100%;height:100%}.fm-tmpl-listview-shop-header .shop-header-msg{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-tmpl-listview-shop-header .shop-header-msg .shop-header-name{display:flex;justify-content:space-between;margin-bottom:6px}.fm-tmpl-listview-shop-header .shop-header-msg .shop-header-name-text{padding-right:6px;line-height:22px;font-size:16px;color:#333}.fm-tmpl-listview-shop .shop-content-item,.fm-tmpl-listview-shop-header .shop-header-msg .shop-header-site{line-height:18px;font-size:13px;color:#999}.fm-tmpl-listview-shop-header .shop-header-msg .shop-header-name-status{flex-shrink:0}.fm-tmpl-listview-shop .shop-content-item{margin-bottom:8px;padding:0 10px}.fm-tmpl-listview-shop-footer{border-top:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-shop-footer{border-top:none}html:not([data-scale]) .fm-tmpl-listview-shop-footer::before{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:100%;height:1PX;transform-origin:50% 50%;transform:scaleY(.5)}.fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item::after{transform:scaleX(.5)}}.fm-tmpl-listview-shop-footer .shop-footer-btns{display:flex;flex-direction:row;align-items:center}.fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item{position:relative;flex:1;height:44px;padding:0 6px;line-height:44px;font-size:12px;color:#999;text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item .fm-icon{font-size:14px;margin-right:4px}.fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item::after{position:absolute;right:0;top:50%;width:1px;height:22px;margin-top:-11px;background-color:#ddd;content:''}.fm-tmpl-listview-shop-footer .shop-footer-btns .shop-footer-btn-item:last-child::after{display:none}.fm-tmpl-listview-shop-first{padding-top:10px}.fm-tmpl-listview-menu{padding-bottom:10px;background:#f9fafb}.fm-tmpl-listview-menu-inner{padding:10px 16px 0;background-color:#fff}.fm-tmpl-listview-menu-text{margin-bottom:10px;line-height:20px;font-size:14px;color:#666}.fm-tmpl-listview-menu-content .menu-list{display:flex;align-items:center;flex-wrap:wrap}.fm-tmpl-listview-menu-content .menu-list-item{flex:0 0 25%;display:flex;flex-direction:column;align-items:center;margin-bottom:10px}.fm-tmpl-listview-menu-content .menu-list-item-icon{width:46px;height:46px;margin-bottom:6px;line-height:46px;text-align:center;color:#fff;border-radius:16px;background-color:#40a9ff}.fm-tmpl-listview-menu-content .menu-list-item-icon .fm-icon{font-size:26px}.fm-tmpl-listview-menu-content .menu-list-item-text{line-height:20px;font-size:14px;color:#666}.fm-tmpl-listview-menu-last{padding-bottom:0}.fm-tmpl-listview-menus.fm-listview-content{display:flex;align-items:center;flex-wrap:wrap}.fm-tmpl-listview-menus .fm-listview-item{flex:0 0 33.3333%}.fm-tmpl-listview-menus-item{display:flex;flex-direction:column;align-items:center;margin-bottom:16px}.fm-tmpl-listview-menus-item .menu-list-item-icon{width:46px;height:46px;margin-bottom:6px;line-height:46px;text-align:center;color:#fff;border-radius:16px;background-color:#40a9ff}.fm-tmpl-listview-menus-item .menu-list-item-icon .fm-icon{font-size:26px}.fm-tmpl-listview-menus-item .menu-list-item-text{line-height:20px;font-size:14px;color:#666}.fm-tmpl-listview-basic{display:flex;align-items:flex-start;padding:0 16px;margin-bottom:8px;font-size:14px;line-height:20px}.fm-tmpl-listview-basic .basic-lable{flex-shrink:0;width:82px;margin-right:14px;color:#999;text-align:right}.fm-tmpl-listview-basic .basic-text{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden;color:#333}.fm-tmpl-listview-basic-last{margin-bottom:0}.fm-tmpl-listview-list{padding-left:16px}.fm-tmpl-listview-list .fm-tmpl-listview-list-inner{display:flex;justify-content:space-between;height:44px;padding-right:16px;font-size:15px;color:#333;line-height:44px;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-list .fm-tmpl-listview-list-inner{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-list .fm-tmpl-listview-list-inner::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-list .fm-tmpl-listview-list-inner .list-text{color:#FBB902}.fm-tmpl-listview-list-last .fm-tmpl-listview-list-inner{border-bottom:0}.fm-tmpl-listview-list-last .fm-tmpl-listview-list-inner::after{display:none!important}.fm-tmpl-listview-sign{padding:0 16px;background:#fff}.fm-tmpl-listview-sign .fm-tmpl-listview-sign-inner{margin-left:12px}.fm-tmpl-listview-sign .fm-tmpl-sign-text{position:relative;padding-left:18px}.fm-tmpl-listview-sign .fm-tmpl-sign-text .fm-tmpl-sign-circle{position:absolute;left:-8px;top:2px;width:18px;height:18px;border-radius:50%;background-color:rgba(54,165,246,.2)}.fm-tmpl-listview-sign .fm-tmpl-sign-text .text{line-height:22px;font-size:16px;color:#333;font-weight:600}.fm-tmpl-listview-sign .fm-tmpl-sign-text::after{position:absolute;left:-5px;top:5px;width:6px;height:6px;border:3px solid #fff;background-color:#36a5f6;border-radius:50%;content:'';box-sizing:content-box}.fm-tmpl-listview-sign .fm-tmpl-sign-text::before{position:absolute;left:-.5px;top:0;bottom:0;width:1px;border:1px dashed #ddd;background-color:transparent;content:'';transform:scaleX(.5)}.fm-tmpl-listview-sign .fm-tmpl-sign-content{padding:10px 0 10px 18px;border-left:1px dashed #ddd}.fm-tmpl-listview-sign .fm-tmpl-sign-content-inner{padding:10px 12px;background:#f4f7f9}.fm-tmpl-listview-sign .fm-tmpl-sign-content-name{display:flex;align-items:center;padding-bottom:6px;line-height:20px}.fm-tmpl-listview-sign .fm-tmpl-sign-content-name .fm-icon{margin-right:6px;font-size:16px;color:#36a5f6}.fm-tmpl-listview-sign .fm-tmpl-sign-content-name .name-text{font-size:15px;color:#333}.fm-tmpl-listview-sign .fm-tmpl-sign-content-label{padding-bottom:10px;font-size:14px;color:#999}.fm-tmpl-listview-sign .fm-tmpl-sign-content-imgs{display:flex;align-items:center;flex-wrap:wrap}.fm-tmpl-listview-sign .fm-tmpl-sign-content-imgs .fm-tmpl-sign-content-img{width:60px;height:60px;margin-right:10px;margin-bottom:10px;overflow:hidden}.fm-tmpl-listview-sign .fm-tmpl-sign-content-imgs .fm-tmpl-sign-content-img img{display:block;width:100%;height:100%;-o-object-fit:scale-down;object-fit:scale-down}.fm-tmpl-listview-sign.fm-tmpl-listview-sign-last{padding-bottom:12px}.fm-tmpl-listview-sign.fm-tmpl-listview-sign-last .fm-tmpl-sign-content{border-left:none}.fm-tmpl-listview-sign.fm-tmpl-listview-sign-last .fm-tmpl-sign-text::before{height:6px}.fm-tmpl-listview-sign.fm-tmpl-listview-sign-first{padding-top:12px}.fm-tmpl-listview-sign.fm-tmpl-listview-sign-first .fm-tmpl-sign-text::before{top:6px}.fm-tmpl-listview-bill{padding-left:12px}.fm-tmpl-listview-bill-content{display:flex}.fm-tmpl-listview-bill-content .bill-img-round-wrapper{padding-top:12px;margin-right:10px}.fm-tmpl-listview-bill-content .bill-img-round-wrapper .bill-img-round-img{width:30px;height:30px;border-radius:50%;text-align:center;color:#fff;background:#3a90ff}.fm-tmpl-listview-bill-content .bill-img-round-wrapper .bill-img-round-img .fm-icon{font-size:18px;line-height:30px}.fm-tmpl-listview-bill-content .bill-detail-content{flex-shrink:1;flex-grow:1;flex-basis:0;padding:12px 16px 8px 0;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-bill-content .bill-detail-content{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-bill-content .bill-detail-content::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-header{display:flex;align-items:center;justify-content:space-between;margin:0 0 6px}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-header .title{line-height:22px;font-weight:400;font-size:16px;color:#333}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-header .time{line-height:18px;color:#999;font-size:13px}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info{display:flex;margin-bottom:4px}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info-text{display:flex;flex-shrink:1;flex-grow:1;flex-basis:0;align-items:flex-start;line-height:18px;font-size:13px;color:#999}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info-text .title{flex-shrink:0}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info-text .text-orange{color:#FF9800}.fm-tmpl-listview-bill-content .bill-detail-content .bill-detail-info-status{padding-left:6px;margin-top:-2px}.fm-tmpl-listview-client{padding:0 8px 10px;background:#f9fafb}.fm-tmpl-listview-client-inner{background:#fff}.fm-tmpl-listview-client-header{padding:10px 10px 18px;display:flex;flex-direction:row}.fm-tmpl-listview-client-header .client-header-icon{flex-shrink:0;width:46px;height:46px;line-height:46px;margin-right:10px;text-align:center;background-color:#3a90ff;border-radius:6px}.fm-tmpl-listview-client-header .client-header-icon .fm-icon{font-size:24px;color:#fff}.fm-tmpl-listview-client-header .client-header-msg{flex-shrink:1;flex-grow:1;flex-basis:0;overflow:hidden}.fm-tmpl-listview-client-header .client-header-msg .client-header-name{display:flex;justify-content:space-between;margin-bottom:6px}.fm-tmpl-listview-client-header .client-header-msg .client-header-name-text{padding-right:6px;line-height:22px;font-size:16px;color:#333}.fm-tmpl-listview-client-header .client-header-msg .client-header-name-status{flex-shrink:0}.fm-tmpl-listview-client-header .client-header-msg .client-header-name-time{font-size:13px;color:#999}.fm-tmpl-listview-client-header .client-header-msg .client-header-site{line-height:18px;font-size:13px;color:#999}.fm-tmpl-listview-client-content .client-content-info{display:flex;align-items:center}.fm-tmpl-listview-client-content .text-orange{font-size:14px;color:#FF9800}.fm-tmpl-listview-client .client-content-item{display:flex;align-items:center;flex:1;margin-bottom:8px;padding:0 10px;line-height:18px;font-size:13px;color:#999}.fm-tmpl-listview-client .client-content-item .fm-icon{font-size:14px;margin-right:2px}.fm-tmpl-listview-client-first{padding-top:10px}.fm-tmpl-listview-client.fm-tmpl-listview-client-simple .fm-tmpl-listview-client-header{padding-bottom:10px}.fm-tmpl-listview-client.fm-tmpl-listview-client-simple .fm-tmpl-listview-client-header .client-header-msg .client-header-name{margin-bottom:0}.fm-tmpl-listview-client .text-success{color:#5CC171}.fm-tmpl-listview-client .text-warning{color:#FF9800}.fm-tmpl-listview-client .text-danger{color:#F24645}.fm-tmpl-listview-client .text-submit{color:#5AC1C3}.fm-tmpl-listview-client .text-info{color:#4D9AFF}.fm-tmpl-extend-card{padding:12px 16px}.fm-tmpl-extend-card-inner{position:relative;background-image:linear-gradient(152deg,#53bdfd 0,#287cf3 97%);box-shadow:0 2px 4px 0 rgba(57,66,100,.04);border-radius:10px;overflow:hidden}.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list{display:flex;justify-content:space-between;align-items:center;padding:20px}.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item{display:flex;flex-direction:column;align-items:center;flex:1;color:#fff}.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item .extend-card-item-text{display:flex;align-items:baseline}.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item .extend-card-item-text .item-text{display:block;font-size:24px;line-height:32px}.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item .extend-card-item-text .item-text-tip{font-size:12px}.fm-tmpl-extend-card-inner .fm-tmpl-extend-card-list .fm-tmpl-extend-card-item .extend-card-item-text .card-item-title{font-size:14px}.fm-tmpl-extend-card-inner::before{right:-7%;top:20%;width:80%;height:340%;border-radius:50%;opacity:.23;background-image:linear-gradient(180deg,#63ccfa 0,#36a5f6 100%);z-index:1}.fm-tmpl-extend-card-inner::after{right:-37%;bottom:-10%;width:60%;height:240%;border-radius:50%;opacity:.15;background-image:linear-gradient(134deg,#3addd5 0,#24c2d8 100%);z-index:0}.fm-tmpl-listview-liaison{padding-left:16px;margin-top:10px;background-color:#fff}.fm-tmpl-listview-liaison .liaison-header{display:flex;flex-direction:row;justify-content:space-between;padding:12px 16px 12px 0;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-liaison .liaison-header{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-liaison .liaison-header::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-liaison .liaison-header-title{flex:1 1 0;padding-right:16px;font-size:16px;color:#333;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-tmpl-listview-liaison .liaison-header-tag{flex-shrink:0}.fm-tmpl-listview-liaison .liaison-content{padding:10px 0}.fm-tmpl-listview-liaison .liaison-content-info{display:flex;flex-direction:row;align-items:center;line-height:18px;color:#999;font-size:13px;margin:0 0 6px}.fm-tmpl-listview-booklist .booklist-btns .fm-button,.fm-tmpl-listview-liaison .liaison-actions .fm-button{margin-left:13px}.fm-tmpl-listview-liaison .liaison-content-info-title{flex-shrink:0;width:100px;padding-right:10px}.fm-tmpl-listview-liaison .liaison-content-info-text{flex:1 1 0;color:#333}.fm-tmpl-listview-liaison .liaison-actions{padding:0 16px 10px;text-align:right}.fm-tmpl-listview-liaison .liaison-actions .fm-button:first-child{margin-left:0}.fm-tmpl-listview-approve{padding:10px 0 10px 16px;background-color:#fff}.fm-tmpl-listview-approve .fm-approve-flow-item{padding-left:7px}.fm-tmpl-listview-approve .fm-approve-flow-item-header{border-left:1px dashed #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-approve .fm-approve-flow-item-header{border-left:none}html:not([data-scale]) .fm-tmpl-listview-approve .fm-approve-flow-item-header::before{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:1PX;height:100%;transform-origin:100% 50%;transform:scaleX(.5)}}.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner{position:relative;display:flex;flex-direction:row;align-items:center;padding-left:20px}.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon{position:absolute;left:-7px;top:0;z-index:100;display:flex;align-items:center;justify-content:center;width:15px;height:15px;background-color:rgba(58,144,255,.4);border-radius:50%}.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon-inner{width:7px;height:7px;background-color:#3a90ff;border-radius:50%}.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-content{flex-shrink:1;flex-grow:1;flex-basis:0;line-height:21px;font-size:15px;color:#4c4c4c;font-weight:700}.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-right{flex-shrink:0;padding-left:6px}.fm-tmpl-listview-approve .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-right .fm-icon{color:#979797}.fm-tmpl-listview-approve .fm-approve-flow-item-content{padding:12px 0 30px 20px;border-left:1px dashed #d4d4d4;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-approve .fm-approve-flow-item-content{border-left:none}html:not([data-scale]) .fm-tmpl-listview-approve .fm-approve-flow-item-content::before{content:'';position:absolute;background-color:#d4d4d4;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:1PX;height:100%;transform-origin:100% 50%;transform:scaleX(.5)}}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list{display:flex;flex-direction:row;align-items:flex-start;margin-bottom:14px}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list:last-child{margin-bottom:0}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-avatar{position:relative;display:flex;flex-direction:row;align-items:center;width:36px;height:36px}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-avatar-img{display:block;width:36px;height:36px;border-radius:50%}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content{flex:1 1 0;margin-left:10px}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-main{display:flex;align-items:center;justify-content:space-between;height:36px}.fm-tmpl-listview-approve .fm-approve-flow-item-last .fm-approve-flow-item-content::before,.fm-tmpl-listview-approve .fm-approve-flow-item-last .fm-approve-flow-item-header::before{display:none!important}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left,.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-name{font-size:14px;color:#666}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-status{margin-left:8px;color:#3a90ff}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-status-success{color:#5cc171}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-status-apply{color:#3a90ff}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-left .item-list-content-status-running{color:#ff9800}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-date{flex-shrink:0;font-size:13px;color:#999}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-list-content .item-list-content-message{line-height:20px;font-size:14px;color:#333}.fm-tmpl-listview-approve .fm-approve-flow-item-content .fm-approve-flow-item-date{font-size:13px;color:rgba(51,51,51,.65)}.fm-tmpl-listview-approve .fm-approve-flow-item-running .fm-approve-flow-item .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon{background-color:rgba(255,152,0,.4)}.fm-tmpl-listview-approve .fm-approve-flow-item-running .fm-approve-flow-item .fm-approve-flow-item-header-inner .fm-approve-flow-item-header-icon .fm-approve-flow-item-header-icon-inner{background-color:#ff9800}.fm-tmpl-listview-approve .fm-approve-flow-item-last .fm-approve-flow-item-header{border-left:0}.fm-tmpl-listview-approve .fm-approve-flow-item-last .fm-approve-flow-item-content{padding-bottom:12px;border-left:0}.fm-tmpl-listview-product-header{padding:12px 14px;line-height:20px;font-size:14px;color:#3a90ff}.fm-tmpl-listview-product-item .fm-listview-item .fm-listview-item-content{transform:none}.fm-tmpl-listview-product{padding:12px 16px 0}.fm-tmpl-listview-product .fm-tmpl-listview-product-inner{padding-bottom:12px;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-product .fm-tmpl-listview-product-inner{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-product .fm-tmpl-listview-product-inner::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-product .tmpl-product-title{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}.fm-tmpl-listview-product .tmpl-product-title .tmpl-product-title-collect{flex-shrink:0}.fm-tmpl-listview-product .tmpl-product-title-text{font-size:17px;color:#333}.fm-tmpl-listview-product .tmpl-product-title-collect{flex-shrink:0;font-size:14px;color:#666}.fm-tmpl-listview-product .tmpl-product-title-collect .collect-text{margin-left:4px}.fm-tmpl-listview-product .tmpl-product-title-collect.tmpl-product-title-collected .fm-icon{color:#ff9800}.fm-tmpl-listview-product .tmpl-product-content{position:relative;padding-right:40px}.fm-tmpl-listview-product .tmpl-product-content-item{display:flex;align-items:center;margin-bottom:10px;font-size:14px;color:#666}.fm-tmpl-listview-product .tmpl-product-content .tmpl-product-add-btn{position:absolute;right:0;bottom:0}.fm-tmpl-listview-product .tmpl-product-content .tmpl-product-add-btn .fm-button-add{width:30px;height:30px}.fm-tmpl-listview-product .tmpl-product-content .tmpl-product-add-btn .fm-button-add .fm-icon{font-size:14px}.fm-tmpl-listview-product .tmpl-product-footer{display:flex;align-items:center;justify-content:space-between;margin-top:6px}.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-price{margin-right:10px;font-size:17px;color:red;font-weight:600}.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-inner{border-radius:10px;box-shadow:none}.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-arrow,.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-inner{border:1px solid #ddd}.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-inner-wrapper{padding:0}.fm-tmpl-listview-product .tmpl-product-footer .fm-popover .fm-popover-inner-wrapper .fm-popover-item{min-width:50px;height:46px;line-height:46px;text-align:center;font-size:16px;color:#666}.fm-tmpl-listview-product .tmpl-product-footer .fm-overlay{background:0 0}.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-unit{padding:3px 6px;border-radius:6px;background-color:rgba(58,144,255,.2);font-size:14px;color:#333}.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-unit-text{margin-right:4px}.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-unit .fm-icon{font-size:12px;color:#666}.fm-tmpl-listview-product .tmpl-product-footer .tmpl-product-footer-right{flex-shrink:0;font-size:12px;color:#666}.fm-tmpl-listview-product.fm-tmpl-listview-product-first{padding-top:0}.fm-card-tmpl-booklist-header{padding:11px 16px;line-height:22px;font-size:16px;color:#333;font-weight:600}.fm-tmpl-listview-booklist{padding:0 16px;color:#333;border-bottom:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-booklist{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-booklist::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-booklist-last{border-bottom:0}.fm-tmpl-listview-booklist-last::after{display:none!important}.fm-tmpl-listview-booklist .booklist-header{display:flex;flex-direction:row;align-items:flex-start;justify-content:space-between;padding:12px 0 6px;line-height:22px;font-size:16px}.fm-tmpl-listview-booklist .booklist-header-price{flex-shrink:0;color:#fa6400}.fm-tmpl-listview-booklist .booklist-main{padding-bottom:8px}.fm-tmpl-listview-booklist .booklist-main-item{line-height:18px;padding-bottom:4px;font-size:13px;color:#999}.fm-tmpl-listview-booklist .booklist-btns{padding:8px 0 6px;text-align:right}.fm-tmpl-dialog-plan,.fm-tmpl-dialog-type{border-radius:5px!important}.fm-tmpl-dialog-plan .fm-dialog-footer,.fm-tmpl-dialog-type .fm-dialog-footer{border-top:1px solid #ddd;position:relative}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-dialog-plan .fm-dialog-footer,html:not([data-scale]) .fm-tmpl-dialog-type .fm-dialog-footer{border-top:none}html:not([data-scale]) .fm-tmpl-dialog-plan .fm-dialog-footer::before,html:not([data-scale]) .fm-tmpl-dialog-type .fm-dialog-footer::before{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:100%;height:1PX;transform-origin:50% 50%;transform:scaleY(.5)}}.fm-tmpl-dialog-plan .fm-dialog-footer .fm-button,.fm-tmpl-dialog-type .fm-dialog-footer .fm-button{font-size:14px;color:#666}.fm-tmpl-dialog-type-content{padding:20px}.fm-tmpl-dialog-type-content .fm-dialog-type-list{display:flex;align-items:center;justify-content:center}.fm-tmpl-dialog-type-content .fm-dialog-type-list-item{flex:1}.fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-icon{width:60px;height:60px;margin:0 auto;line-height:60px;text-align:center;border:1px solid #3D91FF;border-radius:50%}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-icon{position:relative;border:none}html:not([data-scale]) .fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-icon::before{content:'';position:absolute;left:0;top:0;width:200%;height:200%;border:1px solid #3D91FF;border-radius:100%;transform-origin:0 0;transform:scale(.5);box-sizing:border-box;pointer-events:none}}.fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-icon .fm-icon{font-size:26px;color:#3D91FF}.fm-tmpl-dialog-type-content .fm-dialog-type-list-item .type-list-item-text{margin-top:12px;font-size:16px;text-align:center;color:#666}.fm-tmpl-dialog-type-content .fm-dialog-type-list-item:active .type-list-item-icon{background-color:#3D91FF}.fm-tmpl-dialog-type-content .fm-dialog-type-list-item:active .type-list-item-icon .fm-icon{color:#fff}.fm-tmpl-dialog-plan-content{padding:20px 30px}.fm-tmpl-dialog-plan-content .fm-dialog-plan-item{display:flex;justify-content:center;height:40px;line-height:40px;margin-bottom:16px;align-items:center;color:#666;border:1px solid #ddd;border-radius:4px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-dialog-plan-content .fm-dialog-plan-item{position:relative;border:none}html:not([data-scale]) .fm-tmpl-dialog-plan-content .fm-dialog-plan-item::before{content:'';position:absolute;left:0;top:0;width:200%;height:200%;border:1px solid #ddd;border-radius:8px;transform-origin:0 0;transform:scale(.5);box-sizing:border-box;pointer-events:none}}.fm-tmpl-dialog-plan-content .fm-dialog-plan-item .plan-item-icon{margin-right:14px}.fm-tmpl-dialog-plan-content .fm-dialog-plan-item .fm-icon{color:#666}.fm-tmpl-dialog-plan-content .fm-dialog-plan-item:active,.fm-tmpl-dialog-plan-content .fm-dialog-plan-item:active .fm-icon{color:#3D91FF}.fm-tmpl-dialog-plan-content .fm-dialog-plan-item:active::before{border-color:#3D91FF!important}.fm-title{position:relative;padding-left:16px}.fm-title::before{position:absolute;left:0;top:50%;width:5px;height:16px;margin:-8px 0 0}.fm-title-text{font-size:16px;line-height:21px;color:#333}.fm-tmpl-search-action{position:relative}.fm-tmpl-search-action .fm-icon{font-size:20px;color:#666}.fm-tmpl-search-action-badge{position:absolute;top:0;right:0;min-width:16px;padding:0 3px;margin-top:4px;color:#fff;font-weight:500;font-size:12px;line-height:14px;text-align:center;background-color:#ee0a24;border:1px solid #fff;border-radius:16px;transform:translate(50%,-50%);transform-origin:100%}.fm-list-view-swipe-toolbar{display:flex;align-items:center;justify-content:center;padding:0 12px;height:100%;background-color:#f24645;font-size:16px;color:#fff}.fm-static-text-common{padding:12px 16px;background-color:#fff;margin-bottom:10px;font-size:13px;line-height:1.42;-moz-tab-size:4;-o-tab-size:4;tab-size:4;text-align:left;white-space:pre-wrap;word-wrap:break-word}.fm-static-text-common p:not(:last-child){padding-bottom:18px}.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:center}.fm-tmpl-listview-common .fm-tmpl-title{line-height:22px}.fm-tmpl-listview-common .fm-tmpl-price{font-size:18px;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;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.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;overflow:hidden}.fm-tmpl-listview-common .fm-tmpl-col-1:not(:last-child){padding-right:10px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .fm-tmpl-listview-common{border-bottom:none}html:not([data-scale]) .fm-tmpl-listview-common::after{content:'';position:absolute;background-color:#ddd;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1PX;transform-origin:50% 100%;transform:scaleY(.5)}}.fm-tmpl-listview-cell .fm-tmpl-row:not(:last-child){padding-bottom:3px}.fm-tmpl-listview-cell .fm-tmpl-label{font-size:13px;line-height:18px;color:#999}.fm-tmpl-listview-cell .fm-tmpl-label .fm-tmpl-label-title{width:auto} \ No newline at end of file +@charset "UTF-8";html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0}html{line-height:1;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{min-height:100vh;display:flex;color:#333;background-color:#fff;position:relative;transform:scale(1)}html,body{overflow:hidden;-webkit-overflow-scrolling:auto}a{text-decoration:none;background:transparent}a img{border:none}ol,ul{list-style:none}table{border-collapse:collapse;border-spacing:0}caption,th,td{font-weight:400;vertical-align:middle}q,blockquote{quotes:none}q:before,q:after,blockquote:before,blockquote:after{content:"";content:none}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary{display:block}*,*:before,*:after{box-sizing:border-box}button,input[type=number],input[type=text],input[type=password],input[type=email],input[type=search],select,textarea{margin:0;font-family:inherit;appearance:none;-webkit-appearance:none}#app{position:absolute;inset:0;overflow:hidden;-webkit-overflow-scrolling:auto}@supports ((height: constant(safe-area-inset-top)) or (height: env(safe-area-inset-top))) and (-webkit-overflow-scrolling: touch){body{min-height:calc(100vh - 20px)}}.fm-tmpl-listview-common{font-size:16px;color:#333;padding:12px 16px 12px 0;margin-left:16px}.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-cell .fm-tmpl-row:not(:last-child){padding-bottom:3px}.fm-tmpl-listview-cell .fm-tmpl-label{font-size:13px;line-height:18px;color:#999}.fm-tmpl-listview-cell .fm-tmpl-label .fm-tmpl-label-title{width:auto}.fm-tmpl-listview-card{margin:10px 12px 0;padding:0;border-radius:8px;background:#fff;overflow:hidden;box-shadow:0 2px 8px #51789f1f}.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-common-footer{border-top:1px solid #ddd;position:relative;border-top:none}.fm-tmpl-listview-card .fm-tmpl-listview-common-footer:before{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}.fm-tmpl-listview-common:not(.fm-tmpl-listview-card){border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-tmpl-listview-common:not(.fm-tmpl-listview-card):after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-listview-item:last-child .fm-tmpl-listview-card{margin-bottom:10px} diff --git a/packages/mobile-render/public/assets/farris-mobile-ui-vue.css b/packages/mobile-render/public/assets/farris-mobile-ui-vue.css index f5b06f98f6e..16df0875d6a 100644 --- a/packages/mobile-render/public/assets/farris-mobile-ui-vue.css +++ b/packages/mobile-render/public/assets/farris-mobile-ui-vue.css @@ -1 +1 @@ -@charset "UTF-8";:root{--fm-black: #000;--fm-white: #fff;--fm-gray-1: #f2f3f5;--fm-gray-2: #eee;--fm-gray-3: #ddd;--fm-gray-4: #ccc;--fm-gray-5: #999;--fm-gray-6: #666;--fm-gray-7: #333;--fm-red: #F24645;--fm-red-light: #f9e8e8;--fm-blue: #3A90FF;--fm-blue-2: #65a7ff;--fm-blue-light: #ecf2fe;--fm-green: #5CC171;--fm-green-2: #5AC1C3;--fm-green-light: #e9f5ed;--fm-orange: #FF9800;--fm-orange-2: #FA6400;--fm-orange-3: #FFB400;--fm-orange-light: #faf0e1;--fm-primary-color: var(--fm-blue);--fm-success-color: var(--fm-green);--fm-danger-color: var(--fm-red);--fm-warning-color: var(--fm-orange);--fm-submit-color: var(--fm-green-2);--fm-primary-color-light: var(--fm-blue-light);--fm-success-color-light: var(--fm-green-light);--fm-danger-color-light: var(--fm-red-light);--fm-warning-color-light: var(--fm-orange-light);--fm-text-color: var(--fm-gray-7);--fm-text-color-light: var(--fm-gray-5);--fm-active-color: var(--fm-gray-1);--fm-disabled-color: var(--fm-gray-4);--fm-readonly-color: var(--fm-gray-6);--fm-active-opacity: .7;--fm-readonly-opacity: .6;--fm-disabled-opacity: .5;--fm-background: var(--fm-gray-1);--fm-background-white: var(--fm-white);--fm-box-shadow-color: var(--fm-gray-1);--fm-padding-base: 4px;--fm-padding-xs: 8px;--fm-padding-sm: 12px;--fm-padding-md: 16px;--fm-padding-lg: 24px;--fm-padding-xl: 32px;--fm-padding-horizontal-xs: 0 var(--fm-padding-xs);--fm-padding-horizontal-sm: 0 var(--fm-padding-sm);--fm-padding-horizontal-md: 0 var(--fm-padding-md);--fm-padding-horizontal-lg: 0 var(--fm-padding-lg);--fm-margin-base: 4px;--fm-margin-xs: 8px;--fm-margin-sm: 12px;--fm-margin-md: 16px;--fm-margin-lg: 24px;--fm-margin-xl: 32px;--fm-margin-horizontal-xs: 0 var(--fm-margin-xs);--fm-margin-horizontal-sm: 0 var(--fm-margin-sm);--fm-margin-horizontal-md: 0 var(--fm-margin-md);--fm-margin-horizontal-lg: 0 var(--fm-margin-lg);--fm-font-bold-light: 500;--fm-font-bold: 600;--fm-font-size: 16px;--fm-line-height: 1.2;--fm-line-height-lg: 1.5;--fm-font-size-xs: 10px;--fm-font-size-sm: 12px;--fm-font-size-md: 14px;--fm-font-size-lg: 16px;--fm-gradient-blue: linear-gradient(-45deg,var(--fm-blue-2) 0%, var(--fm-blue) 100%);--fm-gradient-orange: linear-gradient(-45deg,var(--fm-orange) 0%, var(--fm-orange-2) 100%);--fm-base-font: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Segoe UI, Arial, Roboto, "PingFang SC", "miui", "Hiragino Sans GB", "Microsoft Yahei", sans-serif;--fm-price-font: avenir-heavy, "PingFang SC", helvetica neue, arial, sans-serif;--fm-duration-base: .3s;--fm-duration-fast: .2s;--fm-ease-out: ease-out;--fm-ease-in: ease-in;--fm-noborder: none;--fm-radius-sm: 2px;--fm-radius-md: 4px;--fm-radius-lg: 8px;--fm-radius-max: 999px;--fm-zindex-1: 9;--fm-zindex-2: 10;--fm-zindex-3: 99;--fm-zindex-4: 100;--fm-zindex-5: 999;--fm-zindex-6: 1000}*,*:before,*:after{box-sizing:border-box}body,h1,h2,h3,h4,p,figure,blockquote,dl,dd{margin:0}ul[role=list],ol[role=list]{list-style:none}html:focus-within{scroll-behavior:smooth}body{min-height:100vh;text-rendering:optimizeSpeed;line-height:1.5;font-family:-apple-system,Noto Sans,Helvetica Neue,Helvetica,Nimbus Sans L,Arial,Liberation Sans,PingFang SC,Hiragino Sans GB,Noto Sans CJK SC,Source Han Sans SC,Source Han Sans CN,Microsoft YaHei,Wenquanyi Micro Hei,WenQuanYi Zen Hei,ST Heiti,SimHei,WenQuanYi Zen Hei Sharp,sans-serif}a:not([class]){text-decoration-skip-ink:auto}img,picture{max-width:100%;display:block}input,button,textarea,select{font:inherit}@font-face{font-family:farrisMobile;font-style:normal;font-weight:400;src:url(data:font/ttf;base64,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AADmFAAAACUAAOYVAADmFQAAACYAAOYWAADmFgAAACcAAOYXAADmFwAAACgAAOYYAADmGAAAACkAAOYZAADmGQAAAHYAAOYaAADmGgAAAHUAAOYbAADmGwAAAHQAAOYcAADmHAAAAHMAAOYdAADmHQAAACoAAOYeAADmHgAAACsAAOYfAADmHwAAAHAAAOYgAADmIAAAAHEAAOYhAADmIQAAAHIAAOYiAADmIgAAAG8AAOYjAADmIwAAACwAAOYkAADmJAAAAGUAAOYlAADmJQAAAGYAAOYmAADmJgAAAGcAAOYnAADmJwAAAGgAAOYoAADmKAAAAGkAAOYpAADmKQAAAGoAAOYqAADmKgAAAGsAAOYrAADmKwAAAGwAAOYsAADmLAAAAG0AAOYtAADmLQAAAG4AAOYuAADmLgAAAGMAAOYvAADmLwAAAGQAAOYwAADmMAAAAGIAAOYyAADmMgAAADQAAOYzAADmMwAAAC0AAOY0AADmNAAAAC4AAOY2AADmNgAAAC8AAOY3AADmNwAAADAAAOY5AADmOQAAADEAAOY6AADmOgAAADIAAOZVAADmVQAAADUAAOZWAADmVgAAADoAAOZXAADmVwAAADcAAOZYAADmWAAAADgAAOZZAADmWQAAAD0AAOZaAADmWgAAAF4AAOZbAADmWwAAAF8AAOZcAADmXAAAAGAAAOZdAADmXQAAAGEAAOZeAADmXgAAADYAAOZfAADmXwAAADsAAOZgAADmYAAAADwAAOZhAADmYQAAADkAAOZiAADmYgAAAD4AAOZjAADmYwAAAD8AAOZkAADmZAAAAEAAAOZlAADmZQAAAEEAAOZmAADmZgAAAEIAAOZnAADmZwAAAEMAAOZoAADmaAAAAEQAAOZpAADmaQAAAEUAAOZqAADmagAAAEYAAOZrAADmawAAAEcAAOZsAADmbAAAAEgAAOZtAADmbQAAAEkAAOZuAADmbgAAAEoAAOZvAADmbwAAAEsAAOZwAADmcAAAAEwAAOZxAADmcQAAAE0AAOZyAADmcgAAAE4AAOZzAADmcwAAAE8AAOZ0AADmdAAAAFAAAOZ1AADmdQAAAFEAAOZ2AADmdgAAAFIAAOZ3AADmdwAAAFMAAOZ4AADmeAAAAFQAAOZ5AADmeQAAAFUAAOZ6AADmegAAAFYAAOZ7AADmewAAAFcAAOZ8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AV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFzAXQBdQF2AXcBeAF5AXoBewF8AX0BfgF/AYABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+AAlzLW1vcmUtbzEIcy1kZWxldGUIcy1iYWNrLW8Gcy1zY2FuEHMtb3JnYW5pemF0aW9uLW8Jcy1ncm91cC1vCXMtZmlsdGVyMQlzLWNsZWFyLW8Ocy1pbGx1c3RyYXRlLW8Icy1tb21lbnQIcy1zaG9wLW8Kcy1tb21lbnQtbwZzLXNob3AKcy1yZXZva2UtbwpzLXN1Ym1pdC1vB3MtYXBwLW8Gcy1ib29rBXMtYXBwBHMtbXkJcy1jb21tZW50C3MtY29tbWVudC1vCHMtYm9vay1vBnMtbXktbwxzLWxvY2F0aW9uLW8Kcy1sb2NhdGlvbgZzLW5ld3MIcy1uZXdzLW8Jcy1TZW5kaW5nCnMtSW1wb3J0LW8Icy1FZGl0LW8Icy1RUmNvZGULcy1CcmllZmNhc2URcy1Ob3RpZmljYXRpb25vZmYIcy1QZW5jaWwIcy1TdGFyLW8Jcy1CYXJDb2RlD3MtU2FsZU1lc3NhZ2UtbwxzLUxpc3R2aWV3LW8Lcy1QaWN0dXJlLW8Ocy1TYXZlRmlsbGV0LW8Ocy1TaG9wcGluZ2NhcnQJcy1QZW5kaW5nDnMtRXhwYW5kdmlldy1vCHMtTG9jay1vCXMtU2VydmljZQpzLVdhbGxldC1vEHMtU2hvcHBpbmdjYXJ0LW8Lcy1TZXR0aW5nLW8Ncy1VbmZvbGRSZWMtbwlzLVByb2ZpbGUGTGluay1vDVVzZXJTZXR0aW5nLW8Jcy1hZ3JlZS1vDHMtYXJyb3ctZG93bgdzLWFkZC1vB3MtYW5uZXgMcy1hcnJvdy1sZWZ0CnMtYXJyb3ctdXAScy1jaGVja2JveC1jaGVja2VkCnMtY2hlY2tib3gHcy1hcnJvdwpzLWV4Y2hhbmdlB3MtY2xlYXIJcy1jaGVja2VkB3MtZXllLW8Lcy1jbG9zZS1leWUEcy1hdAxzLWZlZWRiYWNrLW8Pcy1mb2xkLWNpcmNsZS1vB3MtY3Jvc3MHcy1taW51cwZzLWZpbGUPcy1mb2xkLXRyaWFuZ2xlCHMtZmlsdGVyCXMtZm9yd29yZAZzLXBsdXMJcy1maWxlZGVsCHMtZm9sZC1vCXMtaW1hZ2UtbwhzLW1vcmUtbw5zLXJlZGlvLWNpcmNsZQpzLXJlamVjdC1vCXMtc3VjY2VzcwlzLXJlZnJlc2gGcy1zdGFyDXMtcHJvY2Vzc2Zsb3cRcy11bmZvbGQtY2lyY2xlLW8Icy1yZXdpbmQKcy11bmZvbGQtbwtzLXdhcm5pbmctbxFzLXVuZm9sZC10cmlhbmdsZQlzLXByaW50LW8Kcy1zZWFyY2gtbwhBaXJwbGFuZQVUcmFpbgNCdXMEVGF4aQxvdmVydGltZW1lYWwTZm0taS10cmFmZmljZGV0YWlscw9mbS1pLXRyYWZmaWNzdWITZm0taS1hY2NvbW1vZGF0aW9uMQ1mbS1pLWJ1c2luZXNzC2ZtLWktYnVkZ2V0CWZtLWktZ2lmdBFmbS1pLWNhbmNlbGxhdGlvbgxmbS1pLWludm9pY2UJZm0taS1saXN0CmZtLWktbWVhbHMIZm0taS1wYXkMZm0taS1zdWJzaWR5B3Nob3V6aGUTZm0taS1jb3N0YWxsb2NhdGlvbgxmbS1pLXBheW1lbnQOZm0taS1JdGluZXJhcnkOZm0taS1tb3JleGUwMmQPZm0taS1pbWFnZXhlMDJlEGZtLWktcmVqZWN0eGUwMmYPZm0taS1hZ3JlZXhlMDMxDWZtLWktY2FyZGZvbGQPZm0taS1jYXJkdW5mb2xkEWZtLWktdHJhZmZpY290aGVyD2ZtLWktYm90dG9tc2F2ZRBmbS1pLXRyYWZmaWNib2F0D2ZtLWktdHJhZmZpY2NhchFmbS1pLXRyYWZmaWNwbGFuZRFmbS1pLXRyYWZmaWN0cmFpbg9mbS1pLXRyYWZmaWNidXMMZm0taS1hZGRncmF5CmZtLWktY2xvc2UIZm0taS1hZGQJZm0taS1tb3JlCmZtLWktY2hlY2sPZm0taS1iYWNrY2lyY2xlCmZtLWktYWdyZWUMZm0taS1sb2FkaW5nDGZtLWktZmlsZWRlbAlmbS1pLWZpbGUQZm0taS1wcm9jZXNzZmxvdwxmbS1pLXJlZHN0YXIQZm0taS1yaWdodGNpcmNsZQ9mbS1pLXRpbWVjaXJjbGUOZm0taS1zY3JlZW5pbmcMZm0taS11bmNoZWNrDmZtLWktb3BlcmF0aW9uE2ZtLWktYXBwcm92YWxhbW91bnQLZm0taS1hZ3JlZWQOZm0taS1pbnByb2Nlc3MNZm0taS1mZWVkYmFjawpmbS1pLXByaW50DmZtLWktaW1wb3J0YW50GmZtLWktYW1vdW50b2ZyZWltYnVyc2VtZW50FGZtLWktc2FmZXR5YXNzaXN0YW50C2ZtLWktcmVtaW5kDWZtLWktZXllb3BwZW4NZm0taS1leWVjbG9zZRBmbS1pLVBob3RvZ3JhcGh5D2ZtLWktcGhvdG9ncmFwaA9mbS1pLWFkZHBpY3R1cmUTZm0taS10b3Bfb3RoZXItZmFjZQ5mbS1pLXRvcF9vdGhlcgtmbS1pLWRlbGV0ZQ1mbS1pLW5leHRwYWdlDmZtLWktYWRkYnV0dG9uFmZtLWktd2FpdGZvcnByb2Nlc3NpbmcTZm0taS13YXJuaW5nbWVzc2FnZRJmbS1pLWZhaWx1cmVwcm9tcHQUZm0taS1zdWNjZXNzZnVsaGludHMKZm0taS1vdGhlcgxmbS1pLXJldHJhY3QOZm0taS1kcm9wLWRvd24LZm0taS1jYW5jZWwLZm0taS1zZWFyY2gTZm0taS1tdWx0aXBsZWNob2ljZRFmbS1pLXNpbmdsZWNob2ljZQ9mbS1pLW1pY3JvcGhvbmUXZm0taS1hcnJvdy1jaGV2cm9uLWxlZnQPZm0taS1oZWxwY2VudGVyDmZtLWktc3dlZXBjb2RlDmZtLWktZ3JvdXBjaGF0DmZtLWktYWRkZnJpZW5kC2ZtLWktdG9wX215EGZtLWktdG9wX215LWZhY2UPZm0taS10b3BfZnJpZW5kFGZtLWktdG9wX2ZyaWVuZC1mYWNlFWZtLWktdG9wX3B1YmxpY3ByYWlzZRpmbS1pLXRvcF9wdWJsaWNwcmFpc2UtZmFjZQ1mbS1pLXRvcF9ob21lEmZtLWktdG9wX2hvbWUtZmFjZQAAAAA=) format("truetype")}@keyframes fm-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fm-fade-out{0%{opacity:1}to{opacity:0}}.fm-fade-enter-active{animation:.3s fm-fade-in both ease-out}.fm-fade-leave-active{animation:.3s fm-fade-out both ease-in}.fm-slide-up-enter-from,.fm-slide-up-leave-to{transform:translate3d(0,100%,0)}.fm-slide-down-enter-from,.fm-slide-down-leave-to{transform:translate3d(0,-100%,0)}.fm-slide-left-enter-from,.fm-slide-left-leave-to{transform:translate3d(-100%,0,0)}.fm-slide-right-enter-from,.fm-slide-right-leave-to{transform:translate3d(100%,0,0)}.fm-slide-up-enter-active,.fm-slide-down-enter-active,.fm-slide-left-enter-active,.fm-slide-right-enter-active{transition-timing-function:ease-out}.fm-slide-up-leave-active,.fm-slide-down-leave-active,.fm-slide-left-leave-active,.fm-slide-right-leave-active{transition-timing-function:ease-in}.fm-slide-in-enter-active,.fm-slide-in-leave-active,.fm-slide-out-enter-active,.fm-slide-out-leave-active{will-change:transform;transition:all .3s;height:100%;width:100%;top:0;position:absolute;backface-visibility:hidden;perspective:1000}.fm-slide-in-leave-to,.fm-slide-out-enter-from{transform:translate(-100%);opacity:0}.fm-slide-in-enter-from,.fm-slide-out-leave-to{transform:translate(100%);opacity:0}@keyframes fm-drop-down-in{0%{height:0;opacity:0}to{opacity:1}}@keyframes fm-drop-down-out{0%{opacity:1}to{height:0;opacity:0}}.fm-drop-down-enter-active{animation:.3s fm-drop-down-in both ease-out}.fm-drop-down-leave-active{animation:.3s fm-drop-down-out both ease-in}@keyframes fm-rotate{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}:root{--fm-button-height: 42px;--fm-button-padding: 0 14px;--fm-button-radius: 2px;--fm-button-border-width: 1px;--fm-button-color: var(--fm-white);--fm-button-line-height: var(--fm-line-height);--fm-button-font-size: var(--fm-font-size);--fm-button-plain-background: var(--fm-white);--fm-button-lg-height: 46px;--fm-button-lg-font-size: 18px;--fm-button-md-height: 38px;--fm-button-md-font-size: 14px;--fm-button-sm-height: 34px;--fm-button-sm-padding: 0 8px;--fm-button-sm-font-size: 12px;--fm-button-xs-height: 28px;--fm-button-xs-font-size: 10px;--fm-button-secondary-color: var(--fm-blue-light)}.fm-button{position:relative;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;text-align:center;margin:0;border:none;transition:opacity .2s;color:var(--fm-button-color);height:var(--fm-button-height);padding:var(--fm-button-padding);font-size:var(--fm-button-font-size);line-height:var(--fm-button-line-height);border-radius:var(--fm-button-radius)}.fm-button--primary,.fm-button--info{background:var(--fm-primary-color)}.fm-button--secondary{color:var(--fm-primary-color);background:var(--fm-button-secondary-color)}.fm-button--danger{background-color:var(--fm-danger-color)}.fm-button--warning{background-color:var(--fm-warning-color)}.fm-button--success{background-color:var(--fm-success-color)}.fm-button--plain{box-shadow:none;background:var(--fm-button-plain-background)}.fm-button--plain.fm-button--primary,.fm-button--plain.fm-button--info{color:var(--fm-primary-color);border:var(--fm-button-border-width) solid var(--fm-primary-color)}.fm-button--plain.fm-button--success{color:var(--fm-success-color);border:var(--fm-button-border-width) solid var(--fm-success-color)}.fm-button--plain.fm-button--danger{color:var(--fm-danger-color);border:var(--fm-button-border-width) solid var(--fm-danger-color)}.fm-button--plain.fm-button--warning{color:var(--fm-button-warning-color);border:var(--fm-button-border-width) solid var(--fm-button-warning-color)}.fm-button--noborder{border:none!important}.fm-button--large{height:var(--fm-button-lg-height);font-size:var(--fm-button-lg-font-size)}.fm-button--normal{height:var(--fm-button-md-height);font-size:var(--fm-button-md-font-size)}.fm-button--small{height:var(--fm-button-sm-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-sm-font-size)}.fm-button--mini{height:var(--fm-button-xs-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-xs-font-size)}.fm-button--block{display:flex;width:100%}.fm-button--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-button--loading:before,.fm-button--disabled:before{display:none}.fm-button--round{border-radius:var(--fm-radius-max)}.fm-button--square{border-radius:0}.fm-button__loading{display:inline-block;width:20px;max-width:100%;height:20px;max-height:100%;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-button__loading circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}.fm-button__loading-icon-circular{color:#fff}.fm-button__loading-text{margin-left:6px}.fm-button__icon:not(:last-child){margin-right:6px}.fm-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;background-color:#000;border:inherit;border-color:#000;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;content:" "}.fm-button:active:before{opacity:.1}.fm-button-edit__tags{min-height:24px;flex:1;display:flex;overflow:auto}.fm-button-edit__tag:not(:last-child){margin-right:6px}:root{--fm-button-group-gap: 16px}.fm-button-group{display:inline-flex;flex-wrap:nowrap;max-width:100%}.fm-button-group+.fm-button-group{margin-left:var(--fm-button-group-gap)}.fm-button-group__item{margin:0;min-width:0;max-width:100%;white-space:nowrap;flex:0 1 auto;user-select:none}.fm-button-group__item--bare-vertical{display:inline-flex;flex-direction:column;align-items:center;justify-content:space-between;color:#666}.fm-button-group__item--bare-vertical .fm-button-group__item-icon{font-size:20px}.fm-button-group__item--bare-vertical .fm-button-group__item-text{font-size:10px;line-height:16px}.fm-button-group__item--bare-vertical.fm-button-group__item--disabled{cursor:not-allowed;opacity:.5}.fm-button-group--block{display:flex}.fm-button-group--vertical{flex-direction:column}.fm-button-group--block .fm-button-group__item{width:auto;flex:10000 1 0%}.fm-button-group--horizontal.fm-button-group--mode-default .fm-button-group__item+.fm-button-group__item{margin-left:var(--fm-button-group-gap)}.fm-button-group--vertical.fm-button-group--mode-default .fm-button-group__item+.fm-button-group__item{margin-top:var(--fm-button-group-gap)}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:not(:first-child):not(:last-child),.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:not(:first-child):not(:last-child){border-radius:0}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:first-child{border-bottom-left-radius:0;border-bottom-right-radius:0}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:last-child{border-top-left-radius:0;border-top-right-radius:0}.fm-button-group--horizontal.fm-button-group--mode-outline .fm-button-group__item:not(:first-child){border-left:0}.fm-button-group--vertical.fm-button-group--mode-outline .fm-button-group__item:not(:first-child){border-top:0}.fm-button-group--horizontal.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after,.fm-button-group--vertical.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after{content:"";display:block;position:absolute;background-color:var(--fm-gray-3)}.fm-button-group--horizontal.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after{width:1px;right:0;top:var(--fm-padding-xs);bottom:var(--fm-padding-xs)}.fm-button-group--vertical.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after{height:1px;bottom:0;left:var(--fm-padding-xs);right:var(--fm-padding-xs)}.fm-button-group--fill{flex:1}:root{--fm-card-background: var(--fm-white);--fm-card-title-color: var(--fm-gray-7)}.fm-card{background-color:var(--fm-card-background)}.fm-card__header{display:flex;justify-content:space-between;align-items:center;padding:11px 16px 10px;border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-card__header:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-card__title{position:relative;padding-left:var(--fm-padding-md);color:var(--fm-card-title-color);font-size:var(--fm-font-size-lg);line-height:var(--fm-line-height-lg);font-weight:var(--fm-font-bold-light);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-card__title:before{content:"";position:absolute;left:0;top:50%;width:3px;height:14px;margin:-7px 0 0;background:var(--fm-primary-color)}.fm-card__footer{border-top:1px solid #ddd;position:relative;border-top:none}.fm-card__footer:before{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}:root{--fm-cell-padding: 10px 16px;--fm-cell-margin: 5px;--fm-cell-line-height: 24px;--fm-cell-font-size: var(--fm-font-size);--fm-cell-background: var(--fm-background-white);--fm-cell-color: var(--fm-text-color);--fm-cell-label-font-size: 12px;--fm-cell-label-line-height: 18px;--fm-cell-label-color: var(--fm-text-color-light);--fm-cell-required-color: var(--fm-danger-color)}.fm-cell{width:100%;padding:var(--fm-cell-padding);background-color:var(--fm-cell-background);color:var(--fm-cell-color);font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);position:relative;display:flex;overflow:hidden}.fm-cell--bottom-border,.fm-cell:not(:last-child){border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-cell--bottom-border:after,.fm-cell:not(:last-child):after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-cell--bottom-border:after,.fm-cell:not(:last-child):after{left:16px!important}.fm-cell.fm-cell-all-width:not(:last-child):after{left:0!important}.fm-cell--clickable{cursor:pointer}.fm-cell--clickable:active{background-color:var(--fm-active-color)}.fm-cell--required .fm-cell-title{position:relative}.fm-cell--required .fm-cell-title .fm-cell-title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-cell__title,.fm-cell__value{flex:1;font-size:inherit}.fm-cell__title{display:inline-block;overflow:hidden}.fm-cell__title-text{display:flex;word-break:break-all}.fm-cell__title-text span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-cell__right{display:flex;overflow:hidden;flex-direction:column}.fm-cell__right-content{display:flex;flex:1}.fm-cell__right--fill{flex:1}.fm-cell__value{position:relative;overflow:hidden;text-align:right;vertical-align:middle;word-wrap:break-word}.fm-cell__value--alone{text-align:left}.fm-cell__label{margin-top:var(--fm-cell-margin);color:var(--fm-cell-label-color);font-size:var(--fm-cell-label-font-size);line-height:var(--fm-cell-label-line-height)}.fm-cell--center{align-items:center}.fm-cell__extra,.fm-cell__left-icon,.fm-cell__right-icon{min-width:1em;font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);display:flex;align-items:center}.fm-cell__left-icon{margin-right:var(--fm-cell-margin)}.fm-cell__extra,.fm-cell__right-icon{margin-left:var(--fm-cell-margin)}.fm-cell--noborder .fm-cell:after{display:none!important}.fm-cell--card{padding-left:0;padding-right:0}.fm-checkbox-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-checkbox-group--vertical{flex-direction:column}.fm-checkbox-group--vertical .fm-checkbox:not(:last-child){margin-bottom:8px}.fm-checkbox{margin-top:4px;margin-bottom:4px}:root{--fm-checker-color: var(--fm-text-color);--fm-checker-font-size: var(--fm-font-size);--fm-checker-icon-color: var(--fm-text-color-light);--fm-checker-icon-background: var(--fm-background-white);--fm-checker-icon-radius: var(--fm-radius-md);--fm-checker-checked-icon-color: var(--fm-primary-color);--fm-checker-button-background: var(--fm-gray-2);--fm-checker-disabled-color: var(--fm-disabled-color);--fm-checker-disabled-icon-color: var(--fm-gray-1)}.fm-checker{display:flex;align-items:center;color:var(--fm-checker-color);font-size:var(--fm-checker-font-size)}.fm-checker__icon{display:inline-block;align-items:center}.fm-checker__icon .fm-icon{display:block;height:20px;width:20px;line-height:18px;font-size:14px;text-align:center;border-radius:var(--fm-checker-icon-radius);border:1px solid var(--fm-checker-icon-color);color:var(--fm-checker-icon-background);background-color:var(--fm-checker-icon-background)}.fm-checker__label{margin-left:8px;margin-right:8px;display:inline-block;line-height:20px}.fm-checker:first-child .fm-checker_button{margin-left:0}.fm-checker--round .fm-checker__icon .fm-icon{border-radius:100%}.fm-checker--button .fm-checker__label{font-size:13px;text-align:center;border-radius:14px;line-height:28px;padding:0 12px;min-width:60px;margin-right:0;color:var(--fm-checker-color);background:var(--fm-checker-button-background)}.fm-checker--checked .fm-checker__icon .fm-icon{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-checked-icon-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--checked.fm-checker--button .fm-checker__label{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--readonly{opacity:var(--fm-readonly-opacity)}.fm-checker--disabled{color:var(--fm-checker-disabled-color)}.fm-checker--disabled .fm-checker__icon .fm-icon{border-color:var(--fm-checker-disabled-color);background-color:var(--fm-checker-disabled-icon-color);color:var(--fm-checker-disabled-icon-color)}.fm-checker--disabled.fm-checker--checked .fm-checker__icon .fm-icon{background-color:var(--fm-checker-disabled-color);border-color:var(--fm-checker-disabled-color)}:root{--fm-icon-font-size: 14px;--fm-icon-color: inherit}.fm-icon{font-family:farrisMobile!important;font-size:var(--fm-icon-font-size);font-style:normal;color:var(--fm-icon-color);display:inline-block;width:1em;height:1em;font-weight:400;line-height:1;vertical-align:middle;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fm-icon:before{display:inline-block}.fm-icon-filter:before{content:"\e697"}.fm-icon-cardfold:before{content:"\e6b7"}.fm-icon-cardunfold:before{content:"\e6b8"}.fm-icon-trafficother:before{content:"\e6b9"}.fm-icon-bottomsave:before{content:"\e6ba"}.fm-icon-trafficboat:before{content:"\e6bb"}.fm-icon-trafficcar:before{content:"\e6bc"}.fm-icon-trafficplane:before{content:"\e6bd"}.fm-icon-traffictrain:before{content:"\e6be"}.fm-icon-trafficbus:before{content:"\e6bf"}.fm-icon-addgray:before{content:"\e6a7"}.fm-icon-close:before{content:"\e6a8"}.fm-icon-add-line:before{content:"\e6a9"}.fm-icon-more:before{content:"\e6aa"}.fm-icon-check:before{content:"\e6ab"}.fm-icon-backcircle:before{content:"\e6ac"}.fm-icon-agree:before{content:"\e6ad"}.fm-icon-loading:before{content:"\e6ae"}.fm-icon-filedel:before{content:"\e6af"}.fm-icon-file:before{content:"\e6b0"}.fm-icon-processflow:before{content:"\e6b1"}.fm-icon-redstar:before{content:"\e6b2"}.fm-icon-rightcircle:before{content:"\e6b3"}.fm-icon-timecircle:before{content:"\e6b4"}.fm-icon-screening:before{content:"\e6b5"}.fm-icon-uncheck:before{content:"\e6b6"}.fm-icon-operation:before{content:"\e02c"}.fm-icon-approvalamount:before{content:"\e02b"}.fm-icon-agreed:before{content:"\e02a"}.fm-icon-inprocess:before{content:"\e029"}.fm-icon-feedback:before{content:"\e028"}.fm-icon-print:before{content:"\e027"}.fm-icon-important:before{content:"\e026"}.fm-icon-amountofreimbursement:before{content:"\e025"}.fm-icon-safetyassistant:before{content:"\e024"}.fm-icon-remind:before{content:"\e023"}.fm-icon-eyeoppen:before{content:"\e022"}.fm-icon-eyeclose:before{content:"\e01e"}.fm-icon-photography:before{content:"\e021"}.fm-icon-photograph:before{content:"\e020"}.fm-icon-addpicture:before{content:"\e01f"}.fm-icon-top_other-face:before{content:"\e01d"}.fm-icon-top_other:before{content:"\e01c"}.fm-icon-delete:before{content:"\e01b"}.fm-icon-nextpage:before{content:"\e01a"}.fm-icon-addbutton:before{content:"\e019"}.fm-icon-waitforprocessing:before{content:"\e018"}.fm-icon-warningmessage:before{content:"\e017"}.fm-icon-failureprompt:before{content:"\e016"}.fm-icon-successfulhints:before{content:"\e015"}.fm-icon-other:before{content:"\e014"}.fm-icon-retract:before{content:"\e013"}.fm-icon-drop-down:before{content:"\e012"}.fm-icon-cancel:before{content:"\e011"}.fm-icon-search:before{content:"\e010"}.fm-icon-multiplechoice:before{content:"\e00f"}.fm-icon-singlechoice:before{content:"\e00e"}.fm-icon-microphone:before{content:"\e00d"}.fm-icon-arrow-chevron-left:before{content:"\e00c"}.fm-icon-helpcenter:before{content:"\e00b"}.fm-icon-sweepcode:before{content:"\e00a"}.fm-icon-groupchat:before{content:"\e009"}.fm-icon-addfriend:before{content:"\e008"}.fm-icon-top_my:before{content:"\e007"}.fm-icon-top_my-face:before{content:"\e006"}.fm-icon-top_friend:before{content:"\e005"}.fm-icon-top_friend-face:before{content:"\e004"}.fm-icon-top_publicpraise:before{content:"\e003"}.fm-icon-top_publicpraise-face:before{content:"\e002"}.fm-icon-top_home:before{content:"\e001"}.fm-icon-top_home-face:before{content:"\e000"}.fm-icon-s-agree-o:before{content:"\e655"}.fm-icon-s-arrow-down:before{content:"\e656"}.fm-icon-s-add-o:before{content:"\e657"}.fm-icon-s-annex:before{content:"\e658"}.fm-icon-s-arrow:before{content:"\e659"}.fm-icon-s-arrow-up:before{content:"\e65e"}.fm-icon-s-checkbox-checked:before{content:"\e65f"}.fm-icon-s-checkbox:before{content:"\e660"}.fm-icon-s-arrow-left:before{content:"\e661"}.fm-icon-s-exchange:before{content:"\e662"}.fm-icon-s-clear:before{content:"\e663"}.fm-icon-s-checked:before{content:"\e664"}.fm-icon-s-eye-o:before{content:"\e665"}.fm-icon-s-close-eye:before{content:"\e666"}.fm-icon-s-at:before{content:"\e667"}.fm-icon-s-feedback-o:before{content:"\e668"}.fm-icon-s-fold-circle-o:before{content:"\e669"}.fm-icon-s-cross:before{content:"\e66a"}.fm-icon-s-minus:before{content:"\e66b"}.fm-icon-s-file:before{content:"\e66c"}.fm-icon-s-fold-triangle:before{content:"\e66d"}.fm-icon-s-filter:before{content:"\e66e"}.fm-icon-s-forword:before{content:"\e66f"}.fm-icon-s-plus:before{content:"\e670"}.fm-icon-s-filedel:before{content:"\e671"}.fm-icon-s-fold-o:before{content:"\e672"}.fm-icon-s-image-o:before{content:"\e673"}.fm-icon-s-more-o:before{content:"\e674"}.fm-icon-s-redio-circle:before{content:"\e675"}.fm-icon-s-reject-o:before{content:"\e676"}.fm-icon-s-success:before{content:"\e677"}.fm-icon-s-refresh:before{content:"\e678"}.fm-icon-s-star:before{content:"\e679"}.fm-icon-s-processflow:before{content:"\e67a"}.fm-icon-s-unfold-circle-o:before{content:"\e67b"}.fm-icon-s-rewind:before{content:"\e67c"}.fm-icon-s-unfold-o:before{content:"\e67d"}.fm-icon-s-save-o:before{content:"\e67e"}.fm-icon-s-warning-o:before{content:"\e67f"}.fm-icon-s-unfold-triangle:before{content:"\e680"}.fm-icon-s-print-o:before{content:"\e681"}.fm-icon-s-search-o:before{content:"\e682"}.fm-icon-s-news:before{content:"\e683"}.fm-icon-s-news-o:before{content:"\e684"}.fm-icon-s-shop:before{content:"\e68c"}.fm-icon-s-sending:before{content:"\e60b"}.fm-icon-s-import-o:before{content:"\e60c"}.fm-icon-s-edit-o:before{content:"\e60d"}.fm-icon-s-qrcode:before{content:"\e60e"}.fm-icon-s-briefcase:before{content:"\e60f"}.fm-icon-s-notificationoff:before{content:"\e610"}.fm-icon-s-pencil:before{content:"\e611"}.fm-icon-s-star-o:before{content:"\e612"}.fm-icon-s-barcode:before{content:"\e613"}.fm-icon-s-salemessage-o:before{content:"\e614"}.fm-icon-s-listview-o:before{content:"\e615"}.fm-icon-s-picture-o:before{content:"\e616"}.fm-icon-s-savefillet-o:before{content:"\e617"}.fm-icon-s-shoppingcart:before{content:"\e618"}.fm-icon-s-pending:before{content:"\e61d"}.fm-icon-s-expandview-o:before{content:"\e61e"}.fm-icon-s-lock-o:before{content:"\e623"}.fm-icon-s-my:before{content:"\e692"}.fm-icon-s-service:before{content:"\e633"}.fm-icon-s-wallet-o:before{content:"\e634"}.fm-icon-s-shoppingcart-o:before{content:"\e636"}.fm-icon-s-setting-o:before{content:"\e637"}.fm-icon-s-my-o:before{content:"\e696"}.fm-icon-s-unfoldrec-o:before{content:"\e639"}.fm-icon-s-profile:before{content:"\e63a"}.fm-icon-s-link-o:before{content:"\e609"}.fm-icon-s-usersetting-o:before{content:"\e632"}.fm-icon-s-shop-o:before{content:"\e68a"}.fm-icon-s-list:before{content:"\e62a"}.fm-icon-s-location-o:before{content:"\e685"}.fm-icon-s-location:before{content:"\e686"}.fm-icon-s-moment:before{content:"\e689"}.fm-icon-s-moment-o:before{content:"\e68b"}.fm-icon-s-revoke-o:before{content:"\e687"}.fm-icon-s-submit-o:before{content:"\e688"}.fm-icon-s-app-o:before{content:"\e68f"}.fm-icon-s-app:before{content:"\e691"}.fm-icon-s-book-o:before{content:"\e695"}.fm-icon-s-book:before{content:"\e690"}.fm-icon-s-comment:before{content:"\e693"}.fm-icon-s-comment-o:before{content:"\e694"}.fm-icon-s-illustrate-o:before{content:"\e68d"}.fm-icon-s-clear-o:before{content:"\e68e"}.fm-icon-friend:before{content:"\e005"}.fm-icon-scan:before{content:"\e69a"}.fm-icon-back:before{content:"\e69b"}.fm-icon-menu:before{content:"\e69d"}:root{--fm-navbar-background: var(--fm-background-white);--fm-navbar-color: var(--fm-text-color);--fm-navbar-height: 44px;--fm-navbar-title-size: 17px;--fm-navbar-side-size: 16px;--fm-navbar-arrow-size: 16px;--fm-navbar-toolbar-item-height: 46px}.fm-navbar{position:relative;z-index:9;display:flex;align-items:center;line-height:1.5;text-align:center;user-select:none;height:var(--fm-navbar-height);color:var(--fm-navbar-color);background-color:var(--fm-navbar-background)}.fm-navbar--fixed{position:fixed;top:0;left:0;width:100%}.fm-navbar--bottom-border{border-bottom:1px solid #e6e6e6;position:relative;border-bottom:none}.fm-navbar--bottom-border:after{content:"";position:absolute;background-color:#e6e6e6;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-navbar__title{max-width:60%;margin:0 auto;font-weight:500;font-size:var(--fm-navbar-title-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-navbar__left,.fm-navbar__right{position:absolute;top:0;bottom:0;display:flex;align-items:center;max-width:30%;padding:0 16px;font-size:var(--fm-navbar-side-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;cursor:pointer}.fm-navbar__left{left:0}.fm-navbar__left:active{opacity:var(--fm-active-opacity)}.fm-navbar__left.fm-navbar-left-padding{padding-left:14px}.fm-navbar__right{right:0}.fm-navbar__right .fm-navbar-text:active{opacity:var(--fm-active-opacity)}.fm-navbar__left-arrow{min-width:1em;margin-right:4px;font-size:var(--fm-navbar-arrow-size)}.fm-navbar__toolbar{padding:0!important}.fm-navbar__toolbar-item{padding:0 var(--fm-padding-sm);height:var(--fm-navbar-toolbar-item-height);line-height:var(--fm-navbar-toolbar-item-height);user-select:none;cursor:pointer}.fm-navbar__toolbar-item:not(:last-child){border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-navbar__toolbar-item:not(:last-child):after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-navbar__toolbar-item--disabled{opacity:var(--fm-disabled-opacity);cursor:not-allowed}:root{--fm-input-group-size: var(--fm-font-size);--fm-input-group-color: var(--fm-text-color);--fm-input-group-sub-size: 13px;--fm-input-group-padding: 10px 16px;--fm-input-group-sub-color: var(--fm-text-color-light);--fm-input-group-border-color: var(--fm-gray-2)}.fm-input-group{display:flex;flex-direction:column;background-color:var(--fm-white)}.fm-input-group--padding{padding:var(--fm-input-group-padding)}.fm-input-group__body{flex:1;display:flex;align-items:center;min-height:24px;color:var(--fm-input-group-color);font-size:var(--fm-input-group-size)}.fm-input-group__body--border{border:1px solid var(--fm-input-group-border-color);padding:4px 8px;border-radius:4px}.fm-input-group__control{display:flex;width:100%;min-width:0;margin:0;padding:0;border:0;resize:none;color:inherit;font-size:inherit;outline:none;line-height:inherit;background-color:transparent}.fm-input-group__control::placeholder{color:var(--fm-input-group-sub-color)}.fm-input-group__control:disabled{opacity:1;cursor:not-allowed;color:var(--fm-disabled-color);-webkit-text-fill-color:currentColor}.fm-input-group__control::-webkit-search-cancel-button{display:none}.fm-input-group__control--readonly{cursor:default;color:var(--fm-readonly-color)}.fm-input-group__control--left{justify-content:flex-start;text-align:left}.fm-input-group__control--center{justify-content:center;text-align:center}.fm-input-group__control--right{justify-content:flex-end;text-align:right}.fm-input-group__clear{cursor:pointer;margin-right:-8px;padding:4px 8px;color:var(--fm-input-group-sub-color);flex-shrink:0;box-sizing:content-box}.fm-input-group__left-icon{margin:auto 4px auto 0}.fm-input-group__right-icon{margin:auto 0 auto 4px}.fm-input-group__word-limit{margin-top:4px;line-height:18px;text-align:right;font-size:var(--fm-input-group-sub-size);color:var(--fm-input-group-sub-color)}.fm-radio-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-radio-group--vertical{flex-direction:column}.fm-radio-group--vertical .fm-radio:not(:last-child){margin-bottom:8px}.fm-radio{margin-top:4px;margin-bottom:4px}:root,:host{--fm-rate-icon-size: 20px;--fm-rate-icon-gutter: var(--fm-padding-base);--fm-rate-icon-void-color: var(--fm-gray-4);--fm-rate-icon-full-color: var(--fm-orange-3);--fm-rate-icon-disabled-color: var(--fm-gray-4)}.fm-rate{display:inline-flex;cursor:pointer;user-select:none;flex-wrap:wrap}.fm-rate__item{position:relative}.fm-rate__item:not(:last-child){padding-right:var(--fm-rate-icon-gutter)}.fm-rate__icon{display:block;width:1em;color:var(--fm-rate-icon-void-color);font-size:var(--fm-rate-icon-size)}.fm-rate__icon--half{position:absolute;top:0;left:0;overflow:hidden;pointer-events:none;color:var(--fm-rate-icon-full-color)}.fm-rate__icon--full{color:var(--fm-rate-icon-full-color)}.fm-rate__icon--disabled{color:var(--fm-rate-icon-disabled-color)}.fm-rate--disabled{cursor:not-allowed}.fm-rate--readonly{cursor:default}:root{--fm-form-item-size: var(--fm-font-size);--fm-form-item-color: var(--fm-text-color);--fm-form-item-label-width: 105px;--fm-form-item-sub-size: 13px}.fm-form-item{font-size:var(--fm-form-item-size);color:var(--fm-form-item-color)}.fm-form-item--vertical{flex-direction:column}.fm-form-item--vertical .fm-form-item__label{margin-bottom:4px}.fm-form-item__label{display:flex;flex:none;align-items:flex-start;text-align:left;width:var(--fm-form-item-label-width);margin-right:4px}.fm-form-item__label--left{justify-content:flex-start}.fm-form-item__label--center{justify-content:center}.fm-form-item__label--right{justify-content:flex-end}.fm-form-item__label--required{position:relative}.fm-form-item__label--required .fm-cell__title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-form-item__content{display:flex}.fm-form-item__content .fm-input-group{padding:0;flex:1}.fm-form-item__content--left{justify-content:flex-start}.fm-form-item__content--left input.fm-input-group__control{justify-content:flex-start;text-align:left}.fm-form-item__content--center{justify-content:center}.fm-form-item__content--center input.fm-input-group__control{justify-content:flex-center;text-align:center}.fm-form-item__content--right{justify-content:flex-end}.fm-form-item__content--right input.fm-input-group__control{justify-content:flex-end;text-align:right}.fm-form-item__error-message{color:var(--fm-danger-color);font-size:var(--fm-form-item-sub-size)}.fm-form-item__error-message--left{text-align:left}.fm-form-item__error-message--center{text-align:center}.fm-form-item__error-message--right{text-align:right}:root{--fm-overlay-background: rgba(0, 0, 0, .4);--fm-overlay-zindex: 98}.fm-overlay{width:100%;position:fixed;top:0;left:0;z-index:var(--fm-overlay-zindex);background-color:var(--fm-overlay-background);bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-overlay{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}:root{--fm-popup-background: var(--fm-white);--fm-popup-zindex: var(--fm-zindex-3);--fm-popup-radius: 16px}.fm-popup{position:fixed;max-height:100%;overflow-y:auto;background-color:var(--fm-popup-background);transition:all var(--fm-duration-base);z-index:var(--fm-popup-zindex)}.fm-popup--center{top:50%;left:50%;transform:translate(-50%,-50%)}.fm-popup--center.fm-popup--round{border-radius:var(--fm-popup-radius)}.fm-popup--top,.fm-popup--bottom{left:0;right:0}.fm-popup--top{top:0}.fm-popup--top.fm-popup--round{border-radius:0 0 var(--fm-popup-radius) var(--fm-popup-radius)}.fm-popup--bottom{bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--bottom{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--bottom.fm-popup--round{border-radius:var(--fm-popup-radius) var(--fm-popup-radius) 0 0}.fm-popup--left,.fm-popup--right{top:0;bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--left,.fm-popup--right{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--left{left:0}.fm-popup--left.fm-popup--round{border-radius:0 var(--fm-popup-radius) var(--fm-popup-radius) 0}.fm-popup--right{right:0}.fm-popup--right.fm-popup--round{border-radius:var(--fm-popup-radius) 0 0 var(--fm-popup-radius)}:root{--fm-popover-zindex: var(--fm-zindex-5);--fm-popover-padding: var(--fm-padding-sm);--fm-popover-border-radius: var(--fm-radius-lg);--fm-popover-arrow-size: 8px;--fm-popover-content-font-size: var(--fm-font-size);--fm-popover-content-line-height: var(--fm-line-height);--fm-popover-light-theme-color: var(--fm-gray-7);--fm-popover-light-theme-background: var(--fm-white);--fm-popover-dark-theme-color: var(--fm-white);--fm-popover-dark-theme-background: var(--fm-gray-7);--fm-popover-shadow: 0 6px 30px 5px rgba(0, 0, 0, .05), 0 16px 24px 2px rgba(0, 0, 0, .04), 0 8px 10px -5px rgba(0, 0, 0, .08)}.fm-popover{position:absolute;overflow:visible;top:0;left:0;transition:opacity .15s;background-color:transparent;z-index:var(--fm-popover-zindex)}.fm-popover__wrapper{display:inline-block}.fm-popover__content{position:relative;padding:var(--fm-popover-padding);border-radius:var(--fm-popover-border-radius);font-size:var(--fm-popover-content-font-size);line-height:var(--fm-popover-content-line-height);word-break:break-all}.fm-popover__arrow{position:absolute;width:0;height:0;z-index:1;border-style:solid;border-color:transparent;border-width:var(--fm-popover-arrow-size, 8px)}.fm-popover__arrow--top{border-bottom-width:0;border-top-color:currentColor;margin-bottom:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--right{border-left-width:0;border-right-color:currentColor;margin-left:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--bottom{border-top-width:0;border-bottom-color:currentColor;margin-top:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--left{border-right-width:0;border-left-color:currentColor;margin-right:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover--light .fm-popover__content{background:var(--fm-popover-light-theme-background);color:var(--fm-popover-light-theme-color);box-shadow:var(--fm-popover-shadow)}.fm-popover--light .fm-popover__arrow{color:var(--fm-popover-light-theme-background)}.fm-popover--dark .fm-popover__content{background:var(--fm-popover-dark-theme-background);color:var(--fm-popover-dark-theme-color);box-shadow:var(--fm-popover-shadow)}.fm-popover--dark .fm-popover__arrow{color:var(--fm-popover-dark-theme-background)}:root{--fm-switch-background: var(--fm-text-color-light);--fm-switch-on-color: var(--fm-primary-color)}.fm-switch{position:relative;cursor:pointer;display:inline-block;transition:background-color var(--fm-duration-base);background-color:var(--fm-switch-background)}.fm-switch--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-switch--readonly{cursor:default;opacity:var(--fm-readonly-opacity)}.fm-switch--loading{cursor:default}.fm-switch--on{background-color:var(--fm-switch-on-color)}.fm-switch--on .fm-switch__loadding{color:var(--fm-switch-on-color)}.fm-switch__node{display:flex;align-items:center;justify-content:center;position:absolute;top:1px;left:1px;z-index:1;width:28px;height:28px;border-radius:100%;background-color:var(--fm-white);transition:transform var(--fm-duration-base) cubic-bezier(.3,1.05,.4,1.05)}:root{--fm-toast-zindex: var(--fm-zindex-5);--fm-toast-color: var(--fm-white);--fm-toast-font-size: 16px;--fm-toast-background: var(--fm-gray-7);--fm-toast-icon-font-size: 48px}.fm-toast{position:fixed;top:50%;left:50%;display:-webkit-box;display:-webkit-flex;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:content-box;max-width:70%;padding:16px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;border-radius:7px;transform:translate(-50%,-50%);color:var(--fm-toast-color);z-index:var(--fm-toast-zindex);font-size:var(--fm-toast-font-size);background-color:var(--fm-toast-background)}.fm-toast--top{top:50px;transform:translate(-50%)}.fm-toast--bottom{top:auto;bottom:50px}.fm-toast--info,.fm-toast--success,.fm-toast--warning,.fm-toast--error{width:88px;min-height:88px}.fm-toast__icon-wrapper{margin-bottom:8px}.fm-toast--default{padding:8px 16px}.fm-toast--loading{min-width:84px;min-height:84px}.fm-toast--loading-icon{position:relative;display:inline-block;width:30px;height:30px;margin-bottom:8px;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-toast--loading-icon circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}:root{--fm-notify-color: var(--fm-white);--fm-notify-zindex: var(--fm-zindex-5);--fm-notify-info-background: var(--fm-primary-color);--fm-notify-success-background: var(--fm-success-color);--fm-notify-warning-background: var(--fm-warning-color);--fm-notify-error-background: var(--fm-danger-color)}.fm-notify{position:fixed;left:0;top:0;z-index:var(--fm-notify-zindex);display:flex;align-items:center;justify-content:center;width:100%;max-height:100%;padding:8px 16px;box-sizing:border-box;color:var(--fm-notify-color);font-size:14px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;overflow-y:auto}.fm-notify--info{background-color:var(--fm-notify-info-background)}.fm-notify--success{background-color:var(--fm-notify-success-background)}.fm-notify--warning{background-color:var(--fm-notify-warning-background)}.fm-notify--error{background-color:var(--fm-notify-error-background)}:root{--fm-dialog-background: var(--fm-background-2);--fm-dialog-padding-top: 24px;--fm-dialog-padding-left: 16px;--fm-dialog-header-font-size: 17px;--fm-dialog-header-line-height: 24px;--fm-dialog-content-font-size: 15px;--fm-dialog-content-line-height: 20px;--fm-dialog-footer-height: 50px;--fm-border-color: var(--fm-gray-4)}@media screen and (min-width: 375px){.fm-dialog{width:320px}}@media screen and (min-width: 280px) and (max-width: 375px){.fm-dialog{width:240px}}.fm-dialog{display:flex;flex-direction:column;background-color:var(--fm-dialog-background);overflow:hidden}.fm-dialog__header{padding-top:var(--fm-dialog-padding-top);padding-left:var(--fm-dialog-header-padding-left);padding-right:var(--fm-dialog-header-padding-left);font-weight:var(--fm-font-bold-light);font-size:var(--fm-dialog-header-font-size);color:var(--fm-text-color);line-height:var(--fm-dialog-header-line-height);text-align:center}.fm-dialog__content{max-height:70vh;overflow-y:auto}.fm-dialog__content__message{padding:var(--fm-dialog-padding-top) var(--fm-dialog-padding-left);font-size:var(--fm-dialog-content-font-size);line-height:var(--fm-dialog-content-line-height);white-space:pre-wrap;text-align:center;word-wrap:break-word}.fm-dialog__content__message--has-title{padding-top:11px;color:var(--fm-text-color-light)}.fm-dialog__content--prompt{padding:14px}.fm-dialog__content--prompt__input{display:block}.fm-dialog__footer{display:flex;flex-direction:row;align-items:center;border-top:1px solid var(--fm-border-color);position:relative;border-top:none}.fm-dialog__footer:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}.fm-dialog__footer .fm-button{border:0;height:var(--fm-dialog-footer-height);border-right:1px solid var(--fm-border-color);position:relative;border-right:none}.fm-dialog__footer .fm-button:after{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 0 auto auto;width:1px;height:100%;background:var(--fm-border-color);transform-origin:100% 50%;transform:scaleX(.5)}.fm-dialog__footer .fm-button:last-child{border-right:0}.fm-dialog__footer .fm-button:last-child:after{display:none!important}.fm-dialog__footer .fm-button--default{color:var(--fm-text-color)}.fm-dialog__footer--is-column{flex-direction:column}.fm-dialog__footer--is-column__button{border-top:1px solid var(--fm-border-color);position:relative;border-top:none}.fm-dialog__footer--is-column__button:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}.fm-dialog__footer--is-column__button:first-child{border-top:0}.fm-dialog__footer--is-column__button:first-child:before{display:none!important}.fm-dialog.fm-dialog--relative{position:relative}.fm-dialog.fm-dialog--relative__header{padding-right:40px}.fm-dialog__close{position:absolute;right:16px;top:16px;width:22px;height:22px;line-height:22px;text-align:center}.fm-dialog__close .fm-icon{font-size:15px;color:var(--fm-text-color-2)}:root,:host{--fm-loading-color: var(--fm-gray-5);--fm-loading-text-font-size: 14px;--fm-loading-text-line-height: 1.4}.fm-loading{display:flex;align-items:center;position:relative;color:var(--fm-loading-color)}.fm-loading__text{color:var(--fm-loading-color);font-size:var(--fm-loading-text-font-size);line-height:var(--fm-loading-text-line-height);margin-left:var(--fm-margin-xs)}.fm-loading--vertical{flex-direction:column}.fm-loading--vertical .fm-loading__text{margin-top:var(--fm-margin-xs);margin-left:0}.fm-loading__circular{display:block;animation:fm-rotate 2s linear infinite}.fm-loading__circular circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:3;stroke-linecap:round}.fm-loading__spinner{display:block;position:relative;animation:fm-rotate 1s linear infinite;animation-timing-function:steps(12)}.fm-loading__line{position:absolute;top:0;left:0;width:100%;height:100%}.fm-loading__line-inner{display:block;width:2px;height:25%;margin:0 auto;background-color:currentColor;border-radius:40%}.fm-loading__ring{display:block;animation:fm-rotate .75s linear infinite;border:4px solid;border-right-color:transparent;border-radius:50%}@keyframes fm-circular{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40}to{stroke-dasharray:90,150;stroke-dashoffset:-120}}.fm-loading__line--1{transform:rotate(30deg);opacity:1}.fm-loading__line--2{transform:rotate(60deg);opacity:.9375}.fm-loading__line--3{transform:rotate(90deg);opacity:.875}.fm-loading__line--4{transform:rotate(120deg);opacity:.8125}.fm-loading__line--5{transform:rotate(150deg);opacity:.75}.fm-loading__line--6{transform:rotate(180deg);opacity:.6875}.fm-loading__line--7{transform:rotate(210deg);opacity:.625}.fm-loading__line--8{transform:rotate(240deg);opacity:.5625}.fm-loading__line--9{transform:rotate(270deg);opacity:.5}.fm-loading__line--10{transform:rotate(300deg);opacity:.4375}.fm-loading__line--11{transform:rotate(330deg);opacity:.375}.fm-loading__line--12{transform:rotate(360deg);opacity:.3125}:root,:host{--fm-pull-refresh-head-height: 50px;--fm-pull-refresh-head-font-size: var(--fm-font-size-md);--fm-pull-refresh-head-text-color: var(--fm-text-color-light);--fm-pull-refresh-animation-duration: .3s}.fm-pull-refresh{overflow:hidden}.fm-pull-refresh__track{position:relative;height:100%}.fm-pull-refresh__track--not-pulling{transition:transform ease var(--fm-pull-refresh-animation-duration)}.fm-pull-refresh__head{position:absolute;left:0;width:100%;height:var(--fm-pull-refresh-head-height);color:var(--fm-pull-refresh-head-text-color);font-size:var(--fm-pull-refresh-head-font-size);line-height:var(--fm-pull-refresh-head-height);text-align:center;transform:translateY(-100%);display:flex;justify-content:center;align-items:center;flex-direction:column;overflow:hidden}:root,:host{--fm-list-text-color: var(--fm-gray-5);--fm-list-text-font-size: var(--fm-font-size-md, 14px);--fm-list-text-line-height: 50px;--fm-list-loading-icon-size: 16px}.fm-list__loading,.fm-list__error,.fm-list__load-more,.fm-list__finished-info{color:var(--fm-list-text-color);font-size:var(--fm-list-text-font-size);line-height:var(--fm-list-text-line-height);text-align:center}.fm-list__loading-container{display:flex;height:var(--fm-list-text-line-height);justify-content:center;align-items:center}:root,:host{--fm-listview-checkbox-container-width: 40px;--fm-listview-toolbar-height: 42px;--fm-listview-split-line-color: rgb(230, 235, 235);--fm-listview-empty-text-color: var(--fm-gray-5);--fm-listview-empty-text-font-size: var(--fm-font-size-md, 14px);--fm-listview-empty-text-line-height: 50px}.fm-list-view--fill{height:100%;flex-grow:1;flex-shrink:1;display:flex;flex-direction:column;overflow:hidden}.fm-list-view--fill .fm-list-view__track{flex:1 1 0;overflow:auto;-webkit-overflow-scrolling:touch}.fm-list-view--fill .fm-pull-refresh{min-height:100%}.fm-list-view .fm-list{user-select:none;-webkit-user-select:none}.fm-list-view__item{display:flex;position:relative;overflow:hidden}.fm-list-view__item-checker{display:flex;position:absolute;height:100%;width:var(--fm-listview-checkbox-container-width);justify-content:center;align-items:center}.fm-list-view__item-content{flex:1;transform:translate(0)}.fm-list-view__content--split .fm-list-view__item:not(:last-child):not(.fm-list-view__item--child){border-bottom:1px solid var(--fm-listview-split-line-color)}.fm-list-view--multi-select .fm-list-view__item-content{transform:translate(var(--fm-listview-checkbox-container-width))}.fm-list-view__item--group{display:block}.fm-list-view__item-group-header{padding:10px 16px;line-height:20px;font-size:var(--fm-font-size-md);color:var(--fm-gray-5)}.fm-list-view__empty-message{display:block;color:var(--fm-listview-empty-text-color);font-size:var(--fm-listview-empty-text-font-size);line-height:var(--fm-listview-empty-text-line-height);text-align:center}.fm-list-view__item-text{padding:13px 20px;color:var(--fm-gray-7);font-size:var(--fm-font-size)}.fm-list-view__toolbar{display:flex;align-items:center;height:var(--fm-listview-toolbar-height)}.fm-list-view__toolbar-item{flex:1}:root,:host{--fm-swipe-cell-button-text-color: var(--fm-white);--fm-swipe-cell-button-bg-color: var(--fm-gray-4);--fm-swipe-cell-button-font-size: var(--fm-font-size);--fm-swipe-cell-button-icon-size: var(--fm-font-size);--fm-swipe-cell-button-padding: var(--fm-padding-md)}.fm-swipe-cell{position:relative;overflow:hidden}.fm-swipe-cell__wrapper{transition-timing-function:cubic-bezier(.18,.89,.32,1);transition-property:transform}.fm-swipe-cell__left,.fm-swipe-cell__right{position:absolute;top:0;height:100%;display:flex}.fm-swipe-cell__left{left:0;transform:translate3d(-100%,0,0);flex-direction:row-reverse}.fm-swipe-cell__right{right:0;transform:translate3d(100%,0,0)}.fm-swipe-cell__button{display:inline-flex;justify-content:center;align-items:center;height:100%;padding:0 var(--fm-swipe-cell-button-padding);color:var(--fm-swipe-cell-button-text-color);background-color:var(--fm-swipe-cell-button-bg-color)}.fm-swipe-cell__icon{font-size:var(--fm-swipe-cell-button-icon-size)}.fm-swipe-cell__text{font-size:var(--fm-swipe-cell-button-font-size)}.fm-swipe-cell__icon+.fm-swipe-cell__text:not(:empty){margin-left:6px}:root,:host{--fm-action-sheet-max-height: 80%;--fm-action-sheet-border-radius: 12px;--fm-action-sheet-description-color: var(--fm-gray-5);--fm-action-sheet-description-line-height: 22px;--fm-action-sheet-description-font-size: var(--fm-font-size-md);--fm-action-sheet-description-padding: 12px 16px;--fm-action-sheet-item-default-background: var(--fm-background-white);--fm-action-sheet-item-active-background: #f2f3f5;--fm-action-sheet-item-padding: 13px 16px;--fm-action-sheet-item-text-color: #1a1a1a;--fm-action-sheet-item-disabled-text-color: #bdbdbd;--fm-action-sheet-item-subtitle-color: var(--fm-gray-5);--fm-action-sheet-item-icon-size: 18px;--fm-action-sheet-item-icon-margin-right: 8px;--fm-action-sheet-item-title-font-size: var(--fm-font-size-lg);--fm-action-sheet-item-title-line-height: 24px;--fm-action-sheet-item-subtitle-font-size: var(--fm-font-size-sm);--fm-action-sheet-item-subtitle-line-height: 18px;--fm-action-sheet-item-subtitle-margin-top: 2px;--fm-action-sheet-footer-gap-color: #f5f5f5;--fm-action-sheet-divider-color: #e7e7e7;--fm-action-sheet-cancel-height: 48px;--fm-action-sheet-cancel-color: #1a1a1a;--fm-action-sheet-cancel-font-size: var(--fm-font-size-lg);--fm-action-sheet-cancel-font-weight: 500}.fm-action-sheet{display:flex;flex-direction:column;max-height:var(--fm-action-sheet-max-height);overflow:hidden;user-select:none}.fm-action-sheet--round{border-top-left-radius:var(--fm-action-sheet-border-radius);border-top-right-radius:var(--fm-action-sheet-border-radius)}.fm-action-sheet__description{flex-shrink:0;color:var(--fm-action-sheet-description-color);line-height:var(--fm-action-sheet-description-line-height);font-size:var(--fm-action-sheet-description-font-size);text-align:center;padding:var(--fm-action-sheet-description-padding);position:relative}.fm-action-sheet__description--left{text-align:left}.fm-action-sheet__content{flex:1 auto;overflow-y:auto;-webkit-overflow-scrolling:touch}.fm-action-sheet__item,.fm-action-sheet__cancel{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__item:active,.fm-action-sheet__cancel:active{background-color:var(--fm-action-sheet-item-active-background)}.fm-action-sheet__item{display:flex;position:relative;flex-wrap:wrap;align-items:center;justify-content:center;text-align:center;padding:var(--fm-action-sheet-item-padding);color:var(--fm-action-sheet-item-text-color);cursor:pointer}.fm-action-sheet__item-icon{font-size:var(--fm-action-sheet-item-icon-size);margin-right:var(--fm-action-sheet-item-icon-margin-right)}.fm-action-sheet__item-title{font-size:var(--fm-action-sheet-item-title-font-size);line-height:var(--fm-action-sheet-item-title-line-height)}.fm-action-sheet__item-subtitle{font-size:var(--fm-action-sheet-item-subtitle-font-size);line-height:var(--fm-action-sheet-item-subtitle-line-height);width:100%;margin-top:var(--fm-action-sheet-item-subtitle-margin-top);color:var(--fm-action-sheet-item-subtitle-color);overflow-wrap:break-word}.fm-action-sheet__item--left{text-align:left;justify-content:flex-start}.fm-action-sheet__item--disabled{color:var(--fm-action-sheet-item-disabled-text-color);cursor:not-allowed}.fm-action-sheet__item--disabled:active{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__description:after,.fm-action-sheet__item:after{content:"";display:block;position:absolute;height:1px;bottom:0;left:0;right:0;transform:scaleY(.5);background-color:var(--fm-action-sheet-divider-color)}.fm-action-sheet__footer-gap{height:8px;background-color:var(--fm-action-sheet-footer-gap-color)}.fm-action-sheet__cancel{display:flex;flex-direction:column;justify-content:center;align-items:center;height:var(--fm-action-sheet-cancel-height);cursor:pointer;color:var(--fm-action-sheet-cancel-color);font-size:var(--fm-action-sheet-cancel-font-size);font-weight:var(--fm-action-sheet-cancel-font-weight)}:root{--fm-tab-bar-item-color: var(--fm-text-color);--fm-tab-bar-item-active-color: var(--fm-primary-color);--fm-tab-bar-item-font-size: 16px}.fm-tab-bar-item{flex:1 0 auto;position:relative;display:inline-flex;align-items:center;justify-content:center;margin:0 12px;line-height:44px}.fm-tab-bar-item--actived{color:var(--fm-tab-bar-item-active-color)}.fm-tab-bar-item--disabled{color:var(--fm-disabled-color)}.fm-tab-bar-item--dot .fm-tab-bar-item__text:after{content:"";position:absolute;top:0;right:0;width:8px;height:8px;background-color:var(--fm-danger-color);border-radius:100%;transform:translate(100%,100%)}.fm-tab-bar-item__text{position:relative;display:flex;justify-content:center;min-width:40px}.fm-tab-bar-item__ink{position:absolute;bottom:0;left:0;right:0;height:4px;background-color:var(--fm-tab-bar-item-active-color);border-radius:2px}.fm-tab-bar-item__badge{position:absolute;top:2px;right:0;padding:0 4px;max-width:28px;font-weight:500;font-size:12px;line-height:14px;border-radius:7px;color:var(--fm-background-white);background-color:var(--fm-danger-color);transform:translate(50%)}.fm-tab-bar-item__icon{position:relative;display:flex;align-items:center;justify-content:center;padding-right:4px}:root{--fm-tab-bar-height: 44px;--fm-tab-bar-background: var(--fm-background-white);--fm-tab-bar-color: var(--fm-text-color);--fm-tab-bar-active-color: var(--fm-primary-color);--fm-tab-bar-font-size: 16px}.fm-tab-bar{position:relative;background:var(--fm-tab-bar-background);color:var(--fm-tab-bar-color);font-size:var(--fm-tab-bar-font-size)}.fm-tab-bar--bottom-line{border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-tab-bar--bottom-line:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-tab-bar__scroll-wrapper{position:relative;width:100%;overflow:hidden}.fm-tab-bar__list{display:flex;justify-content:space-between;min-width:100%;transition:all .3s cubic-bezier(.17,.89,.45,1)}.fm-tab-bar__ink{position:absolute;bottom:0;left:0;display:block;height:4px;background-color:var(--fm-tab-bar-active-color);transition:all var(--fm-duration-base);border-radius:2px}.fm-tab-bar__ink--disabled{background-color:var(--fm-disabled-color)}.fm-tabs{overflow:hidden}.fm-tabs__content{display:flex}.fm-tab{display:block;flex-shrink:0;width:100%;height:100%;overflow:auto;word-break:break-all}.fm-tab--collapse{height:0;overflow:visible}:root{--fm-tag-padding: 0 6px;--fm-tag-height: 18px;--fm-tag-font-size: 12px;--fm-tag-border-radius: 2px;--fm-tag-color: var(--fm-white)}.fm-tag{position:relative;display:inline-flex;align-items:center;white-space:nowrap;padding:0 4px;color:var(--fm-tag-color);font-size:var(--fm-tag-font-size);line-height:var(--fm-tag-height);border-radius:var(--fm-tag-border-radius)}.fm-tag--primary{background-color:var(--fm-primary-color)}.fm-tag--success{background-color:var(--fm-success-color)}.fm-tag--danger{background-color:var(--fm-danger-color)}.fm-tag--warning{background-color:var(--fm-warning-color)}.fm-tag--plain{background-color:var(--fm-white)}.fm-tag--plain.fm-tag--primary{border:1px solid var(--fm-primary-color);color:var(--fm-primary-color)}.fm-tag--plain.fm-tag--success{border:1px solid var(--fm-success-color);color:var(--fm-success-color)}.fm-tag--plain.fm-tag--warning{border:1px solid var(--fm-warning-color);color:var(--fm-warning-color)}.fm-tag--plain.fm-tag--danger{border:1px solid var(--fm-danger-color);color:var(--fm-danger-color)}.fm-tag--medium{padding:2px 6px}.fm-tag--large{padding:4px 8px;font-size:14px;border-radius:4px}.fm-tag--round{border-radius:100px}.fm-tag--mark{border-radius:0 100px 100px 0}.fm-tag__close{font-size:8px;margin-left:4px}.fm-tag--large .fm-tag__close{font-size:10px}: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}.fm-picker-panel__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker-panel__toolbar-left,.fm-picker-panel__toolbar-right{padding:0 16px}.fm-picker-panel__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker-panel__content{position:relative;display:flex;cursor:grab}.fm-picker-panel__columns{display:flex;flex:1;overflow:hidden}.fm-picker-panel__column{flex:1}.fm-picker-panel__column-item{display:flex;align-items:center;justify-content:center;height:44px}.fm-picker-panel__mask{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;background-image:linear-gradient(180deg,#ffffffe6,#fff6),linear-gradient(0deg,#ffffffe6,#fff6);background-repeat:no-repeat;background-position:top,bottom;transform:translateZ(0);pointer-events:none}.fm-picker-panel__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(.5)}.fm-picker-group__header{text-align:left}.fm-picker-group__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker-group__toolbar-left,.fm-picker-group__toolbar-right{padding:0 16px}.fm-picker-group__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker-group__tab-bar{display:inline-block}:root{--fm-lookup-panel-background: var(--fm-background);--fm-lookup-panel-search-list-zindex: var(--fm-zindex-3)}.fm-lookup-panel{height:100%;display:flex;flex-direction:column;overflow:hidden;background-color:var(--fm-lookup-panel-background)}.fm-lookup-panel__header{background-color:var(--fm-background-white)}.fm-lookup-panel__header__search{border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-lookup-panel__header__search:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-lookup-panel__header__selected-wrapper{display:flex;padding:6px 16px;overflow:auto}.fm-lookup-panel__header__selected-item{font-size:14px;line-height:20px;word-break:keep-all;white-space:nowrap;padding:4px 6px;color:var(--fm-primary-color);background-color:var(--fm-primary-color-light);border-radius:4px}.fm-lookup-panel__header__selected-item:not(:last-child){margin-right:8px}.fm-lookup-panel__footer{padding:0 16px;height:48px;display:flex;align-items:center;justify-content:space-between;box-shadow:0 0 7px 0 var(--fm-box-shadow-color);border-top:1px solid var(--fm-gray-1);background-color:var(--fm-background-white)}.fm-lookup-panel__content{flex:1;display:flex;overflow:hidden;margin-top:10px;position:relative}.fm-lookup-panel__list{flex:1;overflow-y:auto;background-color:var(--fm-background-white)}.fm-lookup-panel__list-item{display:flex;align-items:center;background-color:#fff}.fm-lookup-panel__list-checker{padding-left:16px}.fm-lookup-panel__search-list{position:absolute;inset:0;display:none;overflow-y:auto;z-index:var(--fm-lookup-panel-search-list-zindex);background-color:var(--fm-background-white)}.fm-lookup-panel__popup-selected{width:100%;display:flex;flex-direction:column}.fm-lookup-panel__popup-selected__footer-left{color:var(--fm-primary-color)}.fm-lookup-panel__selected-list{flex:1;overflow:auto}.fm-lookup-panel__empty{padding:12px 16px}.fm-lookup-panel__empty__text{text-align:center;color:var(--fm-text-color-light)}.fm-lookup-panel__breadcrumb{display:flex;align-items:center;height:42px;padding:0 16px;overflow:auto;border-bottom:1px solid var(--fm-border-color);position:relative;border-bottom:none}.fm-lookup-panel__breadcrumb:after{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-lookup-panel__breadcrumb__item{display:flex;align-items:center;color:var(--fm-primary-color);padding-right:8px;flex-shrink:0}.fm-lookup-panel__breadcrumb__item:last-child{color:var(--fm-text-color-light)}.fm-lookup-panel__breadcrumb__icon{font-size:10px;padding-left:4px}.fm-lookup-panel__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)}: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)}.fm-search{display:flex;align-items:center;padding:8px 12px;color:var(--fm-search-color);background-color:var(--fm-search-background)}.fm-search__input-wrapper{flex:1;padding:5px 8px;border-radius:17px;background-color:var(--fm-search-input-background)}.fm-search__input{background-color:var(--fm-search-input-background)}.fm-search__search-icon{margin-right:4px;color:var(--fm-text-color-light)}.fm-filter-panel{height:100%;display:flex;flex-direction:column;padding:8px 16px}.fm-filter-panel__content{flex:1}.fm-filter-panel__footer{padding:8px 16px}.fm-filter-panel__field:not(:first-child){margin-top:16px}.fm-filter-panel__field__title{display:flex;align-items:center;justify-content:space-between;line-height:22px}.fm-filter-panel__field__content{padding-top:12px}.fm-filter-panel__field__range{display:flex;align-items:center}.fm-filter-panel__field__range__splitter{width:8px;margin:0 8px;border:1px solid #999}.fm-filter-panel__field__list{display:flex;flex-wrap:wrap;margin:0 -5px}.fm-filter-panel__field__list__item{height:30px;width:89px;font-size:13px;text-align:center;overflow:hidden;padding:6px 8px;margin:0 5px 10px;background:var(--fm-background);border-radius:var(--fm-radius-md);color:var(--fm-primary-color)}.fm-filter-panel__field__list__item--selected{background:var(--fm-primary-color);color:var(--fm-background-white)}.fm-filter-panel__field .fm-input-group .fm-input-group__body{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}.fm-filter__portal{display:flex;align-items:center;padding:8px 16px}.fm-filter__portal__icon{font-size:20px}.fm-filter__portal__search{flex:1;padding:0 0 0 8px}.fm-page-container{flex:1;display:flex;flex-direction:column;background:#f9fafb;overflow:hidden;-webkit-overflow-scrolling:auto;position:absolute;inset:0}.fm-page-container .drag-container{display:inherit;flex-direction:inherit;flex-shrink:1;flex-grow:1;flex-basis:0%;flex-wrap:inherit;justify-content:inherit;align-items:inherit;width:100%;overflow:inherit}.fm-page-body-container{flex-basis:0;flex-shrink:1;flex-grow:1;padding-bottom:12px;overflow:auto;display:flex;flex-direction:column}.fm-page-header-container{flex-shrink:0}.fm-page-footer-container{background-color:#fff}.fm-float-container{position:absolute!important;bottom:60px;right:30px} +@charset "UTF-8";:root{--fm-black: #000;--fm-white: #fff;--fm-gray-1: #f2f3f5;--fm-gray-2: #eee;--fm-gray-3: #ddd;--fm-gray-4: #ccc;--fm-gray-5: #999;--fm-gray-6: #666;--fm-gray-7: #333;--fm-red: #F24645;--fm-red-light: #f9e8e8;--fm-blue: #3A90FF;--fm-blue-2: #65a7ff;--fm-blue-light: #ecf2fe;--fm-green: #5CC171;--fm-green-2: #5AC1C3;--fm-green-light: #e9f5ed;--fm-orange: #FF9800;--fm-orange-2: #FA6400;--fm-orange-3: #FFB400;--fm-orange-light: #faf0e1;--fm-primary-color: var(--fm-blue);--fm-success-color: var(--fm-green);--fm-danger-color: var(--fm-red);--fm-warning-color: var(--fm-orange);--fm-submit-color: var(--fm-green-2);--fm-primary-color-light: var(--fm-blue-light);--fm-success-color-light: var(--fm-green-light);--fm-danger-color-light: var(--fm-red-light);--fm-warning-color-light: var(--fm-orange-light);--fm-text-color: var(--fm-gray-7);--fm-text-color-light: var(--fm-gray-5);--fm-active-color: var(--fm-gray-1);--fm-disabled-color: var(--fm-gray-4);--fm-readonly-color: var(--fm-gray-6);--fm-active-opacity: .7;--fm-readonly-opacity: .6;--fm-disabled-opacity: .5;--fm-background: var(--fm-gray-1);--fm-background-white: var(--fm-white);--fm-box-shadow-color: var(--fm-gray-1);--fm-padding-base: 4px;--fm-padding-xs: 8px;--fm-padding-sm: 12px;--fm-padding-md: 16px;--fm-padding-lg: 24px;--fm-padding-xl: 32px;--fm-padding-horizontal-xs: 0 var(--fm-padding-xs);--fm-padding-horizontal-sm: 0 var(--fm-padding-sm);--fm-padding-horizontal-md: 0 var(--fm-padding-md);--fm-padding-horizontal-lg: 0 var(--fm-padding-lg);--fm-margin-base: 4px;--fm-margin-xs: 8px;--fm-margin-sm: 12px;--fm-margin-md: 16px;--fm-margin-lg: 24px;--fm-margin-xl: 32px;--fm-margin-horizontal-xs: 0 var(--fm-margin-xs);--fm-margin-horizontal-sm: 0 var(--fm-margin-sm);--fm-margin-horizontal-md: 0 var(--fm-margin-md);--fm-margin-horizontal-lg: 0 var(--fm-margin-lg);--fm-font-bold-light: 500;--fm-font-bold: 600;--fm-font-size: 16px;--fm-line-height: 1.2;--fm-line-height-lg: 1.5;--fm-font-size-xs: 10px;--fm-font-size-sm: 12px;--fm-font-size-md: 14px;--fm-font-size-lg: 16px;--fm-gradient-blue: linear-gradient(-45deg,var(--fm-blue-2) 0%, var(--fm-blue) 100%);--fm-gradient-orange: linear-gradient(-45deg,var(--fm-orange) 0%, var(--fm-orange-2) 100%);--fm-base-font: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Segoe UI, Arial, Roboto, "PingFang SC", "miui", "Hiragino Sans GB", "Microsoft Yahei", sans-serif;--fm-price-font: avenir-heavy, "PingFang SC", helvetica neue, arial, sans-serif;--fm-duration-base: .3s;--fm-duration-fast: .2s;--fm-ease-out: ease-out;--fm-ease-in: ease-in;--fm-noborder: none;--fm-radius-sm: 2px;--fm-radius-md: 4px;--fm-radius-lg: 8px;--fm-radius-max: 999px;--fm-zindex-1: 9;--fm-zindex-2: 10;--fm-zindex-3: 99;--fm-zindex-4: 100;--fm-zindex-5: 999;--fm-zindex-6: 1000}*,*:before,*:after{box-sizing:border-box}body,h1,h2,h3,h4,p,figure,blockquote,dl,dd{margin:0}ul[role=list],ol[role=list]{list-style:none}html:focus-within{scroll-behavior:smooth}body{min-height:100vh;text-rendering:optimizeSpeed;line-height:1.5;font-family:-apple-system,Noto Sans,Helvetica Neue,Helvetica,Nimbus Sans L,Arial,Liberation Sans,PingFang SC,Hiragino Sans GB,Noto Sans CJK SC,Source Han Sans SC,Source Han Sans CN,Microsoft YaHei,Wenquanyi Micro Hei,WenQuanYi Zen Hei,ST Heiti,SimHei,WenQuanYi Zen Hei Sharp,sans-serif}a:not([class]){text-decoration-skip-ink:auto}img,picture{max-width:100%;display:block}input,button,textarea,select{font:inherit}@font-face{font-family:farrisMobile;font-style:normal;font-weight:400;src:url(data:font/ttf;base64,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AADmFAAAACUAAOYVAADmFQAAACYAAOYWAADmFgAAACcAAOYXAADmFwAAACgAAOYYAADmGAAAACkAAOYZAADmGQAAAHYAAOYaAADmGgAAAHUAAOYbAADmGwAAAHQAAOYcAADmHAAAAHMAAOYdAADmHQAAACoAAOYeAADmHgAAACsAAOYfAADmHwAAAHAAAOYgAADmIAAAAHEAAOYhAADmIQAAAHIAAOYiAADmIgAAAG8AAOYjAADmIwAAACwAAOYkAADmJAAAAGUAAOYlAADmJQAAAGYAAOYmAADmJgAAAGcAAOYnAADmJwAAAGgAAOYoAADmKAAAAGkAAOYpAADmKQAAAGoAAOYqAADmKgAAAGsAAOYrAADmKwAAAGwAAOYsAADmLAAAAG0AAOYtAADmLQAAAG4AAOYuAADmLgAAAGMAAOYvAADmLwAAAGQAAOYwAADmMAAAAGIAAOYyAADmMgAAADQAAOYzAADmMwAAAC0AAOY0AADmNAAAAC4AAOY2AADmNgAAAC8AAOY3AADmNwAAADAAAOY5AADmOQAAADEAAOY6AADmOgAAADIAAOZVAADmVQAAADUAAOZWAADmVgAAADoAAOZXAADmVwAAADcAAOZYAADmWAAAADgAAOZZAADmWQAAAD0AAOZaAADmWgAAAF4AAOZbAADmWwAAAF8AAOZcAADmXAAAAGAAAOZdAADmXQAAAGEAAOZeAADmXgAAADYAAOZfAADmXwAAADsAAOZgAADmYAAAADwAAOZhAADmYQAAADkAAOZiAADmYgAAAD4AAOZjAADmYwAAAD8AAOZkAADmZAAAAEAAAOZlAADmZQAAAEEAAOZmAADmZgAAAEIAAOZnAADmZwAAAEMAAOZoAADmaAAAAEQAAOZpAADmaQAAAEUAAOZqAADmagAAAEYAAOZrAADmawAAAEcAAOZsAADmbAAAAEgAAOZtAADmbQAAAEkAAOZuAADmbgAAAEoAAOZvAADmbwAAAEsAAOZwAADmcAAAAEwAAOZxAADmcQAAAE0AAOZyAADmcgAAAE4AAOZzAADmcwAAAE8AAOZ0AADmdAAAAFAAAOZ1AADmdQAAAFEAAOZ2AADmdgAAAFIAAOZ3AADmdwAAAFMAAOZ4AADmeAAAAFQAAOZ5AADmeQAAAFUAAOZ6AADmegAAAFYAAOZ7AADmewAAAFcAAOZ8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AV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFzAXQBdQF2AXcBeAF5AXoBewF8AX0BfgF/AYABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+AAlzLW1vcmUtbzEIcy1kZWxldGUIcy1iYWNrLW8Gcy1zY2FuEHMtb3JnYW5pemF0aW9uLW8Jcy1ncm91cC1vCXMtZmlsdGVyMQlzLWNsZWFyLW8Ocy1pbGx1c3RyYXRlLW8Icy1tb21lbnQIcy1zaG9wLW8Kcy1tb21lbnQtbwZzLXNob3AKcy1yZXZva2UtbwpzLXN1Ym1pdC1vB3MtYXBwLW8Gcy1ib29rBXMtYXBwBHMtbXkJcy1jb21tZW50C3MtY29tbWVudC1vCHMtYm9vay1vBnMtbXktbwxzLWxvY2F0aW9uLW8Kcy1sb2NhdGlvbgZzLW5ld3MIcy1uZXdzLW8Jcy1TZW5kaW5nCnMtSW1wb3J0LW8Icy1FZGl0LW8Icy1RUmNvZGULcy1CcmllZmNhc2URcy1Ob3RpZmljYXRpb25vZmYIcy1QZW5jaWwIcy1TdGFyLW8Jcy1CYXJDb2RlD3MtU2FsZU1lc3NhZ2UtbwxzLUxpc3R2aWV3LW8Lcy1QaWN0dXJlLW8Ocy1TYXZlRmlsbGV0LW8Ocy1TaG9wcGluZ2NhcnQJcy1QZW5kaW5nDnMtRXhwYW5kdmlldy1vCHMtTG9jay1vCXMtU2VydmljZQpzLVdhbGxldC1vEHMtU2hvcHBpbmdjYXJ0LW8Lcy1TZXR0aW5nLW8Ncy1VbmZvbGRSZWMtbwlzLVByb2ZpbGUGTGluay1vDVVzZXJTZXR0aW5nLW8Jcy1hZ3JlZS1vDHMtYXJyb3ctZG93bgdzLWFkZC1vB3MtYW5uZXgMcy1hcnJvdy1sZWZ0CnMtYXJyb3ctdXAScy1jaGVja2JveC1jaGVja2VkCnMtY2hlY2tib3gHcy1hcnJvdwpzLWV4Y2hhbmdlB3MtY2xlYXIJcy1jaGVja2VkB3MtZXllLW8Lcy1jbG9zZS1leWUEcy1hdAxzLWZlZWRiYWNrLW8Pcy1mb2xkLWNpcmNsZS1vB3MtY3Jvc3MHcy1taW51cwZzLWZpbGUPcy1mb2xkLXRyaWFuZ2xlCHMtZmlsdGVyCXMtZm9yd29yZAZzLXBsdXMJcy1maWxlZGVsCHMtZm9sZC1vCXMtaW1hZ2UtbwhzLW1vcmUtbw5zLXJlZGlvLWNpcmNsZQpzLXJlamVjdC1vCXMtc3VjY2VzcwlzLXJlZnJlc2gGcy1zdGFyDXMtcHJvY2Vzc2Zsb3cRcy11bmZvbGQtY2lyY2xlLW8Icy1yZXdpbmQKcy11bmZvbGQtbwtzLXdhcm5pbmctbxFzLXVuZm9sZC10cmlhbmdsZQlzLXByaW50LW8Kcy1zZWFyY2gtbwhBaXJwbGFuZQVUcmFpbgNCdXMEVGF4aQxvdmVydGltZW1lYWwTZm0taS10cmFmZmljZGV0YWlscw9mbS1pLXRyYWZmaWNzdWITZm0taS1hY2NvbW1vZGF0aW9uMQ1mbS1pLWJ1c2luZXNzC2ZtLWktYnVkZ2V0CWZtLWktZ2lmdBFmbS1pLWNhbmNlbGxhdGlvbgxmbS1pLWludm9pY2UJZm0taS1saXN0CmZtLWktbWVhbHMIZm0taS1wYXkMZm0taS1zdWJzaWR5B3Nob3V6aGUTZm0taS1jb3N0YWxsb2NhdGlvbgxmbS1pLXBheW1lbnQOZm0taS1JdGluZXJhcnkOZm0taS1tb3JleGUwMmQPZm0taS1pbWFnZXhlMDJlEGZtLWktcmVqZWN0eGUwMmYPZm0taS1hZ3JlZXhlMDMxDWZtLWktY2FyZGZvbGQPZm0taS1jYXJkdW5mb2xkEWZtLWktdHJhZmZpY290aGVyD2ZtLWktYm90dG9tc2F2ZRBmbS1pLXRyYWZmaWNib2F0D2ZtLWktdHJhZmZpY2NhchFmbS1pLXRyYWZmaWNwbGFuZRFmbS1pLXRyYWZmaWN0cmFpbg9mbS1pLXRyYWZmaWNidXMMZm0taS1hZGRncmF5CmZtLWktY2xvc2UIZm0taS1hZGQJZm0taS1tb3JlCmZtLWktY2hlY2sPZm0taS1iYWNrY2lyY2xlCmZtLWktYWdyZWUMZm0taS1sb2FkaW5nDGZtLWktZmlsZWRlbAlmbS1pLWZpbGUQZm0taS1wcm9jZXNzZmxvdwxmbS1pLXJlZHN0YXIQZm0taS1yaWdodGNpcmNsZQ9mbS1pLXRpbWVjaXJjbGUOZm0taS1zY3JlZW5pbmcMZm0taS11bmNoZWNrDmZtLWktb3BlcmF0aW9uE2ZtLWktYXBwcm92YWxhbW91bnQLZm0taS1hZ3JlZWQOZm0taS1pbnByb2Nlc3MNZm0taS1mZWVkYmFjawpmbS1pLXByaW50DmZtLWktaW1wb3J0YW50GmZtLWktYW1vdW50b2ZyZWltYnVyc2VtZW50FGZtLWktc2FmZXR5YXNzaXN0YW50C2ZtLWktcmVtaW5kDWZtLWktZXllb3BwZW4NZm0taS1leWVjbG9zZRBmbS1pLVBob3RvZ3JhcGh5D2ZtLWktcGhvdG9ncmFwaA9mbS1pLWFkZHBpY3R1cmUTZm0taS10b3Bfb3RoZXItZmFjZQ5mbS1pLXRvcF9vdGhlcgtmbS1pLWRlbGV0ZQ1mbS1pLW5leHRwYWdlDmZtLWktYWRkYnV0dG9uFmZtLWktd2FpdGZvcnByb2Nlc3NpbmcTZm0taS13YXJuaW5nbWVzc2FnZRJmbS1pLWZhaWx1cmVwcm9tcHQUZm0taS1zdWNjZXNzZnVsaGludHMKZm0taS1vdGhlcgxmbS1pLXJldHJhY3QOZm0taS1kcm9wLWRvd24LZm0taS1jYW5jZWwLZm0taS1zZWFyY2gTZm0taS1tdWx0aXBsZWNob2ljZRFmbS1pLXNpbmdsZWNob2ljZQ9mbS1pLW1pY3JvcGhvbmUXZm0taS1hcnJvdy1jaGV2cm9uLWxlZnQPZm0taS1oZWxwY2VudGVyDmZtLWktc3dlZXBjb2RlDmZtLWktZ3JvdXBjaGF0DmZtLWktYWRkZnJpZW5kC2ZtLWktdG9wX215EGZtLWktdG9wX215LWZhY2UPZm0taS10b3BfZnJpZW5kFGZtLWktdG9wX2ZyaWVuZC1mYWNlFWZtLWktdG9wX3B1YmxpY3ByYWlzZRpmbS1pLXRvcF9wdWJsaWNwcmFpc2UtZmFjZQ1mbS1pLXRvcF9ob21lEmZtLWktdG9wX2hvbWUtZmFjZQAAAAA=) format("truetype")}@keyframes fm-fade-in{0%{opacity:0}to{opacity:1}}@keyframes fm-fade-out{0%{opacity:1}to{opacity:0}}.fm-fade-enter-active{animation:.3s fm-fade-in both ease-out}.fm-fade-leave-active{animation:.3s fm-fade-out both ease-in}.fm-slide-up-enter-from,.fm-slide-up-leave-to{transform:translate3d(0,100%,0)}.fm-slide-down-enter-from,.fm-slide-down-leave-to{transform:translate3d(0,-100%,0)}.fm-slide-left-enter-from,.fm-slide-left-leave-to{transform:translate3d(-100%,0,0)}.fm-slide-right-enter-from,.fm-slide-right-leave-to{transform:translate3d(100%,0,0)}.fm-slide-up-enter-active,.fm-slide-down-enter-active,.fm-slide-left-enter-active,.fm-slide-right-enter-active{transition-timing-function:ease-out}.fm-slide-up-leave-active,.fm-slide-down-leave-active,.fm-slide-left-leave-active,.fm-slide-right-leave-active{transition-timing-function:ease-in}.fm-slide-in-enter-active,.fm-slide-in-leave-active,.fm-slide-out-enter-active,.fm-slide-out-leave-active{will-change:transform;transition:all .3s;height:100%;width:100%;top:0;position:absolute;backface-visibility:hidden;perspective:1000}.fm-slide-in-leave-to,.fm-slide-out-enter-from{transform:translate(-100%);opacity:0}.fm-slide-in-enter-from,.fm-slide-out-leave-to{transform:translate(100%);opacity:0}@keyframes fm-drop-down-in{0%{height:0;opacity:0}to{opacity:1}}@keyframes fm-drop-down-out{0%{opacity:1}to{height:0;opacity:0}}.fm-drop-down-enter-active{animation:.3s fm-drop-down-in both ease-out}.fm-drop-down-leave-active{animation:.3s fm-drop-down-out both ease-in}@keyframes fm-rotate{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}:root{--fm-button-height: 42px;--fm-button-padding: 0 14px;--fm-button-radius: 2px;--fm-button-border-width: 1px;--fm-button-color: var(--fm-white);--fm-button-line-height: var(--fm-line-height);--fm-button-font-size: var(--fm-font-size);--fm-button-plain-background: var(--fm-white);--fm-button-lg-height: 46px;--fm-button-lg-font-size: 18px;--fm-button-md-height: 38px;--fm-button-md-font-size: 14px;--fm-button-sm-height: 34px;--fm-button-sm-padding: 0 8px;--fm-button-sm-font-size: 12px;--fm-button-xs-height: 28px;--fm-button-xs-font-size: 10px;--fm-button-secondary-color: var(--fm-blue-light)}.fm-button{position:relative;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;text-align:center;margin:0;border:none;transition:opacity .2s;color:var(--fm-button-color);height:var(--fm-button-height);padding:var(--fm-button-padding);font-size:var(--fm-button-font-size);line-height:var(--fm-button-line-height);border-radius:var(--fm-button-radius)}.fm-button--primary{background:var(--fm-primary-color)}.fm-button--secondary{color:var(--fm-primary-color);background:var(--fm-button-secondary-color)}.fm-button--danger{background-color:var(--fm-danger-color)}.fm-button--warning{background-color:var(--fm-warning-color)}.fm-button--success{background-color:var(--fm-success-color)}.fm-button--plain{box-shadow:none;background:var(--fm-button-plain-background)}.fm-button--plain.fm-button--primary{color:var(--fm-primary-color);border:var(--fm-button-border-width) solid var(--fm-primary-color)}.fm-button--plain.fm-button--success{color:var(--fm-success-color);border:var(--fm-button-border-width) solid var(--fm-success-color)}.fm-button--plain.fm-button--danger{color:var(--fm-danger-color);border:var(--fm-button-border-width) solid var(--fm-danger-color)}.fm-button--plain.fm-button--warning{color:var(--fm-button-warning-color);border:var(--fm-button-border-width) solid var(--fm-button-warning-color)}.fm-button--noborder{border:none!important}.fm-button--large{height:var(--fm-button-lg-height);font-size:var(--fm-button-lg-font-size)}.fm-button--middle{height:var(--fm-button-md-height);font-size:var(--fm-button-md-font-size)}.fm-button--small{height:var(--fm-button-sm-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-sm-font-size)}.fm-button--mini{height:var(--fm-button-xs-height);padding:var(--fm-button-sm-padding);font-size:var(--fm-button-xs-font-size)}.fm-button--block{display:flex;width:100%}.fm-button--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-button--loading:before,.fm-button--disabled:before{display:none}.fm-button--round{border-radius:var(--fm-radius-max)}.fm-button--square{border-radius:0}.fm-button__loading{display:inline-block;width:20px;max-width:100%;height:20px;max-height:100%;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-button__loading circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}.fm-button__loading-icon-circular{color:#fff}.fm-button__loading-text{margin-left:6px}.fm-button__icon:not(:last-child){margin-right:6px}.fm-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;background-color:#000;border:inherit;border-color:#000;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;content:" "}.fm-button:active:before{opacity:.1}.fm-button-edit__tags{min-height:24px;flex:1;display:flex;overflow:auto}.fm-button-edit__tag:not(:last-child){margin-right:6px}:root{--fm-button-group-gap: 16px}.fm-button-group{display:inline-flex;flex-wrap:nowrap;max-width:100%}.fm-button-group+.fm-button-group{margin-left:var(--fm-button-group-gap)}.fm-button-group__item{margin:0;min-width:0;max-width:100%;white-space:nowrap;flex:0 1 auto;user-select:none;outline:none!important}.fm-button-group__item--bare-vertical{display:inline-flex;flex-direction:column;align-items:center;justify-content:space-between;color:#666}.fm-button-group__item--bare-vertical .fm-button-group__item-icon{font-size:20px}.fm-button-group__item--bare-vertical .fm-button-group__item-text{font-size:10px;line-height:16px}.fm-button-group__item--bare-vertical.fm-button-group__item--disabled{cursor:not-allowed;opacity:.5}.fm-button-group--block{display:flex}.fm-button-group--vertical{flex-direction:column}.fm-button-group--block .fm-button-group__item{width:auto;flex:10000 1 0%}.fm-button-group--horizontal.fm-button-group--mode-default .fm-button-group__item+.fm-button-group__item{margin-left:var(--fm-button-group-gap)}.fm-button-group--vertical.fm-button-group--mode-default .fm-button-group__item+.fm-button-group__item{margin-top:var(--fm-button-group-gap)}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:not(:first-child):not(:last-child),.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:not(:first-child):not(:last-child){border-radius:0}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:first-child:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:first-child:not(:last-child){border-bottom-left-radius:0;border-bottom-right-radius:0}.fm-button-group--horizontal:not(.fm-button-group--mode-default) .fm-button-group__item:last-child:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.fm-button-group--vertical:not(.fm-button-group--mode-default) .fm-button-group__item:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.fm-button-group--horizontal.fm-button-group--mode-outline .fm-button-group__item:not(:first-child){border-left:0}.fm-button-group--vertical.fm-button-group--mode-outline .fm-button-group__item:not(:first-child){border-top:0}.fm-button-group--horizontal.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after,.fm-button-group--vertical.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after{content:"";display:block;position:absolute;background-color:var(--fm-gray-3)}.fm-button-group--horizontal.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after{width:1px;right:0;top:var(--fm-padding-xs);bottom:var(--fm-padding-xs)}.fm-button-group--vertical.fm-button-group--mode-text .fm-button-group__item:not(:last-child):after{height:1px;bottom:0;left:var(--fm-padding-xs);right:var(--fm-padding-xs)}.fm-button-group--fill{flex:1}:root{--fm-card-background: var(--fm-white);--fm-card-title-color: var(--fm-gray-7)}.fm-card{background-color:var(--fm-card-background)}.fm-card__header{display:flex;justify-content:space-between;align-items:center;padding:11px 16px 10px;border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-card__header:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-card__title{position:relative;padding-left:var(--fm-padding-md);color:var(--fm-card-title-color);font-size:var(--fm-font-size-lg);line-height:var(--fm-line-height-lg);font-weight:var(--fm-font-bold-light);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-card__title:before{content:"";position:absolute;left:0;top:50%;width:3px;height:14px;margin:-7px 0 0;background:var(--fm-primary-color)}.fm-card__footer{border-top:1px solid #ddd;position:relative;border-top:none}.fm-card__footer:before{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}:root{--fm-cell-padding: 10px 16px;--fm-cell-margin: 5px;--fm-cell-line-height: 24px;--fm-cell-font-size: var(--fm-font-size);--fm-cell-background: var(--fm-background-white);--fm-cell-color: var(--fm-text-color);--fm-cell-label-font-size: 12px;--fm-cell-label-line-height: 18px;--fm-cell-label-color: var(--fm-text-color-light);--fm-cell-required-color: var(--fm-danger-color)}.fm-cell{width:100%;padding:var(--fm-cell-padding);background-color:var(--fm-cell-background);color:var(--fm-cell-color);font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);position:relative;display:flex;overflow:hidden}.fm-cell--bottom-border,.fm-cell:not(:last-child){border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-cell--bottom-border:after,.fm-cell:not(:last-child):after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-cell--bottom-border:after,.fm-cell:not(:last-child):after{left:16px!important}.fm-cell.fm-cell-all-width:not(:last-child):after{left:0!important}.fm-cell--clickable{cursor:pointer}.fm-cell--clickable:active{background-color:var(--fm-active-color)}.fm-cell--required .fm-cell-title{position:relative}.fm-cell--required .fm-cell-title .fm-cell-title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-cell__title,.fm-cell__value{flex:1;font-size:inherit}.fm-cell__title{display:inline-block;overflow:hidden}.fm-cell__title-text{display:flex;word-break:break-all}.fm-cell__title-text span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-cell__right{display:flex;overflow:hidden;flex-direction:column}.fm-cell__right-content{display:flex;flex:1}.fm-cell__right--fill{flex:1}.fm-cell__value{position:relative;overflow:hidden;text-align:right;vertical-align:middle;word-wrap:break-word}.fm-cell__value--alone{text-align:left}.fm-cell__label{margin-top:var(--fm-cell-margin);color:var(--fm-cell-label-color);font-size:var(--fm-cell-label-font-size);line-height:var(--fm-cell-label-line-height)}.fm-cell--center{align-items:center}.fm-cell__extra,.fm-cell__left-icon,.fm-cell__right-icon{min-width:1em;font-size:var(--fm-cell-font-size);line-height:var(--fm-cell-line-height);display:flex;align-items:center}.fm-cell__left-icon{margin-right:var(--fm-cell-margin)}.fm-cell__extra,.fm-cell__right-icon{margin-left:var(--fm-cell-margin)}.fm-cell--noborder .fm-cell:after{display:none!important}.fm-cell--card{padding-left:0;padding-right:0}.fm-checkbox-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-checkbox-group--vertical{flex-direction:column}.fm-checkbox-group--vertical .fm-checkbox:not(:last-child){margin-bottom:8px}.fm-checkbox{margin-top:4px;margin-bottom:4px}:root{--fm-checker-color: var(--fm-text-color);--fm-checker-font-size: var(--fm-font-size);--fm-checker-icon-color: var(--fm-text-color-light);--fm-checker-icon-background: var(--fm-background-white);--fm-checker-icon-radius: var(--fm-radius-md);--fm-checker-checked-icon-color: var(--fm-primary-color);--fm-checker-button-background: var(--fm-gray-2);--fm-checker-disabled-color: var(--fm-disabled-color);--fm-checker-disabled-icon-color: var(--fm-gray-1)}.fm-checker{display:flex;align-items:center;color:var(--fm-checker-color);font-size:var(--fm-checker-font-size)}.fm-checker__icon{display:inline-block;align-items:center}.fm-checker__icon .fm-icon{display:block;height:20px;width:20px;line-height:18px;font-size:14px;text-align:center;border-radius:var(--fm-checker-icon-radius);border:1px solid var(--fm-checker-icon-color);color:var(--fm-checker-icon-background);background-color:var(--fm-checker-icon-background)}.fm-checker__label{margin-left:8px;margin-right:8px;display:inline-block;line-height:20px}.fm-checker:first-child .fm-checker_button{margin-left:0}.fm-checker--round .fm-checker__icon .fm-icon{border-radius:100%}.fm-checker--button .fm-checker__label{font-size:13px;text-align:center;border-radius:14px;line-height:28px;padding:0 12px;min-width:60px;margin-right:0;color:var(--fm-checker-color);background:var(--fm-checker-button-background)}.fm-checker--checked .fm-checker__icon .fm-icon{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-checked-icon-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--checked.fm-checker--button .fm-checker__label{color:var(--fm-checker-icon-background);border-color:var(--fm-checker-color);background-color:var(--fm-checker-checked-icon-color)}.fm-checker--readonly{opacity:var(--fm-readonly-opacity)}.fm-checker--disabled{color:var(--fm-checker-disabled-color)}.fm-checker--disabled .fm-checker__icon .fm-icon{border-color:var(--fm-checker-disabled-color);background-color:var(--fm-checker-disabled-icon-color);color:var(--fm-checker-disabled-icon-color)}.fm-checker--disabled.fm-checker--checked .fm-checker__icon .fm-icon{background-color:var(--fm-checker-disabled-color);border-color:var(--fm-checker-disabled-color)}:root{--fm-icon-font-size: 14px;--fm-icon-color: inherit}.fm-icon{font-family:farrisMobile!important;font-size:var(--fm-icon-font-size);font-style:normal;color:var(--fm-icon-color);display:inline-block;width:1em;height:1em;font-weight:400;line-height:1;vertical-align:middle;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fm-icon:before{display:inline-block}.fm-icon-filter:before{content:"\e697"}.fm-icon-cardfold:before{content:"\e6b7"}.fm-icon-cardunfold:before{content:"\e6b8"}.fm-icon-trafficother:before{content:"\e6b9"}.fm-icon-bottomsave:before{content:"\e6ba"}.fm-icon-trafficboat:before{content:"\e6bb"}.fm-icon-trafficcar:before{content:"\e6bc"}.fm-icon-trafficplane:before{content:"\e6bd"}.fm-icon-traffictrain:before{content:"\e6be"}.fm-icon-trafficbus:before{content:"\e6bf"}.fm-icon-addgray:before{content:"\e6a7"}.fm-icon-close:before{content:"\e6a8"}.fm-icon-add-line:before{content:"\e6a9"}.fm-icon-more:before{content:"\e6aa"}.fm-icon-check:before{content:"\e6ab"}.fm-icon-backcircle:before{content:"\e6ac"}.fm-icon-agree:before{content:"\e6ad"}.fm-icon-loading:before{content:"\e6ae"}.fm-icon-filedel:before{content:"\e6af"}.fm-icon-file:before{content:"\e6b0"}.fm-icon-processflow:before{content:"\e6b1"}.fm-icon-redstar:before{content:"\e6b2"}.fm-icon-rightcircle:before{content:"\e6b3"}.fm-icon-timecircle:before{content:"\e6b4"}.fm-icon-screening:before{content:"\e6b5"}.fm-icon-uncheck:before{content:"\e6b6"}.fm-icon-operation:before{content:"\e02c"}.fm-icon-approvalamount:before{content:"\e02b"}.fm-icon-agreed:before{content:"\e02a"}.fm-icon-inprocess:before{content:"\e029"}.fm-icon-feedback:before{content:"\e028"}.fm-icon-print:before{content:"\e027"}.fm-icon-important:before{content:"\e026"}.fm-icon-amountofreimbursement:before{content:"\e025"}.fm-icon-safetyassistant:before{content:"\e024"}.fm-icon-remind:before{content:"\e023"}.fm-icon-eyeoppen:before{content:"\e022"}.fm-icon-eyeclose:before{content:"\e01e"}.fm-icon-photography:before{content:"\e021"}.fm-icon-photograph:before{content:"\e020"}.fm-icon-addpicture:before{content:"\e01f"}.fm-icon-top_other-face:before{content:"\e01d"}.fm-icon-top_other:before{content:"\e01c"}.fm-icon-delete:before{content:"\e01b"}.fm-icon-nextpage:before{content:"\e01a"}.fm-icon-addbutton:before{content:"\e019"}.fm-icon-waitforprocessing:before{content:"\e018"}.fm-icon-warningmessage:before{content:"\e017"}.fm-icon-failureprompt:before{content:"\e016"}.fm-icon-successfulhints:before{content:"\e015"}.fm-icon-other:before{content:"\e014"}.fm-icon-retract:before{content:"\e013"}.fm-icon-drop-down:before{content:"\e012"}.fm-icon-cancel:before{content:"\e011"}.fm-icon-search:before{content:"\e010"}.fm-icon-multiplechoice:before{content:"\e00f"}.fm-icon-singlechoice:before{content:"\e00e"}.fm-icon-microphone:before{content:"\e00d"}.fm-icon-arrow-chevron-left:before{content:"\e00c"}.fm-icon-helpcenter:before{content:"\e00b"}.fm-icon-sweepcode:before{content:"\e00a"}.fm-icon-groupchat:before{content:"\e009"}.fm-icon-addfriend:before{content:"\e008"}.fm-icon-top_my:before{content:"\e007"}.fm-icon-top_my-face:before{content:"\e006"}.fm-icon-top_friend:before{content:"\e005"}.fm-icon-top_friend-face:before{content:"\e004"}.fm-icon-top_publicpraise:before{content:"\e003"}.fm-icon-top_publicpraise-face:before{content:"\e002"}.fm-icon-top_home:before{content:"\e001"}.fm-icon-top_home-face:before{content:"\e000"}.fm-icon-s-agree-o:before{content:"\e655"}.fm-icon-s-arrow-down:before{content:"\e656"}.fm-icon-s-add-o:before{content:"\e657"}.fm-icon-s-annex:before{content:"\e658"}.fm-icon-s-arrow:before{content:"\e659"}.fm-icon-s-arrow-up:before{content:"\e65e"}.fm-icon-s-checkbox-checked:before{content:"\e65f"}.fm-icon-s-checkbox:before{content:"\e660"}.fm-icon-s-arrow-left:before{content:"\e661"}.fm-icon-s-exchange:before{content:"\e662"}.fm-icon-s-clear:before{content:"\e663"}.fm-icon-s-checked:before{content:"\e664"}.fm-icon-s-eye-o:before{content:"\e665"}.fm-icon-s-close-eye:before{content:"\e666"}.fm-icon-s-at:before{content:"\e667"}.fm-icon-s-feedback-o:before{content:"\e668"}.fm-icon-s-fold-circle-o:before{content:"\e669"}.fm-icon-s-cross:before{content:"\e66a"}.fm-icon-s-minus:before{content:"\e66b"}.fm-icon-s-file:before{content:"\e66c"}.fm-icon-s-fold-triangle:before{content:"\e66d"}.fm-icon-s-filter:before{content:"\e66e"}.fm-icon-s-forword:before{content:"\e66f"}.fm-icon-s-plus:before{content:"\e670"}.fm-icon-s-filedel:before{content:"\e671"}.fm-icon-s-fold-o:before{content:"\e672"}.fm-icon-s-image-o:before{content:"\e673"}.fm-icon-s-more-o:before{content:"\e674"}.fm-icon-s-redio-circle:before{content:"\e675"}.fm-icon-s-reject-o:before{content:"\e676"}.fm-icon-s-success:before{content:"\e677"}.fm-icon-s-refresh:before{content:"\e678"}.fm-icon-s-star:before{content:"\e679"}.fm-icon-s-processflow:before{content:"\e67a"}.fm-icon-s-unfold-circle-o:before{content:"\e67b"}.fm-icon-s-rewind:before{content:"\e67c"}.fm-icon-s-unfold-o:before{content:"\e67d"}.fm-icon-s-save-o:before{content:"\e67e"}.fm-icon-s-warning-o:before{content:"\e67f"}.fm-icon-s-unfold-triangle:before{content:"\e680"}.fm-icon-s-print-o:before{content:"\e681"}.fm-icon-s-search-o:before{content:"\e682"}.fm-icon-s-news:before{content:"\e683"}.fm-icon-s-news-o:before{content:"\e684"}.fm-icon-s-shop:before{content:"\e68c"}.fm-icon-s-sending:before{content:"\e60b"}.fm-icon-s-import-o:before{content:"\e60c"}.fm-icon-s-edit-o:before{content:"\e60d"}.fm-icon-s-qrcode:before{content:"\e60e"}.fm-icon-s-briefcase:before{content:"\e60f"}.fm-icon-s-notificationoff:before{content:"\e610"}.fm-icon-s-pencil:before{content:"\e611"}.fm-icon-s-star-o:before{content:"\e612"}.fm-icon-s-barcode:before{content:"\e613"}.fm-icon-s-salemessage-o:before{content:"\e614"}.fm-icon-s-listview-o:before{content:"\e615"}.fm-icon-s-picture-o:before{content:"\e616"}.fm-icon-s-savefillet-o:before{content:"\e617"}.fm-icon-s-shoppingcart:before{content:"\e618"}.fm-icon-s-pending:before{content:"\e61d"}.fm-icon-s-expandview-o:before{content:"\e61e"}.fm-icon-s-lock-o:before{content:"\e623"}.fm-icon-s-my:before{content:"\e692"}.fm-icon-s-service:before{content:"\e633"}.fm-icon-s-wallet-o:before{content:"\e634"}.fm-icon-s-shoppingcart-o:before{content:"\e636"}.fm-icon-s-setting-o:before{content:"\e637"}.fm-icon-s-my-o:before{content:"\e696"}.fm-icon-s-unfoldrec-o:before{content:"\e639"}.fm-icon-s-profile:before{content:"\e63a"}.fm-icon-s-link-o:before{content:"\e609"}.fm-icon-s-usersetting-o:before{content:"\e632"}.fm-icon-s-shop-o:before{content:"\e68a"}.fm-icon-s-list:before{content:"\e62a"}.fm-icon-s-location-o:before{content:"\e685"}.fm-icon-s-location:before{content:"\e686"}.fm-icon-s-moment:before{content:"\e689"}.fm-icon-s-moment-o:before{content:"\e68b"}.fm-icon-s-revoke-o:before{content:"\e687"}.fm-icon-s-submit-o:before{content:"\e688"}.fm-icon-s-app-o:before{content:"\e68f"}.fm-icon-s-app:before{content:"\e691"}.fm-icon-s-book-o:before{content:"\e695"}.fm-icon-s-book:before{content:"\e690"}.fm-icon-s-comment:before{content:"\e693"}.fm-icon-s-comment-o:before{content:"\e694"}.fm-icon-s-illustrate-o:before{content:"\e68d"}.fm-icon-s-clear-o:before{content:"\e68e"}.fm-icon-friend:before{content:"\e005"}.fm-icon-scan:before{content:"\e69a"}.fm-icon-back:before{content:"\e69b"}.fm-icon-menu:before{content:"\e69d"}:root{--fm-navbar-background: var(--fm-background-white);--fm-navbar-color: var(--fm-text-color);--fm-navbar-height: 44px;--fm-navbar-title-size: 17px;--fm-navbar-side-size: 16px;--fm-navbar-arrow-size: 16px;--fm-navbar-toolbar-item-height: 46px}.fm-navbar{position:relative;z-index:9;display:flex;align-items:center;line-height:1.5;text-align:center;user-select:none;height:var(--fm-navbar-height);color:var(--fm-navbar-color);background-color:var(--fm-navbar-background)}.fm-navbar--fixed{position:fixed;top:0;left:0;width:100%}.fm-navbar--bottom-border{border-bottom:1px solid #e6e6e6;position:relative;border-bottom:none}.fm-navbar--bottom-border:after{content:"";position:absolute;background-color:#e6e6e6;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-navbar__title{max-width:60%;margin:0 auto;font-weight:500;font-size:var(--fm-navbar-title-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-navbar__left,.fm-navbar__right{position:absolute;top:0;bottom:0;display:flex;align-items:center;max-width:30%;padding:0 16px;font-size:var(--fm-navbar-side-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;cursor:pointer}.fm-navbar__left{left:0}.fm-navbar__left:active{opacity:var(--fm-active-opacity)}.fm-navbar__left.fm-navbar-left-padding{padding-left:14px}.fm-navbar__right{right:0}.fm-navbar__right .fm-navbar-text:active{opacity:var(--fm-active-opacity)}.fm-navbar__left-arrow{min-width:1em;margin-right:4px;font-size:var(--fm-navbar-arrow-size)}.fm-navbar__toolbar{padding:0!important}.fm-navbar__toolbar-item{padding:0 var(--fm-padding-sm);height:var(--fm-navbar-toolbar-item-height);line-height:var(--fm-navbar-toolbar-item-height);user-select:none;cursor:pointer}.fm-navbar__toolbar-item:not(:last-child){border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-navbar__toolbar-item:not(:last-child):after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-navbar__toolbar-item--disabled{opacity:var(--fm-disabled-opacity);cursor:not-allowed}:root{--fm-input-group-size: var(--fm-font-size);--fm-input-group-color: var(--fm-text-color);--fm-input-group-sub-size: 13px;--fm-input-group-padding: 10px 16px;--fm-input-group-sub-color: var(--fm-text-color-light);--fm-input-group-border-color: var(--fm-gray-2)}.fm-input-group{display:flex;flex-direction:column;background-color:var(--fm-white)}.fm-input-group--padding{padding:var(--fm-input-group-padding)}.fm-input-group__body{flex:1;display:flex;align-items:center;min-height:24px;color:var(--fm-input-group-color);font-size:var(--fm-input-group-size)}.fm-input-group__body--border{border:1px solid var(--fm-input-group-border-color);padding:4px 8px;border-radius:4px}.fm-input-group__control{display:flex;width:100%;min-width:0;margin:0;padding:0;border:0;resize:none;color:inherit;font-size:inherit;outline:none;line-height:inherit;background-color:transparent}.fm-input-group__control::placeholder{color:var(--fm-input-group-sub-color)}.fm-input-group__control:disabled{opacity:1;cursor:not-allowed;color:var(--fm-disabled-color);-webkit-text-fill-color:currentColor}.fm-input-group__control::-webkit-search-cancel-button{display:none}.fm-input-group__control--readonly{cursor:default;color:var(--fm-readonly-color)}.fm-input-group__control--left{justify-content:flex-start;text-align:left}.fm-input-group__control--center{justify-content:center;text-align:center}.fm-input-group__control--right{justify-content:flex-end;text-align:right}.fm-input-group__clear{cursor:pointer;margin-right:-8px;padding:4px 8px;color:var(--fm-input-group-sub-color);flex-shrink:0;box-sizing:content-box}.fm-input-group__left-icon{margin:auto 4px auto 0}.fm-input-group__right-icon{margin:auto 0 auto 4px}.fm-input-group__word-limit{margin-top:4px;line-height:18px;text-align:right;font-size:var(--fm-input-group-sub-size);color:var(--fm-input-group-sub-color)}.fm-radio-group{display:flex;overflow:visible;text-align:left;flex-wrap:wrap}.fm-radio-group--vertical{flex-direction:column}.fm-radio-group--vertical .fm-radio:not(:last-child){margin-bottom:8px}.fm-radio{margin-top:4px;margin-bottom:4px}:root,:host{--fm-rate-icon-size: 20px;--fm-rate-icon-gutter: var(--fm-padding-base);--fm-rate-icon-void-color: var(--fm-gray-4);--fm-rate-icon-full-color: var(--fm-orange-3);--fm-rate-icon-disabled-color: var(--fm-gray-4)}.fm-rate{display:inline-flex;cursor:pointer;user-select:none;flex-wrap:wrap}.fm-rate__item{position:relative}.fm-rate__item:not(:last-child){padding-right:var(--fm-rate-icon-gutter)}.fm-rate__icon{display:block;width:1em;color:var(--fm-rate-icon-void-color);font-size:var(--fm-rate-icon-size)}.fm-rate__icon--half{position:absolute;top:0;left:0;overflow:hidden;pointer-events:none;color:var(--fm-rate-icon-full-color)}.fm-rate__icon--full{color:var(--fm-rate-icon-full-color)}.fm-rate__icon--disabled{color:var(--fm-rate-icon-disabled-color)}.fm-rate--disabled{cursor:not-allowed}.fm-rate--readonly{cursor:default}:root{--fm-form-item-size: var(--fm-font-size);--fm-form-item-color: var(--fm-text-color);--fm-form-item-label-width: 105px;--fm-form-item-sub-size: 13px}.fm-form-item{font-size:var(--fm-form-item-size);color:var(--fm-form-item-color)}.fm-form-item--vertical{flex-direction:column}.fm-form-item--vertical .fm-form-item__label{margin-bottom:4px}.fm-form-item__label{display:flex;flex:none;align-items:flex-start;text-align:left;width:var(--fm-form-item-label-width);margin-right:4px}.fm-form-item__label--left{justify-content:flex-start}.fm-form-item__label--center{justify-content:center}.fm-form-item__label--right{justify-content:flex-end}.fm-form-item__label--required{position:relative}.fm-form-item__label--required .fm-cell__title-text:after{padding-left:2px;color:var(--fm-cell-required-color);font-size:12px;content:"*"}.fm-form-item__content{display:flex}.fm-form-item__content .fm-input-group{padding:0;flex:1}.fm-form-item__content--left{justify-content:flex-start}.fm-form-item__content--left input.fm-input-group__control{justify-content:flex-start;text-align:left}.fm-form-item__content--center{justify-content:center}.fm-form-item__content--center input.fm-input-group__control{justify-content:flex-center;text-align:center}.fm-form-item__content--right{justify-content:flex-end}.fm-form-item__content--right input.fm-input-group__control{justify-content:flex-end;text-align:right}.fm-form-item__error-message{color:var(--fm-danger-color);font-size:var(--fm-form-item-sub-size)}.fm-form-item__error-message--left{text-align:left}.fm-form-item__error-message--center{text-align:center}.fm-form-item__error-message--right{text-align:right}:root{--fm-overlay-background: rgba(0, 0, 0, .4);--fm-overlay-zindex: 98}.fm-overlay{width:100%;position:fixed;top:0;left:0;z-index:var(--fm-overlay-zindex);background-color:var(--fm-overlay-background);bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-overlay{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}:root{--fm-popup-background: var(--fm-white);--fm-popup-zindex: var(--fm-zindex-3);--fm-popup-radius: 16px}.fm-popup{position:fixed;max-height:100%;overflow-y:auto;background-color:var(--fm-popup-background);transition:all var(--fm-duration-base);z-index:var(--fm-popup-zindex)}.fm-popup--center{top:50%;left:50%;transform:translate(-50%,-50%)}.fm-popup--center.fm-popup--round{border-radius:var(--fm-popup-radius)}.fm-popup--top,.fm-popup--bottom{left:0;right:0}.fm-popup--top{top:0}.fm-popup--top.fm-popup--round{border-radius:0 0 var(--fm-popup-radius) var(--fm-popup-radius)}.fm-popup--bottom{bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--bottom{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--bottom.fm-popup--round{border-radius:var(--fm-popup-radius) var(--fm-popup-radius) 0 0}.fm-popup--left,.fm-popup--right{top:0;bottom:0}@supports ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) and (-webkit-overflow-scrolling: touch){.fm-popup--left,.fm-popup--right{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom)}}.fm-popup--left{left:0}.fm-popup--left.fm-popup--round{border-radius:0 var(--fm-popup-radius) var(--fm-popup-radius) 0}.fm-popup--right{right:0}.fm-popup--right.fm-popup--round{border-radius:var(--fm-popup-radius) 0 0 var(--fm-popup-radius)}:root{--fm-popover-zindex: var(--fm-zindex-5);--fm-popover-padding: var(--fm-padding-sm);--fm-popover-border-radius: var(--fm-radius-lg);--fm-popover-arrow-size: 8px;--fm-popover-content-font-size: var(--fm-font-size);--fm-popover-content-line-height: var(--fm-line-height);--fm-popover-light-theme-color: var(--fm-gray-7);--fm-popover-light-theme-background: var(--fm-white);--fm-popover-dark-theme-color: var(--fm-white);--fm-popover-dark-theme-background: var(--fm-gray-7);--fm-popover-shadow: 0 6px 30px 5px rgba(0, 0, 0, .05), 0 16px 24px 2px rgba(0, 0, 0, .04), 0 8px 10px -5px rgba(0, 0, 0, .08)}.fm-popover{position:absolute;overflow:visible;top:0;left:0;transition:opacity .15s;background-color:transparent;z-index:var(--fm-popover-zindex)}.fm-popover__wrapper{display:inline-block}.fm-popover__content{position:relative;padding:var(--fm-popover-padding);border-radius:var(--fm-popover-border-radius);font-size:var(--fm-popover-content-font-size);line-height:var(--fm-popover-content-line-height);word-break:break-all}.fm-popover__arrow{position:absolute;width:0;height:0;z-index:1;border-style:solid;border-color:transparent;border-width:var(--fm-popover-arrow-size, 8px)}.fm-popover__arrow--top{border-bottom-width:0;border-top-color:currentColor;margin-bottom:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--right{border-left-width:0;border-right-color:currentColor;margin-left:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--bottom{border-top-width:0;border-bottom-color:currentColor;margin-top:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover__arrow--left{border-right-width:0;border-left-color:currentColor;margin-right:calc(var(--fm-popover-arrow-size) * -1)}.fm-popover--light .fm-popover__content{background:var(--fm-popover-light-theme-background);color:var(--fm-popover-light-theme-color);box-shadow:var(--fm-popover-shadow)}.fm-popover--light .fm-popover__arrow{color:var(--fm-popover-light-theme-background)}.fm-popover--dark .fm-popover__content{background:var(--fm-popover-dark-theme-background);color:var(--fm-popover-dark-theme-color);box-shadow:var(--fm-popover-shadow)}.fm-popover--dark .fm-popover__arrow{color:var(--fm-popover-dark-theme-background)}:root{--fm-switch-background: var(--fm-text-color-light);--fm-switch-on-color: var(--fm-primary-color)}.fm-switch{position:relative;cursor:pointer;display:inline-block;transition:background-color var(--fm-duration-base);background-color:var(--fm-switch-background)}.fm-switch--disabled{cursor:not-allowed;opacity:var(--fm-disabled-opacity)}.fm-switch--readonly{cursor:default;opacity:var(--fm-readonly-opacity)}.fm-switch--loading{cursor:default}.fm-switch--on{background-color:var(--fm-switch-on-color)}.fm-switch--on .fm-switch__loadding{color:var(--fm-switch-on-color)}.fm-switch__node{display:flex;align-items:center;justify-content:center;position:absolute;top:1px;left:1px;z-index:1;width:28px;height:28px;border-radius:100%;background-color:var(--fm-white);transition:transform var(--fm-duration-base) cubic-bezier(.3,1.05,.4,1.05)}:root{--fm-toast-zindex: var(--fm-zindex-5);--fm-toast-color: var(--fm-white);--fm-toast-font-size: 16px;--fm-toast-background: var(--fm-gray-7);--fm-toast-icon-font-size: 48px}.fm-toast{position:fixed;top:50%;left:50%;display:-webkit-box;display:-webkit-flex;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:content-box;max-width:70%;padding:16px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;border-radius:7px;transform:translate(-50%,-50%);color:var(--fm-toast-color);z-index:var(--fm-toast-zindex);font-size:var(--fm-toast-font-size);background-color:var(--fm-toast-background)}.fm-toast--top{top:50px;transform:translate(-50%)}.fm-toast--bottom{top:auto;bottom:50px}.fm-toast--info,.fm-toast--success,.fm-toast--warning,.fm-toast--error{width:88px;min-height:88px}.fm-toast__icon-wrapper{margin-bottom:8px}.fm-toast--default{padding:8px 16px}.fm-toast--loading{min-width:84px;min-height:84px}.fm-toast--loading-icon{position:relative;display:inline-block;width:30px;height:30px;margin-bottom:8px;vertical-align:middle;animation:fm-rotate 2s linear infinite}.fm-toast--loading-icon circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:4;stroke-linecap:round}:root{--fm-notify-color: var(--fm-white);--fm-notify-zindex: var(--fm-zindex-5);--fm-notify-info-background: var(--fm-primary-color);--fm-notify-success-background: var(--fm-success-color);--fm-notify-warning-background: var(--fm-warning-color);--fm-notify-error-background: var(--fm-danger-color)}.fm-notify{position:fixed;left:0;top:0;z-index:var(--fm-notify-zindex);display:flex;align-items:center;justify-content:center;width:100%;max-height:100%;padding:8px 16px;box-sizing:border-box;color:var(--fm-notify-color);font-size:14px;line-height:20px;white-space:pre-wrap;text-align:center;word-wrap:break-word;overflow-y:auto}.fm-notify--info{background-color:var(--fm-notify-info-background)}.fm-notify--success{background-color:var(--fm-notify-success-background)}.fm-notify--warning{background-color:var(--fm-notify-warning-background)}.fm-notify--error{background-color:var(--fm-notify-error-background)}:root{--fm-dialog-background: var(--fm-background-2);--fm-dialog-padding-top: 24px;--fm-dialog-padding-left: 16px;--fm-dialog-header-font-size: 17px;--fm-dialog-header-line-height: 24px;--fm-dialog-content-font-size: 15px;--fm-dialog-content-line-height: 20px;--fm-dialog-footer-height: 50px;--fm-border-color: var(--fm-gray-4)}@media screen and (min-width: 375px){.fm-dialog{width:320px}}@media screen and (min-width: 280px) and (max-width: 375px){.fm-dialog{width:240px}}.fm-dialog{display:flex;flex-direction:column;background-color:var(--fm-dialog-background);overflow:hidden}.fm-dialog__header{padding-top:var(--fm-dialog-padding-top);padding-left:var(--fm-dialog-header-padding-left);padding-right:var(--fm-dialog-header-padding-left);font-weight:var(--fm-font-bold-light);font-size:var(--fm-dialog-header-font-size);color:var(--fm-text-color);line-height:var(--fm-dialog-header-line-height);text-align:center}.fm-dialog__content{max-height:70vh;overflow-y:auto}.fm-dialog__content__message{padding:var(--fm-dialog-padding-top) var(--fm-dialog-padding-left);font-size:var(--fm-dialog-content-font-size);line-height:var(--fm-dialog-content-line-height);white-space:pre-wrap;text-align:center;word-wrap:break-word}.fm-dialog__content__message--has-title{padding-top:11px;color:var(--fm-text-color-light)}.fm-dialog__content--prompt{padding:14px}.fm-dialog__content--prompt__input{display:block}.fm-dialog__footer{display:flex;flex-direction:row;align-items:center;border-top:1px solid var(--fm-border-color);position:relative;border-top:none}.fm-dialog__footer:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}.fm-dialog__footer .fm-button{border:0;height:var(--fm-dialog-footer-height);border-right:1px solid var(--fm-border-color);position:relative;border-right:none}.fm-dialog__footer .fm-button:after{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 0 auto auto;width:1px;height:100%;background:var(--fm-border-color);transform-origin:100% 50%;transform:scaleX(.5)}.fm-dialog__footer .fm-button:last-child{border-right:0}.fm-dialog__footer .fm-button:last-child:after{display:none!important}.fm-dialog__footer .fm-button--default{color:var(--fm-text-color)}.fm-dialog__footer--is-column{flex-direction:column}.fm-dialog__footer--is-column__button{border-top:1px solid var(--fm-border-color);position:relative;border-top:none}.fm-dialog__footer--is-column__button:before{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:0 auto auto 0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}.fm-dialog__footer--is-column__button:first-child{border-top:0}.fm-dialog__footer--is-column__button:first-child:before{display:none!important}.fm-dialog.fm-dialog--relative{position:relative}.fm-dialog.fm-dialog--relative__header{padding-right:40px}.fm-dialog__close{position:absolute;right:16px;top:16px;width:22px;height:22px;line-height:22px;text-align:center}.fm-dialog__close .fm-icon{font-size:15px;color:var(--fm-text-color-2)}:root,:host{--fm-loading-color: var(--fm-gray-5);--fm-loading-text-font-size: 14px;--fm-loading-text-line-height: 1.4}.fm-loading{display:flex;align-items:center;position:relative;color:var(--fm-loading-color)}.fm-loading__text{color:var(--fm-loading-color);font-size:var(--fm-loading-text-font-size);line-height:var(--fm-loading-text-line-height);margin-left:var(--fm-margin-xs)}.fm-loading--vertical{flex-direction:column}.fm-loading--vertical .fm-loading__text{margin-top:var(--fm-margin-xs);margin-left:0}.fm-loading__circular{display:block;animation:fm-rotate 2s linear infinite}.fm-loading__circular circle{animation:fm-circular 1.5s ease-in-out infinite;stroke:currentColor;stroke-width:3;stroke-linecap:round}.fm-loading__spinner{display:block;position:relative;animation:fm-rotate 1s linear infinite;animation-timing-function:steps(12)}.fm-loading__line{position:absolute;top:0;left:0;width:100%;height:100%}.fm-loading__line-inner{display:block;width:2px;height:25%;margin:0 auto;background-color:currentColor;border-radius:40%}.fm-loading__ring{display:block;animation:fm-rotate .75s linear infinite;border:4px solid;border-right-color:transparent;border-radius:50%}.fm-loading-popup{display:flex;align-items:center;justify-content:center;width:100px;height:100px;background-color:inherit}@keyframes fm-circular{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40}to{stroke-dasharray:90,150;stroke-dashoffset:-120}}.fm-loading__line--1{transform:rotate(30deg);opacity:1}.fm-loading__line--2{transform:rotate(60deg);opacity:.9375}.fm-loading__line--3{transform:rotate(90deg);opacity:.875}.fm-loading__line--4{transform:rotate(120deg);opacity:.8125}.fm-loading__line--5{transform:rotate(150deg);opacity:.75}.fm-loading__line--6{transform:rotate(180deg);opacity:.6875}.fm-loading__line--7{transform:rotate(210deg);opacity:.625}.fm-loading__line--8{transform:rotate(240deg);opacity:.5625}.fm-loading__line--9{transform:rotate(270deg);opacity:.5}.fm-loading__line--10{transform:rotate(300deg);opacity:.4375}.fm-loading__line--11{transform:rotate(330deg);opacity:.375}.fm-loading__line--12{transform:rotate(360deg);opacity:.3125}:root,:host{--fm-pull-refresh-head-height: 50px;--fm-pull-refresh-head-font-size: var(--fm-font-size-md);--fm-pull-refresh-head-text-color: var(--fm-text-color-light);--fm-pull-refresh-animation-duration: .3s}.fm-pull-refresh{overflow:hidden}.fm-pull-refresh__track{position:relative;height:100%}.fm-pull-refresh__track--not-pulling{transition:transform ease var(--fm-pull-refresh-animation-duration)}.fm-pull-refresh__head{position:absolute;left:0;width:100%;height:var(--fm-pull-refresh-head-height);color:var(--fm-pull-refresh-head-text-color);font-size:var(--fm-pull-refresh-head-font-size);line-height:var(--fm-pull-refresh-head-height);text-align:center;transform:translateY(-100%);display:flex;justify-content:center;align-items:center;flex-direction:column;overflow:hidden}:root,:host{--fm-list-text-color: var(--fm-gray-5);--fm-list-text-font-size: var(--fm-font-size-md, 14px);--fm-list-text-line-height: 50px;--fm-list-loading-icon-size: 16px}.fm-list__loading,.fm-list__error,.fm-list__load-more,.fm-list__finished-info{color:var(--fm-list-text-color);font-size:var(--fm-list-text-font-size);line-height:var(--fm-list-text-line-height);text-align:center}.fm-list__loading-container{display:flex;height:var(--fm-list-text-line-height);justify-content:center;align-items:center}:root,:host{--fm-listview-checkbox-container-width: 40px;--fm-listview-toolbar-height: 42px;--fm-listview-split-line-color: rgb(230, 235, 235);--fm-listview-empty-text-color: var(--fm-gray-5);--fm-listview-empty-text-font-size: var(--fm-font-size-md, 14px);--fm-listview-empty-text-line-height: 50px}.fm-list-view--fill{height:100%;flex-grow:1;flex-shrink:1;display:flex;flex-direction:column;overflow:hidden}.fm-list-view--fill .fm-list-view__track{flex:1 1 0;overflow:auto;-webkit-overflow-scrolling:touch}.fm-list-view--fill .fm-pull-refresh{min-height:100%}.fm-list-view .fm-list{user-select:none;-webkit-user-select:none}.fm-list-view__item{display:flex;position:relative;overflow:hidden}.fm-list-view__item-checker{display:flex;position:absolute;height:100%;width:var(--fm-listview-checkbox-container-width);justify-content:center;align-items:center}.fm-list-view__item-content{flex:1;transform:translate(0)}.fm-list-view__content--split .fm-list-view__item:not(:last-child):not(.fm-list-view__item--child){border-bottom:1px solid var(--fm-listview-split-line-color)}.fm-list-view--multi-select .fm-list-view__item-content{transform:translate(var(--fm-listview-checkbox-container-width))}.fm-list-view__item--group{display:block}.fm-list-view__item-group-header{padding:10px 16px;line-height:20px;font-size:var(--fm-font-size-md);color:var(--fm-gray-5)}.fm-list-view__empty-message{display:block;color:var(--fm-listview-empty-text-color);font-size:var(--fm-listview-empty-text-font-size);line-height:var(--fm-listview-empty-text-line-height);text-align:center}.fm-list-view__item-text{padding:13px 20px;color:var(--fm-gray-7);font-size:var(--fm-font-size)}.fm-list-view__toolbar{display:flex;align-items:center;height:var(--fm-listview-toolbar-height)}.fm-list-view__toolbar-item{flex:1}:root,:host{--fm-swipe-cell-button-text-color: var(--fm-white);--fm-swipe-cell-button-bg-color: var(--fm-gray-4);--fm-swipe-cell-button-font-size: var(--fm-font-size);--fm-swipe-cell-button-icon-size: var(--fm-font-size);--fm-swipe-cell-button-padding: var(--fm-padding-md)}.fm-swipe-cell{position:relative;overflow:hidden}.fm-swipe-cell__wrapper{transition-timing-function:cubic-bezier(.18,.89,.32,1);transition-property:transform}.fm-swipe-cell__left,.fm-swipe-cell__right{position:absolute;top:0;height:100%;display:flex}.fm-swipe-cell__left{left:0;transform:translate3d(-100%,0,0);flex-direction:row-reverse}.fm-swipe-cell__right{right:0;transform:translate3d(100%,0,0)}.fm-swipe-cell__button{display:inline-flex;justify-content:center;align-items:center;height:100%;padding:0 var(--fm-swipe-cell-button-padding);color:var(--fm-swipe-cell-button-text-color);background-color:var(--fm-swipe-cell-button-bg-color)}.fm-swipe-cell__button--primary,.fm-swipe-cell__button--info{background:var(--fm-primary-color)}.fm-swipe-cell__button--secondary{color:var(--fm-primary-color);background:var(--fm-button-secondary-color)}.fm-swipe-cell__button--danger{background-color:var(--fm-danger-color)}.fm-swipe-cell__button--warning{background-color:var(--fm-warning-color)}.fm-swipe-cell__button--success{background-color:var(--fm-success-color)}.fm-swipe-cell__icon{font-size:var(--fm-swipe-cell-button-icon-size)}.fm-swipe-cell__text{font-size:var(--fm-swipe-cell-button-font-size)}.fm-swipe-cell__icon+.fm-swipe-cell__text:not(:empty){margin-left:6px}:root,:host{--fm-action-sheet-max-height: 80%;--fm-action-sheet-border-radius: 12px;--fm-action-sheet-description-color: var(--fm-gray-5);--fm-action-sheet-description-line-height: 22px;--fm-action-sheet-description-font-size: var(--fm-font-size-md);--fm-action-sheet-description-padding: 12px 16px;--fm-action-sheet-item-default-background: var(--fm-background-white);--fm-action-sheet-item-active-background: #f2f3f5;--fm-action-sheet-item-padding: 13px 16px;--fm-action-sheet-item-text-color: #1a1a1a;--fm-action-sheet-item-disabled-text-color: #bdbdbd;--fm-action-sheet-item-subtitle-color: var(--fm-gray-5);--fm-action-sheet-item-icon-size: 18px;--fm-action-sheet-item-icon-margin-right: 8px;--fm-action-sheet-item-title-font-size: var(--fm-font-size-lg);--fm-action-sheet-item-title-line-height: 24px;--fm-action-sheet-item-subtitle-font-size: var(--fm-font-size-sm);--fm-action-sheet-item-subtitle-line-height: 18px;--fm-action-sheet-item-subtitle-margin-top: 2px;--fm-action-sheet-footer-gap-color: #f5f5f5;--fm-action-sheet-divider-color: #e7e7e7;--fm-action-sheet-cancel-height: 48px;--fm-action-sheet-cancel-color: #1a1a1a;--fm-action-sheet-cancel-font-size: var(--fm-font-size-lg);--fm-action-sheet-cancel-font-weight: 500}.fm-action-sheet{display:flex;flex-direction:column;max-height:var(--fm-action-sheet-max-height);overflow:hidden;user-select:none}.fm-action-sheet--round{border-top-left-radius:var(--fm-action-sheet-border-radius);border-top-right-radius:var(--fm-action-sheet-border-radius)}.fm-action-sheet__description{flex-shrink:0;color:var(--fm-action-sheet-description-color);line-height:var(--fm-action-sheet-description-line-height);font-size:var(--fm-action-sheet-description-font-size);text-align:center;padding:var(--fm-action-sheet-description-padding);position:relative}.fm-action-sheet__description--left{text-align:left}.fm-action-sheet__content{flex:1 auto;overflow-y:auto;-webkit-overflow-scrolling:touch}.fm-action-sheet__item,.fm-action-sheet__cancel{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__item:active,.fm-action-sheet__cancel:active{background-color:var(--fm-action-sheet-item-active-background)}.fm-action-sheet__item{display:flex;position:relative;flex-wrap:wrap;align-items:center;justify-content:center;text-align:center;padding:var(--fm-action-sheet-item-padding);color:var(--fm-action-sheet-item-text-color);cursor:pointer}.fm-action-sheet__item-icon{font-size:var(--fm-action-sheet-item-icon-size);margin-right:var(--fm-action-sheet-item-icon-margin-right)}.fm-action-sheet__item-title{font-size:var(--fm-action-sheet-item-title-font-size);line-height:var(--fm-action-sheet-item-title-line-height)}.fm-action-sheet__item-subtitle{font-size:var(--fm-action-sheet-item-subtitle-font-size);line-height:var(--fm-action-sheet-item-subtitle-line-height);width:100%;margin-top:var(--fm-action-sheet-item-subtitle-margin-top);color:var(--fm-action-sheet-item-subtitle-color);overflow-wrap:break-word}.fm-action-sheet__item--left{text-align:left;justify-content:flex-start}.fm-action-sheet__item--disabled{color:var(--fm-action-sheet-item-disabled-text-color);cursor:not-allowed}.fm-action-sheet__item--disabled:active{background-color:var(--fm-action-sheet-item-default-background)}.fm-action-sheet__description:after,.fm-action-sheet__item:after{content:"";display:block;position:absolute;height:1px;bottom:0;left:0;right:0;transform:scaleY(.5);background-color:var(--fm-action-sheet-divider-color)}.fm-action-sheet__footer-gap{height:8px;background-color:var(--fm-action-sheet-footer-gap-color)}.fm-action-sheet__cancel{display:flex;flex-direction:column;justify-content:center;align-items:center;height:var(--fm-action-sheet-cancel-height);cursor:pointer;color:var(--fm-action-sheet-cancel-color);font-size:var(--fm-action-sheet-cancel-font-size);font-weight:var(--fm-action-sheet-cancel-font-weight)}:root{--fm-tab-bar-item-color: var(--fm-text-color);--fm-tab-bar-item-active-color: var(--fm-primary-color);--fm-tab-bar-item-font-size: 16px}.fm-tab-bar-item{flex:1 0 auto;position:relative;display:inline-flex;align-items:center;justify-content:center;margin:0 12px;line-height:44px}.fm-tab-bar-item--actived{color:var(--fm-tab-bar-item-active-color)}.fm-tab-bar-item--disabled{color:var(--fm-disabled-color)}.fm-tab-bar-item--dot .fm-tab-bar-item__text:after{content:"";position:absolute;top:0;right:0;width:8px;height:8px;background-color:var(--fm-danger-color);border-radius:100%;transform:translate(100%,100%)}.fm-tab-bar-item__text{position:relative;display:flex;justify-content:center;min-width:40px}.fm-tab-bar-item__ink{position:absolute;bottom:0;left:0;right:0;height:4px;background-color:var(--fm-tab-bar-item-active-color);border-radius:2px}.fm-tab-bar-item__badge{position:absolute;top:2px;right:0;padding:0 4px;max-width:28px;font-weight:500;font-size:12px;line-height:14px;border-radius:7px;color:var(--fm-background-white);background-color:var(--fm-danger-color);transform:translate(50%)}.fm-tab-bar-item__icon{position:relative;display:flex;align-items:center;justify-content:center;padding-right:4px}:root{--fm-tab-bar-height: 44px;--fm-tab-bar-background: var(--fm-background-white);--fm-tab-bar-color: var(--fm-text-color);--fm-tab-bar-active-color: var(--fm-primary-color);--fm-tab-bar-font-size: 16px}.fm-tab-bar{position:relative;background:var(--fm-tab-bar-background);color:var(--fm-tab-bar-color);font-size:var(--fm-tab-bar-font-size)}.fm-tab-bar--bottom-line{border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-tab-bar--bottom-line:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-tab-bar__scroll-wrapper{position:relative;width:100%;overflow:hidden}.fm-tab-bar__list{display:flex;justify-content:space-between;min-width:100%;transition:all .3s cubic-bezier(.17,.89,.45,1)}.fm-tab-bar__ink{position:absolute;bottom:0;left:0;display:block;height:4px;background-color:var(--fm-tab-bar-active-color);transition:all var(--fm-duration-base);border-radius:2px}.fm-tab-bar__ink--disabled{background-color:var(--fm-disabled-color)}.fm-tabs{overflow:hidden}.fm-tabs__content{display:flex}.fm-tab{display:block;flex-shrink:0;width:100%;height:100%;overflow:auto;word-break:break-all}.fm-tab--collapse{height:0;overflow:visible}:root{--fm-tag-padding: 0 6px;--fm-tag-height: 18px;--fm-tag-font-size: 12px;--fm-tag-border-radius: 2px;--fm-tag-color: var(--fm-white)}.fm-tag{position:relative;display:inline-flex;align-items:center;white-space:nowrap;padding:0 4px;color:var(--fm-tag-color);font-size:var(--fm-tag-font-size);line-height:var(--fm-tag-height);border-radius:var(--fm-tag-border-radius)}.fm-tag--primary{background-color:var(--fm-primary-color)}.fm-tag--success{background-color:var(--fm-success-color)}.fm-tag--danger{background-color:var(--fm-danger-color)}.fm-tag--warning{background-color:var(--fm-warning-color)}.fm-tag--plain{background-color:var(--fm-white)}.fm-tag--plain.fm-tag--primary{border:1px solid var(--fm-primary-color);color:var(--fm-primary-color)}.fm-tag--plain.fm-tag--success{border:1px solid var(--fm-success-color);color:var(--fm-success-color)}.fm-tag--plain.fm-tag--warning{border:1px solid var(--fm-warning-color);color:var(--fm-warning-color)}.fm-tag--plain.fm-tag--danger{border:1px solid var(--fm-danger-color);color:var(--fm-danger-color)}.fm-tag--medium{padding:2px 6px}.fm-tag--large{padding:4px 8px;font-size:14px;border-radius:4px}.fm-tag--round{border-radius:100px}.fm-tag--mark{border-radius:0 100px 100px 0}.fm-tag__close{font-size:8px;margin-left:4px}.fm-tag--large .fm-tag__close{font-size:10px}: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}.fm-picker-panel__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker-panel__toolbar-left,.fm-picker-panel__toolbar-right{padding:0 16px}.fm-picker-panel__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker-panel__content{position:relative;display:flex;cursor:grab}.fm-picker-panel__columns{display:flex;flex:1;overflow:hidden}.fm-picker-panel__column{flex:1}.fm-picker-panel__column-item{display:flex;align-items:center;justify-content:center;height:44px}.fm-picker-panel__mask{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;background-image:linear-gradient(180deg,#ffffffe6,#fff6),linear-gradient(0deg,#ffffffe6,#fff6);background-repeat:no-repeat;background-position:top,bottom;transform:translateZ(0);pointer-events:none}.fm-picker-panel__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(.5)}.fm-picker-group__header{text-align:left}.fm-picker-group__toolbar{display:flex;justify-content:space-between;align-items:center;height:var(--fm-picker-toolbar-height)}.fm-picker-group__toolbar-left,.fm-picker-group__toolbar-right{padding:0 16px}.fm-picker-group__toolbar-title{font-weight:500;font-size:16px;max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fm-picker-group__tab-bar{display:inline-block}:root{--fm-lookup-panel-background: var(--fm-background);--fm-lookup-panel-search-list-zindex: var(--fm-zindex-3)}.fm-lookup-panel{height:100%;display:flex;flex-direction:column;overflow:hidden;background-color:var(--fm-lookup-panel-background)}.fm-lookup-panel__header{background-color:var(--fm-background-white)}.fm-lookup-panel__header__search{border-bottom:1px solid #ddd;position:relative;border-bottom:none}.fm-lookup-panel__header__search:after{content:"";position:absolute;background-color:#ddd;display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-lookup-panel__header__selected-wrapper{display:flex;padding:6px 16px;overflow:auto}.fm-lookup-panel__header__selected-item{font-size:14px;line-height:20px;word-break:keep-all;white-space:nowrap;padding:4px 6px;color:var(--fm-primary-color);background-color:var(--fm-primary-color-light);border-radius:4px}.fm-lookup-panel__header__selected-item:not(:last-child){margin-right:8px}.fm-lookup-panel__footer{padding:0 16px;height:48px;display:flex;align-items:center;justify-content:space-between;box-shadow:0 0 7px 0 var(--fm-box-shadow-color);border-top:1px solid var(--fm-gray-1);background-color:var(--fm-background-white)}.fm-lookup-panel__content{flex:1;display:flex;overflow:hidden;margin-top:10px;position:relative}.fm-lookup-panel__list{flex:1;overflow-y:auto;background-color:var(--fm-background-white)}.fm-lookup-panel__list-item{display:flex;align-items:center;background-color:#fff}.fm-lookup-panel__list-checker{padding-left:16px}.fm-lookup-panel__search-list{position:absolute;inset:0;display:none;overflow-y:auto;z-index:var(--fm-lookup-panel-search-list-zindex);background-color:var(--fm-background-white)}.fm-lookup-panel__popup-selected{width:100%;display:flex;flex-direction:column}.fm-lookup-panel__popup-selected__footer-left{color:var(--fm-primary-color)}.fm-lookup-panel__selected-list{flex:1;overflow:auto}.fm-lookup-panel__empty{padding:12px 16px}.fm-lookup-panel__empty__text{text-align:center;color:var(--fm-text-color-light)}.fm-lookup-panel__breadcrumb{display:flex;align-items:center;height:42px;padding:0 16px;overflow:auto;border-bottom:1px solid var(--fm-border-color);position:relative;border-bottom:none}.fm-lookup-panel__breadcrumb:after{content:"";position:absolute;background-color:var(--fm-border-color);display:block;z-index:1;inset:auto auto 0 0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}.fm-lookup-panel__breadcrumb__item{display:flex;align-items:center;color:var(--fm-primary-color);padding-right:8px;flex-shrink:0}.fm-lookup-panel__breadcrumb__item:last-child{color:var(--fm-text-color-light)}.fm-lookup-panel__breadcrumb__icon{font-size:10px;padding-left:4px}.fm-lookup-panel__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)}: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)}.fm-search{display:flex;align-items:center;padding:8px 12px;color:var(--fm-search-color);background-color:var(--fm-search-background)}.fm-search__input-wrapper{flex:1;padding:5px 8px;border-radius:17px;background-color:var(--fm-search-input-background)}.fm-search__input{background-color:var(--fm-search-input-background)}.fm-search__search-icon{margin-right:4px;color:var(--fm-text-color-light)}.fm-filter-panel{height:100%;display:flex;flex-direction:column;padding:8px 16px}.fm-filter-panel__content{flex:1}.fm-filter-panel__footer{padding:8px 16px}.fm-filter-panel__field:not(:first-child){margin-top:16px}.fm-filter-panel__field__title{display:flex;align-items:center;justify-content:space-between;line-height:22px}.fm-filter-panel__field__content{padding-top:12px}.fm-filter-panel__field__range{display:flex;align-items:center}.fm-filter-panel__field__range__splitter{width:8px;margin:0 8px;border:1px solid #999}.fm-filter-panel__field__list{display:flex;flex-wrap:wrap;margin:0 -5px}.fm-filter-panel__field__list__item{height:30px;width:89px;font-size:13px;text-align:center;overflow:hidden;padding:6px 8px;margin:0 5px 10px;background:var(--fm-background);border-radius:var(--fm-radius-md);color:var(--fm-primary-color)}.fm-filter-panel__field__list__item--selected{background:var(--fm-primary-color);color:var(--fm-background-white)}.fm-filter-panel__field .fm-input-group .fm-input-group__body{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}.fm-filter__portal{display:flex;align-items:center;padding:8px 16px}.fm-filter__portal__icon{font-size:20px}.fm-filter__portal__search{flex:1;padding:0 0 0 8px}.fm-page-container{flex:1;display:flex;flex-direction:column;background:#f9fafb;overflow:hidden;-webkit-overflow-scrolling:auto;position:absolute;inset:0}.fm-page-container .drag-container{display:inherit;flex-direction:inherit;flex-shrink:1;flex-grow:1;flex-basis:0%;flex-wrap:inherit;justify-content:inherit;align-items:inherit;width:100%;overflow:inherit}.fm-page-body-container{flex-basis:0;flex-shrink:1;flex-grow:1;padding-bottom:12px;overflow:auto;display:flex;flex-direction:column}.fm-page-header-container{flex-shrink:0}.fm-page-footer-container{background-color:#fff}.fm-float-container{position:absolute!important} diff --git a/packages/mobile-render/src/main.ts b/packages/mobile-render/src/main.ts index c50637e2bb6..73a71f7ee4d 100644 --- a/packages/mobile-render/src/main.ts +++ b/packages/mobile-render/src/main.ts @@ -49,7 +49,7 @@ const pluginManager = PluginManager.getInstance(plugins); */ router.beforeEach(async (to: any, from: any, next: any) => { if (checkFormRoute(to, router)) { - next(); + return next(); } await addFormRoute(to, router, devkit); next({ ...to, replace: true });; diff --git a/packages/mobile-ui-vue/components/button-edit/src/button-edit.props.ts b/packages/mobile-ui-vue/components/button-edit/src/button-edit.props.ts index 493da6ffb30..bf1268d7ad0 100644 --- a/packages/mobile-ui-vue/components/button-edit/src/button-edit.props.ts +++ b/packages/mobile-ui-vue/components/button-edit/src/button-edit.props.ts @@ -1,7 +1,7 @@ -import { ExtractPropTypes, PropType } from 'vue'; +import { ExtractPropTypes, PropType, TeleportProps } from 'vue'; import { inputCommonProps } from '@farris/mobile-ui-vue/input-group'; import { popupProps } from '@farris/mobile-ui-vue/popup'; -import { tagProps, TagSize, TagType } from '@farris/mobile-ui-vue/tag'; +import { TagSize, TagType } from '@farris/mobile-ui-vue/tag'; export const BUTTON_EDIT_NAME = 'FmButtonEdit'; @@ -35,6 +35,8 @@ export const buttonEditProps = { tagCloseable: { type: Boolean, default: false }, + teleport: { type: [String, Object] as PropType, default: 'body' }, + popupWidth: { type: String, default: undefined }, popupHeight: { type: String, default: undefined }, diff --git a/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx b/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx index 740e2c79009..ff5498290c2 100644 --- a/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx +++ b/packages/mobile-ui-vue/components/button/src/designer/button.design.component.tsx @@ -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 { computed, defineComponent, inject, onMounted, ref, SetupContext } from 'vue'; import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/common';; import { ButtonProps, buttonProps } from '../button.props'; @@ -37,8 +21,6 @@ export default defineComponent({ context.expose(componentInstance.value); - const { schema } = componentInstance.value; - const buttonProps = computed(() => ({ round: props.round, block: props.block, @@ -46,13 +28,12 @@ export default defineComponent({ type: props.type, plain: props.plain, size: props.size, + text: props.text })); return () => { return ( - +