From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/components/Search/src/Search.vue |  157 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 157 insertions(+), 0 deletions(-)

diff --git a/src/components/Search/src/Search.vue b/src/components/Search/src/Search.vue
new file mode 100644
index 0000000..3218a63
--- /dev/null
+++ b/src/components/Search/src/Search.vue
@@ -0,0 +1,157 @@
+<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'
+
+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'])
+
+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'
+        }
+      }
+    ])
+  }
+  return schema
+})
+
+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)
+}
+
+const bottonButtonStyle = computed(() => {
+  return {
+    textAlign: props.buttomPosition as unknown as 'left' | 'center' | 'right'
+  }
+})
+
+const setVisible = () => {
+  unref(elFormRef)?.resetFields()
+  visible.value = !unref(visible)
+}
+</script>
+
+<template>
+  <!-- update by 鑺嬭壙锛歝lass="-mb-15px" 鐢ㄤ簬闄嶄綆鍜� ContentWrap 缁勪欢鐨勫簳閮ㄨ窛绂伙紝閬垮厤绌洪殭杩囧ぇ -->
+  <Form
+    :inline="inline"
+    :is-col="isCol"
+    :is-custom="false"
+    :label-width="labelWidth"
+    :schema="newSchema"
+    class="-mb-15px"
+    hide-required-asterisk
+    @register="register"
+  >
+    <template #action>
+      <div v-if="layout === 'inline'">
+        <!-- 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>
+        <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 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>

--
Gitblit v1.8.0