mirror of
				https://github.com/continew-org/continew-admin-ui.git
				synced 2025-10-31 10:57:10 +08:00 
			
		
		
		
	refactor: 重构用户管理搜索栏(支持多条件展开及折叠)
This commit is contained in:
		| @@ -37,6 +37,7 @@ export interface UserImportResp { | |||||||
| export interface UserQuery { | export interface UserQuery { | ||||||
|   description?: string |   description?: string | ||||||
|   status?: number |   status?: number | ||||||
|  |   createTime?: Array<string> | ||||||
|   deptId?: string |   deptId?: string | ||||||
|   sort: Array<string> |   sort: Array<string> | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| <template> | <template> | ||||||
|   <a-form ref="formRef" v-bind="options.form" :model="modelValue" size="large" :auto-label-width="true"> |   <a-form ref="formRef" v-bind="options.form" :model="modelValue" :auto-label-width="true"> | ||||||
|     <a-row :gutter="14" v-bind="options.row" class="w-full"> |     <a-row :gutter="14" v-bind="options.row" class="w-full"> | ||||||
|       <template v-for="(item, index) in columns" :key="item.field"> |       <template v-for="(item, index) in columns" :key="item.field"> | ||||||
|         <a-col |         <a-col | ||||||
| @@ -150,10 +150,9 @@ | |||||||
|               </template> |               </template> | ||||||
|  |  | ||||||
|               <template v-if="item.type === 'range-picker'"> |               <template v-if="item.type === 'range-picker'"> | ||||||
|                 <a-range-picker |                 <DateRangePicker v-bind="(item.props as A.RangePickerInstance['$props'])" | ||||||
|                   v-bind="(item.props as A.RangePickerInstance['$props'])" |  | ||||||
|                                  :model-value="modelValue[item.field as keyof typeof modelValue]" |                                  :model-value="modelValue[item.field as keyof typeof modelValue]" | ||||||
|                   @update:model-value="valueChange($event, item.field)"></a-range-picker> |                                  @update:model-value="valueChange($event, item.field)" /> | ||||||
|               </template> |               </template> | ||||||
|  |  | ||||||
|               <template v-if="item.type === 'color-picker'"> |               <template v-if="item.type === 'color-picker'"> | ||||||
| @@ -191,7 +190,7 @@ | |||||||
|         </a-col> |         </a-col> | ||||||
|       </template> |       </template> | ||||||
|       <a-col v-if="!options.btns?.hide" :span="options.btns?.span || 12" v-bind="options.btns?.col"> |       <a-col v-if="!options.btns?.hide" :span="options.btns?.span || 12" v-bind="options.btns?.col"> | ||||||
|         <a-space wrap> |         <a-space wrap :size="[8, 16]"> | ||||||
|           <slot name="suffix"> |           <slot name="suffix"> | ||||||
|             <a-button type="primary" @click="emit('search')"> |             <a-button type="primary" @click="emit('search')"> | ||||||
|               <template #icon><icon-search /></template> |               <template #icon><icon-search /></template> | ||||||
| @@ -219,6 +218,7 @@ | |||||||
| import type * as A from '@arco-design/web-vue' | import type * as A from '@arco-design/web-vue' | ||||||
| import { cloneDeep } from 'lodash-es' | import { cloneDeep } from 'lodash-es' | ||||||
| import type { Columns, ColumnsItem, ColumnsItemDisabled, ColumnsItemHide, Options } from './type' | import type { Columns, ColumnsItem, ColumnsItemDisabled, ColumnsItemHide, Options } from './type' | ||||||
|  | import DateRangePicker from '@/components/DateRangePicker/index.vue' | ||||||
|  |  | ||||||
| interface Props { | interface Props { | ||||||
|   modelValue: any |   modelValue: any | ||||||
| @@ -304,4 +304,8 @@ watch(cloneForm as any, (newVal, oldVal) => { | |||||||
| }) | }) | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <style lang="scss" scoped></style> | <style lang="scss" scoped> | ||||||
|  |   :deep(.arco-form-item-layout-inline) { | ||||||
|  |     margin-right: 0; | ||||||
|  |   } | ||||||
|  | </style> | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ const title = computed( | |||||||
| const formRef = ref<InstanceType<typeof GiForm>>() | const formRef = ref<InstanceType<typeof GiForm>>() | ||||||
|  |  | ||||||
| const options: Options = { | const options: Options = { | ||||||
|   form: {}, |   form: { size: 'large' }, | ||||||
|   col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 }, |   col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 }, | ||||||
|   btns: { hide: true } |   btns: { hide: true } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ import { useUserStore } from '@/stores' | |||||||
| const { width } = useWindowSize() | const { width } = useWindowSize() | ||||||
|  |  | ||||||
| const options: Options = { | const options: Options = { | ||||||
|   form: {}, |   form: { size: 'large' }, | ||||||
|   col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 }, |   col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 }, | ||||||
|   btns: { hide: true } |   btns: { hide: true } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ const title = computed(() => (isUpdate.value ? '修改部门' : '新增部门')) | |||||||
| const formRef = ref<InstanceType<typeof GiForm>>() | const formRef = ref<InstanceType<typeof GiForm>>() | ||||||
|  |  | ||||||
| const options: Options = { | const options: Options = { | ||||||
|   form: {}, |   form: { size: 'large' }, | ||||||
|   col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 }, |   col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 }, | ||||||
|   btns: { hide: true } |   btns: { hide: true } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -38,7 +38,7 @@ const title = computed(() => (isUpdate.value ? '修改字典项' : '新增字典 | |||||||
| const formRef = ref<InstanceType<typeof GiForm>>() | const formRef = ref<InstanceType<typeof GiForm>>() | ||||||
|  |  | ||||||
| const options: Options = { | const options: Options = { | ||||||
|   form: {}, |   form: { size: 'large' }, | ||||||
|   col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 }, |   col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 }, | ||||||
|   btns: { hide: true } |   btns: { hide: true } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ const title = computed(() => (isUpdate.value ? '修改字典' : '新增字典')) | |||||||
| const formRef = ref<InstanceType<typeof GiForm>>() | const formRef = ref<InstanceType<typeof GiForm>>() | ||||||
|  |  | ||||||
| const options: Options = { | const options: Options = { | ||||||
|   form: {}, |   form: { size: 'large' }, | ||||||
|   col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 }, |   col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 }, | ||||||
|   btns: { hide: true } |   btns: { hide: true } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -49,7 +49,7 @@ const { form, resetForm } = useForm({ | |||||||
|   content: '' |   content: '' | ||||||
| }) | }) | ||||||
| const options: Options = { | const options: Options = { | ||||||
|   form: {}, |   form: { size: 'large' }, | ||||||
|   col: { xs: 24, sm: 24, md: 12, lg: 12, xl: 12, xxl: 12 }, |   col: { xs: 24, sm: 24, md: 12, lg: 12, xl: 12, xxl: 12 }, | ||||||
|   btns: { hide: true } |   btns: { hide: true } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ const dataId = ref('') | |||||||
| const formRef = ref<InstanceType<typeof GiForm>>() | const formRef = ref<InstanceType<typeof GiForm>>() | ||||||
|  |  | ||||||
| const options: Options = { | const options: Options = { | ||||||
|   form: {}, |   form: { size: 'large' }, | ||||||
|   col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 }, |   col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 }, | ||||||
|   btns: { hide: true } |   btns: { hide: true } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -145,7 +145,7 @@ onMounted(() => { | |||||||
|   height: 100%; |   height: 100%; | ||||||
|  |  | ||||||
|   &__search { |   &__search { | ||||||
|     margin-bottom: 10px; |     margin-bottom: 16px; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   &__container { |   &__container { | ||||||
|   | |||||||
| @@ -8,24 +8,23 @@ | |||||||
|       </a-space> |       </a-space> | ||||||
|     </a-row> |     </a-row> | ||||||
|     <a-row align="stretch" :gutter="14" class="h-full page_content"> |     <a-row align="stretch" :gutter="14" class="h-full page_content"> | ||||||
|       <a-col :xs="0" :sm="8" :md="7" :lg="6" :xl="5" :xxl="4" flex="260px" class="h-full ov-hidden"> |       <a-col :xs="0" :sm="0" :md="6" :lg="5" :xl="5" :xxl="4" class="h-full ov-hidden"> | ||||||
|         <DeptTree placeholder="请输入名称" @node-click="handleSelectDept" /> |         <DeptTree placeholder="请输入名称" @node-click="handleSelectDept" /> | ||||||
|       </a-col> |       </a-col> | ||||||
|       <a-col :xs="24" :sm="16" :md="17" :lg="18" :xl="19" :xxl="20" flex="1" class="h-full ov-hidden"> |       <a-col :xs="24" :sm="24" :md="18" :lg="19" :xl="19" :xxl="20" class="h-full ov-hidden"> | ||||||
|         <GiTable row-key="id" :data="dataList" :columns="columns" :loading="loading" |         <GiForm v-model="queryForm" :options="options" :columns="queryFormColumns" @search="search" @reset="reset"></GiForm> | ||||||
|                  :scroll="{ x: '100%', y: '100%', minWidth: 1500 }" :pagination="pagination" :disabled-tools="['size']" |         <GiTable | ||||||
|                  :disabled-column-keys="['username']" @refresh="search"> |           row-key="id" | ||||||
|  |           :data="dataList" | ||||||
|  |           :columns="columns" | ||||||
|  |           :loading="loading" | ||||||
|  |           :scroll="{ x: '100%', y: '100%', minWidth: 1500 }" | ||||||
|  |           :pagination="pagination" | ||||||
|  |           :disabled-tools="['size']" | ||||||
|  |           :disabled-column-keys="['username']" | ||||||
|  |           @refresh="search" | ||||||
|  |         > | ||||||
|           <template #custom-left> |           <template #custom-left> | ||||||
|             <a-input v-model="queryForm.description" placeholder="请输入用户名/昵称/描述" allow-clear @change="search"> |  | ||||||
|               <template #prefix> |  | ||||||
|                 <icon-search /> |  | ||||||
|               </template> |  | ||||||
|             </a-input> |  | ||||||
|             <a-select v-model="queryForm.status" :options="DisEnableStatusList" placeholder="请选择状态" allow-clear |  | ||||||
|                       style="width: 150px" @change="search" /> |  | ||||||
|             <a-button @click="reset">重置</a-button> |  | ||||||
|           </template> |  | ||||||
|           <template #custom-right> |  | ||||||
|             <a-button v-permission="['system:user:add']" type="primary" @click="onAdd"> |             <a-button v-permission="['system:user:add']" type="primary" @click="onAdd"> | ||||||
|               <template #icon> |               <template #icon> | ||||||
|                 <icon-plus /> |                 <icon-plus /> | ||||||
| @@ -38,13 +37,14 @@ | |||||||
|               </template> |               </template> | ||||||
|               <span>导入</span> |               <span>导入</span> | ||||||
|             </a-button> |             </a-button> | ||||||
|             <a-tooltip content="导出"> |           </template> | ||||||
|               <a-button v-permission="['system:user:export']" class="gi_hover_btn-border" @click="onExport"> |           <template #custom-right> | ||||||
|  |             <a-button v-permission="['system:user:export']" @click="onExport"> | ||||||
|               <template #icon> |               <template #icon> | ||||||
|                 <icon-download /> |                 <icon-download /> | ||||||
|               </template> |               </template> | ||||||
|  |               <template #default>导出</template> | ||||||
|             </a-button> |             </a-button> | ||||||
|             </a-tooltip> |  | ||||||
|           </template> |           </template> | ||||||
|           <template #username="{ record }"> |           <template #username="{ record }"> | ||||||
|             <GiCellAvatar :avatar="getAvatar(record.avatar, record.gender)" :name="record.username" is-link |             <GiCellAvatar :avatar="getAvatar(record.avatar, record.gender)" :name="record.username" is-link | ||||||
| @@ -66,9 +66,13 @@ | |||||||
|           <template #action="{ record }"> |           <template #action="{ record }"> | ||||||
|             <a-space> |             <a-space> | ||||||
|               <a-link v-permission="['system:user:update']" @click="onUpdate(record)">修改</a-link> |               <a-link v-permission="['system:user:update']" @click="onUpdate(record)">修改</a-link> | ||||||
|               <a-link v-permission="['system:user:delete']" status="danger" |               <a-link | ||||||
|                       :title="record.isSystem ? '系统内置数据不能删除' : '删除'" :disabled="record.disabled" |                 v-permission="['system:user:delete']" | ||||||
|                       @click="onDelete(record)"> |                 status="danger" | ||||||
|  |                 :title="record.isSystem ? '系统内置数据不能删除' : '删除'" | ||||||
|  |                 :disabled="record.disabled" | ||||||
|  |                 @click="onDelete(record)" | ||||||
|  |               > | ||||||
|                 删除 |                 删除 | ||||||
|               </a-link> |               </a-link> | ||||||
|               <a-dropdown> |               <a-dropdown> | ||||||
| @@ -97,8 +101,9 @@ import UserImportDrawer from './UserImportDrawer.vue' | |||||||
| import UserDetailDrawer from './UserDetailDrawer.vue' | import UserDetailDrawer from './UserDetailDrawer.vue' | ||||||
| import UserResetPwdModal from './UserResetPwdModal.vue' | import UserResetPwdModal from './UserResetPwdModal.vue' | ||||||
| import { type UserQuery, type UserResp, deleteUser, exportUser, listUser } from '@/apis/system' | import { type UserQuery, type UserResp, deleteUser, exportUser, listUser } from '@/apis/system' | ||||||
|  | import type { Columns, Options } from '@/components/GiForm' | ||||||
| import type { TableInstanceColumns } from '@/components/GiTable/type' | import type { TableInstanceColumns } from '@/components/GiTable/type' | ||||||
| import { useDownload, useTable } from '@/hooks' | import { useBreakpointIndex, useDownload, useTable } from '@/hooks' | ||||||
| import { isMobile } from '@/utils' | import { isMobile } from '@/utils' | ||||||
| import getAvatar from '@/utils/avatar' | import getAvatar from '@/utils/avatar' | ||||||
| import has from '@/utils/has' | import has from '@/utils/has' | ||||||
| @@ -109,7 +114,6 @@ defineOptions({ name: 'SystemUser' }) | |||||||
| const queryForm = reactive<UserQuery>({ | const queryForm = reactive<UserQuery>({ | ||||||
|   sort: ['t1.createTime,desc'] |   sort: ['t1.createTime,desc'] | ||||||
| }) | }) | ||||||
|  |  | ||||||
| const { | const { | ||||||
|   tableData: dataList, |   tableData: dataList, | ||||||
|   loading, |   loading, | ||||||
| @@ -118,6 +122,52 @@ const { | |||||||
|   handleDelete |   handleDelete | ||||||
| } = useTable((page) => listUser({ ...queryForm, ...page }), { immediate: false }) | } = useTable((page) => listUser({ ...queryForm, ...page }), { immediate: false }) | ||||||
|  |  | ||||||
|  | const options: Options = reactive({ | ||||||
|  |   form: { layout: 'inline' }, | ||||||
|  |   col: { xs: 24, sm: 24, md: 5, lg: 5, xl: 5, xxl: 5 }, | ||||||
|  |   btns: { col: { xs: 24, sm: 24, md: 7, lg: 7, xl: 7, xxl: 7 } }, | ||||||
|  |   fold: { enable: true, index: 2, defaultCollapsed: true } | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | useBreakpointIndex((index) => { | ||||||
|  |   // 自适应折叠,让折叠后始终一行显示 | ||||||
|  |   options.fold && (options.fold.index = index) | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | const queryFormColumns: Columns = reactive([ | ||||||
|  |   { | ||||||
|  |     type: 'input', | ||||||
|  |     field: 'description', | ||||||
|  |     item: { | ||||||
|  |       hideLabel: true | ||||||
|  |     }, | ||||||
|  |     props: { | ||||||
|  |       placeholder: '请输入用户名/昵称/描述', | ||||||
|  |       allowClear: true | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     type: 'select', | ||||||
|  |     field: 'status', | ||||||
|  |     options: DisEnableStatusList, | ||||||
|  |     item: { | ||||||
|  |       hideLabel: true | ||||||
|  |     }, | ||||||
|  |     props: { | ||||||
|  |       placeholder: '请选择状态', | ||||||
|  |       allowClear: true | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     type: 'range-picker', | ||||||
|  |     field: 'createTime', | ||||||
|  |     item: { | ||||||
|  |       hideLabel: true | ||||||
|  |     }, | ||||||
|  |     col: { xs: 24, sm: 24, md: 10, lg: 10, xl: 10, xxl: 10 } | ||||||
|  |   } | ||||||
|  | ]) | ||||||
|  |  | ||||||
| const columns: TableInstanceColumns[] = [ | const columns: TableInstanceColumns[] = [ | ||||||
|   { |   { | ||||||
|     title: '序号', |     title: '序号', | ||||||
| @@ -162,6 +212,7 @@ const columns: TableInstanceColumns[] = [ | |||||||
| const reset = () => { | const reset = () => { | ||||||
|   queryForm.description = undefined |   queryForm.description = undefined | ||||||
|   queryForm.status = undefined |   queryForm.status = undefined | ||||||
|  |   queryForm.createTime = [] | ||||||
|   search() |   search() | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user