import _ from 'lodash'; import { queryUser as queryUserDefault, likeQueryUserById as likeQueryUserByIdDefault, } from '../server'; import { formatUserRender } from '../utils'; import { Button, Checkbox, Divider, Select, Space } from 'antd'; import { debounce } from 'lodash'; import { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { useIntl } from 'umi'; type UserType = { id: number; nameZh?: string; nameEn?: string; state?: number; account?: string; disabled?: boolean; }; export interface UserSelectProps { /** * @description 是否禁用。 * @default false * */ disabled?: boolean; value?: any; onChange?: (value: any) => void; /** * @description 可以选择单选还是多选,multiple是多选。 */ mode?: 'multiple' | 'tags' | undefined; /** * @description 是否需要展示全选功能。 */ showAllChecked?: boolean; state?: 0 | 1; placeholder?: string; /** * @description 选择填入本人 */ currentUser?: UserType; /** * @description 自定义的用户查询,如果自定义了queryUser,就一定要自定义likeQueryUserById */ queryUser?: (search: string, state?: 0 | 1) => Promise<{ data: { list: UserType[] } }>; /** * @description 自定义的用户根据id查询, 如果自定义了likeQueryUserById,就一定要自定义queryUser,如果没有自定义的likeQueryUserById 直接设置false就好了。 */ likeQueryUserById?: ((ids: number[]) => Promise<{ data: { list: UserType[] } }>) | false; } const UserSelect = ({ disabled = false, value, onChange, placeholder, mode, showAllChecked = false, state, currentUser, queryUser = queryUserDefault, likeQueryUserById = likeQueryUserByIdDefault, }: UserSelectProps) => { const { formatMessage } = useIntl(); const [options, setOptions] = useState([]); const [selectUserMap, setSelectUserMap] = useState({}); const [user, setUser] = useState(); const [disabledUserOptions, setDisabledUserOptions] = useState([]); const disabledUsers = useMemo( () => (mode ? value?.filter((item) => item?.disabled)?.map((item) => item?.id) : []), [value, mode], ); const valueIds = useMemo(() => (mode ? value?.map((item) => item?.id) : [value]), [value, mode]); const handleChange = useCallback( (val) => { if (mode) { // 原来的id // 删除的id const disabledIds = _.difference( valueIds, val?.map((item) => item), )?.filter((item) => _.includes(disabledUsers, item)); // 存在操作情况,要么新增一个,要么删除一个,要么全删, 要么全选。 // 所以要看有没有被删掉不能操作的id,有的话需要加进去。 onChange?.( [...val, ...disabledIds]?.map((item) => ({ ...(selectUserMap[item] || { id: item }), disabled: _.includes(disabledUsers, item), })), ); return; } onChange?.(val); }, [onChange, selectUserMap, mode, valueIds, disabledUsers], ); const searchChange = useMemo( () => debounce(async (val) => { if (!val) return; const { data: { list }, } = await queryUser(val.trim(), state); const newUserMap = {}; disabledUserOptions?.forEach((item) => { if (!_.find(list, { id: item.id })) { list?.push(item); } }); const res = list?.map((item) => { newUserMap[item.id] = { ...item, disabled: item.disabled || _.includes(disabledUsers, item?.id), }; return { label: (
{formatUserRender( { nameZh: item?.nameZh, account: item?.nameEn, id: item?.id, state: item?.state, }, false, false, )}
), key: item.id, value: item.id, disabled: item.disabled || _.includes(disabledUsers, item?.id), }; }); setOptions(res); setSelectUserMap((susemap) => ({ ...newUserMap, ...susemap })); }, 200), [queryUser, state, disabledUsers, disabledUserOptions], ); useEffect(() => { if (mode && value?.length > 0 && !_.isBoolean(likeQueryUserById)) { (likeQueryUserById as (ids: number[]) => Promise<{ data: { list: UserType[] } }>)?.( value?.map((item: { id: any }) => item?.id), ).then((resData) => { const { data: { list }, } = resData; const newUserMap = {}; setDisabledUserOptions( list ?.filter((item) => _.includes(disabledUsers, item?.id)) ?.map((item) => ({ ...item, disabled: true, })) || [], ); const res = list?.map((item) => { const itemDisabled = _.includes(disabledUsers, item?.id); newUserMap[item.id] = { cnName: item.nameZh || item.nameEn, userName: item.account, state: item.state, id: item.id, disabled: itemDisabled, }; return { label: (
{formatUserRender( { nameZh: item?.nameZh || item?.nameEn, account: item.account, id: item?.id, state: item?.state, }, itemDisabled, false, )}
), key: item.id, value: item.id, disabled: itemDisabled, }; }); setOptions(res); setSelectUserMap((susermap) => ({ ...susermap, ...newUserMap })); }); } if (!mode && value && !_.isBoolean(likeQueryUserById)) { ( likeQueryUserById as (ids: (number | string)[]) => Promise<{ data: { list: UserType[] } }> )?.([value]).then((resData) => { const { data: { list }, } = resData; const itemDisabled = _.includes(disabledUsers, list?.[0]?.id); const res = [ { label: (
{formatUserRender( { nameZh: list?.[0]?.nameZh || list?.[0]?.nameEn, account: list?.[0].account, id: list?.[0]?.id, state: list?.[0]?.state, }, itemDisabled, false, )}
), key: list?.[0].id, value: list?.[0].id, disabled: itemDisabled, }, ]; setOptions(res); }); } }, [value, disabledUsers, mode, likeQueryUserById]); useEffect(() => { if (!currentUser || currentUser?.nameEn) { setUser(currentUser); return; } if (!_.isBoolean(likeQueryUserById)) { (likeQueryUserById as (ids: number[]) => Promise<{ data: { list: UserType[] } }>)?.([ currentUser?.id, ]) .then((resData) => { const { data: { list }, } = resData; setUser(list[0]); }) .catch((error) => { console.error(error); }); } }, [currentUser, likeQueryUserById]); return (