From a62251f900066434ace128e785e9f8bae421df29 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sun, 8 Feb 2026 11:56:18 +0800 Subject: [PATCH] =?UTF-8?q?feat(form-create):=20=E6=96=B0=E5=A2=9E=20ifram?= =?UTF-8?q?e=20=E5=92=8C=E7=9C=81=E5=B8=82=E5=8C=BA=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=99=A8=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 iframe 网页嵌入组件,支持 URL 配置和实时预览 - 新增省市区三级联动选择器组件 --- .../FormCreate/src/components/AreaSelect.vue | 145 ++++++++++++++++++ .../src/components/IframeComponent.vue | 102 ++++++++++++ src/components/FormCreate/src/config/index.ts | 6 +- .../src/config/useAreaSelectRule.ts | 74 +++++++++ .../FormCreate/src/config/useIframeRule.ts | 74 +++++++++ .../FormCreate/src/useFormCreateDesigner.ts | 8 +- src/plugins/formCreate/index.ts | 4 + 7 files changed, 410 insertions(+), 3 deletions(-) create mode 100644 src/components/FormCreate/src/components/AreaSelect.vue create mode 100644 src/components/FormCreate/src/components/IframeComponent.vue create mode 100644 src/components/FormCreate/src/config/useAreaSelectRule.ts create mode 100644 src/components/FormCreate/src/config/useIframeRule.ts diff --git a/src/components/FormCreate/src/components/AreaSelect.vue b/src/components/FormCreate/src/components/AreaSelect.vue new file mode 100644 index 00000000..32ef3296 --- /dev/null +++ b/src/components/FormCreate/src/components/AreaSelect.vue @@ -0,0 +1,145 @@ + + + + diff --git a/src/components/FormCreate/src/components/IframeComponent.vue b/src/components/FormCreate/src/components/IframeComponent.vue new file mode 100644 index 00000000..49ac1a88 --- /dev/null +++ b/src/components/FormCreate/src/components/IframeComponent.vue @@ -0,0 +1,102 @@ + + + + + + diff --git a/src/components/FormCreate/src/config/index.ts b/src/components/FormCreate/src/config/index.ts index b1e2ddea..d4d384c3 100644 --- a/src/components/FormCreate/src/config/index.ts +++ b/src/components/FormCreate/src/config/index.ts @@ -4,6 +4,8 @@ import { useUploadImgsRule } from './useUploadImgsRule' import { useDictSelectRule } from './useDictSelectRule' import { useEditorRule } from './useEditorRule' import { useSelectRule } from './useSelectRule' +import { useIframeRule } from './useIframeRule' +import { useAreaSelectRule } from './useAreaSelectRule' export { useUploadFileRule, @@ -11,5 +13,7 @@ export { useUploadImgsRule, useDictSelectRule, useEditorRule, - useSelectRule + useSelectRule, + useIframeRule, + useAreaSelectRule } diff --git a/src/components/FormCreate/src/config/useAreaSelectRule.ts b/src/components/FormCreate/src/config/useAreaSelectRule.ts new file mode 100644 index 00000000..59405da6 --- /dev/null +++ b/src/components/FormCreate/src/config/useAreaSelectRule.ts @@ -0,0 +1,74 @@ +import { generateUUID } from '@/utils' +import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' + +/** + * 省市区选择器规则 + */ +export const useAreaSelectRule = () => { + const label = '省市区选择器' + const name = 'AreaSelect' + + return { + icon: 'icon-location', + label, + name, + rule() { + return { + type: name, + field: generateUUID(), + title: label, + info: '', + $required: false + } + }, + props(_, { t }) { + return localeProps(t, name + '.props', [ + makeRequiredRule(), + { + type: 'select', + field: 'level', + title: '选择层级', + value: 3, + options: [ + { label: '省', value: 1 }, + { label: '省/市', value: 2 }, + { label: '省/市/区', value: 3 } + ], + info: '限制可选择的地区层级' + }, + { + type: 'input', + field: 'placeholder', + title: '占位符', + value: '请选择省市区' + }, + { + type: 'switch', + field: 'clearable', + title: '是否可清空', + value: true + }, + { + type: 'switch', + field: 'showAllLevels', + title: '显示完整路径', + value: true, + info: '输入框中是否显示选中值的完整路径' + }, + { + type: 'input', + field: 'separator', + title: '分隔符', + value: '/', + info: '选项分隔符' + }, + { + type: 'switch', + field: 'disabled', + title: '是否禁用', + value: false + } + ]) + } + } +} diff --git a/src/components/FormCreate/src/config/useIframeRule.ts b/src/components/FormCreate/src/config/useIframeRule.ts new file mode 100644 index 00000000..5a3e4787 --- /dev/null +++ b/src/components/FormCreate/src/config/useIframeRule.ts @@ -0,0 +1,74 @@ +import { generateUUID } from '@/utils' +import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' + +/** + * iframe 组件规则 + */ +export const useIframeRule = () => { + const label = '网页 iframe' + const name = 'IframeComponent' + + return { + icon: 'icon-link', + label, + name, + rule() { + return { + type: name, + field: generateUUID(), + title: label, + info: '', + $required: false + } + }, + props(_, { t }) { + return localeProps(t, name + '.props', [ + makeRequiredRule(), + { + type: 'input', + field: 'url', + title: 'URL 地址', + value: '', + info: '请输入完整的 HTTP 或 HTTPS 地址' + }, + { + type: 'input', + field: 'height', + title: 'iframe 高度', + value: '500px', + info: '支持 px、%、vh 等单位' + }, + { + type: 'input', + field: 'width', + title: 'iframe 宽度', + value: '100%', + info: '支持 px、%、vw 等单位' + }, + { + type: 'select', + field: 'loading', + title: '加载方式', + value: 'lazy', + options: [ + { label: '懒加载', value: 'lazy' }, + { label: '立即加载', value: 'eager' } + ] + }, + { + type: 'switch', + field: 'allowfullscreen', + title: '允许全屏', + value: true + }, + { + type: 'input', + field: 'sandbox', + title: 'sandbox 属性', + value: '', + info: '安全沙箱限制,如:allow-scripts allow-same-origin' + } + ]) + } + } +} diff --git a/src/components/FormCreate/src/useFormCreateDesigner.ts b/src/components/FormCreate/src/useFormCreateDesigner.ts index 5769b4ba..9658f8b7 100644 --- a/src/components/FormCreate/src/useFormCreateDesigner.ts +++ b/src/components/FormCreate/src/useFormCreateDesigner.ts @@ -4,7 +4,9 @@ import { useSelectRule, useUploadFileRule, useUploadImgRule, - useUploadImgsRule + useUploadImgsRule, + useIframeRule, + useAreaSelectRule } from './config' import { Ref } from 'vue' import { Menu } from '@/components/FormCreate/src/type' @@ -36,7 +38,9 @@ export const useFormCreateDesigner = async (designer: Ref) => { designer.value?.removeMenuItem('upload') // 移除自带的富文本组件规则,使用 editorRule 替代 designer.value?.removeMenuItem('fcEditor') - const components = [editorRule, uploadFileRule, uploadImgRule, uploadImgsRule] + const iframeRule = useIframeRule() + const areaSelectRule = useAreaSelectRule() + const components = [editorRule, uploadFileRule, uploadImgRule, uploadImgsRule, iframeRule, areaSelectRule] components.forEach((component) => { // 插入组件规则 designer.value?.addComponent(component) diff --git a/src/plugins/formCreate/index.ts b/src/plugins/formCreate/index.ts index 6e0a971f..42593050 100644 --- a/src/plugins/formCreate/index.ts +++ b/src/plugins/formCreate/index.ts @@ -69,6 +69,8 @@ import { useApiSelect } from '@/components/FormCreate' import { Editor } from '@/components/Editor' import DictSelect from '@/components/FormCreate/src/components/DictSelect.vue' import DeptSelect from '@/components/FormCreate/src/components/DeptSelect.vue' +import IframeComponent from '@/components/FormCreate/src/components/IframeComponent.vue' +import AreaSelect from '@/components/FormCreate/src/components/AreaSelect.vue' const UserSelect = useApiSelect({ name: 'UserSelect', @@ -114,6 +116,8 @@ const components = [ DeptSelect, ApiSelect, Editor, + IframeComponent, + AreaSelect, ElCollapse, ElCollapseItem, ElCard