Pre Merge pull request !765 from 宿命的风/master

pull/765/MERGE
宿命的风 2025-07-06 08:40:30 +00:00 committed by Gitee
commit ec573ac1a8
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
9 changed files with 193 additions and 15 deletions

2
run.bat Normal file
View File

@ -0,0 +1,2 @@
title ǰ¶Ë·þÎñ
npm run dev

View File

@ -0,0 +1,51 @@
<template>
<el-tree-select
v-bind="attrs"
:data="deptList"
:props="defaultProps"
check-strictly
node-key="id"
placeholder="请选择"
:multiple="multiple"
:show-checkbox="showCheckbox"
:filterable="filterable"
:clearable="clearable"
/>
</template>
<script lang="ts" setup>
import { defaultProps, handleTree } from '@/utils/tree'
import * as DeptApi from '@/api/system/dept'
defineOptions({ name: 'DeptTreeSelect' })
const attrs = useAttrs()
//
interface Props {
multiple: boolean, //
showCheckbox: boolean, //
filterable:boolean, //
formCreateInject?: any
}
const props = withDefaults(defineProps<Props>(), {
multiple: false,
showCheckbox: false,
filterable:false,
clearable:false
})
const deptList = ref<Tree[]>([]) //
onMounted(async () => {
const rule = props.formCreateInject.rule
const data = await DeptApi.getSimpleDeptList() //1.
if (!data || data.length === 0) {
return
}
deptList.value = handleTree(data)
rule.options= data
})
</script>

View File

