diff --git a/src/components/DictSelect/index.ts b/src/components/DictSelect/index.ts
new file mode 100644
index 00000000..164035fd
--- /dev/null
+++ b/src/components/DictSelect/index.ts
@@ -0,0 +1,3 @@
+import DictSelect from './src/DictSelect.vue'
+
+export { DictSelect }
diff --git a/src/components/DictSelect/src/DictSelect.vue b/src/components/DictSelect/src/DictSelect.vue
new file mode 100644
index 00000000..c0d585ab
--- /dev/null
+++ b/src/components/DictSelect/src/DictSelect.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/FormCreate/src/config/index.ts b/src/components/FormCreate/src/config/index.ts
index e098ce48..5403ce0e 100644
--- a/src/components/FormCreate/src/config/index.ts
+++ b/src/components/FormCreate/src/config/index.ts
@@ -1,5 +1,13 @@
import { useUploadFileRule } from './useUploadFileRule'
import { useUploadImgRule } from './useUploadImgRule'
import { useUploadImgsRule } from './useUploadImgsRule'
+import { useDictSelectRule } from './useDictSelectRule'
+import { useUserSelectRule } from './useUserSelectRule'
-export { useUploadFileRule, useUploadImgRule, useUploadImgsRule }
+export {
+ useUploadFileRule,
+ useUploadImgRule,
+ useUploadImgsRule,
+ useDictSelectRule,
+ useUserSelectRule
+}
diff --git a/src/components/FormCreate/src/config/useDictSelectRule.ts b/src/components/FormCreate/src/config/useDictSelectRule.ts
new file mode 100644
index 00000000..51cd33b7
--- /dev/null
+++ b/src/components/FormCreate/src/config/useDictSelectRule.ts
@@ -0,0 +1,124 @@
+import { generateUUID } from '@/utils'
+import * as DictDataApi from '@/api/system/dict/dict.type'
+import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils'
+
+export const useDictSelectRule = () => {
+ const label = '字典选择器'
+ const name = 'DictSelect'
+ const dictOptions = ref<{ label: string; value: string }[]>([]) // 字典类型下拉数据
+ onMounted(async () => {
+ const data = await DictDataApi.getSimpleDictTypeList()
+ if (!data || data.length === 0) {
+ return
+ }
+ dictOptions.value =
+ data?.map((item: DictDataApi.DictTypeVO) => ({
+ label: item.name,
+ value: item.type
+ })) ?? []
+ })
+ 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: 'select',
+ field: 'dictType',
+ title: '字典类型',
+ value: '',
+ options: dictOptions.value
+ },
+ {
+ type: 'select',
+ field: 'valueType',
+ title: '字典值类型',
+ value: 'str',
+ options: [
+ { label: '数字', value: 'int' },
+ { label: '字符串', value: 'str' },
+ { label: '布尔值', value: 'bool' }
+ ]
+ },
+ { type: 'switch', field: 'multiple', title: '是否多选' },
+ {
+ type: 'switch',
+ field: 'disabled',
+ title: '是否禁用'
+ },
+ { type: 'switch', field: 'clearable', title: '是否可以清空选项' },
+ {
+ type: 'switch',
+ field: 'collapseTags',
+ title: '多选时是否将选中值按文字的形式展示'
+ },
+ {
+ type: 'inputNumber',
+ field: 'multipleLimit',
+ title: '多选时用户最多可以选择的项目数,为 0 则不限制',
+ props: { min: 0 }
+ },
+ {
+ type: 'input',
+ field: 'autocomplete',
+ title: 'autocomplete 属性'
+ },
+ { type: 'input', field: 'placeholder', title: '占位符' },
+ {
+ type: 'switch',
+ field: 'filterable',
+ title: '是否可搜索'
+ },
+ { type: 'switch', field: 'allowCreate', title: '是否允许用户创建新条目' },
+ {
+ type: 'input',
+ field: 'noMatchText',
+ title: '搜索条件无匹配时显示的文字'
+ },
+ {
+ type: 'switch',
+ field: 'remote',
+ title: '其中的选项是否从服务器远程加载'
+ },
+ {
+ type: 'Struct',
+ field: 'remoteMethod',
+ title: '自定义远程搜索方法'
+ },
+ { type: 'input', field: 'noDataText', title: '选项为空时显示的文字' },
+ {
+ type: 'switch',
+ field: 'reserveKeyword',
+ title: '多选且可搜索时,是否在选中一个选项后保留当前的搜索关键词'
+ },
+ {
+ type: 'switch',
+ field: 'defaultFirstOption',
+ title: '在输入框按下回车,选择第一个匹配项'
+ },
+ {
+ type: 'switch',
+ field: 'popperAppendToBody',
+ title: '是否将弹出框插入至 body 元素',
+ value: true
+ },
+ {
+ type: 'switch',
+ field: 'automaticDropdown',
+ title: '对于不可搜索的 Select,是否在输入框获得焦点后自动弹出选项菜单'
+ }
+ ])
+ }
+ }
+}
diff --git a/src/components/FormCreate/src/config/useUserSelectRule.ts b/src/components/FormCreate/src/config/useUserSelectRule.ts
new file mode 100644
index 00000000..23521134
--- /dev/null
+++ b/src/components/FormCreate/src/config/useUserSelectRule.ts
@@ -0,0 +1,107 @@
+import { generateUUID } from '@/utils'
+import * as UserApi from '@/api/system/user'
+import { localeProps, makeOptionsRule, makeRequiredRule } from '@/components/FormCreate/src/utils'
+
+export const useUserSelectRule = () => {
+ const label = 'aa选择器'
+ const name = 'select'
+ const userOptions = ref<{ label: string; value: number }[]>([]) // 用户下拉数据
+ onMounted(async () => {
+ const data = await UserApi.getSimpleUserList()
+ if (!data || data.length === 0) {
+ return
+ }
+ userOptions.value =
+ data?.map((item: UserApi.UserVO) => ({
+ label: item.nickname,
+ value: item.id
+ })) ?? []
+ })
+ 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(),
+ makeOptionsRule(t, 'options', userOptions.value),
+ { type: 'switch', field: 'multiple', title: '是否多选' },
+ {
+ type: 'switch',
+ field: 'disabled',
+ title: '是否禁用'
+ },
+ { type: 'switch', field: 'clearable', title: '是否可以清空选项' },
+ {
+ type: 'switch',
+ field: 'collapseTags',
+ title: '多选时是否将选中值按文字的形式展示'
+ },
+ {
+ type: 'inputNumber',
+ field: 'multipleLimit',
+ title: '多选时用户最多可以选择的项目数,为 0 则不限制',
+ props: { min: 0 }
+ },
+ {
+ type: 'input',
+ field: 'autocomplete',
+ title: 'autocomplete 属性'
+ },
+ { type: 'input', field: 'placeholder', title: '占位符' },
+ {
+ type: 'switch',
+ field: 'filterable',
+ title: '是否可搜索'
+ },
+ { type: 'switch', field: 'allowCreate', title: '是否允许用户创建新条目' },
+ {
+ type: 'input',
+ field: 'noMatchText',
+ title: '搜索条件无匹配时显示的文字'
+ },
+ {
+ type: 'switch',
+ field: 'remote',
+ title: '其中的选项是否从服务器远程加载'
+ },
+ {
+ type: 'Struct',
+ field: 'remoteMethod',
+ title: '自定义远程搜索方法'
+ },
+ { type: 'input', field: 'noDataText', title: '选项为空时显示的文字' },
+ {
+ type: 'switch',
+ field: 'reserveKeyword',
+ title: '多选且可搜索时,是否在选中一个选项后保留当前的搜索关键词'
+ },
+ {
+ type: 'switch',
+ field: 'defaultFirstOption',
+ title: '在输入框按下回车,选择第一个匹配项'
+ },
+ {
+ type: 'switch',
+ field: 'popperAppendToBody',
+ title: '是否将弹出框插入至 body 元素',
+ value: true
+ },
+ {
+ type: 'switch',
+ field: 'automaticDropdown',
+ title: '对于不可搜索的 Select,是否在输入框获得焦点后自动弹出选项菜单'
+ }
+ ])
+ }
+ }
+}
diff --git a/src/components/FormCreate/src/useFormCreateDesigner.ts b/src/components/FormCreate/src/useFormCreateDesigner.ts
index b6855a99..e142970d 100644
--- a/src/components/FormCreate/src/useFormCreateDesigner.ts
+++ b/src/components/FormCreate/src/useFormCreateDesigner.ts
@@ -1,4 +1,10 @@
-import { useUploadFileRule, useUploadImgRule, useUploadImgsRule } from './config'
+import {
+ useDictSelectRule,
+ useUploadFileRule,
+ useUploadImgRule,
+ useUploadImgsRule,
+ useUserSelectRule
+} from './config'
import { Ref } from 'vue'
/**
@@ -12,11 +18,19 @@ export const useFormCreateDesigner = (designer: Ref) => {
const uploadFileRule = useUploadFileRule()
const uploadImgRule = useUploadImgRule()
const uploadImgsRule = useUploadImgsRule()
+ const dictSelectRule = useDictSelectRule()
+ const userSelectRule = useUserSelectRule()
onMounted(() => {
// 移除自带的上传组件规则,使用 uploadFileRule、uploadImgRule、uploadImgsRule 替代
designer.value?.removeMenuItem('upload')
- const components = [uploadFileRule, uploadImgRule, uploadImgsRule]
+ const components = [
+ uploadFileRule,
+ uploadImgRule,
+ uploadImgsRule,
+ dictSelectRule,
+ userSelectRule
+ ]
components.forEach((component) => {
// 插入组件规则
designer.value?.addComponent(component)
diff --git a/src/components/FormCreate/src/utils/index.ts b/src/components/FormCreate/src/utils/index.ts
index 49901b5f..e5480981 100644
--- a/src/components/FormCreate/src/utils/index.ts
+++ b/src/components/FormCreate/src/utils/index.ts
@@ -17,3 +17,63 @@ export const localeProps = (t, prefix, rules) => {
return rule
})
}
+
+export function upper(str) {
+ return str.replace(str[0], str[0].toLocaleUpperCase())
+}
+
+export function makeOptionsRule(t, to, userOptions) {
+ console.log(userOptions[0])
+ const options = [
+ { label: t('props.optionsType.struct'), value: 0 },
+ { label: t('props.optionsType.json'), value: 1 },
+ { label: '用户数据', value: 2 }
+ ]
+
+ const control = [
+ {
+ value: 0,
+ rule: [
+ {
+ type: 'TableOptions',
+ field: 'formCreate' + upper(to).replace('.', '>'),
+ props: { defaultValue: [] }
+ }
+ ]
+ },
+ {
+ value: 1,
+ rule: [
+ {
+ type: 'Struct',
+ field: 'formCreate' + upper(to).replace('.', '>'),
+ props: { defaultValue: [] }
+ }
+ ]
+ },
+ {
+ value: 2,
+ rule: [
+ {
+ type: 'TableOptions',
+ field: 'formCreate' + upper(to).replace('.', '>'),
+ props: { modelValue: [] }
+ }
+ ]
+ }
+ ]
+ options.splice(0, 0)
+ control.push()
+
+ return {
+ type: 'radio',
+ title: t('props.options'),
+ field: '_optionType',
+ value: 0,
+ options,
+ props: {
+ type: 'button'
+ },
+ control
+ }
+}
diff --git a/src/plugins/formCreate/index.ts b/src/plugins/formCreate/index.ts
index ffbcc010..9e083641 100644
--- a/src/plugins/formCreate/index.ts
+++ b/src/plugins/formCreate/index.ts
@@ -19,6 +19,7 @@ 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'
const components = [
ElAside,
@@ -35,7 +36,8 @@ const components = [
ElTabPane,
UploadImg,
UploadImgs,
- UploadFile
+ UploadFile,
+ DictSelect
]
// 参考 http://www.form-create.com/v3/element-ui/auto-import.html 文档