Skip to content

Commit 7c158af

Browse files
author
puhui999
committed
form-create: 字典选择器分离,重新封装 api 选择器
1 parent c77526e commit 7c158af

File tree

10 files changed

+205
-91
lines changed

10 files changed

+205
-91
lines changed

src/components/FormCreate/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import { useFormCreateDesigner } from './src/useFormCreateDesigner'
2-
import { useCurrencySelect } from './src/components/useCurrencySelect'
2+
import { useApiSelect } from './src/components/useApiSelect'
33

4-
export { useFormCreateDesigner, useCurrencySelect }
4+
export { useFormCreateDesigner, useApiSelect }
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<!-- 数据字典 Select 选择器 -->
2+
<template>
3+
<el-select v-if="selectType === 'select'" class="w-1/1" v-bind="attrs">
4+
<el-option
5+
v-for="(dict, index) in getDictOptions"
6+
:key="index"
7+
:label="dict.label"
8+
:value="dict.value"
9+
/>
10+
</el-select>
11+
<el-radio-group v-if="selectType === 'radio'" class="w-1/1" v-bind="attrs">
12+
<el-radio v-for="(dict, index) in getDictOptions" :key="index" :value="dict.value">
13+
{{ dict.label }}
14+
</el-radio>
15+
</el-radio-group>
16+
<el-checkbox-group v-if="selectType === 'checkbox'" class="w-1/1" v-bind="attrs">
17+
<el-checkbox
18+
v-for="(dict, index) in getDictOptions"
19+
:key="index"
20+
:label="dict.label"
21+
:value="dict.value"
22+
/>
23+
</el-checkbox-group>
24+
</template>
25+
26+
<script lang="ts" setup>
27+
import { getBoolDictOptions, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
28+
29+
defineOptions({ name: 'DictSelect' })
30+
31+
const attrs = useAttrs()
32+
33+
// 接受父组件参数
34+
interface Props {
35+
dictType: string // 字典类型
36+
valueType?: 'str' | 'int' | 'bool' // 字典值类型
37+
selectType?: 'select' | 'radio' | 'checkbox' // 选择器类型,下拉框 select、多选框 checkbox、单选框 radio
38+
formCreateInject?: any
39+
}
40+
41+
const props = withDefaults(defineProps<Props>(), {
42+
valueType: 'str',
43+
selectType: 'select'
44+
})
45+
46+
// 获得字典配置
47+
const getDictOptions = computed(() => {
48+
switch (props.valueType) {
49+
case 'str':
50+
return getStrDictOptions(props.dictType)
51+
case 'int':
52+
return getIntDictOptions(props.dictType)
53+
case 'bool':
54+
return getBoolDictOptions(props.dictType)
55+
default:
56+
return []
57+
}
58+
})
59+
</script>

src/components/FormCreate/src/components/useCurrencySelect.tsx renamed to src/components/FormCreate/src/components/useApiSelect.tsx

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import request from '@/config/axios'
22
import { isEmpty } from '@/utils/is'
3-
import { CurrencySelectProps } from '@/components/FormCreate/src/type'
4-
import { getBoolDictOptions, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
3+
import { ApiSelectProps } from '@/components/FormCreate/src/type'
4+
import { jsonParse } from '@/utils'
55

6-
export const useCurrencySelect = (option: CurrencySelectProps) => {
6+
export const useApiSelect = (option: ApiSelectProps) => {
77
return defineComponent({
88
name: option.name,
99
props: {
@@ -18,74 +18,75 @@ export const useCurrencySelect = (option: CurrencySelectProps) => {
1818
default: () => option.valueField ?? 'value'
1919
},
2020
// api 接口
21-
restful: {
21+
url: {
2222
type: String,
23-
default: () => option.restful ?? ''
23+
default: () => option.url ?? ''
2424
},
25-
// 字典类型
26-
dictType: {
25+
// 请求类型
26+
method: {
2727
type: String,
28-
default: ''
28+
default: 'GET'
2929
},
30-
// 字典值类型 'str' | 'int' | 'bool'
31-
dictValueType: {
30+
// 请求参数
31+
data: {
3232
type: String,
33-
default: 'str'
33+
default: ''
3434
},
3535
// 选择器类型,下拉框 select、多选框 checkbox、单选框 radio
3636
selectType: {
3737
type: String,
3838
default: 'select'
39+
},
40+
// 是否多选
41+
multiple: {
42+
type: Boolean,
43+
default: false
3944
}
40-
// // 是否多选
41-
// multiple: {
42-
// type: Boolean,
43-
// default: false
44-
// }
4545
},
4646
setup(props) {
4747
const attrs = useAttrs()
4848
const options = ref<any[]>([]) // 下拉数据
4949
const getOptions = async () => {
5050
options.value = []
51-
// 字典选择器
52-
if (option.isDict) {
53-
options.value = getDictOptions()
54-
return
55-
}
5651
// 接口选择器
57-
if (isEmpty(props.restful)) {
52+
if (isEmpty(props.url)) {
5853
return
5954
}
60-
// TODO 只支持 GET 查询,复杂下拉构建条件请使用业务表单
61-
const data = await request.get({ url: props.restful })
55+
let data = []
56+
switch (props.method) {
57+
case 'GET':
58+
data = await request.get({ url: props.url })
59+
break
60+
case 'POST':
61+
data = await request.post({ url: props.url, data: jsonParse(props.data) })
62+
break
63+
}
64+
6265
if (Array.isArray(data)) {
6366
options.value = data.map((item: any) => ({
6467
label: item[props.labelField],
6568
value: item[props.valueField]
6669
}))
6770
return
6871
}
69-
console.log(`接口[${props.restful}] 返回结果不是一个数组`)
70-
}
71-
// 获得字典配置
72-
const getDictOptions = () => {
73-
switch (props.dictValueType) {
74-
case 'str':
75-
return getStrDictOptions(props.dictType)
76-
case 'int':
77-
return getIntDictOptions(props.dictType)
78-
case 'bool':
79-
return getBoolDictOptions(props.dictType)
80-
default:
81-
return []
82-
}
72+
console.log(`接口[${props.url}] 返回结果不是一个数组`)
8373
}
74+
8475
onMounted(async () => {
8576
await getOptions()
8677
})
87-
// TODO puhui999: 单下拉多选的时候页面会卡住报错,下次解决
78+
8879
const buildSelect = () => {
80+
if (props.multiple) {
81+
// fix:多写此步是为了解决 multiple 属性问题
82+
return (
83+
<el-select class="w-1/1" {...attrs} multiple>
84+
{options.value.map((item, index) => (
85+
<el-option key={index} label={item.label} value={item.value} />
86+
))}
87+
</el-select>
88+
)
89+
}
8990
return (
9091
<el-select class="w-1/1" {...attrs}>
9192
{options.value.map((item, index) => (

src/components/FormCreate/src/config/selectRule.ts

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ const selectRule = [
88
{ label: '下拉框', value: 'select' },
99
{ label: '单选框', value: 'radio' },
1010
{ label: '多选框', value: 'checkbox' }
11+
],
12+
// 参考 https://www.form-create.com/v3/guide/control 组件联动,单选框和多选框不需要多选属性
13+
control: [
14+
{
15+
value: 'select',
16+
condition: '=',
17+
method: 'hidden',
18+
rule: ['multiple']
19+
}
1120
]
1221
},
1322
{ type: 'switch', field: 'multiple', title: '是否多选' },
@@ -79,4 +88,60 @@ const selectRule = [
7988
}
8089
]
8190

82-
export default selectRule
91+
const apiSelectRule = [
92+
{
93+
type: 'input',
94+
field: 'url',
95+
title: 'url 地址',
96+
props: {
97+
placeholder: '/system/user/simple-list'
98+
}
99+
},
100+
{
101+
type: 'select',
102+
field: 'method',
103+
title: '请求类型',
104+
value: 'GET',
105+
options: [
106+
{ label: 'GET', value: 'GET' },
107+
{ label: 'POST', value: 'POST' }
108+
],
109+
control: [
110+
{
111+
value: 'GET',
112+
condition: '!=',
113+
method: 'hidden',
114+
rule: [
115+
{
116+
type: 'input',
117+
field: 'data',
118+
title: '请求参数 JSON 格式',
119+
props: {
120+
autosize: true,
121+
type: 'textarea',
122+
placeholder: '{"type": 1}'
123+
}
124+
}
125+
]
126+
}
127+
]
128+
},
129+
{
130+
type: 'input',
131+
field: 'labelField',
132+
title: 'label 属性',
133+
props: {
134+
placeholder: 'nickname'
135+
}
136+
},
137+
{
138+
type: 'input',
139+
field: 'valueField',
140+
title: 'value 属性',
141+
props: {
142+
placeholder: 'id'
143+
}
144+
}
145+
]
146+
147+
export { selectRule, apiSelectRule }

src/components/FormCreate/src/config/useDictSelectRule.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { generateUUID } from '@/utils'
22
import * as DictDataApi from '@/api/system/dict/dict.type'
33
import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils'
4-
import selectRule from '@/components/FormCreate/src/config/selectRule'
4+
import { selectRule } from '@/components/FormCreate/src/config/selectRule'
55

66
/**
77
* 字典选择器规则,如果规则使用到动态数据则需要单独配置不能使用 useSelectRule

src/components/FormCreate/src/config/useSelectRule.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { generateUUID } from '@/utils'
22
import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils'
3-
import selectRule from '@/components/FormCreate/src/config/selectRule'
3+
import { selectRule } from '@/components/FormCreate/src/config/selectRule'
44
import { SelectRuleOption } from '@/components/FormCreate/src/type'
55

66
/**

src/components/FormCreate/src/type/index.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { Rule } from '@form-create/element-ui' //左侧拖拽按钮
22

3-
//左侧拖拽按钮
3+
// 左侧拖拽按钮
44
export interface MenuItem {
55
label: string
66
name: string
77
icon: string
88
}
99

10-
//左侧拖拽按钮分类
10+
// 左侧拖拽按钮分类
1111
export interface Menu {
1212
title: string
1313
name: string
@@ -16,7 +16,7 @@ export interface Menu {
1616

1717
export interface MenuList extends Array<Menu> {}
1818

19-
//拖拽组件的规则
19+
// 拖拽组件的规则
2020
export interface DragRule {
2121
icon: string
2222
name: string
@@ -33,17 +33,17 @@ export interface DragRule {
3333
}
3434

3535
// 通用下拉组件 Props 类型
36-
export interface CurrencySelectProps {
36+
export interface ApiSelectProps {
3737
name: string // 组件名称
3838
labelField?: string // 选项标签
3939
valueField?: string // 选项的值
40-
restful?: string // api 接口
40+
url?: string // url 接口
4141
isDict?: boolean // 是否字典选择器
4242
}
4343

4444
// 选择组件规则配置类型
4545
export interface SelectRuleOption {
4646
label: string // label 名称
4747
name: string // 组件名称
48-
props?: Rule[] // 组件规则
48+
props?: any[] // 组件规则
4949
}

src/components/FormCreate/src/useFormCreateDesigner.ts

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
} from './config'
99
import { Ref } from 'vue'
1010
import { Menu } from '@/components/FormCreate/src/type'
11+
import { apiSelectRule } from '@/components/FormCreate/src/config/selectRule'
1112

1213
/**
1314
* 表单设计器增强 hook
@@ -50,36 +51,12 @@ export const useFormCreateDesigner = async (designer: Ref) => {
5051
const userSelectRule = useSelectRule({ name: 'UserSelect', label: '用户选择器' })
5152
const deptSelectRule = useSelectRule({ name: 'DeptSelect', label: '部门选择器' })
5253
const dictSelectRule = useDictSelectRule()
53-
const restfulSelectRule = useSelectRule({
54-
name: 'RestfulSelect',
54+
const apiSelectRule0 = useSelectRule({
55+
name: 'ApiSelect',
5556
label: '接口选择器',
56-
props: [
57-
{
58-
type: 'input',
59-
field: 'restful',
60-
title: 'restful api 接口',
61-
props: {
62-
placeholder: '/system/user/simple-list'
63-
}
64-
},
65-
{
66-
type: 'input',
67-
field: 'labelField',
68-
title: 'label 属性',
69-
props: {
70-
placeholder: 'nickname'
71-
}
72-
},
73-
{
74-
type: 'input',
75-
field: 'valueField',
76-
title: 'value 属性',
77-
props: {
78-
placeholder: 'id'
79-
}
80-
}
81-
]
57+
props: [...apiSelectRule]
8258
})
59+
8360
/**
8461
* 构建系统字段菜单
8562
*/
@@ -88,7 +65,7 @@ export const useFormCreateDesigner = async (designer: Ref) => {
8865
designer.value?.removeMenuItem('select')
8966
designer.value?.removeMenuItem('radio')
9067
designer.value?.removeMenuItem('checkbox')
91-
const components = [userSelectRule, deptSelectRule, dictSelectRule, restfulSelectRule]
68+
const components = [userSelectRule, deptSelectRule, dictSelectRule, apiSelectRule0]
9269
const menu: Menu = {
9370
name: 'system',
9471
title: '系统字段',

0 commit comments

Comments
 (0)