@ -45,15 +45,18 @@ const props = withDefaults(defineProps<Props>(), {
// //
const getDictOptions = computed(() => { const getDictOptions = computed(() => {
switch (props.valueType) { const rule = props.formCreateInject.rule
case 'str': let options
return getStrDictOptions(props.dictType) if(props.valueType === 'str'){
case 'int': options = getStrDictOptions(props.dictType)
return getIntDictOptions(props.dictType) }else if(props.valueType === 'int'){
case 'bool': options = getIntDictOptions(props.dictType)
return getBoolDictOptions(props.dictType) }else if(props.valueType === 'bool'){
default: options = getBoolDictOptions(props.dictType)
return [] }else {
options = []
} }
rule.options= options
return options
}) })
</script> </script>

View File

@ -2,6 +2,7 @@ import request from '@/config/axios'
import { isEmpty } from '@/utils/is' import { isEmpty } from '@/utils/is'
import { ApiSelectProps } from '@/components/FormCreate/src/type' import { ApiSelectProps } from '@/components/FormCreate/src/type'
import { jsonParse } from '@/utils' import { jsonParse } from '@/utils'
import { object } from 'vue-types'
export const useApiSelect = (option: ApiSelectProps) => { export const useApiSelect = (option: ApiSelectProps) => {
return defineComponent({ return defineComponent({
@ -95,6 +96,9 @@ export const useApiSelect = (option: ApiSelectProps) => {
} }
function parseOptions(data: any) { function parseOptions(data: any) {
const api = props.formCreateInject.api
api.setData(props.formCreateInject.field,data)
// 情况一:如果有自定义解析函数优先使用自定义解析 // 情况一:如果有自定义解析函数优先使用自定义解析
if (!isEmpty(props.parseFunc)) { if (!isEmpty(props.parseFunc)) {
options.value = parseFunc()?.(data) options.value = parseFunc()?.(data)
@ -111,6 +115,7 @@ export const useApiSelect = (option: ApiSelectProps) => {
parseOptions0(data) parseOptions0(data)
return return
} }
// 情况三:不是 yudao-vue-pro 标准返回 // 情况三:不是 yudao-vue-pro 标准返回
console.warn( console.warn(
`接口[${props.url}] 返回结果不是 yudao-vue-pro 标准返回建议采用自定义解析函数处理` `接口[${props.url}] 返回结果不是 yudao-vue-pro 标准返回建议采用自定义解析函数处理`

View File

@ -2,6 +2,7 @@ import { useUploadFileRule } from './useUploadFileRule'
import { useUploadImgRule } from './useUploadImgRule' import { useUploadImgRule } from './useUploadImgRule'
import { useUploadImgsRule } from './useUploadImgsRule' import { useUploadImgsRule } from './useUploadImgsRule'
import { useDictSelectRule } from './useDictSelectRule' import { useDictSelectRule } from './useDictSelectRule'
import { useDeptTreeSelectRule } from './useDeptTreeSelectRule'
import { useEditorRule } from './useEditorRule' import { useEditorRule } from './useEditorRule'
import { useSelectRule } from './useSelectRule' import { useSelectRule } from './useSelectRule'
@ -10,6 +11,7 @@ export {
useUploadImgRule, useUploadImgRule,
useUploadImgsRule, useUploadImgsRule,
useDictSelectRule, useDictSelectRule,
useDeptTreeSelectRule,
useEditorRule, useEditorRule,
useSelectRule useSelectRule
} }

View File

@ -0,0 +1,36 @@
import { generateUUID } from '@/utils'
import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils'
import { selectRule } from '@/components/FormCreate/src/config/selectRule'
import { cloneDeep } from 'lodash-es'
/**
* 使使 useSelectRule
*/
export const useDeptTreeSelectRule = () => {
const label = '部门树选择'
const name = 'DeptTreeSelect'
const event = ['click','change','visibleChange','clear','blur','focus']
const rules = cloneDeep(selectRule)
return {
icon: 'icon-doc-text',
label,
name,
event: event,
rule() {
return {
type: name,
field: generateUUID(),
title: label,
info: '',
$required: false
}
},
props(_, { t }) {
return localeProps(t, name + '.props', [
makeRequiredRule(),
{ type: 'switch', field: 'showCheckbox', title: '是否显示复选框' },
...rules
])
}
}
}

View File

@ -12,6 +12,7 @@ export const useDictSelectRule = () => {
const name = 'DictSelect' const name = 'DictSelect'
const rules = cloneDeep(selectRule) const rules = cloneDeep(selectRule)
const dictOptions = ref<{ label: string; value: string }[]>([]) // 字典类型下拉数据 const dictOptions = ref<{ label: string; value: string }[]>([]) // 字典类型下拉数据
const event = ['click','change','visibleChange','clear','blur','focus']
onMounted(async () => { onMounted(async () => {
const data = await DictDataApi.getSimpleDictTypeList() const data = await DictDataApi.getSimpleDictTypeList()
if (!data || data.length === 0) { if (!data || data.length === 0) {
@ -27,6 +28,7 @@ export const useDictSelectRule = () => {
icon: 'icon-doc-text', icon: 'icon-doc-text',
label, label,
name, name,
event: event,
rule() { rule() {
return { return {
type: name, type: name,

View File

@ -1,10 +1,12 @@
import { import {
useDictSelectRule, useDictSelectRule,
useDeptTreeSelectRule,
useEditorRule, useEditorRule,
useSelectRule, useSelectRule,
useUploadFileRule, useUploadFileRule,
useUploadImgRule, useUploadImgRule,
useUploadImgsRule useUploadImgsRule,
useTreeSelectRule
} from './config' } from './config'
import { Ref } from 'vue' import { Ref } from 'vue'
import { Menu } from '@/components/FormCreate/src/type' import { Menu } from '@/components/FormCreate/src/type'
@ -19,6 +21,8 @@ import { apiSelectRule } from '@/components/FormCreate/src/config/selectRule'
* - * -
* - * -
* - * -
* -
* -
* - * -
*/ */
export const useFormCreateDesigner = async (designer: Ref) => { export const useFormCreateDesigner = async (designer: Ref) => {
@ -48,23 +52,33 @@ export const useFormCreateDesigner = async (designer: Ref) => {
}) })
} }
const event = ['click','change','visibleChange','clear','blur','focus']
const userSelectRule = useSelectRule({ const userSelectRule = useSelectRule({
name: 'UserSelect', name: 'UserSelect',
label: '用户选择器', label: '用户选择器',
icon: 'icon-user-o' icon: 'icon-user-o',
event: event,
}) })
const deptSelectRule = useSelectRule({ const deptSelectRule = useSelectRule({
name: 'DeptSelect', name: 'DeptSelect',
label: '部门选择器', label: '部门选择器',
icon: 'icon-address-card-o' icon: 'icon-address-card-o',
event: event,
}) })
const dictSelectRule = useDictSelectRule() const dictSelectRule = useDictSelectRule()
const deptTreeSelectRule = useDeptTreeSelectRule()
const apiSelectRule0 = useSelectRule({ const apiSelectRule0 = useSelectRule({
name: 'ApiSelect', name: 'ApiSelect',
label: '接口选择器', label: '接口选择器',
icon: 'icon-server', icon: 'icon-server',
props: [...apiSelectRule], props: [...apiSelectRule],
event: ['click', 'change', 'visibleChange', 'clear', 'blur', 'focus'] event: event,
})
const postSelectRule = useSelectRule({
name: 'PostSelect',
label: '岗位选择器',
icon: 'icon-address-card-o',
event: event,
}) })
/** /**
@ -75,7 +89,7 @@ export const useFormCreateDesigner = async (designer: Ref) => {
// designer.value?.removeMenuItem('select') // designer.value?.removeMenuItem('select')
// designer.value?.removeMenuItem('radio') // designer.value?.removeMenuItem('radio')
// designer.value?.removeMenuItem('checkbox') // designer.value?.removeMenuItem('checkbox')
const components = [userSelectRule, deptSelectRule, dictSelectRule, apiSelectRule0] const components = [userSelectRule, deptSelectRule, dictSelectRule, apiSelectRule0,deptTreeSelectRule,postSelectRule]
const menu: Menu = { const menu: Menu = {
name: 'system', name: 'system',
title: '系统字段', title: '系统字段',

View File

@ -1,5 +1,7 @@
import type { App } from 'vue' import type { App } from 'vue'
// 👇使用 form-create 需额外全局引入 element plus 组件 import { getAccessToken, getTenantId } from '@/utils/auth'
import { config } from '@/config/axios/config'
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>使用 form-create 需额外全局引入 element plus 组件
import { import {
// ElAutocomplete, // ElAutocomplete,
// ElButton, // ElButton,
@ -67,6 +69,7 @@ import { UploadFile, UploadImg, UploadImgs } from '@/components/UploadFile'
import { useApiSelect } from '@/components/FormCreate' import { useApiSelect } from '@/components/FormCreate'
import { Editor } from '@/components/Editor' import { Editor } from '@/components/Editor'
import DictSelect from '@/components/FormCreate/src/components/DictSelect.vue' import DictSelect from '@/components/FormCreate/src/components/DictSelect.vue'
import DeptTreeSelect from '@/components/FormCreate/src/components/DeptTreeSelect.vue'
const UserSelect = useApiSelect({ const UserSelect = useApiSelect({
name: 'UserSelect', name: 'UserSelect',
@ -84,6 +87,13 @@ const ApiSelect = useApiSelect({
name: 'ApiSelect' name: 'ApiSelect'
}) })
const PostSelect = useApiSelect({
name: 'PostSelect',
labelField: 'name',
valueField: 'id',
url: '/system/post/simple-list'
})
const components = [ const components = [
ElAlert, ElAlert,
ElTransfer, ElTransfer,
@ -114,6 +124,7 @@ const components = [
UploadImgs, UploadImgs,
UploadFile, UploadFile,
DictSelect, DictSelect,
DeptTreeSelect,
UserSelect, UserSelect,
DeptSelect, DeptSelect,
ApiSelect, ApiSelect,
@ -121,6 +132,7 @@ const components = [
ElCollapse, ElCollapse,
ElCollapseItem, ElCollapseItem,
ElCard, ElCard,
PostSelect,
] ]
// 参考 http://www.form-create.com/v3/element-ui/auto-import.html 文档 // 参考 http://www.form-create.com/v3/element-ui/auto-import.html 文档
@ -132,3 +144,54 @@ export const setupFormCreate = (app: App<Element>) => {
app.use(formCreate) app.use(formCreate)
app.use(FcDesigner) app.use(FcDesigner)
} }
formCreate.setData('globalToken',getAccessToken())
formCreate.setData('tenantId',getTenantId())
const { default_headers } = config
// 重写 formCreate 的内置 fetch 方法
formCreate.fetch = (options) => {
const { dataType } = options
// 获取或生成 Token
const token = getAccessToken(); // 这里的 token 可以从 Vuex、localStorage 或其他地方获取
const tenantId = getTenantId()
let headers = {}
// 设置请求头,附加 Authorization token
const action = options.action.trim().toLowerCase()
if(action.startsWith('http://') || action.startsWith('https://') )
{
console.log("URL带有http:// 或 https:// 开头,无需进行处理")
headers = {
'Content-Type': dataType || default_headers,
...options.headers,
};
}else
{
options.action = config.base_url+action
headers = {
'Content-Type': dataType || default_headers,
...options.headers,
Authorization: `Bearer ${token}`,
'tenant-id': tenantId
};
}
// 发起请求
fetch(options.action, {
method: options.method || 'GET', // 默认请求方法为 GET
headers: headers, // 包含 Authorization 的请求头
body: options.method !== 'GET' ? JSON.stringify(options.data) : null, // 如果是 POST 或其他方法,添加请求体
})
.then(response => response.json()) // 解析响应为 JSON
.then(data => {
if (options.onSuccess) {
options.onSuccess(data); // 成功回调
}
})
.catch(error => {
if (options.onError) {
options.onError(error); // 失败回调
}
});
};