From f9866c4dbf398435926e6bfd027f2d00421f77bb Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Wed, 2 Jul 2025 16:19:12 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dmobile-ui-vue?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/designer-canvas/index.ts | 8 - .../components/designer-item.component.tsx | 340 --------------- .../designer-canvas/src/components/maps.ts | 49 --- .../src/composition/function/drag-resolve.tsx | 230 ----------- .../src/designer-canvas.component.tsx | 143 ------- .../use-response-form-layout-setting.ts | 128 ------ .../enum-field-input.design.component.tsx | 6 +- .../src/composition/entity/base-property.ts | 130 ------ .../composition/entity/input-base-property.ts | 390 ------------------ .../src/composition/entity/use-input-rules.ts | 62 --- 10 files changed, 3 insertions(+), 1483 deletions(-) delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/index.ts delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/components/designer-item.component.tsx delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/components/maps.ts delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/composition/function/drag-resolve.tsx delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/designer-canvas.component.tsx delete mode 100644 packages/mobile-ui-vue/components/dynamic-form/src/composition/use-response-form-layout-setting.ts delete mode 100644 packages/mobile-ui-vue/components/property-panel/src/composition/entity/base-property.ts delete mode 100644 packages/mobile-ui-vue/components/property-panel/src/composition/entity/input-base-property.ts delete mode 100644 packages/mobile-ui-vue/components/property-panel/src/composition/entity/use-input-rules.ts diff --git a/packages/mobile-ui-vue/components/designer-canvas/index.ts b/packages/mobile-ui-vue/components/designer-canvas/index.ts deleted file mode 100644 index d2d31b946fc..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { DgControl } from './src/composition/dg-control'; -import type { DesignerHostService, UseDesignerRules } from './src/composition/types'; -export * from './src/composition/props/designer-canvas.props'; -export * from './src/composition/function/use-designer-component'; -export * from './src/composition/function/use-designer-inner-component'; -export * from './src/types'; - -export { DgControl, UseDesignerRules, DesignerHostService }; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-item.component.tsx b/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-item.component.tsx deleted file mode 100644 index 10b54bee926..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-item.component.tsx +++ /dev/null @@ -1,340 +0,0 @@ - -import { Ref, SetupContext, computed, defineComponent, inject, onMounted, provide, ref, watch, onBeforeUnmount } from 'vue'; -import { DesignerItemPropsType, designerItemProps } from '../composition/props/designer-item.props'; -import { componentMap, componentPropsConverter } from './maps'; -import { UseDragula } from '../composition/types'; -import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from '../types'; -import FDesignerPlaceholder from './designer-placeholder.component'; -import { canvasChanged, setPositionOfButtonGroup } from '../composition/designer-canvas-changed'; -import { getCustomClass } from '@farris/mobile-ui-vue/common'; - -const FDesignerItem = defineComponent({ - name: 'FDesignerItem', - props: designerItemProps, - emits: ['selectionChange'], - setup(props: DesignerItemPropsType, context) { - const id = ref(`${props.modelValue.id}-component`); - const canMove = ref(props.canMove); - const canDelete = ref(props.canDelete); - const canNested = ref(false); - const schema = ref(props.modelValue); - const componentId = ref(props.componentId || ''); - const designComponentStyle = ref(''); - const designComponentClass = ref(''); - const designCustomClass = ref(props.customClass); - const designerItemElementRef = ref(); - const useDragulaComposition = inject('canvas-dragula'); - const componentInstance = ref() as Ref; - const parent = inject('design-item-context'); - const designItemContext = { designerItemElementRef, componentInstance, schema: schema.value, parent, setupContext: context as SetupContext }; - provide('design-item-context', designItemContext); - const useFormSchema = inject('useFormSchema'); - - const designerItemClass = computed(() => { - const componentClass = props.modelValue.appearance ? (props.modelValue.appearance.class as string) || '' : ''; - const customButtons = componentInstance.value?.getCustomButtons && componentInstance.value.getCustomButtons(); - let classObject = { - 'farris-component': true, - // 受position-relative影响,整个容器的高度不能被撑起 - 'flex-fill': schema.value.id === 'root-component', - 'position-relative': canMove.value && canDelete.value || (customButtons?.length), - 'farris-nested': canNested.value, - 'can-move': canMove.value, - 'd-none': designerItemElementRef.value && (designerItemElementRef.value as HTMLElement).classList.contains('d-none'), - 'dgComponentSelected': designerItemElementRef.value && (designerItemElementRef.value as HTMLElement).classList.contains('dgComponentSelected'), - 'dgComponentFocused': designerItemElementRef.value && (designerItemElementRef.value as HTMLElement).classList.contains('dgComponentFocused'), - } as Record; - classObject[`farris-component-${schema.value.type}`] = true; - classObject = getCustomClass(classObject, componentClass); - classObject = getCustomClass(classObject, designComponentClass.value); - classObject = getCustomClass(classObject, designCustomClass.value); - return classObject; - }); - - const desginerItemStyle = computed(() => { - const styleObject = {} as Record; - const componentStyle = props.modelValue.appearance ? (props.modelValue.appearance.style as string) || '' : ''; - if (componentStyle) { - componentStyle.split(';').reduce((result: Record, styleString: string) => { - const [styleKey, styleValue] = styleString.split(':'); - result[styleKey] = styleValue; - return result; - }, styleObject); - } - if (designComponentStyle.value) { - designComponentStyle.value.split(';').reduce((result: Record, styleString: string) => { - const [styleKey, styleValue] = styleString.split(':'); - if (styleKey) { - result[styleKey] = styleValue; - } - return result; - }, styleObject); - } - return styleObject; - }); - - function onClickDeleteButton(payload: MouseEvent, schemaToRemove: ComponentSchema) { - if (payload) { - payload.preventDefault(); - payload.stopPropagation(); - } - - // 连同所属组件一起删除,使用场景如data-grid、form控件等。 - if (componentInstance.value.triggerBelongedComponentToDeleteWhenDeleted) { - const belongedComponentInstance = componentInstance.value.getBelongedComponentInstance(componentInstance); - if (belongedComponentInstance && belongedComponentInstance.parent) { - const belongedComponentInstanceParent = ref(belongedComponentInstance?.parent) as any; - const indexToRemove = belongedComponentInstanceParent.value.contents.findIndex( - (contentItem: ComponentSchema) => contentItem.id === belongedComponentInstance.schema.id - ); - belongedComponentInstanceParent.value?.contents?.splice(indexToRemove, 1); - - canvasChanged.value++; - } - return; - } - componentInstance.value.onRemoveComponent(); - let parentContext = parent; - let locatePredicate: any = (contentItem: ComponentSchema) => contentItem.id === schemaToRemove.id; - if (schemaToRemove.type === 'component') { - parentContext = parent?.parent; - locatePredicate = (contentItem: ComponentSchema) => contentItem.component === schemaToRemove.id; - - } - if (parentContext && parentContext.schema.contents) { - const indexToRemove = parentContext.schema.contents.findIndex(locatePredicate); - parentContext.schema.contents.splice(indexToRemove, 1); - - canvasChanged.value++; - context.emit('selectionChange'); - - } - - } - - function renderDeleteButton(componentSchema: ComponentSchema) { - return ( - canDelete.value && ( -
{ - onClickDeleteButton(payload, componentSchema); - }}> - -
- ) - ); - } - - function renderMoveButton() { - return ( - canMove.value && ( -
- -
- ) - ); - } - - function renderCustomButtons() { - const customButtons = componentInstance.value?.getCustomButtons && componentInstance.value.getCustomButtons(); - - return ( - customButtons && - !!customButtons.length && - customButtons.map((buttonConfig: any) => { - return ( -
buttonConfig.onClick && buttonConfig.onClick(payload)}> - -
- ); - }) - ); - } - - function renderIconPanel(componentSchema: ComponentSchema) { - return ( -
-
- {renderDeleteButton(componentSchema)} - {renderMoveButton()} - {renderCustomButtons()} -
-
- ); - } - - function onSelectionChange(schemaType: string, schemaValue: ComponentSchema, componentId: string, componentInstance: DesignerComponentInstance) { - context.emit('selectionChange', schemaType, schemaValue, componentId, componentInstance); - } - - function renderContent(viewSchema: ComponentSchema) { - const componentKey = viewSchema.type; - const Component = componentMap[componentKey]; - const propsConverter = componentPropsConverter[componentKey]; - const viewProps = propsConverter ? propsConverter(viewSchema) : {}; - viewProps.customClass = props.ignore ? viewProps.customClass : ''; - viewProps.componentId = componentId.value; - viewProps.id = viewSchema.id; - const shouldShowPlaceholder = viewSchema.contents && viewSchema.contents.length === 0; - const hasContent = viewSchema.contents && !!viewSchema.contents.length; - return hasContent && Component ? ( - - {(viewSchema.contents as ComponentSchema[]).map((contentSchema: any) => ( - - ))} - - ) : Component ? ( - shouldShowPlaceholder ? ( - - - - ) : ( - - ) - ) : ( -
- ); - } - - function renderChildComponentContent(viewSchema: ComponentSchema) { - const componentKey = viewSchema.type; - if (componentKey === 'component-ref') { - // eslint-disable-next-line prefer-const - let componentSchema = useFormSchema?.getFormSchema().module.components - .find((component: any) => component.id === viewSchema.component); - if (componentSchema) { - - return ; - } - } - } - watch( - () => props.modelValue, - (value: any) => { - schema.value = value; - id.value = `${value.id}-component`; - componentId.value = value.id; - } - ); - - function updatePositionOfButtonGroup(event: Event | any) { - const targetElement = event?.target as any; - setPositionOfButtonGroup(targetElement); - } - /** - * 记录滚动区域 - */ - function recordScrollContainer(element: HTMLElement) { - if (!window['scrollContainerList']) { window['scrollContainerList'] = new Set(); } - - const id = element.getAttribute('id'); - if (id) { - window['scrollContainerList'].add(id); - } - } - - function updatePositionOfBtnGroupWhenScroll(event: Event | any) { - const targetElement = event?.target as any; - recordScrollContainer(targetElement); - updatePositionOfButtonGroup(event); - } - function bindingScrollEvent() { - if (schema.value?.contents?.length && designerItemElementRef.value) { - designerItemElementRef.value.addEventListener('scroll', updatePositionOfBtnGroupWhenScroll); - } - } - - onMounted(() => { - if (designerItemElementRef.value && componentInstance.value && componentInstance.value.schema) { - const draggableContainer = designerItemElementRef.value.querySelector( - `[data-dragref='${componentInstance.value.schema.id}-container']` - ); - if (useDragulaComposition && draggableContainer) { - useDragulaComposition.attachComponents(draggableContainer, schema.value); - } - canNested.value = componentInstance.value.canNested !== undefined ? componentInstance.value.canNested : canNested.value; - canDelete.value = componentInstance.value.canDelete !== undefined ? componentInstance.value.canDelete : canDelete.value; - canMove.value = componentInstance.value.canMove !== undefined ? componentInstance.value.canMove : canMove.value; - designComponentStyle.value = componentInstance.value.styles || ''; - designComponentClass.value = componentInstance.value.designerClass || ''; - if (designerItemElementRef.value) { - designerItemElementRef.value.componentInstance = componentInstance; - designerItemElementRef.value.designItemContext = designItemContext; - } - componentInstance.value.belongedComponentId = componentId.value; - - } - bindingScrollEvent(); - - canvasChanged.value++; - }); - - onBeforeUnmount(() => { - if (designerItemElementRef.value) { - designerItemElementRef.value.removeEventListener('scroll', updatePositionOfButtonGroup); - } - }); - - function onClickDesignerItem(payload: MouseEvent) { - if (payload) { - payload.preventDefault(); - payload.stopPropagation(); - } - let draggabledesignerItemElementRef: any = designItemContext.designerItemElementRef; - const designerItemElement = designerItemElementRef.value as HTMLElement; - if (designerItemElement) { - const currentFocusedElements = document.getElementsByClassName('dgComponentFocused') as HTMLCollectionOf; - // 重复点击 - const duplicateClick = - currentFocusedElements && - currentFocusedElements.length === 1 && - currentFocusedElements[0] === designerItemElementRef.value; - if (!duplicateClick) { - Array.from(currentFocusedElements).forEach((element: HTMLElement) => element.classList.remove('dgComponentFocused')); - Array.from(document.getElementsByClassName('dgComponentSelected') as HTMLCollectionOf).forEach( - (element: HTMLElement) => element.classList.remove('dgComponentSelected') - ); - - designerItemElement.classList.add('dgComponentFocused'); - context.emit('selectionChange', schema.value.type, schema.value, componentId.value, componentInstance.value); - if (componentInstance.value.getDraggableDesignItemElement) { - draggabledesignerItemElementRef = componentInstance.value.getDraggableDesignItemElement(designItemContext); - if (draggabledesignerItemElementRef && draggabledesignerItemElementRef.value) { - draggabledesignerItemElementRef.value.classList.add('dgComponentSelected'); - - } - } - - } - } - - updatePositionOfButtonGroup({ target: draggabledesignerItemElementRef?.value }); - } - - return () => { - return ( - schema.value.type === 'component-ref' ? - renderChildComponentContent(schema.value) : -
- {renderIconPanel(schema.value)} - {renderContent(schema.value)} -
- ); - }; - } -}); -export default FDesignerItem; 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 deleted file mode 100644 index 329fd482b8e..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/components/maps.ts +++ /dev/null @@ -1,49 +0,0 @@ -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"; -import Form from "@farris/mobile-ui-vue/form"; -import InputGroup from "@farris/mobile-ui-vue/input-group"; -import ListView from "@farris/mobile-ui-vue/list-view"; -import Navbar from "@farris/mobile-ui-vue/navbar"; -import PageBodyContainer from "@farris/mobile-ui-vue/page-body-container"; -import PageContainer from "@farris/mobile-ui-vue/page-container"; -import PageFooterContainer from "@farris/mobile-ui-vue/page-footer-container"; -import Textarea from "@farris/mobile-ui-vue/textarea"; - -const componentMap: Record = {}; -const componentPropsConverter: Record = {}; -const componentPropertyConfigConverter: Record = {}; - - -let hasLoaded = false; -/** - * 加载设计时组件 - */ -function loadDesignerRegister() { - if (!hasLoaded) { - hasLoaded = true; - 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); - DatePicker.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); - Textarea.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); - RadioGroup.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); - Switch.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); - Picker.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); - CheckboxGroup.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); - - } -} - -export { componentMap, componentPropsConverter, componentPropertyConfigConverter, loadDesignerRegister }; 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 deleted file mode 100644 index 05dbcb49147..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/drag-resolve.tsx +++ /dev/null @@ -1,230 +0,0 @@ -import { ModalFunctions } from "../../../../modal/src/composition/type"; -import { ComponentBindingSourceContext, DesignerHostService, DesignerHTMLElement, DraggingResolveContext } from "../types"; -import { DesignViewModelField, FormVariable } from "../../../../common/src/entity/entity-schema"; -import { merge } from "lodash-es"; -import { DgControl } from "../dg-control"; -import { DesignerComponentInstance } from "@farris/mobile-ui-vue"; - -export function dragResolveService(designerHostService: DesignerHostService) { - /** 弹窗实例 */ - let modalEditorRef: ModalFunctions; - /** 拖拽上下文 */ - let componentResolveContext: DraggingResolveContext; - - /** - * 获取拖拽上下文信息 - */ - function getComponentResolveContext(sourceElement: DesignerHTMLElement, sourceContainer: DesignerHTMLElement, targetContainer: DesignerHTMLElement) - : DraggingResolveContext { - - const resolveContext: DraggingResolveContext = { - componentType: String(sourceElement.getAttribute('data-controltype')), - componentFeature: String(sourceElement.getAttribute('data-feature')), - componentCategory: String(sourceElement.getAttribute('data-category')), - label: String(sourceElement.getAttribute('data-controlTypeName')), - sourceType: String(sourceElement.getAttribute('data-sourceType') || 'move'), - parentComponentInstance: targetContainer.componentInstance.value, - sourceElement, - sourceContainer, - targetContainer, - bindingSourceContext: null - }; - - // 现有控件移动位置:从控件实例上获取控件类型 - if (sourceElement.componentInstance) { - resolveContext.componentType = sourceElement.componentInstance.value.schema?.type; - // resolveContext.componentCategory = sourceElement.componentInstance.value.category; - } - - return resolveContext; - } - /** - * 选择绑定实体后事件 - */ - function onSubmitEntitySelctor(bindingSourceContext: ComponentBindingSourceContext) { - componentResolveContext.bindingSourceContext = bindingSourceContext; - - if (modalEditorRef?.modalRef?.value.close) { - modalEditorRef?.modalRef?.value.close(); - } - } - /** - * 取消绑定实体 - */ - function onCancelEntitySelector() { - componentResolveContext.bindingSourceContext = undefined; - if (modalEditorRef?.modalRef?.value.close) { - modalEditorRef?.modalRef?.value.close(); - } - } - /** - * 选择绑定实体窗口 - */ - function renderEntityComponent() { - const { componentType } = componentResolveContext; - const FEntityBindingSelector = designerHostService.uiProviderService.getUiComponent('FEntityBindingSelector'); - return () => (<> ); - } - /** - * 弹出实体绑定窗口 - */ - function triggerBindingEntity() { - return new Promise((resolve, reject) => { - modalEditorRef = designerHostService.modalService.open({ - title: '选择绑定', - width: 800, - height: 600, - fitContent: false, - showButtons: false, - render: renderEntityComponent(), - rejectCallback:()=>{ - componentResolveContext.bindingSourceContext = undefined; - }, - closedCallback: () => { - resolve(componentResolveContext); - }, - draggable: true - }); - }); - } - /** - * 取消绑定字段后事件 - */ - function onCancelFieldSelector() { - componentResolveContext.bindingSourceContext = undefined; - if (modalEditorRef?.modalRef?.value.close) { - modalEditorRef?.modalRef?.value.close(); - } - } - /** - * 获取控件拖拽后的分组信息,以便于后续记录到视图模型 - */ - function getFieldGroupInfo(parentComponentInstance: DesignerComponentInstance) { - let groupId = ''; - let groupName = ''; - if (DgControl['field-set'] && parentComponentInstance.schema.type === DgControl['field-set'].type) { - groupId = parentComponentInstance.schema.id; - groupName = parentComponentInstance.schema.title; - } - return { groupId, groupName }; - } - /** - * 选择绑定字段后事件 - */ - function onSubmitFieldSelctor(data: { selectedData: any, bindingType: any }) { - if (!data || !data.selectedData || !data.bindingType) { - return; - } - const { selectedData, bindingType } = data; - // 若添加到小分组内,需要向vm保存groupId和groupName - const { groupId, groupName } = getFieldGroupInfo(componentResolveContext.parentComponentInstance); - const bindingSourceContext: ComponentBindingSourceContext = { bindingType: 'field' }; - - if (bindingType === 'Form') { - // 绑定字段 - const entityField = selectedData as DesignViewModelField; - bindingSourceContext.entityFieldNode = entityField; - - bindingSourceContext.designViewModelField = merge({}, entityField, { groupId, groupName }); - - componentResolveContext.bindingSourceContext = bindingSourceContext; - } else { - // 绑定变量 - const varibleField = selectedData as FormVariable; - bindingSourceContext.variableFieldNode = merge({}, varibleField, { groupId, groupName }); - componentResolveContext.bindingSourceContext = bindingSourceContext; - } - - if (modalEditorRef?.modalRef?.value.close) { - modalEditorRef?.modalRef?.value.close(); - } - } - /** - * 绑定字段弹窗 - */ - function renderFieldComponent() { - const { parentComponentInstance } = componentResolveContext; - const viewModelId = designerHostService.formSchemaUtils.getViewModelIdByComponentId(parentComponentInstance?.belongedComponentId); - const editorParams = { - viewModelId, - designerHostService, - disableOccupiedFields: true, - componentSchema: { editor: { type: componentResolveContext.componentType } } - }; - const bindingSettings = { enable: false }; - - const FBindingSelectorContainer = designerHostService.uiProviderService.getUiComponent('FBindingSelectorContainer'); - - return () => (<> ); - } - /** - * 弹出绑定字段的窗口 - */ - function triggerBindingField() { - return new Promise((resolve, reject) => { - modalEditorRef = designerHostService.modalService.open({ - title: '选择绑定', - width: 800, - height: 600, - fitContent: false, - showButtons: false, - render: renderFieldComponent(), - rejectCallback:()=>{ - componentResolveContext.bindingSourceContext = undefined; - }, - closedCallback: () => { - resolve(componentResolveContext); - }, - draggable: true - }); - }); - } - /** - * 生成控件schema结构 - */ - function resolveComponentSchema() { - const { parentComponentInstance } = componentResolveContext; - const componentSchema = parentComponentInstance.addNewChildComponentSchema(componentResolveContext, designerHostService); - componentResolveContext.componentSchema = componentSchema; - } - /** - * 解析拖拽元素,并根据场景展示不同的绑定窗口 - */ - async function resolveBindingSource() { - const { componentCategory } = componentResolveContext; - - switch (componentCategory) { - case 'input': { - await triggerBindingField(); - break; - } - case 'dataCollection': { - await triggerBindingEntity(); - break; - } - - } - } - /** - * 根据拖拽元素解析并创建控件 - */ - async function resolveComponentCreationContextByDrop(sourceElement: DesignerHTMLElement, sourceContainer: DesignerHTMLElement, targetContainer: DesignerHTMLElement): Promise { - componentResolveContext = getComponentResolveContext(sourceElement, sourceContainer, targetContainer); - - await resolveBindingSource(); - - // 若返回 undefined 代表终止后续生成 - if (componentResolveContext.bindingSourceContext === undefined) { - return null; - } else { - resolveComponentSchema(); - return componentResolveContext; - } - - } - - return { - getComponentResolveContext, - resolveComponentCreationContextByDrop - }; -} 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 deleted file mode 100644 index a8b6a7287e1..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/designer-canvas.component.tsx +++ /dev/null @@ -1,143 +0,0 @@ - -import { computed, defineComponent, inject, onMounted, onUnmounted, provide, ref, watch } from 'vue'; -import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from './types'; -import { canvasChanged, setPositionOfButtonGroup } 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'; -import FDesignerItem from './components/designer-item.component'; -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 '@farris/mobile-ui-vue/common'; - -export default defineComponent({ - name: 'FDesignerCanvas', - props: designerCanvasProps, - emits: ['init', 'selectionChange', 'canvasChanged'], - setup(props: DesignerCanvasPropsType, context) { - const schema = ref(); - const componentSchema = ref(); - const designerCanvasElementRef = ref(); - const designerCanvasContainerElementRef = ref(); - const designerItemElementRef = ref(); - const componentInstance = ref(); - const componentId = ref(props.componentId); - let resizeObserver: ResizeObserver | null; - let resizeObserverTimer; - - const designerHostService = { - eventsEditorUtils: inject('eventsEditorUtils'), - formSchemaUtils: inject('useFormSchema'), - formMetadataConverter: inject('formMetadataConverter'), - designViewModelUtils: inject('designViewModelUtils'), - controlCreatorUtils: inject('controlCreatorUtils'), - metadataService: inject('Meatdata_Http_Service_Token'), - schemaService: inject('schemaService'), - useFormCommand: inject('useFormCommand'), - 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); - loadDesignerRegister(); - - provide('canvas-dragula', useDragulaComposition); - provide('design-item-context', { - designerItemElementRef, - componentInstance, - schema: componentSchema.value, - parent: undefined - }); - - const designerCanvasClass = computed(() => { - const classObject = { - 'd-flex': true, - 'flex-fill': true, - 'flex-column': true - } as Record; - return classObject; - }); - - /** - * 用于在设计器里 - * @param designerItem - */ - function updateDesignerItem(item: any, compId: string) { - schema.value = item; - componentId.value = compId; - } - - watch(canvasChanged, () => { - setPositionOfButtonGroup(designerCanvasElementRef.value); - - context.emit('canvasChanged'); - }, { flush: 'post' }); - - /** - * 监听画布尺寸变化,重新计算操作图标位置 - */ - function registerResizeListenner() { - resizeObserver = new ResizeObserver(() => { - if (resizeObserverTimer) { - clearTimeout(resizeObserverTimer); - } - - resizeObserverTimer = setTimeout(() => { - setPositionOfButtonGroup(designerCanvasElementRef.value); - }); - }); - resizeObserver.observe(designerCanvasElementRef.value); - } - - function onSelectionChange(schemaType: string, schemaValue: ComponentSchema, cmpId: string, componentInst: DesignerComponentInstance) { - context.emit('selectionChange', schemaType, schemaValue, cmpId, componentInst); - } - - /** - * 监听画布父容器横向滚动条的滚动,重新计算操作图标位置 - */ - function registerEditorPanelScrollEvent() { - designerCanvasContainerElementRef.value.addEventListener('scroll', (e) => { - setPositionOfButtonGroup(designerCanvasElementRef.value); - }); - } - onMounted(() => { - if (designerCanvasElementRef.value) { - useDragulaComposition.initializeDragula(designerCanvasElementRef.value); - } - schema.value = props.modelValue; - context.emit('init', useDragulaComposition); - registerResizeListenner(); - registerEditorPanelScrollEvent(); - }); - - onUnmounted(() => { - if (resizeObserver) { - resizeObserver.unobserve(designerCanvasElementRef.value); - resizeObserver.disconnect(); - resizeObserver = null; - } - }); - - context.expose({ - updateDesignerItem - }); - - return () => { - return ( -
-
-
- {schema.value && } -
-
-
- ); - }; - } -}); diff --git a/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-response-form-layout-setting.ts b/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-response-form-layout-setting.ts deleted file mode 100644 index 2cf2bb772a8..00000000000 --- a/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-response-form-layout-setting.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { ResponseFormLayoutContext } from "@farris/mobile-ui-vue/response-layout-editor"; -import { FormUnifiedColumnLayout, UseResponseFormLayoutSetting } from "../types"; -import { DgControl } from "@farris/mobile-ui-vue/designer-canvas"; -import { useResponseLayoutEditorSetting } from - "../../../response-layout-editor/src/composition/converter/use-response-layout-editor-setting"; - -export function useResponseFormLayoutSetting(formShemaService, componentId: string): UseResponseFormLayoutSetting { - function getFormNode(formSchemaId, formNode = null): any { - if (formNode) { return formNode; } - const componentNode = formShemaService.getComponentById(componentId); - return formShemaService.selectNode(componentNode, item => item.id === formSchemaId); - } - function checkIsInFormComponent(componentId: string): boolean { - const componentNode = formShemaService.getComponentById(componentId); - if (!componentNode || !componentNode.componentType || !componentNode.componentType.startsWith('form')) { - return false; - } - return true; - - } - /** - * 组装每种屏幕下的宽度样式值,例如col-md-6,则uniqueColClassInMD为6 - */ - function assembleUnifiedLayoutContext(propertyData: any): FormUnifiedColumnLayout { - - const formNode = getFormNode(propertyData.id); - const responseLayoutService = useResponseLayoutEditorSetting(formShemaService); - const responseLayoutConfig: ResponseFormLayoutContext[] = []; - responseLayoutService.getResonseFormLayoutConfig(formNode, responseLayoutConfig, 1); - - - // 收集每种屏幕下的列数 - const columnInSMArray = responseLayoutConfig.map(config => config.columnInSM); - const columnInMDArray = responseLayoutConfig.map(config => config.columnInMD); - const columnInLGArray = responseLayoutConfig.map(config => config.columnInLG); - const columnInELArray = responseLayoutConfig.map(config => config.columnInEL); - - /** - * 校验宽度样式值是否一致 - */ - function checkIsUniqueColumn(columnsInScreen: number[]) { - const keySet = new Set(columnsInScreen); - const exclusiveKeys = Array.from(keySet); - - if (exclusiveKeys.length === 1) { - return true; - } - return false; - } - - // 只有每个控件的宽度都一样时,才认为form上有统一宽度,否则认为是自定义的控件宽度,此处传递null - const uniqueColClassInSM = checkIsUniqueColumn(columnInSMArray) ? columnInSMArray[0] : 0; - const uniqueColClassInMD = checkIsUniqueColumn(columnInMDArray) ? columnInMDArray[0] : 0; - const uniqueColClassInLG = checkIsUniqueColumn(columnInLGArray) ? columnInLGArray[0] : 0; - const uniqueColClassInEL = checkIsUniqueColumn(columnInELArray) ? columnInELArray[0] : 0; - - return { - uniqueColClassInSM, - uniqueColClassInMD, - uniqueColClassInLG, - uniqueColClassInEL - }; - } - - /** - * 校验宽度样式值是否一致 - */ - function checkIsUniqueColumn(columnsInScreen: number[]) { - const keySet = new Set(columnsInScreen); - const exclusiveKeys = Array.from(keySet); - - if (exclusiveKeys.length === 1) { - return true; - } - return false; - } - - /** - * 根据统一配置值,修改某一个控件的class样式 - */ - function changeControlClassInByColumn(controlClass: string, unifiedLayout: FormUnifiedColumnLayout) { - let originColClass; - let originColMDClass; - let originColXLClass; - let originColELClass; - let otherClassItems = [] as any; - if (controlClass) { - const controlClassArray = controlClass.split(' '); - const colClassItems = controlClassArray.filter(classItem => classItem.startsWith('col-')); - originColClass = colClassItems.find(item => /^col-([1-9]|10|11|12)$/.test(item)); - originColMDClass = colClassItems.find(item => /^col-md-([1-9]|10|11|12)$/.test(item)); - originColXLClass = colClassItems.find(item => /^col-xl-([1-9]|10|11|12)$/.test(item)); - originColELClass = colClassItems.find(item => /^col-el-([1-9]|10|11|12)$/.test(item)); - otherClassItems = controlClassArray.filter(classItem => !classItem.startsWith('col-')); - } - const colClass = unifiedLayout.uniqueColClassInSM ? 'col-' + unifiedLayout.uniqueColClassInSM : originColClass; - const colMDClass = unifiedLayout.uniqueColClassInMD ? 'col-md-' + unifiedLayout.uniqueColClassInMD : originColMDClass; - const colXLClass = unifiedLayout.uniqueColClassInLG ? 'col-xl-' + unifiedLayout.uniqueColClassInLG : originColXLClass; - const colELClass = unifiedLayout.uniqueColClassInEL ? 'col-el-' + unifiedLayout.uniqueColClassInEL : originColELClass; - - const newClassItems = [colClass, colMDClass, colXLClass, colELClass].concat(otherClassItems); - - return newClassItems.join(' '); - } - - /** - * 根据统一配置值,修改卡片区域内所有控件的class样式 - * @param formNode dom节点 - * @param unifiedLayout 统一配置值 - */ - function changeFormControlsByUnifiedLayoutConfig(formNode: any, unifiedLayout: FormUnifiedColumnLayout, formSchemaId) { - formNode = getFormNode(formSchemaId, formNode); - formNode.contents.forEach(control => { - if (control.type === DgControl['fieldset'].type) { - changeFormControlsByUnifiedLayoutConfig(control, unifiedLayout, control.id); - return; - } - if (!control.appearance) { - control.appearance = {}; - } - const controlClass = control.appearance.class; - control.appearance.class = changeControlClassInByColumn(controlClass, unifiedLayout); - - }); - } - - return { checkIsInFormComponent, assembleUnifiedLayoutContext, changeFormControlsByUnifiedLayoutConfig }; -} 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 index a8e103fb4d7..ecbd2d33051 100644 --- 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 @@ -15,10 +15,10 @@ * limitations under the License. */ import { computed, defineComponent, inject, onMounted, readonly, ref, SetupContext } from 'vue'; -import { DesignerHostService, DesignerItemContext, useDesignerComponent } from '@farris/mobile-ui-vue/designer-canvas'; +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';; +import { usePickerDesignerRules } from './use-designer-rules';; export default defineComponent({ name: 'FmEnumFieldInputDesign', @@ -28,7 +28,7 @@ export default defineComponent({ const elementRef = ref(); const designerHostService = inject('designer-host-service'); const designItemContext = inject('design-item-context') as DesignerItemContext; - const designerRulesComposition = useEnumFieldDesignerRules(designItemContext, designerHostService); + const designerRulesComposition = usePickerDesignerRules(designItemContext, designerHostService); const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition); onMounted(() => { diff --git a/packages/mobile-ui-vue/components/property-panel/src/composition/entity/base-property.ts b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/base-property.ts deleted file mode 100644 index 9ec35abb278..00000000000 --- a/packages/mobile-ui-vue/components/property-panel/src/composition/entity/base-property.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { DesignerComponentInstance } from "@farris/mobile-ui-vue/designer-canvas"; -import { DgControl } from "../../../../designer-canvas/src/composition/dg-control"; -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/property-panel/src/composition/entity/input-base-property.ts b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/input-base-property.ts deleted file mode 100644 index a8dd354e606..00000000000 --- a/packages/mobile-ui-vue/components/property-panel/src/composition/entity/input-base-property.ts +++ /dev/null @@ -1,390 +0,0 @@ - -import { BaseControlProperty } from "./base-property"; -import { SchemaDOMMapping } from './schema-dom-mapping'; -import { canvasChanged } from '../../../../designer-canvas/src/composition/designer-canvas-changed'; -import { DesignerComponentInstance } from "../../../../designer-canvas/src/types"; -import { FormUnifiedColumnLayout } from "../type"; -import { - ResponseFormLayoutContext, - UseResponseLayoutEditorSetting, -} from "@farris/mobile-ui-vue/response-layout-editor"; -import { useResponseLayoutEditorSetting } from "../../../../response-layout-editor/src/composition/converter/use-response-layout-editor-setting"; -import { FormSchemaEntityFieldType$Type } from "@farris/mobile-ui-vue/common"; - -export class InputBaseProperty extends BaseControlProperty { - public responseLayoutEditorFunction: UseResponseLayoutEditorSetting; - constructor(componentId: string, designerHostService: any) { - super(componentId, designerHostService); - this.responseLayoutEditorFunction = useResponseLayoutEditorSetting(this.formSchemaUtils); - } - - 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" - }, - responseLayout: { - description: "响应式列宽", - title: "响应式列宽", - type: "boolean", - visible: true, - // 这个属性,标记当属性变更得时候触发重新更新属性 - refreshPanelAfterChanged: true, - editor: { - type: "response-layout-editor-setting", - initialState: self.responseLayoutEditorFunction.checkCanOpenLayoutEditor(propertyData, self.componentId) - } - } - }, - setPropertyRelates(changeObject, prop) { - if (!changeObject) { - return; - } - switch (changeObject && changeObject.propertyID) { - case 'responseLayout': - self.responseLayoutEditorFunction.changeFormControlsByResponseLayoutConfig(changeObject.propertyValue, self.componentId || propertyData.id); - self.updateUnifiedLayoutAfterResponseLayoutChanged(self.componentId); - self.updateElementByParentContainer(propertyData.id, componentInstance); - delete propertyData.responseLayout; - break; - case 'class': - self.updateUnifiedLayoutAfterControlChanged(changeObject.propertyValue, propertyData.id, this.componentId); - 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" - // }, - placeholder: { - description: "空值时,输入控件内的占位文本", - title: "提示文本", - type: "string" - } - }, properties); - - return { ...editorBasic, properties: { ...editorProperties }, setPropertyRelates }; - - } - - - /** - * 修改某一输入控件的样式后更新Form的统一布局配置 - * @param controlClass 控件样式 - * @param controlId 控件Id - * @param componentId 控件所在组件id - */ - private updateUnifiedLayoutAfterControlChanged(controlClass: string, controlId: string, componentId: string) { - const controlClassArray = controlClass.split(' '); - - let colClass = controlClassArray.find(item => /^col-([1-9]|10|11|12)$/.test(item)); - let colMDClass = controlClassArray.find(item => /^col-md-([1-9]|10|11|12)$/.test(item)); - let colXLClass = controlClassArray.find(item => /^col-xl-([1-9]|10|11|12)$/.test(item)); - let colELClass = controlClassArray.find(item => /^col-el-([1-9]|10|11|12)$/.test(item)); - - colClass = colClass || 'col-12'; - colMDClass = colMDClass || 'col-md-' + colClass.replace('col-', ''); - colXLClass = colXLClass || 'col-xl-' + colMDClass.replace('col-md-', ''); - colELClass = colELClass || 'col-el-' + colXLClass.replace('col-xl-', ''); - - const latestControlLayoutConfig = { - id: controlId, - columnInSM: parseInt(colClass.replace('col-', ''), 10), - columnInMD: parseInt(colMDClass.replace('col-md-', ''), 10), - columnInLG: parseInt(colXLClass.replace('col-xl-', ''), 10), - columnInEL: parseInt(colELClass.replace('col-el-', ''), 10), - }; - - this.updateUnifiedLayoutAfterResponseLayoutChanged(componentId, latestControlLayoutConfig); - } - - /** - * 修改控件布局配置后更新Form统一布局配置 - * @param componentId 组件Id - * @param controlLayoutConfig 某单独变动的控件配置项,FormResponseLayoutContext类型 - */ - private updateUnifiedLayoutAfterResponseLayoutChanged(componentId: string, controlLayoutConfig?: any): FormUnifiedColumnLayout | undefined { - const { formNode } = this.responseLayoutEditorFunction.checkCanFindFormNode(componentId); - // 更改form上的统一配置 - if (!formNode || !formNode.unifiedLayout) { - return; - } - const responseLayoutConfig: ResponseFormLayoutContext[] = []; - this.responseLayoutEditorFunction.getResonseFormLayoutConfig(formNode, responseLayoutConfig, 1); - if (controlLayoutConfig) { - const changedControl = responseLayoutConfig.find(c => c.id === controlLayoutConfig.id); - Object.assign(changedControl || {}, controlLayoutConfig); - } - - // 收集每种屏幕下的列数 - const columnInSMArray = responseLayoutConfig.map(config => config.columnInSM); - const columnInMDArray = responseLayoutConfig.map(config => config.columnInMD); - const columnInLGArray = responseLayoutConfig.map(config => config.columnInLG); - const columnInELArray = responseLayoutConfig.map(config => config.columnInEL); - - // 只有每个控件的宽度都一样时,才认为form上有统一宽度,否则认为是自定义的控件宽度,此处传递null - const uniqueColClassInSM = this.checkIsUniqueColumn(columnInSMArray) ? columnInSMArray[0] : null; - const uniqueColClassInMD = this.checkIsUniqueColumn(columnInMDArray) ? columnInMDArray[0] : null; - const uniqueColClassInLG = this.checkIsUniqueColumn(columnInLGArray) ? columnInLGArray[0] : null; - const uniqueColClassInEL = this.checkIsUniqueColumn(columnInELArray) ? columnInELArray[0] : null; - - - Object.assign(formNode.unifiedLayout, { - uniqueColClassInSM, - uniqueColClassInMD, - uniqueColClassInLG, - uniqueColClassInEL - }); - } - /** - * 校验宽度样式值是否一致 - */ - private checkIsUniqueColumn(columnsInScreen: number[]) { - const keySet = new Set(columnsInScreen); - const exclusiveKeys = Array.from(keySet); - - if (exclusiveKeys.length === 1) { - return true; - } - return false; - } - /** - * 枚举项编辑器 - * @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/property-panel/src/composition/entity/use-input-rules.ts b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/use-input-rules.ts deleted file mode 100644 index de3ba04fcd6..00000000000 --- a/packages/mobile-ui-vue/components/property-panel/src/composition/entity/use-input-rules.ts +++ /dev/null @@ -1,62 +0,0 @@ - -import { ref } from "vue"; -import { DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from '../../../../designer-canvas/src/composition/types'; -import { ComponentSchema, DesignerItemContext } from "@farris/mobile-ui-vue/designer-canvas"; - -export function useInputDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { - const schema = designItemContext.schema as ComponentSchema; - /** 组件在拖拽时需要将所属的Component一起拖拽 */ - const triggerBelongedComponentToMoveWhenMoved = ref(true); - /** 组件在删除时需要将所属的Component一起拖拽 */ - const triggerBelongedComponentToDeleteWhenDeleted = ref(true); - /** data-grid所属的上级组件控制规则 */ - /** - * 判断是否可以接收拖拽新增的子级控件 - */ - function canAccepts(draggingContext: DraggingResolveContext): boolean { - return false; - } - - /** - * data-grid是否支持删除,取决于所属组件是否支持删除 - */ - function checkCanDeleteComponent() { - return false; - } - /** - * data-grid是否支持移动,取决于所属组件是否支持移动 - */ - function checkCanMoveComponent() { - return false; - } - - function hideNestedPaddingInDesginerView() { - return true; - } - - function onAcceptMovedChildElement(sourceElement: DesignerHTMLElement) { - } - /** - * 判断data-grid上下文 - */ - function resolveComponentContext() { - - } - // 构造属性配置方法 - function getPropsConfig(componentId: string) { - return null; - } - - return { - canAccepts, - checkCanDeleteComponent, - checkCanMoveComponent, - hideNestedPaddingInDesginerView, - onAcceptMovedChildElement, - resolveComponentContext, - triggerBelongedComponentToMoveWhenMoved, - triggerBelongedComponentToDeleteWhenDeleted, - getPropsConfig - } as UseDesignerRules; - -} -- Gitee From 751e00207cdfd5c2e5563ecf3a069eb30b0e19f2 Mon Sep 17 00:00:00 2001 From: lijiangkun Date: Thu, 3 Jul 2025 08:35:25 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=E6=B3=A8=E5=86=8C=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designer-context/use-mobile-designer-context.ts | 4 ++-- packages/mobile-ui-vue/components/designer.ts | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) 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 021dc0f31c1..ca3121935cc 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,7 +5,7 @@ import SupportedControllers from '../../composition/command/supported-controller import { Component, PageContainer, PageHeaderContainer, PageBodyContainer, PageFooterContainer, Picker, NumberInput, Textarea, DatePicker, DateTimePicker, Lookup, ContentContainer, Card, FloatContainer, Navbar, ListView, Form, FormItem, InputGroup, Button, Switch, CheckboxGroup, RadioGroup, - ButtonGroup, + ButtonGroup,registerDesignerComponents } from '@farris/mobile-ui-vue'; import { useMobileControlCreator } from "../control-creator/use-mobile-control-creator"; import { PageComponent, UsePageSchema } from "../../../components/types"; @@ -27,7 +27,7 @@ export function useMobileDesignerContext(): UseDesignerContext { Form, FormItem, InputGroup, Button, ButtonGroup, ]; - // registerDesignerComponents(componentsToRegister); + registerDesignerComponents(componentsToRegister); /** 支持的控制器 */ const supportedControllers: any = SupportedControllers; diff --git a/packages/mobile-ui-vue/components/designer.ts b/packages/mobile-ui-vue/components/designer.ts index 2f552d0f64f..02145f65060 100644 --- a/packages/mobile-ui-vue/components/designer.ts +++ b/packages/mobile-ui-vue/components/designer.ts @@ -1,4 +1,5 @@ export * from './dynamic-resolver'; +export * from './register-designer'; // export { FDesignerToolbox } from './designer-toolbox'; // export { default as FModal, FModalService, FM_MODAL_SERVICE_TOKEN } from './modal'; // export { FM_UI_PROVIDER_SERVICE_TOKEN } from './common'; -- Gitee