houzhongjian
2024-08-08 820397e43a0b64d35c6d31d2a55475061438593b
提交 | 用户 | 时间
820397 1 <script lang="ts" setup>
H 2 import { PropType } from 'vue'
3 import { propTypes } from '@/utils/propTypes'
4
5 import { useForm } from '@/hooks/web/useForm'
6 import { findIndex } from '@/utils'
7 import { cloneDeep } from 'lodash-es'
8 import { FormSchema } from '@/types/form'
9
10 defineOptions({ name: 'Search' })
11
12 const { t } = useI18n()
13
14 const props = defineProps({
15   // 生成Form的布局结构数组
16   schema: {
17     type: Array as PropType<FormSchema[]>,
18     default: () => []
19   },
20   // 是否需要栅格布局
21   isCol: propTypes.bool.def(false),
22   // 表单label宽度
23   labelWidth: propTypes.oneOfType([String, Number]).def('auto'),
24   // 操作按钮风格位置
25   layout: propTypes.string.validate((v: string) => ['inline', 'bottom'].includes(v)).def('inline'),
26   // 底部按钮的对齐方式
27   buttomPosition: propTypes.string
28     .validate((v: string) => ['left', 'center', 'right'].includes(v))
29     .def('center'),
30   showSearch: propTypes.bool.def(true),
31   showReset: propTypes.bool.def(true),
32   // 是否显示伸缩
33   expand: propTypes.bool.def(false),
34   // 伸缩的界限字段
35   expandField: propTypes.string.def(''),
36   inline: propTypes.bool.def(true),
37   model: {
38     type: Object as PropType<Recordable>,
39     default: () => ({})
40   }
41 })
42
43 const emit = defineEmits(['search', 'reset'])
44
45 const visible = ref(true)
46
47 const newSchema = computed(() => {
48   let schema: FormSchema[] = cloneDeep(props.schema)
49   if (props.expand && props.expandField && !unref(visible)) {
50     const index = findIndex(schema, (v: FormSchema) => v.field === props.expandField)
51     if (index > -1) {
52       const length = schema.length
53       schema.splice(index + 1, length)
54     }
55   }
56   if (props.layout === 'inline') {
57     schema = schema.concat([
58       {
59         field: 'action',
60         formItemProps: {
61           labelWidth: '0px'
62         }
63       }
64     ])
65   }
66   return schema
67 })
68
69 const { register, elFormRef, methods } = useForm({
70   model: props.model || {}
71 })
72
73 const search = async () => {
74   await unref(elFormRef)?.validate(async (isValid) => {
75     if (isValid) {
76       const { getFormData } = methods
77       const model = await getFormData()
78       emit('search', model)
79     }
80   })
81 }
82
83 const reset = async () => {
84   unref(elFormRef)?.resetFields()
85   const { getFormData } = methods
86   const model = await getFormData()
87   emit('reset', model)
88 }
89
90 const bottonButtonStyle = computed(() => {
91   return {
92     textAlign: props.buttomPosition as unknown as 'left' | 'center' | 'right'
93   }
94 })
95
96 const setVisible = () => {
97   unref(elFormRef)?.resetFields()
98   visible.value = !unref(visible)
99 }
100 </script>
101
102 <template>
103   <!-- update by 芋艿:class="-mb-15px" 用于降低和 ContentWrap 组件的底部距离,避免空隙过大 -->
104   <Form
105     :inline="inline"
106     :is-col="isCol"
107     :is-custom="false"
108     :label-width="labelWidth"
109     :schema="newSchema"
110     class="-mb-15px"
111     hide-required-asterisk
112     @register="register"
113   >
114     <template #action>
115       <div v-if="layout === 'inline'">
116         <!-- update by 芋艿:去除搜索的 type="primary",颜色变淡一点 -->
117         <ElButton v-if="showSearch" @click="search">
118           <Icon class="mr-5px" icon="ep:search" />
119           {{ t('common.query') }}
120         </ElButton>
121         <!-- update by 芋艿:将 icon="ep:refresh-right" 修改成 icon="ep:refresh",和 ruoyi-vue 搜索保持一致  -->
122         <ElButton v-if="showReset" @click="reset">
123           <Icon class="mr-5px" icon="ep:refresh" />
124           {{ t('common.reset') }}
125         </ElButton>
126         <ElButton v-if="expand" text @click="setVisible">
127           {{ t(visible ? 'common.shrink' : 'common.expand') }}
128           <Icon :icon="visible ? 'ep:arrow-up' : 'ep:arrow-down'" />
129         </ElButton>
130         <!-- add by 芋艿:补充在搜索后的按钮 -->
131         <slot name="actionMore"></slot>
132       </div>
133     </template>
134     <template v-for="name in Object.keys($slots)" :key="name" #[name]>
135       <slot :name="name"></slot>
136     </template>
137   </Form>
138
139   <template v-if="layout === 'bottom'">
140     <div :style="bottonButtonStyle">
141       <ElButton v-if="showSearch" type="primary" @click="search">
142         <Icon class="mr-5px" icon="ep:search" />
143         {{ t('common.query') }}
144       </ElButton>
145       <ElButton v-if="showReset" @click="reset">
146         <Icon class="mr-5px" icon="ep:refresh-right" />
147         {{ t('common.reset') }}
148       </ElButton>
149       <ElButton v-if="expand" text @click="setVisible">
150         {{ t(visible ? 'common.shrink' : 'common.expand') }}
151         <Icon :icon="visible ? 'ep:arrow-up' : 'ep:arrow-down'" />
152       </ElButton>
153       <!-- add by 芋艿:补充在搜索后的按钮 -->
154       <slot name="actionMore"></slot>
155     </div>
156   </template>
157 </template>