You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

212 lines
5.9 KiB

<script lang="ts" setup>
import { PropType } from 'vue'
import { propTypes } from '@/utils/propTypes'
import { useForm } from '@/hooks/web/useForm'
import { findIndex } from '@/utils'
import { cloneDeep } from 'lodash-es'
import { FormSchema } from '@/types/form'
import { useCache } from '@/hooks/web/useCache'
const { wsCache } = useCache()
defineOptions({ name: 'Search' })
const { t } = useI18n()
const props = defineProps({
// 生成Form的布局结构数组
schema: {
type: Array as PropType<FormSchema[]>,
default: () => []
},
// 是否需要栅格布局
isCol: propTypes.bool.def(false),
// 表单label宽度
labelWidth: propTypes.oneOfType([String, Number]).def('auto'),
// 操作按钮风格位置
layout: propTypes.string.validate((v: string) => ['inline', 'bottom'].includes(v)).def('inline'),
// 底部按钮的对齐方式
buttomPosition: propTypes.string
.validate((v: string) => ['left', 'center', 'right'].includes(v))
.def('center'),
showSearch: propTypes.bool.def(true),
showReset: propTypes.bool.def(true),
// 是否显示伸缩
expand: propTypes.bool.def(false),
// 伸缩的界限字段
expandField: propTypes.string.def(''),
inline: propTypes.bool.def(true),
model: {
type: Object as PropType<Recordable>,
default: () => ({})
}
})
const emit = defineEmits(['search', 'reset','onInput'])
const visible = ref(true)
const newSchema = computed(() => {
let schema: FormSchema[] = cloneDeep(props.schema)
if (props.expand && props.expandField && !unref(visible)) {
const index = findIndex(schema, (v: FormSchema) => v.field === props.expandField)
if (index > -1) {
const length = schema.length
schema.splice(index + 1, length)
}
}
if (props.layout === 'inline') {
schema = schema.concat([
{
field: 'action',
formItemProps: {
labelWidth: '0px'
}
}
])
}
updateSort(schema)
return schema
})
const updateSort= (val)=>{
val.forEach(item=>{
if(!item.sortSearchDefault){
if(item.field=="action"){
item.sortSearchDefault = 9999 // 查询重置等操作按钮
}else{
item.sortSearchDefault = 999 // 默认999
}
}
})
val.sort((column1,column2)=>{
return column1.sortSearchDefault - column2.sortSearchDefault
})
}
const { register, elFormRef, methods } = useForm({
model: props.model || {}
})
const onInput = (field,value) => {
emit('onInput', field,value)
}
const formRef = ref()
const setFormValues = (formData)=>{
formRef.value.setValues(formData)
}
const search = async () => {
await unref(elFormRef)?.validate(async (isValid) => {
if (isValid) {
const { getFormData } = methods
const model = await getFormData()
console.log(model)
emit('search', model)
}
})
}
const reset = async () => {
unref(elFormRef)?.resetFields()
const { getFormData } = methods
const model = await getFormData()
emit('reset', model)
}
const bottonButtonStyle = computed(() => {
return {
textAlign: props.buttomPosition as unknown as 'left' | 'center' | 'right'
}
})
const setVisible = () => {
unref(elFormRef)?.resetFields()
visible.value = !unref(visible)
}
const Search = ref()
onMounted(() => {})
defineExpose({setFormValues}) // 提供 open 方法,用于打开弹窗
</script>
<template>
<!-- update by 芋艿class="-mb-15px" 用于降低和 ContentWrap 组件的底部距离避免空隙过大 -->
<div ref="Search">
<Form ref="formRef"
:inline="inline"
:is-col="isCol"
:is-custom="false"
:label-width="labelWidth"
:schema="newSchema"
class="-mb-15px search"
hide-required-asterisk
@register="register"
@onInput="onInput"
>
<template #action>
<div v-if="layout === 'inline'">
<!-- update by 芋艿:去除搜索的 type="primary",颜色变淡一点 -->
<ElButton type="info" plain v-if="showSearch" @click="search">
<Icon class="mr-5px" icon="ep:search" />
{{ t('common.query') }}
</ElButton>
<!-- update by 芋艿:将 icon="ep:refresh-right" 修改成 icon="ep:refresh",和 ruoyi-vue 搜索保持一致 -->
<ElButton type="info" plain v-if="showReset" @click="reset">
<Icon class="mr-5px" icon="ep:refresh" />
{{ t('common.reset') }}
</ElButton>
<ElButton type="info" plain v-if="expand" text @click="setVisible">
{{ t(visible ? 'common.shrink' : 'common.expand') }}
<Icon :icon="visible ? 'ep:arrow-up' : 'ep:arrow-down'" />
</ElButton>
<!-- add by 芋艿:补充在搜索后的按钮 -->
<slot name="actionMore"></slot>
</div>
</template>
<template v-for="name in Object.keys($slots)" :key="name" #[name]>
<slot :name="name"></slot>
</template>
</Form>
</div>
<template v-if="layout === 'bottom'">
<div :style="bottonButtonStyle">
<ElButton v-if="showSearch" type="primary" @click="search">
<Icon class="mr-5px" icon="ep:search" />
{{ t('common.query') }}
</ElButton>
<ElButton v-if="showReset" @click="reset">
<Icon class="mr-5px" icon="ep:refresh-right" />
{{ t('common.reset') }}
</ElButton>
<ElButton v-if="expand" text @click="setVisible">
{{ t(visible ? 'common.shrink' : 'common.expand') }}
<Icon :icon="visible ? 'ep:arrow-up' : 'ep:arrow-down'" />
</ElButton>
<!-- add by 芋艿:补充在搜索后的按钮 -->
<slot name="actionMore"></slot>
</div>
</template>
</template>
<style lang="scss" scoped>
.search ::v-deep(.el-form-item) {
margin-right: 1%;
width: 20%;
}
.search ::v-deep(.el-form-item:nth-last-child(1)) {
margin-right: 0px;
width: auto;
.el-form-item__content {
flex: 1;
>div{
flex: 1;
button {
width: 46%;
max-width: 80px;
}
}
}
}
</style>