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,