From 769b63d9ca797dd402861e2e6a3110d43f423123 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 30 Apr 2024 00:07:25 +0800 Subject: [PATCH 1/7] =?UTF-8?q?form-create=EF=BC=9A=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E8=87=AA=E5=B8=A6=E7=9A=84=E4=B8=8B=E6=8B=89=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=99=A8=E7=BB=84=E4=BB=B6=EF=BC=8C=E4=BD=BF=E7=94=A8=20curren?= =?UTF-8?q?cySelectRule=20=E6=9B=BF=E4=BB=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FormCreate/index.ts | 3 +- .../FormCreate/src/CurrencySelect/index.vue | 53 +++++++++++++++++++ src/components/FormCreate/src/config/index.ts | 4 +- .../src/config/useCurrencySelectRule.ts | 36 +++++++++++++ .../src/config/useUserSelectRule.ts | 25 --------- .../FormCreate/src/useFormCreateDesigner.ts | 10 ++-- src/plugins/formCreate/index.ts | 4 +- .../system/user/components/UserSelect.vue | 28 ---------- 8 files changed, 101 insertions(+), 62 deletions(-) create mode 100644 src/components/FormCreate/src/CurrencySelect/index.vue create mode 100644 src/components/FormCreate/src/config/useCurrencySelectRule.ts delete mode 100644 src/components/FormCreate/src/config/useUserSelectRule.ts delete mode 100644 src/views/system/user/components/UserSelect.vue diff --git a/src/components/FormCreate/index.ts b/src/components/FormCreate/index.ts index d50ed3c6..66fc7e6f 100644 --- a/src/components/FormCreate/index.ts +++ b/src/components/FormCreate/index.ts @@ -1,3 +1,4 @@ import { useFormCreateDesigner } from './src/useFormCreateDesigner' +import CurrencySelect from './src/CurrencySelect/index.vue' -export { useFormCreateDesigner } +export { useFormCreateDesigner, CurrencySelect } diff --git a/src/components/FormCreate/src/CurrencySelect/index.vue b/src/components/FormCreate/src/CurrencySelect/index.vue new file mode 100644 index 00000000..3591a935 --- /dev/null +++ b/src/components/FormCreate/src/CurrencySelect/index.vue @@ -0,0 +1,53 @@ + + + diff --git a/src/components/FormCreate/src/config/index.ts b/src/components/FormCreate/src/config/index.ts index c3939159..078bc803 100644 --- a/src/components/FormCreate/src/config/index.ts +++ b/src/components/FormCreate/src/config/index.ts @@ -2,7 +2,7 @@ import { useUploadFileRule } from './useUploadFileRule' import { useUploadImgRule } from './useUploadImgRule' import { useUploadImgsRule } from './useUploadImgsRule' import { useDictSelectRule } from './useDictSelectRule' -import { useUserSelectRule } from './useUserSelectRule' +import { useCurrencySelectRule } from './useCurrencySelectRule' import { useEditorRule } from './useEditorRule' export { @@ -10,6 +10,6 @@ export { useUploadImgRule, useUploadImgsRule, useDictSelectRule, - useUserSelectRule, + useCurrencySelectRule, useEditorRule } diff --git a/src/components/FormCreate/src/config/useCurrencySelectRule.ts b/src/components/FormCreate/src/config/useCurrencySelectRule.ts new file mode 100644 index 00000000..7a7b2031 --- /dev/null +++ b/src/components/FormCreate/src/config/useCurrencySelectRule.ts @@ -0,0 +1,36 @@ +import { generateUUID } from '@/utils' +import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' +import selectRule from '@/components/FormCreate/src/config/selectRule' + +export const useCurrencySelectRule = () => { + const label = '通用选择器' + const name = 'CurrencySelect' + return { + icon: 'icon-select', + label, + name, + rule() { + return { + type: name, + field: generateUUID(), + title: label, + info: '下面以获得系统用户下拉数据为例,您可以自行按需更改', + $required: false + } + }, + props(_, { t }) { + return localeProps(t, name + '.props', [ + makeRequiredRule(), + { + type: 'input', + field: 'restful', + title: 'restful api 接口', + value: '/system/user/simple-list' + }, + { type: 'input', field: 'labelField', title: 'label 属性', value: 'nickname' }, + { type: 'input', field: 'valueField', title: 'value 属性', value: 'id' }, + ...selectRule + ]) + } + } +} diff --git a/src/components/FormCreate/src/config/useUserSelectRule.ts b/src/components/FormCreate/src/config/useUserSelectRule.ts deleted file mode 100644 index dd5e51c3..00000000 --- a/src/components/FormCreate/src/config/useUserSelectRule.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { generateUUID } from '@/utils' -import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' -import selectRule from '@/components/FormCreate/src/config/selectRule' - -export const useUserSelectRule = () => { - const label = '用户选择器' - const name = 'UserSelect' - return { - icon: 'icon-select', - label, - name, - rule() { - return { - type: name, - field: generateUUID(), - title: label, - info: '', - $required: false - } - }, - props(_, { t }) { - return localeProps(t, name + '.props', [makeRequiredRule(), ...selectRule]) - } - } -} diff --git a/src/components/FormCreate/src/useFormCreateDesigner.ts b/src/components/FormCreate/src/useFormCreateDesigner.ts index fe42b24f..81a595cc 100644 --- a/src/components/FormCreate/src/useFormCreateDesigner.ts +++ b/src/components/FormCreate/src/useFormCreateDesigner.ts @@ -1,10 +1,10 @@ import { + useCurrencySelectRule, useDictSelectRule, useEditorRule, useUploadFileRule, useUploadImgRule, - useUploadImgsRule, - useUserSelectRule + useUploadImgsRule } from './config' import { Ref } from 'vue' @@ -24,20 +24,22 @@ export const useFormCreateDesigner = (designer: Ref) => { const uploadImgRule = useUploadImgRule() const uploadImgsRule = useUploadImgsRule() const dictSelectRule = useDictSelectRule() - const userSelectRule = useUserSelectRule() + const currencySelectRule = useCurrencySelectRule() onMounted(() => { // 移除自带的上传组件规则,使用 uploadFileRule、uploadImgRule、uploadImgsRule 替代 designer.value?.removeMenuItem('upload') // 移除自带的富文本组件规则,使用 editorRule 替代 designer.value?.removeMenuItem('fc-editor') + // 移除自带的下拉选择器组件,使用 currencySelectRule 替代 + designer.value?.removeMenuItem('select') const components = [ editorRule, uploadFileRule, uploadImgRule, uploadImgsRule, dictSelectRule, - userSelectRule + currencySelectRule ] components.forEach((component) => { // 插入组件规则 diff --git a/src/plugins/formCreate/index.ts b/src/plugins/formCreate/index.ts index 5f8428e6..39be7946 100644 --- a/src/plugins/formCreate/index.ts +++ b/src/plugins/formCreate/index.ts @@ -20,7 +20,7 @@ import install from '@form-create/element-ui/auto-import' //======================= 自定义组件 ======================= import { UploadFile, UploadImg, UploadImgs } from '@/components/UploadFile' import { DictSelect } from '@/components/DictSelect' -import UserSelect from '@/views/system/user/components/UserSelect.vue' +import { CurrencySelect } from '@/components/FormCreate' import { Editor } from '@/components/Editor' const components = [ @@ -40,7 +40,7 @@ const components = [ UploadImgs, UploadFile, DictSelect, - UserSelect, + CurrencySelect, Editor ] diff --git a/src/views/system/user/components/UserSelect.vue b/src/views/system/user/components/UserSelect.vue deleted file mode 100644 index 4a94a745..00000000 --- a/src/views/system/user/components/UserSelect.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - - From 1f1ac1f2461b38190d3a730dc270c20182575a2a Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 30 Apr 2024 14:15:44 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E4=BD=BF=E7=94=A8=20tsx=20=E5=B0=81?= =?UTF-8?q?=E8=A3=85=20form-create=20=E9=80=9A=E7=94=A8=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FormCreate/index.ts | 4 +- .../FormCreate/src/CurrencySelect/index.vue | 53 ----------------- .../src/components/useCurrencySelect.tsx | 59 +++++++++++++++++++ src/components/FormCreate/src/config/index.ts | 6 +- .../src/config/useCurrencySelectRule.ts | 3 +- .../src/config/useDeptSelectRule.ts | 26 ++++++++ .../src/config/useUserSelectRule.ts | 26 ++++++++ src/components/FormCreate/src/type/index.ts | 41 +++++++++++++ .../FormCreate/src/useFormCreateDesigner.ts | 40 ++++++++++++- src/plugins/formCreate/index.ts | 18 +++++- src/views/infra/build/index.vue | 6 +- 11 files changed, 217 insertions(+), 65 deletions(-) delete mode 100644 src/components/FormCreate/src/CurrencySelect/index.vue create mode 100644 src/components/FormCreate/src/components/useCurrencySelect.tsx create mode 100644 src/components/FormCreate/src/config/useDeptSelectRule.ts create mode 100644 src/components/FormCreate/src/config/useUserSelectRule.ts create mode 100644 src/components/FormCreate/src/type/index.ts diff --git a/src/components/FormCreate/index.ts b/src/components/FormCreate/index.ts index 66fc7e6f..9da34889 100644 --- a/src/components/FormCreate/index.ts +++ b/src/components/FormCreate/index.ts @@ -1,4 +1,4 @@ import { useFormCreateDesigner } from './src/useFormCreateDesigner' -import CurrencySelect from './src/CurrencySelect/index.vue' +import { useCurrencySelect } from './src/components/useCurrencySelect' -export { useFormCreateDesigner, CurrencySelect } +export { useFormCreateDesigner, useCurrencySelect } diff --git a/src/components/FormCreate/src/CurrencySelect/index.vue b/src/components/FormCreate/src/CurrencySelect/index.vue deleted file mode 100644 index 3591a935..00000000 --- a/src/components/FormCreate/src/CurrencySelect/index.vue +++ /dev/null @@ -1,53 +0,0 @@ - - - diff --git a/src/components/FormCreate/src/components/useCurrencySelect.tsx b/src/components/FormCreate/src/components/useCurrencySelect.tsx new file mode 100644 index 00000000..ae9636a3 --- /dev/null +++ b/src/components/FormCreate/src/components/useCurrencySelect.tsx @@ -0,0 +1,59 @@ +import request from '@/config/axios' +import { isEmpty } from '@/utils/is' +import { CurrencySelectProps } from '@/components/FormCreate/src/type' + +export const useCurrencySelect = (option: CurrencySelectProps) => { + return defineComponent({ + name: option.name, + props: { + // 字典类型 + labelField: { + type: String, + default: () => option.labelField ?? '' + }, + // 字典值类型 + valueField: { + type: String, + default: () => option.valueField ?? '' + }, + // api 接口 + restful: { + type: String, + default: () => option.restful ?? '' + } + }, + setup(props) { + const attrs = useAttrs() + const options = ref([]) // 下拉数据 + const getOptions = async () => { + options.value = [] + if (isEmpty(props.restful)) { + return + } + // TODO 只支持 GET 查询,复杂下拉构建条件请使用业务表单 + const data = await request.get({ url: props.restful }) + if (Array.isArray(data)) { + options.value = data.map((item: any) => ({ + label: item[props.labelField], + value: item[props.valueField] + })) + return + } + console.log(`接口[${props.restful}] 返回结果不是一个数组`) + } + + onMounted(async () => { + await getOptions() + }) + return () => ( + <> + + {options.value.map((item, index) => ( + + ))} + + + ) + } + }) +} diff --git a/src/components/FormCreate/src/config/index.ts b/src/components/FormCreate/src/config/index.ts index 078bc803..c34d831a 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 { useCurrencySelectRule } from './useCurrencySelectRule' import { useEditorRule } from './useEditorRule' +import { useUserSelectRule } from './useUserSelectRule' +import { useDeptSelectRule } from './useDeptSelectRule' export { useUploadFileRule, @@ -11,5 +13,7 @@ export { useUploadImgsRule, useDictSelectRule, useCurrencySelectRule, - useEditorRule + useEditorRule, + useUserSelectRule, + useDeptSelectRule } diff --git a/src/components/FormCreate/src/config/useCurrencySelectRule.ts b/src/components/FormCreate/src/config/useCurrencySelectRule.ts index 7a7b2031..3ac65a66 100644 --- a/src/components/FormCreate/src/config/useCurrencySelectRule.ts +++ b/src/components/FormCreate/src/config/useCurrencySelectRule.ts @@ -1,8 +1,9 @@ import { generateUUID } from '@/utils' import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' import selectRule from '@/components/FormCreate/src/config/selectRule' +import { DragRule } from '@/components/FormCreate/src/type' -export const useCurrencySelectRule = () => { +export const useCurrencySelectRule = (): DragRule => { const label = '通用选择器' const name = 'CurrencySelect' return { diff --git a/src/components/FormCreate/src/config/useDeptSelectRule.ts b/src/components/FormCreate/src/config/useDeptSelectRule.ts new file mode 100644 index 00000000..e46165c1 --- /dev/null +++ b/src/components/FormCreate/src/config/useDeptSelectRule.ts @@ -0,0 +1,26 @@ +import { generateUUID } from '@/utils' +import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' +import selectRule from '@/components/FormCreate/src/config/selectRule' +import { DragRule } from '@/components/FormCreate/src/type' + +export const useDeptSelectRule = (): DragRule => { + const label = '部门选择器' + const name = 'DeptSelect' + return { + icon: 'icon-select', + label, + name, + rule() { + return { + type: name, + field: generateUUID(), + title: label, + info: '', + $required: false + } + }, + props(_, { t }) { + return localeProps(t, name + '.props', [makeRequiredRule(), ...selectRule]) + } + } +} diff --git a/src/components/FormCreate/src/config/useUserSelectRule.ts b/src/components/FormCreate/src/config/useUserSelectRule.ts new file mode 100644 index 00000000..ff5bc869 --- /dev/null +++ b/src/components/FormCreate/src/config/useUserSelectRule.ts @@ -0,0 +1,26 @@ +import { generateUUID } from '@/utils' +import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' +import selectRule from '@/components/FormCreate/src/config/selectRule' +import { DragRule } from '@/components/FormCreate/src/type' + +export const useUserSelectRule = (): DragRule => { + const label = '用户选择器' + const name = 'UserSelect' + return { + icon: 'icon-select', + label, + name, + rule() { + return { + type: name, + field: generateUUID(), + title: label, + info: '', + $required: false + } + }, + props(_, { t }) { + return localeProps(t, name + '.props', [makeRequiredRule(), ...selectRule]) + } + } +} diff --git a/src/components/FormCreate/src/type/index.ts b/src/components/FormCreate/src/type/index.ts new file mode 100644 index 00000000..38205073 --- /dev/null +++ b/src/components/FormCreate/src/type/index.ts @@ -0,0 +1,41 @@ +import { Rule } from '@form-create/element-ui' //左侧拖拽按钮 + +//左侧拖拽按钮 +export interface MenuItem { + label: string + name: string + icon: string +} + +//左侧拖拽按钮分类 +export interface Menu { + title: string + name: string + list: MenuItem[] +} + +export interface MenuList extends Array {} + +//拖拽组件的规则 +export interface DragRule { + icon: string + name: string + label: string + children?: string + inside?: true + drag?: true | String + dragBtn?: false + mask?: false + + rule(): Rule + + props(v: any, v1: any): Rule[] +} + +// 通用下拉组件 Props 类型 +export interface CurrencySelectProps { + name: string // 组件名称 + labelField?: string // 字典类型 + valueField?: string // 字典值类型 + restful?: string // api 接口 +} diff --git a/src/components/FormCreate/src/useFormCreateDesigner.ts b/src/components/FormCreate/src/useFormCreateDesigner.ts index 81a595cc..1601b1c4 100644 --- a/src/components/FormCreate/src/useFormCreateDesigner.ts +++ b/src/components/FormCreate/src/useFormCreateDesigner.ts @@ -1,12 +1,15 @@ import { useCurrencySelectRule, + useDeptSelectRule, useDictSelectRule, useEditorRule, useUploadFileRule, useUploadImgRule, - useUploadImgsRule + useUploadImgsRule, + useUserSelectRule } from './config' import { Ref } from 'vue' +import { Menu } from '@/components/FormCreate/src/type' /** * 表单设计器增强 hook @@ -26,7 +29,10 @@ export const useFormCreateDesigner = (designer: Ref) => { const dictSelectRule = useDictSelectRule() const currencySelectRule = useCurrencySelectRule() - onMounted(() => { + /** + * 构建表单组件 + */ + const buildFormComponents = () => { // 移除自带的上传组件规则,使用 uploadFileRule、uploadImgRule、uploadImgsRule 替代 designer.value?.removeMenuItem('upload') // 移除自带的富文本组件规则,使用 editorRule 替代 @@ -51,5 +57,35 @@ export const useFormCreateDesigner = (designer: Ref) => { label: component.label }) }) + } + + const userSelectRule = useUserSelectRule() + const deptSelectRule = useDeptSelectRule() + /** + * 构建系统字段菜单 + */ + const buildSystemMenu = () => { + const components = [userSelectRule, deptSelectRule] + const menu: Menu = { + name: 'system', + title: '系统字段', + list: components.map((component) => { + // 插入组件规则 + designer.value?.addComponent(component) + // 插入拖拽按钮到 `system` 分类下 + return { + icon: component.icon, + name: component.name, + label: component.label + } + }) + } + designer.value?.addMenu(menu) + } + + onMounted(async () => { + await nextTick() + buildFormComponents() + buildSystemMenu() }) } diff --git a/src/plugins/formCreate/index.ts b/src/plugins/formCreate/index.ts index 39be7946..da74a7bf 100644 --- a/src/plugins/formCreate/index.ts +++ b/src/plugins/formCreate/index.ts @@ -20,9 +20,22 @@ import install from '@form-create/element-ui/auto-import' //======================= 自定义组件 ======================= import { UploadFile, UploadImg, UploadImgs } from '@/components/UploadFile' import { DictSelect } from '@/components/DictSelect' -import { CurrencySelect } from '@/components/FormCreate' +import { useCurrencySelect } from '@/components/FormCreate' import { Editor } from '@/components/Editor' +const UserSelect = useCurrencySelect({ + name: 'UserSelect', + labelField: 'nickname', + valueField: 'id', + restful: '/system/user/simple-list' +}) +const DeptSelect = useCurrencySelect({ + name: 'DeptSelect', + labelField: 'name', + valueField: 'id', + restful: '/system/dept/simple-list' +}) + const components = [ ElAside, ElPopconfirm, @@ -40,7 +53,8 @@ const components = [ UploadImgs, UploadFile, DictSelect, - CurrencySelect, + UserSelect, + DeptSelect, Editor ] diff --git a/src/views/infra/build/index.vue b/src/views/infra/build/index.vue index 9cee56f0..571acffe 100644 --- a/src/views/infra/build/index.vue +++ b/src/views/infra/build/index.vue @@ -8,11 +8,9 @@ 生成组件 - - - - + + From c1c21d826d72ffa75223378bef68d99419d3b167 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 1 May 2024 17:29:13 +0800 Subject: [PATCH 3/7] =?UTF-8?q?form-create:=20=E5=B0=81=E8=A3=85=E9=80=9A?= =?UTF-8?q?=E7=94=A8=E9=80=89=E6=8B=A9=E5=99=A8=20hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FormCreate/src/config/index.ts | 8 +--- .../src/config/useCurrencySelectRule.ts | 37 -------------- .../src/config/useDictSelectRule.ts | 3 ++ ...{useDeptSelectRule.ts => useSelectRule.ts} | 17 +++++-- .../src/config/useUserSelectRule.ts | 26 ---------- src/components/FormCreate/src/type/index.ts | 7 +++ .../FormCreate/src/useFormCreateDesigner.ts | 48 +++++++++++++++---- src/plugins/formCreate/index.ts | 5 +- 8 files changed, 66 insertions(+), 85 deletions(-) delete mode 100644 src/components/FormCreate/src/config/useCurrencySelectRule.ts rename src/components/FormCreate/src/config/{useDeptSelectRule.ts => useSelectRule.ts} (59%) delete mode 100644 src/components/FormCreate/src/config/useUserSelectRule.ts diff --git a/src/components/FormCreate/src/config/index.ts b/src/components/FormCreate/src/config/index.ts index c34d831a..b1e2ddea 100644 --- a/src/components/FormCreate/src/config/index.ts +++ b/src/components/FormCreate/src/config/index.ts @@ -2,18 +2,14 @@ import { useUploadFileRule } from './useUploadFileRule' import { useUploadImgRule } from './useUploadImgRule' import { useUploadImgsRule } from './useUploadImgsRule' import { useDictSelectRule } from './useDictSelectRule' -import { useCurrencySelectRule } from './useCurrencySelectRule' import { useEditorRule } from './useEditorRule' -import { useUserSelectRule } from './useUserSelectRule' -import { useDeptSelectRule } from './useDeptSelectRule' +import { useSelectRule } from './useSelectRule' export { useUploadFileRule, useUploadImgRule, useUploadImgsRule, useDictSelectRule, - useCurrencySelectRule, useEditorRule, - useUserSelectRule, - useDeptSelectRule + useSelectRule } diff --git a/src/components/FormCreate/src/config/useCurrencySelectRule.ts b/src/components/FormCreate/src/config/useCurrencySelectRule.ts deleted file mode 100644 index 3ac65a66..00000000 --- a/src/components/FormCreate/src/config/useCurrencySelectRule.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { generateUUID } from '@/utils' -import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' -import selectRule from '@/components/FormCreate/src/config/selectRule' -import { DragRule } from '@/components/FormCreate/src/type' - -export const useCurrencySelectRule = (): DragRule => { - const label = '通用选择器' - const name = 'CurrencySelect' - return { - icon: 'icon-select', - label, - name, - rule() { - return { - type: name, - field: generateUUID(), - title: label, - info: '下面以获得系统用户下拉数据为例,您可以自行按需更改', - $required: false - } - }, - props(_, { t }) { - return localeProps(t, name + '.props', [ - makeRequiredRule(), - { - type: 'input', - field: 'restful', - title: 'restful api 接口', - value: '/system/user/simple-list' - }, - { type: 'input', field: 'labelField', title: 'label 属性', value: 'nickname' }, - { type: 'input', field: 'valueField', title: 'value 属性', value: 'id' }, - ...selectRule - ]) - } - } -} diff --git a/src/components/FormCreate/src/config/useDictSelectRule.ts b/src/components/FormCreate/src/config/useDictSelectRule.ts index 7a1afc60..3350cb8e 100644 --- a/src/components/FormCreate/src/config/useDictSelectRule.ts +++ b/src/components/FormCreate/src/config/useDictSelectRule.ts @@ -3,6 +3,9 @@ import * as DictDataApi from '@/api/system/dict/dict.type' import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' import selectRule from '@/components/FormCreate/src/config/selectRule' +/** + * 字典选择器规则,如果规则使用到动态数据则需要单独配置不能使用 useSelectRule + */ export const useDictSelectRule = () => { const label = '字典选择器' const name = 'DictSelect' diff --git a/src/components/FormCreate/src/config/useDeptSelectRule.ts b/src/components/FormCreate/src/config/useSelectRule.ts similarity index 59% rename from src/components/FormCreate/src/config/useDeptSelectRule.ts rename to src/components/FormCreate/src/config/useSelectRule.ts index e46165c1..fd23ac3a 100644 --- a/src/components/FormCreate/src/config/useDeptSelectRule.ts +++ b/src/components/FormCreate/src/config/useSelectRule.ts @@ -1,11 +1,15 @@ import { generateUUID } from '@/utils' import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' import selectRule from '@/components/FormCreate/src/config/selectRule' -import { DragRule } from '@/components/FormCreate/src/type' +import { SelectRuleOption } from '@/components/FormCreate/src/type' -export const useDeptSelectRule = (): DragRule => { - const label = '部门选择器' - const name = 'DeptSelect' +/** + * 通用选择器规则 hook + * @param option 规则配置 + */ +export const useSelectRule = (option: SelectRuleOption) => { + const label = option.label + const name = option.name return { icon: 'icon-select', label, @@ -20,7 +24,10 @@ export const useDeptSelectRule = (): DragRule => { } }, props(_, { t }) { - return localeProps(t, name + '.props', [makeRequiredRule(), ...selectRule]) + if (!option.props) { + option.props = [] + } + return localeProps(t, name + '.props', [makeRequiredRule(), ...option.props, ...selectRule]) } } } diff --git a/src/components/FormCreate/src/config/useUserSelectRule.ts b/src/components/FormCreate/src/config/useUserSelectRule.ts deleted file mode 100644 index ff5bc869..00000000 --- a/src/components/FormCreate/src/config/useUserSelectRule.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { generateUUID } from '@/utils' -import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' -import selectRule from '@/components/FormCreate/src/config/selectRule' -import { DragRule } from '@/components/FormCreate/src/type' - -export const useUserSelectRule = (): DragRule => { - const label = '用户选择器' - const name = 'UserSelect' - return { - icon: 'icon-select', - label, - name, - rule() { - return { - type: name, - field: generateUUID(), - title: label, - info: '', - $required: false - } - }, - props(_, { t }) { - return localeProps(t, name + '.props', [makeRequiredRule(), ...selectRule]) - } - } -} diff --git a/src/components/FormCreate/src/type/index.ts b/src/components/FormCreate/src/type/index.ts index 38205073..8500d776 100644 --- a/src/components/FormCreate/src/type/index.ts +++ b/src/components/FormCreate/src/type/index.ts @@ -39,3 +39,10 @@ export interface CurrencySelectProps { valueField?: string // 字典值类型 restful?: string // api 接口 } + +// 选择组件规则配置类型 +export interface SelectRuleOption { + label: string // label 名称 + name: string // 组件名称 + props?: Rule[] // 组件规则 +} diff --git a/src/components/FormCreate/src/useFormCreateDesigner.ts b/src/components/FormCreate/src/useFormCreateDesigner.ts index 1601b1c4..7c4e48b8 100644 --- a/src/components/FormCreate/src/useFormCreateDesigner.ts +++ b/src/components/FormCreate/src/useFormCreateDesigner.ts @@ -1,12 +1,10 @@ import { - useCurrencySelectRule, - useDeptSelectRule, useDictSelectRule, useEditorRule, + useSelectRule, useUploadFileRule, useUploadImgRule, - useUploadImgsRule, - useUserSelectRule + useUploadImgsRule } from './config' import { Ref } from 'vue' import { Menu } from '@/components/FormCreate/src/type' @@ -18,16 +16,46 @@ import { Menu } from '@/components/FormCreate/src/type' * - 单图上传 * - 多图上传 * - 字典选择器 - * - 系统用户选择器 + * - 用户选择器 + * - 部门选择器 * - 富文本 */ -export const useFormCreateDesigner = (designer: Ref) => { +export const useFormCreateDesigner = async (designer: Ref) => { const editorRule = useEditorRule() const uploadFileRule = useUploadFileRule() const uploadImgRule = useUploadImgRule() const uploadImgsRule = useUploadImgsRule() const dictSelectRule = useDictSelectRule() - const currencySelectRule = useCurrencySelectRule() + const restfulSelectRule = useSelectRule({ + name: 'RestfulSelect', + label: '接口选择器', + props: [ + { + type: 'input', + field: 'restful', + title: 'restful api 接口', + props: { + placeholder: '/system/user/simple-list' + } + }, + { + type: 'input', + field: 'labelField', + title: 'label 属性', + props: { + placeholder: 'nickname' + } + }, + { + type: 'input', + field: 'valueField', + title: 'value 属性', + props: { + placeholder: 'id' + } + } + ] + }) /** * 构建表单组件 @@ -45,7 +73,7 @@ export const useFormCreateDesigner = (designer: Ref) => { uploadImgRule, uploadImgsRule, dictSelectRule, - currencySelectRule + restfulSelectRule ] components.forEach((component) => { // 插入组件规则 @@ -59,8 +87,8 @@ export const useFormCreateDesigner = (designer: Ref) => { }) } - const userSelectRule = useUserSelectRule() - const deptSelectRule = useDeptSelectRule() + const userSelectRule = useSelectRule({ name: 'UserSelect', label: '用户选择器' }) + const deptSelectRule = useSelectRule({ name: 'DeptSelect', label: '部门选择器' }) /** * 构建系统字段菜单 */ diff --git a/src/plugins/formCreate/index.ts b/src/plugins/formCreate/index.ts index da74a7bf..9fc716c3 100644 --- a/src/plugins/formCreate/index.ts +++ b/src/plugins/formCreate/index.ts @@ -35,7 +35,9 @@ const DeptSelect = useCurrencySelect({ valueField: 'id', restful: '/system/dept/simple-list' }) - +const RestfulSelect = useCurrencySelect({ + name: 'RestfulSelect' +}) const components = [ ElAside, ElPopconfirm, @@ -55,6 +57,7 @@ const components = [ DictSelect, UserSelect, DeptSelect, + RestfulSelect, Editor ] From b4d85b782e0c8f3a79202cfba26712e78bdca075 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 1 May 2024 19:53:35 +0800 Subject: [PATCH 4/7] =?UTF-8?q?form-create:=20=E5=B0=81=E8=A3=85=E9=80=9A?= =?UTF-8?q?=E7=94=A8=E9=80=89=E6=8B=A9=E5=99=A8=20hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/DictSelect/index.ts | 3 - src/components/DictSelect/src/DictSelect.vue | 46 -------- .../src/components/useCurrencySelect.tsx | 103 ++++++++++++++++-- .../FormCreate/src/config/selectRule.ts | 11 ++ .../src/config/useDictSelectRule.ts | 2 +- src/components/FormCreate/src/type/index.ts | 5 +- .../FormCreate/src/useFormCreateDesigner.ts | 2 + src/plugins/formCreate/index.ts | 5 +- 8 files changed, 114 insertions(+), 63 deletions(-) delete mode 100644 src/components/DictSelect/index.ts delete mode 100644 src/components/DictSelect/src/DictSelect.vue diff --git a/src/components/DictSelect/index.ts b/src/components/DictSelect/index.ts deleted file mode 100644 index 164035fd..00000000 --- a/src/components/DictSelect/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import DictSelect from './src/DictSelect.vue' - -export { DictSelect } diff --git a/src/components/DictSelect/src/DictSelect.vue b/src/components/DictSelect/src/DictSelect.vue deleted file mode 100644 index 2d59e23c..00000000 --- a/src/components/DictSelect/src/DictSelect.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - diff --git a/src/components/FormCreate/src/components/useCurrencySelect.tsx b/src/components/FormCreate/src/components/useCurrencySelect.tsx index ae9636a3..8da0b696 100644 --- a/src/components/FormCreate/src/components/useCurrencySelect.tsx +++ b/src/components/FormCreate/src/components/useCurrencySelect.tsx @@ -1,25 +1,41 @@ import request from '@/config/axios' import { isEmpty } from '@/utils/is' import { CurrencySelectProps } from '@/components/FormCreate/src/type' +import { getBoolDictOptions, getIntDictOptions, getStrDictOptions } from '@/utils/dict' export const useCurrencySelect = (option: CurrencySelectProps) => { return defineComponent({ name: option.name, props: { - // 字典类型 + // 选项标签 labelField: { type: String, - default: () => option.labelField ?? '' + default: () => option.labelField ?? 'label' }, - // 字典值类型 + // 选项的值 valueField: { type: String, - default: () => option.valueField ?? '' + default: () => option.valueField ?? 'value' }, // api 接口 restful: { type: String, default: () => option.restful ?? '' + }, + // 字典类型 + dictType: { + type: String, + default: '' + }, + // 字典值类型 'str' | 'int' | 'bool' + dictValueType: { + type: String, + default: 'str' + }, + // 选择器类型,下拉框 select、多选框 checkbox、单选框 radio + selectType: { + type: String, + default: 'select' } }, setup(props) { @@ -27,6 +43,12 @@ export const useCurrencySelect = (option: CurrencySelectProps) => { const options = ref([]) // 下拉数据 const getOptions = async () => { options.value = [] + // 字典选择器 + if (option.isDict) { + options.value = getDictOptions() + return + } + // 接口选择器 if (isEmpty(props.restful)) { return } @@ -41,17 +63,78 @@ export const useCurrencySelect = (option: CurrencySelectProps) => { } console.log(`接口[${props.restful}] 返回结果不是一个数组`) } - + // 获得字典配置 + const getDictOptions = () => { + switch (props.dictValueType) { + case 'str': + return getStrDictOptions(props.dictType) + case 'int': + return getIntDictOptions(props.dictType) + case 'bool': + return getBoolDictOptions(props.dictType) + default: + return [] + } + } onMounted(async () => { await getOptions() }) + const buildSelect = () => { + return ( + <> + + {options.value.map((item, index) => ( + + ))} + + + ) + } + const buildCheckbox = () => { + if (isEmpty(options.value)) { + options.value = [ + { label: '选项1', value: '选项1' }, + { label: '选项2', value: '选项2' } + ] + } + return ( + <> + + {options.value.map((item, index) => ( + + ))} + + + ) + } + const buildRadio = () => { + if (isEmpty(options.value)) { + options.value = [ + { label: '选项1', value: '选项1' }, + { label: '选项2', value: '选项2' } + ] + } + return ( + <> + + {options.value.map((item, index) => ( + + {item.label} + + ))} + + + ) + } return () => ( <> - - {options.value.map((item, index) => ( - - ))} - + {props.selectType === 'select' + ? buildSelect() + : props.selectType === 'radio' + ? buildRadio() + : props.selectType === 'checkbox' + ? buildCheckbox() + : buildSelect()} ) } diff --git a/src/components/FormCreate/src/config/selectRule.ts b/src/components/FormCreate/src/config/selectRule.ts index 0974139e..3137aac7 100644 --- a/src/components/FormCreate/src/config/selectRule.ts +++ b/src/components/FormCreate/src/config/selectRule.ts @@ -1,4 +1,15 @@ const selectRule = [ + { + type: 'select', + field: 'selectType', + title: '选择器类型', + value: 'select', + options: [ + { label: '下拉框', value: 'select' }, + { label: '单选框', value: 'radio' }, + { label: '多选框', value: 'checkbox' } + ] + }, { type: 'switch', field: 'multiple', title: '是否多选' }, { type: 'switch', diff --git a/src/components/FormCreate/src/config/useDictSelectRule.ts b/src/components/FormCreate/src/config/useDictSelectRule.ts index 3350cb8e..d2a9c467 100644 --- a/src/components/FormCreate/src/config/useDictSelectRule.ts +++ b/src/components/FormCreate/src/config/useDictSelectRule.ts @@ -46,7 +46,7 @@ export const useDictSelectRule = () => { }, { type: 'select', - field: 'valueType', + field: 'dictValueType', title: '字典值类型', value: 'str', options: [ diff --git a/src/components/FormCreate/src/type/index.ts b/src/components/FormCreate/src/type/index.ts index 8500d776..ac248f11 100644 --- a/src/components/FormCreate/src/type/index.ts +++ b/src/components/FormCreate/src/type/index.ts @@ -35,9 +35,10 @@ export interface DragRule { // 通用下拉组件 Props 类型 export interface CurrencySelectProps { name: string // 组件名称 - labelField?: string // 字典类型 - valueField?: string // 字典值类型 + labelField?: string // 选项标签 + valueField?: string // 选项的值 restful?: string // api 接口 + isDict?: boolean // 是否字典选择器 } // 选择组件规则配置类型 diff --git a/src/components/FormCreate/src/useFormCreateDesigner.ts b/src/components/FormCreate/src/useFormCreateDesigner.ts index 7c4e48b8..69772bd5 100644 --- a/src/components/FormCreate/src/useFormCreateDesigner.ts +++ b/src/components/FormCreate/src/useFormCreateDesigner.ts @@ -67,6 +67,8 @@ export const useFormCreateDesigner = async (designer: Ref) => { designer.value?.removeMenuItem('fc-editor') // 移除自带的下拉选择器组件,使用 currencySelectRule 替代 designer.value?.removeMenuItem('select') + designer.value?.removeMenuItem('radio') + designer.value?.removeMenuItem('checkbox') const components = [ editorRule, uploadFileRule, diff --git a/src/plugins/formCreate/index.ts b/src/plugins/formCreate/index.ts index 9fc716c3..3a647e11 100644 --- a/src/plugins/formCreate/index.ts +++ b/src/plugins/formCreate/index.ts @@ -19,7 +19,6 @@ import formCreate from '@form-create/element-ui' import install from '@form-create/element-ui/auto-import' //======================= 自定义组件 ======================= import { UploadFile, UploadImg, UploadImgs } from '@/components/UploadFile' -import { DictSelect } from '@/components/DictSelect' import { useCurrencySelect } from '@/components/FormCreate' import { Editor } from '@/components/Editor' @@ -38,6 +37,10 @@ const DeptSelect = useCurrencySelect({ const RestfulSelect = useCurrencySelect({ name: 'RestfulSelect' }) +const DictSelect = useCurrencySelect({ + name: 'DictSelect', + isDict: true +}) const components = [ ElAside, ElPopconfirm, From c77526e8c5e5156a705d3f2f92ce9b01acafc678 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 1 May 2024 20:42:53 +0800 Subject: [PATCH 5/7] =?UTF-8?q?form-create:=20=E5=B0=81=E8=A3=85=E9=80=9A?= =?UTF-8?q?=E7=94=A8=E9=80=89=E6=8B=A9=E5=99=A8=20hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/useCurrencySelect.tsx | 46 ++++++------- .../FormCreate/src/useFormCreateDesigner.ts | 65 +++++++++---------- 2 files changed, 52 insertions(+), 59 deletions(-) diff --git a/src/components/FormCreate/src/components/useCurrencySelect.tsx b/src/components/FormCreate/src/components/useCurrencySelect.tsx index 8da0b696..82d708c6 100644 --- a/src/components/FormCreate/src/components/useCurrencySelect.tsx +++ b/src/components/FormCreate/src/components/useCurrencySelect.tsx @@ -37,6 +37,11 @@ export const useCurrencySelect = (option: CurrencySelectProps) => { type: String, default: 'select' } + // // 是否多选 + // multiple: { + // type: Boolean, + // default: false + // } }, setup(props) { const attrs = useAttrs() @@ -79,15 +84,14 @@ export const useCurrencySelect = (option: CurrencySelectProps) => { onMounted(async () => { await getOptions() }) + // TODO puhui999: 单下拉多选的时候页面会卡住报错,下次解决 const buildSelect = () => { return ( - <> - - {options.value.map((item, index) => ( - - ))} - - + + {options.value.map((item, index) => ( + + ))} + ) } const buildCheckbox = () => { @@ -98,13 +102,11 @@ export const useCurrencySelect = (option: CurrencySelectProps) => { ] } return ( - <> - - {options.value.map((item, index) => ( - - ))} - - + + {options.value.map((item, index) => ( + + ))} + ) } const buildRadio = () => { @@ -115,15 +117,13 @@ export const useCurrencySelect = (option: CurrencySelectProps) => { ] } return ( - <> - - {options.value.map((item, index) => ( - - {item.label} - - ))} - - + + {options.value.map((item, index) => ( + + {item.label} + + ))} + ) } return () => ( diff --git a/src/components/FormCreate/src/useFormCreateDesigner.ts b/src/components/FormCreate/src/useFormCreateDesigner.ts index 69772bd5..3875b72c 100644 --- a/src/components/FormCreate/src/useFormCreateDesigner.ts +++ b/src/components/FormCreate/src/useFormCreateDesigner.ts @@ -25,6 +25,30 @@ export const useFormCreateDesigner = async (designer: Ref) => { const uploadFileRule = useUploadFileRule() const uploadImgRule = useUploadImgRule() const uploadImgsRule = useUploadImgsRule() + + /** + * 构建表单组件 + */ + const buildFormComponents = () => { + // 移除自带的上传组件规则,使用 uploadFileRule、uploadImgRule、uploadImgsRule 替代 + designer.value?.removeMenuItem('upload') + // 移除自带的富文本组件规则,使用 editorRule 替代 + designer.value?.removeMenuItem('fc-editor') + const components = [editorRule, uploadFileRule, uploadImgRule, uploadImgsRule] + components.forEach((component) => { + // 插入组件规则 + designer.value?.addComponent(component) + // 插入拖拽按钮到 `main` 分类下 + designer.value?.appendMenuItem('main', { + icon: component.icon, + name: component.name, + label: component.label + }) + }) + } + + const userSelectRule = useSelectRule({ name: 'UserSelect', label: '用户选择器' }) + const deptSelectRule = useSelectRule({ name: 'DeptSelect', label: '部门选择器' }) const dictSelectRule = useDictSelectRule() const restfulSelectRule = useSelectRule({ name: 'RestfulSelect', @@ -56,46 +80,15 @@ export const useFormCreateDesigner = async (designer: Ref) => { } ] }) - - /** - * 构建表单组件 - */ - const buildFormComponents = () => { - // 移除自带的上传组件规则,使用 uploadFileRule、uploadImgRule、uploadImgsRule 替代 - designer.value?.removeMenuItem('upload') - // 移除自带的富文本组件规则,使用 editorRule 替代 - designer.value?.removeMenuItem('fc-editor') - // 移除自带的下拉选择器组件,使用 currencySelectRule 替代 - designer.value?.removeMenuItem('select') - designer.value?.removeMenuItem('radio') - designer.value?.removeMenuItem('checkbox') - const components = [ - editorRule, - uploadFileRule, - uploadImgRule, - uploadImgsRule, - dictSelectRule, - restfulSelectRule - ] - components.forEach((component) => { - // 插入组件规则 - designer.value?.addComponent(component) - // 插入拖拽按钮到 `main` 分类下 - designer.value?.appendMenuItem('main', { - icon: component.icon, - name: component.name, - label: component.label - }) - }) - } - - const userSelectRule = useSelectRule({ name: 'UserSelect', label: '用户选择器' }) - const deptSelectRule = useSelectRule({ name: 'DeptSelect', label: '部门选择器' }) /** * 构建系统字段菜单 */ const buildSystemMenu = () => { - const components = [userSelectRule, deptSelectRule] + // 移除自带的下拉选择器组件,使用 currencySelectRule 替代 + designer.value?.removeMenuItem('select') + designer.value?.removeMenuItem('radio') + designer.value?.removeMenuItem('checkbox') + const components = [userSelectRule, deptSelectRule, dictSelectRule, restfulSelectRule] const menu: Menu = { name: 'system', title: '系统字段', From 7c158af3cc572c7b0b40bee178595660de215ae2 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 6 May 2024 01:24:25 +0800 Subject: [PATCH 6/7] =?UTF-8?q?form-create:=20=E5=AD=97=E5=85=B8=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E5=99=A8=E5=88=86=E7=A6=BB=EF=BC=8C=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E5=B0=81=E8=A3=85=20api=20=E9=80=89=E6=8B=A9=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FormCreate/index.ts | 4 +- .../FormCreate/src/components/DictSelect.vue | 59 ++++++++++++++ ...useCurrencySelect.tsx => useApiSelect.tsx} | 81 ++++++++++--------- .../FormCreate/src/config/selectRule.ts | 67 ++++++++++++++- .../src/config/useDictSelectRule.ts | 2 +- .../FormCreate/src/config/useSelectRule.ts | 2 +- src/components/FormCreate/src/type/index.ts | 12 +-- .../FormCreate/src/useFormCreateDesigner.ts | 35 ++------ src/plugins/formCreate/index.ts | 22 +++-- src/utils/index.ts | 14 ++++ 10 files changed, 206 insertions(+), 92 deletions(-) create mode 100644 src/components/FormCreate/src/components/DictSelect.vue rename src/components/FormCreate/src/components/{useCurrencySelect.tsx => useApiSelect.tsx} (67%) diff --git a/src/components/FormCreate/index.ts b/src/components/FormCreate/index.ts index 9da34889..9d32778b 100644 --- a/src/components/FormCreate/index.ts +++ b/src/components/FormCreate/index.ts @@ -1,4 +1,4 @@ import { useFormCreateDesigner } from './src/useFormCreateDesigner' -import { useCurrencySelect } from './src/components/useCurrencySelect' +import { useApiSelect } from './src/components/useApiSelect' -export { useFormCreateDesigner, useCurrencySelect } +export { useFormCreateDesigner, useApiSelect } diff --git a/src/components/FormCreate/src/components/DictSelect.vue b/src/components/FormCreate/src/components/DictSelect.vue new file mode 100644 index 00000000..204746d1 --- /dev/null +++ b/src/components/FormCreate/src/components/DictSelect.vue @@ -0,0 +1,59 @@ + + + + diff --git a/src/components/FormCreate/src/components/useCurrencySelect.tsx b/src/components/FormCreate/src/components/useApiSelect.tsx similarity index 67% rename from src/components/FormCreate/src/components/useCurrencySelect.tsx rename to src/components/FormCreate/src/components/useApiSelect.tsx index 82d708c6..54c0a33b 100644 --- a/src/components/FormCreate/src/components/useCurrencySelect.tsx +++ b/src/components/FormCreate/src/components/useApiSelect.tsx @@ -1,9 +1,9 @@ import request from '@/config/axios' import { isEmpty } from '@/utils/is' -import { CurrencySelectProps } from '@/components/FormCreate/src/type' -import { getBoolDictOptions, getIntDictOptions, getStrDictOptions } from '@/utils/dict' +import { ApiSelectProps } from '@/components/FormCreate/src/type' +import { jsonParse } from '@/utils' -export const useCurrencySelect = (option: CurrencySelectProps) => { +export const useApiSelect = (option: ApiSelectProps) => { return defineComponent({ name: option.name, props: { @@ -18,47 +18,50 @@ export const useCurrencySelect = (option: CurrencySelectProps) => { default: () => option.valueField ?? 'value' }, // api 接口 - restful: { + url: { type: String, - default: () => option.restful ?? '' + default: () => option.url ?? '' }, - // 字典类型 - dictType: { + // 请求类型 + method: { + type: String, + default: 'GET' + }, + // 请求参数 + data: { type: String, default: '' }, - // 字典值类型 'str' | 'int' | 'bool' - dictValueType: { - type: String, - default: 'str' - }, // 选择器类型,下拉框 select、多选框 checkbox、单选框 radio selectType: { type: String, default: 'select' + }, + // 是否多选 + multiple: { + type: Boolean, + default: false } - // // 是否多选 - // multiple: { - // type: Boolean, - // default: false - // } }, setup(props) { const attrs = useAttrs() const options = ref([]) // 下拉数据 const getOptions = async () => { options.value = [] - // 字典选择器 - if (option.isDict) { - options.value = getDictOptions() - return - } // 接口选择器 - if (isEmpty(props.restful)) { + if (isEmpty(props.url)) { return } - // TODO 只支持 GET 查询,复杂下拉构建条件请使用业务表单 - const data = await request.get({ url: props.restful }) + let data = [] + switch (props.method) { + case 'GET': + data = await request.get({ url: props.url }) + break + case 'POST': + data = await request.post({ url: props.url, data: jsonParse(props.data) }) + break + } + if (Array.isArray(data)) { options.value = data.map((item: any) => ({ label: item[props.labelField], @@ -66,26 +69,24 @@ export const useCurrencySelect = (option: CurrencySelectProps) => { })) return } - console.log(`接口[${props.restful}] 返回结果不是一个数组`) - } - // 获得字典配置 - const getDictOptions = () => { - switch (props.dictValueType) { - case 'str': - return getStrDictOptions(props.dictType) - case 'int': - return getIntDictOptions(props.dictType) - case 'bool': - return getBoolDictOptions(props.dictType) - default: - return [] - } + console.log(`接口[${props.url}] 返回结果不是一个数组`) } + onMounted(async () => { await getOptions() }) - // TODO puhui999: 单下拉多选的时候页面会卡住报错,下次解决 + const buildSelect = () => { + if (props.multiple) { + // fix:多写此步是为了解决 multiple 属性问题 + return ( + + {options.value.map((item, index) => ( + + ))} + + ) + } return ( {options.value.map((item, index) => ( diff --git a/src/components/FormCreate/src/config/selectRule.ts b/src/components/FormCreate/src/config/selectRule.ts index 3137aac7..281d3739 100644 --- a/src/components/FormCreate/src/config/selectRule.ts +++ b/src/components/FormCreate/src/config/selectRule.ts @@ -8,6 +8,15 @@ const selectRule = [ { label: '下拉框', value: 'select' }, { label: '单选框', value: 'radio' }, { label: '多选框', value: 'checkbox' } + ], + // 参考 https://www.form-create.com/v3/guide/control 组件联动,单选框和多选框不需要多选属性 + control: [ + { + value: 'select', + condition: '=', + method: 'hidden', + rule: ['multiple'] + } ] }, { type: 'switch', field: 'multiple', title: '是否多选' }, @@ -79,4 +88,60 @@ const selectRule = [ } ] -export default selectRule +const apiSelectRule = [ + { + type: 'input', + field: 'url', + title: 'url 地址', + props: { + placeholder: '/system/user/simple-list' + } + }, + { + type: 'select', + field: 'method', + title: '请求类型', + value: 'GET', + options: [ + { label: 'GET', value: 'GET' }, + { label: 'POST', value: 'POST' } + ], + control: [ + { + value: 'GET', + condition: '!=', + method: 'hidden', + rule: [ + { + type: 'input', + field: 'data', + title: '请求参数 JSON 格式', + props: { + autosize: true, + type: 'textarea', + placeholder: '{"type": 1}' + } + } + ] + } + ] + }, + { + type: 'input', + field: 'labelField', + title: 'label 属性', + props: { + placeholder: 'nickname' + } + }, + { + type: 'input', + field: 'valueField', + title: 'value 属性', + props: { + placeholder: 'id' + } + } +] + +export { selectRule, apiSelectRule } diff --git a/src/components/FormCreate/src/config/useDictSelectRule.ts b/src/components/FormCreate/src/config/useDictSelectRule.ts index d2a9c467..d158842c 100644 --- a/src/components/FormCreate/src/config/useDictSelectRule.ts +++ b/src/components/FormCreate/src/config/useDictSelectRule.ts @@ -1,7 +1,7 @@ import { generateUUID } from '@/utils' import * as DictDataApi from '@/api/system/dict/dict.type' import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' -import selectRule from '@/components/FormCreate/src/config/selectRule' +import { selectRule } from '@/components/FormCreate/src/config/selectRule' /** * 字典选择器规则,如果规则使用到动态数据则需要单独配置不能使用 useSelectRule diff --git a/src/components/FormCreate/src/config/useSelectRule.ts b/src/components/FormCreate/src/config/useSelectRule.ts index fd23ac3a..93c6e8d5 100644 --- a/src/components/FormCreate/src/config/useSelectRule.ts +++ b/src/components/FormCreate/src/config/useSelectRule.ts @@ -1,6 +1,6 @@ import { generateUUID } from '@/utils' import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' -import selectRule from '@/components/FormCreate/src/config/selectRule' +import { selectRule } from '@/components/FormCreate/src/config/selectRule' import { SelectRuleOption } from '@/components/FormCreate/src/type' /** diff --git a/src/components/FormCreate/src/type/index.ts b/src/components/FormCreate/src/type/index.ts index ac248f11..07e011cf 100644 --- a/src/components/FormCreate/src/type/index.ts +++ b/src/components/FormCreate/src/type/index.ts @@ -1,13 +1,13 @@ import { Rule } from '@form-create/element-ui' //左侧拖拽按钮 -//左侧拖拽按钮 +// 左侧拖拽按钮 export interface MenuItem { label: string name: string icon: string } -//左侧拖拽按钮分类 +// 左侧拖拽按钮分类 export interface Menu { title: string name: string @@ -16,7 +16,7 @@ export interface Menu { export interface MenuList extends Array {} -//拖拽组件的规则 +// 拖拽组件的规则 export interface DragRule { icon: string name: string @@ -33,11 +33,11 @@ export interface DragRule { } // 通用下拉组件 Props 类型 -export interface CurrencySelectProps { +export interface ApiSelectProps { name: string // 组件名称 labelField?: string // 选项标签 valueField?: string // 选项的值 - restful?: string // api 接口 + url?: string // url 接口 isDict?: boolean // 是否字典选择器 } @@ -45,5 +45,5 @@ export interface CurrencySelectProps { export interface SelectRuleOption { label: string // label 名称 name: string // 组件名称 - props?: Rule[] // 组件规则 + props?: any[] // 组件规则 } diff --git a/src/components/FormCreate/src/useFormCreateDesigner.ts b/src/components/FormCreate/src/useFormCreateDesigner.ts index 3875b72c..266739c7 100644 --- a/src/components/FormCreate/src/useFormCreateDesigner.ts +++ b/src/components/FormCreate/src/useFormCreateDesigner.ts @@ -8,6 +8,7 @@ import { } from './config' import { Ref } from 'vue' import { Menu } from '@/components/FormCreate/src/type' +import { apiSelectRule } from '@/components/FormCreate/src/config/selectRule' /** * 表单设计器增强 hook @@ -50,36 +51,12 @@ export const useFormCreateDesigner = async (designer: Ref) => { const userSelectRule = useSelectRule({ name: 'UserSelect', label: '用户选择器' }) const deptSelectRule = useSelectRule({ name: 'DeptSelect', label: '部门选择器' }) const dictSelectRule = useDictSelectRule() - const restfulSelectRule = useSelectRule({ - name: 'RestfulSelect', + const apiSelectRule0 = useSelectRule({ + name: 'ApiSelect', label: '接口选择器', - props: [ - { - type: 'input', - field: 'restful', - title: 'restful api 接口', - props: { - placeholder: '/system/user/simple-list' - } - }, - { - type: 'input', - field: 'labelField', - title: 'label 属性', - props: { - placeholder: 'nickname' - } - }, - { - type: 'input', - field: 'valueField', - title: 'value 属性', - props: { - placeholder: 'id' - } - } - ] + props: [...apiSelectRule] }) + /** * 构建系统字段菜单 */ @@ -88,7 +65,7 @@ export const useFormCreateDesigner = async (designer: Ref) => { designer.value?.removeMenuItem('select') designer.value?.removeMenuItem('radio') designer.value?.removeMenuItem('checkbox') - const components = [userSelectRule, deptSelectRule, dictSelectRule, restfulSelectRule] + const components = [userSelectRule, deptSelectRule, dictSelectRule, apiSelectRule0] const menu: Menu = { name: 'system', title: '系统字段', diff --git a/src/plugins/formCreate/index.ts b/src/plugins/formCreate/index.ts index 3a647e11..adc12136 100644 --- a/src/plugins/formCreate/index.ts +++ b/src/plugins/formCreate/index.ts @@ -19,28 +19,26 @@ import formCreate from '@form-create/element-ui' import install from '@form-create/element-ui/auto-import' //======================= 自定义组件 ======================= import { UploadFile, UploadImg, UploadImgs } from '@/components/UploadFile' -import { useCurrencySelect } from '@/components/FormCreate' +import { useApiSelect } from '@/components/FormCreate' import { Editor } from '@/components/Editor' +import DictSelect from '@/components/FormCreate/src/components/DictSelect.vue' -const UserSelect = useCurrencySelect({ +const UserSelect = useApiSelect({ name: 'UserSelect', labelField: 'nickname', valueField: 'id', - restful: '/system/user/simple-list' + url: '/system/user/simple-list' }) -const DeptSelect = useCurrencySelect({ +const DeptSelect = useApiSelect({ name: 'DeptSelect', labelField: 'name', valueField: 'id', - restful: '/system/dept/simple-list' + url: '/system/dept/simple-list' }) -const RestfulSelect = useCurrencySelect({ - name: 'RestfulSelect' -}) -const DictSelect = useCurrencySelect({ - name: 'DictSelect', - isDict: true +const ApiSelect = useApiSelect({ + name: 'ApiSelect' }) + const components = [ ElAside, ElPopconfirm, @@ -60,7 +58,7 @@ const components = [ DictSelect, UserSelect, DeptSelect, - RestfulSelect, + ApiSelect, Editor ] diff --git a/src/utils/index.ts b/src/utils/index.ts index 274ab7ca..5b29e41a 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -435,3 +435,17 @@ export const areaReplace = (areaName: string) => { .replace('自治区', '') .replace('省', '') } + +/** + * 解析 JSON 字符串 + * + * @param str + */ +export function jsonParse(str: string) { + try { + return JSON.parse(str) + } catch (e) { + console.log(`str[${str}] 不是一个 JSON 字符串`) + return '' + } +} From 9f704fb8ffad0592aadda82b69b2aab37f98c79c Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 6 May 2024 02:12:09 +0800 Subject: [PATCH 7/7] =?UTF-8?q?form-create:=20=E5=AD=97=E4=BD=93=E5=9B=BE?= =?UTF-8?q?=E6=A0=87=E6=89=A9=E5=B1=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/config/useDictSelectRule.ts | 2 +- .../FormCreate/src/config/useSelectRule.ts | 2 +- src/components/FormCreate/src/type/index.ts | 1 + .../FormCreate/src/useFormCreateDesigner.ts | 13 +++++++++-- src/styles/FormCreate/fonts/fontello.woff | Bin 0 -> 4252 bytes src/styles/FormCreate/index.scss | 22 ++++++++++++++++++ src/styles/index.scss | 1 + 7 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 src/styles/FormCreate/fonts/fontello.woff create mode 100644 src/styles/FormCreate/index.scss diff --git a/src/components/FormCreate/src/config/useDictSelectRule.ts b/src/components/FormCreate/src/config/useDictSelectRule.ts index d158842c..3db630bc 100644 --- a/src/components/FormCreate/src/config/useDictSelectRule.ts +++ b/src/components/FormCreate/src/config/useDictSelectRule.ts @@ -22,7 +22,7 @@ export const useDictSelectRule = () => { })) ?? [] }) return { - icon: 'icon-select', + icon: 'icon-doc-text', label, name, rule() { diff --git a/src/components/FormCreate/src/config/useSelectRule.ts b/src/components/FormCreate/src/config/useSelectRule.ts index 93c6e8d5..732c5269 100644 --- a/src/components/FormCreate/src/config/useSelectRule.ts +++ b/src/components/FormCreate/src/config/useSelectRule.ts @@ -11,7 +11,7 @@ export const useSelectRule = (option: SelectRuleOption) => { const label = option.label const name = option.name return { - icon: 'icon-select', + icon: option.icon, label, name, rule() { diff --git a/src/components/FormCreate/src/type/index.ts b/src/components/FormCreate/src/type/index.ts index 07e011cf..42dccc76 100644 --- a/src/components/FormCreate/src/type/index.ts +++ b/src/components/FormCreate/src/type/index.ts @@ -45,5 +45,6 @@ export interface ApiSelectProps { export interface SelectRuleOption { label: string // label 名称 name: string // 组件名称 + icon: string // 组件图标 props?: any[] // 组件规则 } diff --git a/src/components/FormCreate/src/useFormCreateDesigner.ts b/src/components/FormCreate/src/useFormCreateDesigner.ts index 266739c7..69c8f314 100644 --- a/src/components/FormCreate/src/useFormCreateDesigner.ts +++ b/src/components/FormCreate/src/useFormCreateDesigner.ts @@ -48,12 +48,21 @@ export const useFormCreateDesigner = async (designer: Ref) => { }) } - const userSelectRule = useSelectRule({ name: 'UserSelect', label: '用户选择器' }) - const deptSelectRule = useSelectRule({ name: 'DeptSelect', label: '部门选择器' }) + const userSelectRule = useSelectRule({ + name: 'UserSelect', + label: '用户选择器', + icon: 'icon-user-o' + }) + const deptSelectRule = useSelectRule({ + name: 'DeptSelect', + label: '部门选择器', + icon: 'icon-address-card-o' + }) const dictSelectRule = useDictSelectRule() const apiSelectRule0 = useSelectRule({ name: 'ApiSelect', label: '接口选择器', + icon: 'icon-server', props: [...apiSelectRule] }) diff --git a/src/styles/FormCreate/fonts/fontello.woff b/src/styles/FormCreate/fonts/fontello.woff new file mode 100644 index 0000000000000000000000000000000000000000..1e00f4995b27e72b52d7d0fcf602d0206c3d6c89 GIT binary patch literal 4252 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 literal 0 HcmV?d00001 diff --git a/src/styles/FormCreate/index.scss b/src/styles/FormCreate/index.scss new file mode 100644 index 00000000..bb620005 --- /dev/null +++ b/src/styles/FormCreate/index.scss @@ -0,0 +1,22 @@ +// 使用字体图标来源 https://fontello.com/ + +@font-face { + font-family: 'fc-icon'; + src: url('@/styles/FormCreate/fonts/fontello.woff') format('woff'); +} + +.icon-doc-text:before { + content: '\f0f6'; +} + +.icon-server:before { + content: '\f233'; +} + +.icon-address-card-o:before { + content: '\f2bc'; +} + +.icon-user-o:before { + content: '\f2c0'; +} diff --git a/src/styles/index.scss b/src/styles/index.scss index 0952bd07..fbe76f23 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -1,4 +1,5 @@ @import './var.css'; +@import './FormCreate/index.scss'; @import 'element-plus/theme-chalk/dark/css-vars.css'; .reset-margin [class*='el-icon'] + span {