From 7c158af3cc572c7b0b40bee178595660de215ae2 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 6 May 2024 01:24:25 +0800 Subject: [PATCH] =?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 '' + } +}