Browse Source

新增高级查询组件my-select-input

zhontai 2 years ago
parent
commit
92d272e1f5

+ 63 - 0
src/components/my-select-input/index.vue

@@ -0,0 +1,63 @@
+<template>
+  <el-input v-model="state.filter.value" class="my-input-with-select" @keyup.enter="onSearch" v-bind="$attrs">
+    <template v-if="state.filters.length > 0" #prepend>
+      <el-select v-model="state.filter.field" style="width: 100px" @change="onChange">
+        <el-option v-for="field in state.filters" :key="field.field" :label="field.description" :value="field.field" />
+      </el-select>
+    </template>
+  </el-input>
+</template>
+
+<script lang="ts" setup name="my-select-input">
+import { reactive, PropType, watch } from 'vue'
+import { cloneDeep } from 'lodash-es'
+
+const props = defineProps({
+  modelValue: Object as PropType<any | undefined | null>,
+  filters: {
+    type: Array<DynamicFilterInfo>,
+    default() {
+      return []
+    },
+  },
+})
+
+const emits = defineEmits(['update:modelValue', 'search'])
+
+const filters = props.filters.filter((a) => a.componentName === 'el-input')
+let filter = {} as DynamicFilterInfo
+if (filters.length > 0) {
+  filter = cloneDeep(filters.find((a) => a.defaultSelect) || filters[0])
+}
+
+const state = reactive({
+  filters: filters,
+  filter: {
+    field: props.modelValue?.field || filter.field,
+    operator: props.modelValue?.operator || filter.operator,
+    value: props.modelValue?.value || filter.value,
+  } as DynamicFilterInfo,
+})
+
+const onChange = () => {
+  state.filter.value = ''
+}
+
+const onSearch = () => {
+  emits('search', cloneDeep(state.filter))
+}
+
+watch(
+  () => state.filter,
+  () => {
+    emits('update:modelValue', cloneDeep(state.filter))
+  },
+  { deep: true }
+)
+</script>
+
+<style scoped lang="scss">
+.my-input-with-select :deep(.el-input-group__prepend) {
+  background-color: var(--el-fill-color-blank);
+}
+</style>

+ 31 - 0
src/types/views.d.ts

@@ -327,3 +327,34 @@ declare type TableDemoState = {
     param: EmptyObjectType
   }
 }
+
+declare type ComponentEnum = 'el-input'
+declare type OperatorEnum =
+  | 'Contains'
+  | 'StartsWith'
+  | 'EndsWith'
+  | 'NotContains'
+  | 'NotStartsWith'
+  | 'NotEndsWith'
+  | 'Equal'
+  | 'Equals'
+  | 'Eq'
+  | 'NotEqual'
+  | 'GreaterThan'
+  | 'GreaterThanOrEqual'
+  | 'LessThan'
+  | 'LessThanOrEqual'
+  | 'Range'
+  | 'DateRange'
+  | 'Any'
+  | 'NotAny'
+  | 'Custom'
+
+declare type DynamicFilterInfo = {
+  field: string
+  operator: OperatorEnum = 'Eq'
+  value: string
+  description: string
+  defaultSelect: boolean
+  componentName: ComponentEnum = 'el-input'
+}

+ 3 - 3
src/views/admin/role/index.vue

@@ -94,9 +94,9 @@
             @row-click="onUserRowClick"
           >
             <el-table-column type="selection" width="55" />
-            <el-table-column prop="name" label="姓名" show-overflow-tooltip />
-            <!-- <el-table-column prop="mobile" label="手机号" width="120" show-overflow-tooltip />
-            <el-table-column prop="email" label="邮箱" min-width="120" show-overflow-tooltip /> -->
+            <el-table-column prop="name" label="姓名" min-width="120" show-overflow-tooltip />
+            <el-table-column prop="mobile" label="手机号" min-width="120" show-overflow-tooltip />
+            <!-- <el-table-column prop="email" label="邮箱" min-width="120" show-overflow-tooltip /> -->
           </el-table>
         </el-card>
       </el-col>

+ 32 - 6
src/views/admin/user/index.vue

@@ -8,9 +8,9 @@
       </el-col>
       <el-col :xs="24" :sm="16" :md="16" :lg="18" :xl="20">
         <el-card shadow="never" :body-style="{ paddingBottom: '0' }" style="margin-top: 8px">
-          <el-form :model="state.filterModel" :inline="true" @submit.stop.prevent>
-            <el-form-item label="姓名" prop="name">
-              <el-input v-model="state.filterModel.name" placeholder="姓名" @keyup.enter="onQuery" />
+          <el-form inline="true" @submit.stop.prevent>
+            <el-form-item>
+              <my-select-input v-model="state.pageInput.dynamicFilter" :filters="state.filters" @search="onQuery" />
             </el-form-item>
             <el-form-item>
               <el-button type="primary" icon="ele-Search" @click="onQuery"> 查询 </el-button>
@@ -80,6 +80,7 @@ import { auth } from '/@/utils/authFunction'
 const UserForm = defineAsyncComponent(() => import('./components/user-form.vue'))
 const OrgMenu = defineAsyncComponent(() => import('/@/views/admin/org/components/org-menu.vue'))
 const MyDropdownMore = defineAsyncComponent(() => import('/@/components/my-dropdown-more/index.vue'))
+const MySelectInput = defineAsyncComponent(() => import('/@/components/my-select-input/index.vue'))
 
 const { proxy } = getCurrentInstance() as any
 
@@ -88,9 +89,6 @@ const userFormRef = ref()
 const state = reactive({
   loading: false,
   userFormTitle: '',
-  filterModel: {
-    name: '',
-  },
   total: 0,
   pageInput: {
     currentPage: 1,
@@ -98,8 +96,36 @@ const state = reactive({
     filter: {
       orgId: null,
     },
+    dynamicFilter: {},
   } as PageInputUserGetPageDto,
   userListData: [] as Array<UserGetPageOutput>,
+  filters: [
+    {
+      field: 'name',
+      operator: 'Contains',
+      description: '姓名',
+      componentName: 'el-input',
+      defaultSelect: true,
+    },
+    {
+      field: 'mobile',
+      operator: 'Contains',
+      description: '手机号',
+      componentName: 'el-input',
+    },
+    {
+      field: 'email',
+      operator: 'Contains',
+      description: '邮箱',
+      componentName: 'el-input',
+    },
+    {
+      field: 'userName',
+      operator: 'Contains',
+      description: '用户名',
+      componentName: 'el-input',
+    },
+  ] as Array<DynamicFilterInfo>,
 })
 
 onMounted(() => {