Files
ss-crm-manage-web/src/components/Search/src/Search.vue
2024-06-19 11:56:00 +08:00

229 lines
6.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts" name="Search" 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 { useRoute } from 'vue-router'
import * as ClueCacheApi from '@/api/clue/clueCache'
const route = useRoute()
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'),
showLabel: propTypes.bool.def(false),
showSearch: propTypes.bool.def(false),
showReset: propTypes.bool.def(false),
// 是否显示伸缩
expand: propTypes.bool.def(false),
// 伸缩的界限字段
expandField: propTypes.string.def(''),
inline: propTypes.bool.def(true),
inlineBlock: propTypes.bool.def(false),
model: {
type: Object as PropType<Recordable>,
default: () => ({})
}
})
// const emit = defineEmits(['search', 'reset'])
const visible = ref(true)
const SchemaSetting = ref()
const SettingPop = ref()
const checkedSchema = ref([])
// 用户使用的查询条件
const usedSchema = ref([])
const newSchema = computed(() => {
let schema: FormSchema[] = cloneDeep(usedSchema.value)
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'
}
}
])
}
return schema
})
const routeMap = {
CluePool: 1,
ClueOrder: 2
}
async function initSearch() {
reset()
checkedSchema.value = await ClueCacheApi.getClueCache({
settingType: 1,
model: routeMap[route.name]
})
usedSchema.value = props.schema.filter((it) => checkedSchema.value.includes(it.id))
}
function changeSearch() {
ClueCacheApi.setClueCache({
settingType: 1,
model: routeMap[route.name],
clueParamId: checkedSchema.value
})
usedSchema.value = props.schema.filter((it) => checkedSchema.value.includes(it.id))
}
function setSearch() {
unref(SettingPop).SettingPop?.delayHide?.()
}
const { register, elFormRef, methods } = useForm({
model: props.model || {}
})
// const search = async () => {
// await unref(elFormRef)?.validate(async (isValid) => {
// if (isValid) {
// const { getFormData } = methods
// const model = await getFormData()
// emit('search', model)
// }
// })
// }
const reset = async () => {
unref(elFormRef)?.resetFields()
// const { getFormData } = methods
// const model = await getFormData()
// emit('reset', model)
}
async function getFormModel() {
const { getFormData } = methods
const model = await getFormData()
return model
}
defineExpose({
getFormModel,
reset
})
const bottonButtonStyle = computed(() => {
return {
textAlign: props.buttomPosition as unknown as 'left' | 'center' | 'right'
}
})
const setVisible = () => {
unref(elFormRef)?.resetFields()
visible.value = !unref(visible)
}
initSearch()
</script>
<template>
<!-- update by 芋艿class="-mb-15px" 用于降低和 ContentWrap 组件的底部距离避免空隙过大 -->
<Form
:inline="inline"
:inlineBlock="inlineBlock"
:is-col="isCol"
:is-custom="false"
isSearch
:label-width="labelWidth"
:showLabel="showLabel"
:schema="newSchema"
class="-mb-15px"
hide-required-asterisk
@register="register"
>
<template #action>
<div v-if="layout === 'inline'">
<ElButton ref="SchemaSetting" @click="setSearch"> 查询设置 </ElButton>
<el-popover
ref="SettingPop"
:virtual-ref="SchemaSetting"
placement="bottom"
width="120px"
trigger="click"
virtual-triggering
>
<el-checkbox-group v-model="checkedSchema" @change="changeSearch">
<el-checkbox v-for="item in schema" :key="item.id" :label="item.id">
{{ item.label }}
</el-checkbox>
</el-checkbox-group>
</el-popover>
<!-- update by 芋艿去除搜索的 type="primary"颜色变淡一点 -->
<ElButton 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 v-if="showReset" @click="reset">
<!-- <Icon class="mr-5px" icon="ep:refresh" /> -->
{{ t('common.reset') }}
</ElButton>
<!-- add by 芋艿补充在搜索后的按钮 -->
<slot name="actionMore"></slot>
<!-- <ElButton v-if="expand" text @click="setVisible">
{{ t(visible ? 'common.shrink' : 'common.expand') }}
<Icon :icon="visible ? 'ep:arrow-up' : 'ep:arrow-down'" />
</ElButton> -->
</div>
</template>
<template v-for="name in Object.keys($slots)" :key="name" #[name]>
<slot :name="name"></slot>
</template>
</Form>
<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>