diff --git a/apps/web-antd/src/components/form-create/components/area-select.vue b/apps/web-antd/src/components/form-create/components/area-select.vue
new file mode 100644
index 000000000..dd6203cac
--- /dev/null
+++ b/apps/web-antd/src/components/form-create/components/area-select.vue
@@ -0,0 +1,154 @@
+
+
+
+
+
+
diff --git a/apps/web-antd/src/components/form-create/components/iframe.vue b/apps/web-antd/src/components/form-create/components/iframe.vue
new file mode 100644
index 000000000..9f6265a15
--- /dev/null
+++ b/apps/web-antd/src/components/form-create/components/iframe.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/components/form-create/helpers.ts b/apps/web-antd/src/components/form-create/helpers.ts
index 010d27afc..af08c6617 100644
--- a/apps/web-antd/src/components/form-create/helpers.ts
+++ b/apps/web-antd/src/components/form-create/helpers.ts
@@ -17,6 +17,8 @@ import {
useUploadFileRule,
useUploadImageRule,
useUploadImagesRule,
+ useIframeRule,
+ useAreaSelectRule,
} from './rules';
/** 编码表单 Conf */
@@ -160,6 +162,8 @@ export async function useFormCreateDesigner(designer: Ref) {
const uploadFileRule = useUploadFileRule();
const uploadImageRule = useUploadImageRule();
const uploadImagesRule = useUploadImagesRule();
+ const iframeRule = useIframeRule();
+ const areaSelectRule = useAreaSelectRule();
/** 构建表单组件 */
function buildFormComponents() {
@@ -172,6 +176,8 @@ export async function useFormCreateDesigner(designer: Ref) {
uploadFileRule,
uploadImageRule,
uploadImagesRule,
+ iframeRule,
+ areaSelectRule,
];
components.forEach((component) => {
// 插入组件规则
diff --git a/apps/web-antd/src/components/form-create/rules/index.ts b/apps/web-antd/src/components/form-create/rules/index.ts
index db306da35..dc3391f8d 100644
--- a/apps/web-antd/src/components/form-create/rules/index.ts
+++ b/apps/web-antd/src/components/form-create/rules/index.ts
@@ -1,5 +1,7 @@
+export { useAreaSelectRule } from './use-area-select-rule';
export { useDictSelectRule } from './use-dict-select';
export { useEditorRule } from './use-editor-rule';
+export { useIframeRule } from './use-iframe-rule';
export { useSelectRule } from './use-select-rule';
export { useUploadFileRule } from './use-upload-file-rule';
export { useUploadImageRule } from './use-upload-image-rule';
diff --git a/apps/web-antd/src/components/form-create/rules/use-area-select-rule.ts b/apps/web-antd/src/components/form-create/rules/use-area-select-rule.ts
new file mode 100644
index 000000000..64aeeab4d
--- /dev/null
+++ b/apps/web-antd/src/components/form-create/rules/use-area-select-rule.ts
@@ -0,0 +1,77 @@
+import { cloneDeep } from '@vben/utils';
+
+import {
+ localeProps,
+ makeRequiredRule,
+} from '#/components/form-create/helpers';
+
+/** 省市区选择器规则 */
+export function useAreaSelectRule() {
+ const label = '省市区选择器';
+ const name = 'AreaSelect';
+
+ return {
+ icon: 'icon-location',
+ label,
+ name,
+ rule() {
+ return {
+ type: name,
+ field: `area_${Date.now()}`,
+ title: label,
+ info: '',
+ $required: false,
+ modelField: 'value', // 特殊:ele 里是 model-value,antd 里是 value
+ };
+ },
+ props(_: any, { t }: any) {
+ 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/apps/web-antd/src/components/form-create/rules/use-iframe-rule.ts b/apps/web-antd/src/components/form-create/rules/use-iframe-rule.ts
new file mode 100644
index 000000000..39d26d766
--- /dev/null
+++ b/apps/web-antd/src/components/form-create/rules/use-iframe-rule.ts
@@ -0,0 +1,77 @@
+import { buildUUID } from '@vben/utils';
+
+import {
+ localeProps,
+ makeRequiredRule,
+} from '#/components/form-create/helpers';
+
+/** iframe 组件规则 */
+export function useIframeRule() {
+ const label = '网页 iframe';
+ const name = 'IframeComponent';
+
+ return {
+ icon: 'icon-link',
+ label,
+ name,
+ rule() {
+ return {
+ type: name,
+ field: buildUUID(),
+ title: label,
+ info: '',
+ $required: false,
+ modelField: 'value', // 特殊:ele 里是 model-value,antd 里是 value
+ };
+ },
+ props(_: any, { t }: any) {
+ 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/apps/web-antd/src/plugins/form-create/index.ts b/apps/web-antd/src/plugins/form-create/index.ts
index 024aae834..e93252a13 100644
--- a/apps/web-antd/src/plugins/form-create/index.ts
+++ b/apps/web-antd/src/plugins/form-create/index.ts
@@ -34,8 +34,10 @@ import {
// ======================= 自定义组件 =======================
import { useApiSelect } from '#/components/form-create';
+import AreaSelect from '#/components/form-create/components/area-select.vue';
import DeptSelect from '#/components/form-create/components/dept-select.vue';
import DictSelect from '#/components/form-create/components/dict-select.vue';
+import IframeComponent from '#/components/form-create/components/iframe.vue';
import { useImagesUpload } from '#/components/form-create/components/use-images-upload';
import { Tinymce } from '#/components/tinymce';
import { FileUpload, ImageUpload } from '#/components/upload';
@@ -84,6 +86,8 @@ const components = [
Tinymce,
ImageUpload,
FileUpload,
+ IframeComponent,
+ AreaSelect,
];
// 参考 https://www.form-create.com/v3/ant-design-vue/auto-import 文档
diff --git a/apps/web-ele/src/components/form-create/components/area-select.vue b/apps/web-ele/src/components/form-create/components/area-select.vue
new file mode 100644
index 000000000..1687fe145
--- /dev/null
+++ b/apps/web-ele/src/components/form-create/components/area-select.vue
@@ -0,0 +1,151 @@
+
+
+
+
+
+
diff --git a/apps/web-ele/src/components/form-create/components/iframe.vue b/apps/web-ele/src/components/form-create/components/iframe.vue
new file mode 100644
index 000000000..0098e5db9
--- /dev/null
+++ b/apps/web-ele/src/components/form-create/components/iframe.vue
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
diff --git a/apps/web-ele/src/components/form-create/helpers.ts b/apps/web-ele/src/components/form-create/helpers.ts
index a7d750a99..53d51e85e 100644
--- a/apps/web-ele/src/components/form-create/helpers.ts
+++ b/apps/web-ele/src/components/form-create/helpers.ts
@@ -17,6 +17,8 @@ import {
useUploadFileRule,
useUploadImageRule,
useUploadImagesRule,
+ useIframeRule,
+ useAreaSelectRule,
} from './rules';
/** 编码表单 Conf */
@@ -160,6 +162,8 @@ export async function useFormCreateDesigner(designer: Ref) {
const uploadFileRule = useUploadFileRule();
const uploadImageRule = useUploadImageRule();
const uploadImagesRule = useUploadImagesRule();
+ const iframeRule = useIframeRule();
+ const areaSelectRule = useAreaSelectRule();
/** 构建表单组件 */
function buildFormComponents() {
@@ -172,6 +176,8 @@ export async function useFormCreateDesigner(designer: Ref) {
uploadFileRule,
uploadImageRule,
uploadImagesRule,
+ iframeRule,
+ areaSelectRule,
];
components.forEach((component) => {
// 插入组件规则
diff --git a/apps/web-ele/src/components/form-create/rules/index.ts b/apps/web-ele/src/components/form-create/rules/index.ts
index db306da35..dc3391f8d 100644
--- a/apps/web-ele/src/components/form-create/rules/index.ts
+++ b/apps/web-ele/src/components/form-create/rules/index.ts
@@ -1,5 +1,7 @@
+export { useAreaSelectRule } from './use-area-select-rule';
export { useDictSelectRule } from './use-dict-select';
export { useEditorRule } from './use-editor-rule';
+export { useIframeRule } from './use-iframe-rule';
export { useSelectRule } from './use-select-rule';
export { useUploadFileRule } from './use-upload-file-rule';
export { useUploadImageRule } from './use-upload-image-rule';
diff --git a/apps/web-ele/src/components/form-create/rules/use-area-select-rule.ts b/apps/web-ele/src/components/form-create/rules/use-area-select-rule.ts
new file mode 100644
index 000000000..1db16dcb7
--- /dev/null
+++ b/apps/web-ele/src/components/form-create/rules/use-area-select-rule.ts
@@ -0,0 +1,77 @@
+import { cloneDeep } from '@vben/utils';
+
+import {
+ localeProps,
+ makeRequiredRule,
+} from '#/components/form-create/helpers';
+
+/** 省市区选择器规则 */
+export function useAreaSelectRule() {
+ const label = '省市区选择器';
+ const name = 'AreaSelect';
+
+ return {
+ icon: 'icon-location',
+ label,
+ name,
+ rule() {
+ return {
+ type: name,
+ field: `area_${Date.now()}`,
+ title: label,
+ info: '',
+ $required: false,
+ modelField: 'model-value', // 特殊:ele 里是 model-value,antd 里是 value
+ };
+ },
+ props(_: any, { t }: any) {
+ 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/apps/web-ele/src/components/form-create/rules/use-iframe-rule.ts b/apps/web-ele/src/components/form-create/rules/use-iframe-rule.ts
new file mode 100644
index 000000000..7640e8ad3
--- /dev/null
+++ b/apps/web-ele/src/components/form-create/rules/use-iframe-rule.ts
@@ -0,0 +1,77 @@
+import { buildUUID } from '@vben/utils';
+
+import {
+ localeProps,
+ makeRequiredRule,
+} from '#/components/form-create/helpers';
+
+/** iframe 组件规则 */
+export function useIframeRule() {
+ const label = '网页 iframe';
+ const name = 'IframeComponent';
+
+ return {
+ icon: 'icon-link',
+ label,
+ name,
+ rule() {
+ return {
+ type: name,
+ field: buildUUID(),
+ title: label,
+ info: '',
+ $required: false,
+ modelField: 'model-value', // 特殊:ele 里是 model-value,antd 里是 value
+ };
+ },
+ props(_: any, { t }: any) {
+ 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/apps/web-ele/src/plugins/form-create/index.ts b/apps/web-ele/src/plugins/form-create/index.ts
index 785c901de..1121f84ef 100644
--- a/apps/web-ele/src/plugins/form-create/index.ts
+++ b/apps/web-ele/src/plugins/form-create/index.ts
@@ -34,8 +34,10 @@ import {
// ======================= 自定义组件 =======================
import { useApiSelect } from '#/components/form-create';
+import AreaSelect from '#/components/form-create/components/area-select.vue';
import DeptSelect from '#/components/form-create/components/dept-select.vue';
import DictSelect from '#/components/form-create/components/dict-select.vue';
+import IframeComponent from '#/components/form-create/components/iframe.vue';
import { useImagesUpload } from '#/components/form-create/components/use-images-upload';
import { Tinymce } from '#/components/tinymce';
import { FileUpload, ImageUpload } from '#/components/upload';
@@ -60,6 +62,8 @@ const components = [
UserSelect,
DeptSelect,
ApiSelect,
+ IframeComponent,
+ AreaSelect,
ElAlert,
ElTransfer,
ElAside,