mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2025-09-09 20:57:17 +08:00
fix: 修复用户选择器bug
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
:columns="tableColumns"
|
:columns="tableColumns"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:scroll="{ x: '100%', y: '100%', minWidth: 1000 }"
|
:scroll="{ x: '100%', y: '100%', minWidth: 1000 }"
|
||||||
|
style="max-height: 600px"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:disabled-tools="['size', 'fullscreen', 'setting', 'refresh']"
|
:disabled-tools="['size', 'fullscreen', 'setting', 'refresh']"
|
||||||
:row-selection="{ type: props.multiple ? 'checkbox' : 'radio', showCheckedAll: true }"
|
:row-selection="{ type: props.multiple ? 'checkbox' : 'radio', showCheckedAll: true }"
|
||||||
@@ -30,7 +31,9 @@
|
|||||||
@change="search"
|
@change="search"
|
||||||
/>
|
/>
|
||||||
<a-button @click="reset">
|
<a-button @click="reset">
|
||||||
<template #icon><icon-refresh /></template>
|
<template #icon>
|
||||||
|
<icon-refresh />
|
||||||
|
</template>
|
||||||
<template #default>重置</template>
|
<template #default>重置</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
@@ -59,7 +62,7 @@
|
|||||||
|
|
||||||
<a-col :span="24" :md="6" class="section">
|
<a-col :span="24" :md="6" class="section">
|
||||||
<a-card title="已选用户">
|
<a-card title="已选用户">
|
||||||
<a-table :columns="rightColumn" :data="selectedData">
|
<a-table :columns="rightColumn" :data="selectedData" :pagination="paginationOptions">
|
||||||
<template #nickname="{ record }">
|
<template #nickname="{ record }">
|
||||||
{{ record.nickname }}({{ record.username }})
|
{{ record.nickname }}({{ record.username }})
|
||||||
</template>
|
</template>
|
||||||
@@ -78,9 +81,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { TreeNodeData } from '@arco-design/web-vue'
|
import type { TreeNodeData } from '@arco-design/web-vue'
|
||||||
import { useDept } from '@/hooks/app'
|
import { useDept } from '@/hooks/app'
|
||||||
import { useTable } from '@/hooks'
|
import { type Options, useTable } from '@/hooks'
|
||||||
import { type UserQuery, listAllUser, listUser } from '@/apis'
|
import { type UserQuery, type UserResp, listAllUser, listUser } from '@/apis'
|
||||||
import type { UserItem, UserSelectPropType } from '@/components/UserSelect/type'
|
import type { UserSelectPropType } from '@/components/UserSelect/type'
|
||||||
import type { TableInstanceColumns } from '@/components/GiTable/type'
|
import type { TableInstanceColumns } from '@/components/GiTable/type'
|
||||||
import { isMobile } from '@/utils'
|
import { isMobile } from '@/utils'
|
||||||
|
|
||||||
@@ -127,6 +130,11 @@ const rightColumn = [
|
|||||||
const queryForm = reactive<UserQuery>({
|
const queryForm = reactive<UserQuery>({
|
||||||
sort: ['t1.createTime,desc'],
|
sort: ['t1.createTime,desc'],
|
||||||
})
|
})
|
||||||
|
// 定义分页器参数
|
||||||
|
const paginationOptions: Options = {
|
||||||
|
defaultPageSize: 10,
|
||||||
|
defaultSizeOptions: [10, 20, 30, 40, 50],
|
||||||
|
}
|
||||||
|
|
||||||
// 用户列表
|
// 用户列表
|
||||||
const { tableData: dataList, loading, pagination, search } = useTable(
|
const { tableData: dataList, loading, pagination, search } = useTable(
|
||||||
@@ -157,65 +165,92 @@ const filterDeptOptions = (searchKey: string, nodeData: TreeNodeData) => {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedKeys = ref<string[]>([])
|
const allUsers = ref<UserResp[]>() // 用于存储所有用户信息
|
||||||
const selectedData = ref<any[]>([])
|
const selectedKeys = ref<string[]>([]) // 使用 Array 来存储选中的 id
|
||||||
|
const selectedData = ref<Set<UserResp>>(new Set()) // 使用 Set 来存储选中的用户对象
|
||||||
|
|
||||||
const emitSelectedUsers = () => {
|
const emitSelectedUsers = () => {
|
||||||
emit('update:selectedUsers', selectedKeys.value)
|
emit('update:selectedUsers', selectedKeys.value)
|
||||||
}
|
}
|
||||||
// 行选择事件
|
// 行选择事件
|
||||||
const onRowSelect = (rowKeys: string[], rowKey: string, record: UserItem) => {
|
const onRowSelect = (rowKeys: string[], rowKey: string, record: UserResp) => {
|
||||||
selectedData.value = props.multiple
|
if (props.multiple) {
|
||||||
? rowKeys.includes(rowKey)
|
// 多选
|
||||||
? [...selectedData.value, record]
|
if (rowKeys.includes(rowKey)) {
|
||||||
: selectedData.value.filter((item) => item.id !== rowKey)
|
// 包含 选中
|
||||||
: [record]
|
selectedData.value.add(record)
|
||||||
selectedKeys.value = selectedData.value.map((item) => item.id)
|
selectedKeys.value?.push(rowKey)
|
||||||
|
} else {
|
||||||
|
// 不包含 去除
|
||||||
|
selectedData.value.delete(record)
|
||||||
|
selectedKeys.value?.splice(selectedKeys.value?.indexOf(rowKey), 1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 单选
|
||||||
|
selectedData.value.clear()
|
||||||
|
selectedKeys.value = []
|
||||||
|
if (rowKeys.includes(rowKey)) {
|
||||||
|
// 包含 选中
|
||||||
|
selectedData.value.add(record)
|
||||||
|
selectedKeys.value?.push(rowKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
emitSelectedUsers()
|
emitSelectedUsers()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 全选事件
|
// 全选事件
|
||||||
const onTableSelectAll = (checked: boolean) => {
|
const onTableSelectAll = (checked: boolean) => {
|
||||||
selectedData.value = checked
|
if (checked) {
|
||||||
? [...selectedData.value, ...dataList.value.filter((item) => !selectedKeys.value.includes(item.id))]
|
// 选中
|
||||||
: []
|
dataList.value.forEach((item) => {
|
||||||
selectedKeys.value = selectedData.value.map((item) => item.id)
|
selectedData.value.add(item)
|
||||||
|
selectedKeys.value?.push(item.id)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 取消选中
|
||||||
|
dataList.value.forEach((item) => {
|
||||||
|
selectedData.value.delete(item)
|
||||||
|
selectedKeys.value?.splice(selectedKeys.value?.indexOf(item.id), 1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
emitSelectedUsers()
|
emitSelectedUsers()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从选中列表中移除用户
|
// 从选中列表中移除用户
|
||||||
const handleDeleteSelectUser = (user: UserItem) => {
|
const handleDeleteSelectUser = (user: UserResp) => {
|
||||||
selectedData.value = selectedData.value.filter((item) => item.id !== user.id)
|
selectedData.value.delete(user)
|
||||||
selectedKeys.value = selectedData.value.map((item) => item.id)
|
selectedKeys.value?.splice(selectedKeys.value?.indexOf(user.id), 1)
|
||||||
emitSelectedUsers()
|
emitSelectedUsers()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清空所有选中数据
|
// 清空所有选中数据
|
||||||
const onClearSelected = () => {
|
const onClearSelected = () => {
|
||||||
selectedData.value = []
|
selectedData.value.clear()
|
||||||
selectedKeys.value = []
|
selectedKeys.value = []
|
||||||
emitSelectedUsers()
|
emitSelectedUsers()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化函数
|
// 初始化函数
|
||||||
const init = (selectUsers: string[]) => {
|
const init = async (selectUsers: string[]) => {
|
||||||
getDeptList()
|
getDeptList()
|
||||||
search()
|
search()
|
||||||
|
// 获取所有用户数据
|
||||||
|
const { data } = await listAllUser({})
|
||||||
|
allUsers.value = data
|
||||||
|
|
||||||
|
// 过滤已选择的用户
|
||||||
if (selectUsers && selectUsers.length > 0) {
|
if (selectUsers && selectUsers.length > 0) {
|
||||||
// admin的id是number 不是string 类型 所以处理一下
|
if (props.multiple) {
|
||||||
listAllUser({ userIds: selectUsers }).then((dataList) => {
|
selectedData.value = new Set(allUsers.value.filter((item) => selectUsers.includes(item.id)))
|
||||||
selectedData.value = dataList.data.map((data) => {
|
selectedKeys.value = Array.from(selectedData.value).map((user) => user.id)
|
||||||
return { ...data, id: data.id }
|
} else {
|
||||||
})
|
selectedData.value = new Set(allUsers.value.filter((item) => selectUsers[0] === item.id))
|
||||||
})
|
selectedKeys.value = Array.from(selectedData.value).map((user) => user.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(() => props.selectedUsers, (newValue) => {
|
|
||||||
const newSelectedKeys = Array.isArray(newValue) ? newValue : [newValue]
|
|
||||||
selectedKeys.value = newSelectedKeys.filter(Boolean)
|
|
||||||
selectedData.value = dataList.value.filter((item) => selectedKeys.value.includes(item.id))
|
|
||||||
}, { immediate: true })
|
|
||||||
|
|
||||||
defineExpose({ init, onClearSelected })
|
defineExpose({ init, onClearSelected })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@@ -40,19 +40,19 @@ import { useWindowSize } from '@vueuse/core'
|
|||||||
import UserSelectContent from './component/UserSelectContent.vue'
|
import UserSelectContent from './component/UserSelectContent.vue'
|
||||||
import { listUserDict } from '@/apis'
|
import { listUserDict } from '@/apis'
|
||||||
import type { UserSelectPropType } from '@/components/UserSelect/type'
|
import type { UserSelectPropType } from '@/components/UserSelect/type'
|
||||||
|
import type { LabelValueState } from '@/types/global'
|
||||||
|
|
||||||
const props = withDefaults(defineProps<UserSelectPropType>(), {
|
const props = withDefaults(defineProps<UserSelectPropType>(), {
|
||||||
multiple: false, // 是否支持多选
|
multiple: false, // 是否支持多选
|
||||||
value: '',
|
value: [], // 单选时默认值为空数组
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['update:value'])
|
const emit = defineEmits(['update:value'])
|
||||||
|
|
||||||
const { width } = useWindowSize() // 获取窗口的宽度,用于设置弹窗宽度
|
const { width } = useWindowSize() // 获取窗口的宽度,用于设置弹窗宽度
|
||||||
const visible = ref<boolean>(false) // 控制弹窗显示的状态
|
const visible = ref<boolean>(false) // 控制弹窗显示的状态
|
||||||
const userList = ref([]) // 保存用户选项列表
|
const userList = ref<LabelValueState[]>([]) // 保存用户选项列表
|
||||||
const userSelectContentRef = ref() // 引用 UserSelectContent 组件实例
|
const userSelectContentRef = ref() // 引用 UserSelectContent 组件实例
|
||||||
const selectedUsers = ref([]) // 保存已选择的用户
|
const selectedUsers = ref<string[]>([]) // 保存已选择的用户
|
||||||
|
|
||||||
// 打开用户选择弹窗
|
// 打开用户选择弹窗
|
||||||
const onOpen = () => {
|
const onOpen = () => {
|
||||||
visible.value = true
|
visible.value = true
|
||||||
@@ -66,7 +66,13 @@ const emitDataChange = () => {
|
|||||||
|
|
||||||
// 处理用户选择变更事件
|
// 处理用户选择变更事件
|
||||||
const handleSelectChange = (value: any) => {
|
const handleSelectChange = (value: any) => {
|
||||||
selectedUsers.value = props.multiple ? value : [...value]
|
if (props.multiple) {
|
||||||
|
// 多选模式下,selectedUsers 应该是一个数组
|
||||||
|
selectedUsers.value = value
|
||||||
|
} else {
|
||||||
|
// 单选模式下,selectedUsers 只应保存一个值
|
||||||
|
selectedUsers.value = value ? [value] : []
|
||||||
|
}
|
||||||
emitDataChange() // 每次选择变化时发出更新事件
|
emitDataChange() // 每次选择变化时发出更新事件
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,15 +96,3 @@ onMounted(async () => {
|
|||||||
selectedUsers.value = Array.isArray(props.value) ? props.value : props.value?.split(',')
|
selectedUsers.value = Array.isArray(props.value) ? props.value : props.value?.split(',')
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
:deep(.arco-input-append) {
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
.arco-btn {
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
export interface UserSelectPropType {
|
export interface UserSelectPropType {
|
||||||
multiple: boolean
|
multiple: boolean
|
||||||
value?: string[]
|
value: string[] | string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserItem {
|
export interface UserItem {
|
||||||
|
Reference in New Issue
Block a user