import { Button, Empty, Form, Input, Typography } from 'antd'; import { useWatch } from 'antd/lib/form/Form'; import Link from 'antd/lib/typography/Link'; import { Space } from 'antd5'; import _ from 'lodash'; import { useCallback, useContext, useMemo, useState } from 'react'; import { useIntl } from 'umi'; import CustomTree from '../../CustomTree'; import { leafBuildTree, treeLeafNode } from '../../utils/array'; import { relationUserCityRemove } from '../api'; import { DetailContext } from '../detail'; import { createCancelInterceptor } from '../util'; export interface CityTabProps { cityOptions: any[]; oldCityList: any[]; searchSeparator?: string; detailRefresh?: () => void; cityRefresh?: () => void; } const CityTab = (props: CityTabProps) => { const { cityOptions, oldCityList, searchSeparator = ' ', detailRefresh, cityRefresh } = props; const { id: appId, type, useType, currentUser, form, onSyncCitySelect, } = useContext(DetailContext); const { formatMessage } = useIntl(); const [search, setSearch] = useState(''); // 搜索过滤后的树 const treeData = useMemo(() => { if (!search || !search.trim()) return cityOptions; const split = search.trim().split(searchSeparator); const leafKeys = treeLeafNode(cityOptions, (item) => { return split.some((k: string) => item.name?.includes(k)); }).map((item) => item.id); return leafBuildTree(leafKeys, cityOptions); }, [cityOptions, search, searchSeparator]); const cities = useWatch('cities', form); const { data: cityData } = cities || {}; // 选择全部 const selectAll = useCallback( (item?: any) => { const currSelect: any[] = cityData?.filter((v: any) => v) || []; const currKeys = currSelect.map((v) => String(v.id)); const find = (id: string) => { return currSelect.find((v) => String(v.id) === id) ?? { id, expiredAt: undefined }; }; if (item) { const leafs = treeLeafNode([item]).map((v) => String(v.id)); const newKeys = [...new Set([...currKeys, ...leafs])]; const data = newKeys.map(find); form?.setFieldsValue({ cities: { data } }); } else { // 全部选择 const leafs = treeLeafNode(treeData).map((v) => String(v.id)); const newKeys = [...new Set([...currKeys, ...leafs])]; const data = newKeys.map(find); form?.setFieldsValue({ cities: { data } }); } }, [cityData, form, treeData], ); // 取消选择 const unSelectAll = useCallback( (item?: any) => { const currSelect: any[] = cityData?.filter((v: any) => v) || []; const currKeys = currSelect.map((v) => String(v.id)); const oldKeys = oldCityList?.map((v) => String(v.cityId ?? v.id)) ?? []; const find = (id: string) => { return currSelect.find((v) => String(v.id) === id); }; if (item) { const leafs = treeLeafNode([item]).map((v) => String(v.id)); const data = currKeys.filter((id) => !leafs.includes(id) || oldKeys.includes(id)).map(find); form?.setFieldsValue({ cities: { data } }); } else { // 全部取消 const data = oldKeys.map(find); form?.setFieldsValue({ cities: { data } }); } }, [cityData, form, oldCityList], ); return cityOptions?.length ? ( ({ ...item, id: item.cityId ?? item.id }))} onlyLeafCheckable toolbarSpaceSize={'large'} renderToolbar={() => { return ( setSearch(e.target.value)} /> {_.isFunction(onSyncCitySelect) && ( <> )} ); }} renderExpandLeft={() => { return ( selectAll()}> {formatMessage({ id: 'component.AppDetail.city.selectAll' })} unSelectAll()}> {formatMessage({ id: 'component.AppDetail.city.unSelectAll' })} ); }} customRender={(node, item: any) => { const { children } = item; return ( <> {node}  {Array.isArray(children) && children.length > 0 && ( selectAll(item)}> {formatMessage({ id: 'component.check.all' })} unSelectAll(item)}> {formatMessage({ id: 'component.AppDetail.city.unSelectAll' })} )} {useType === 'single' && type === 1 && oldCityList?.find((v) => v.cityId === Number(item.id)) && ( {formatMessage({ id: 'base.common.owned' })} )} ); }} checkInterceptor={ useType !== 'operation' && type === 1 ? (__, info) => { const { checked, node } = info; return createCancelInterceptor({ checked, formatMessage, trigger() { return oldCityList?.find((item) => item.cityId === Number(node?.id)); }, request() { return relationUserCityRemove({ data: [{ appId, userId: currentUser?.id, cityId: Number(node?.id) }], }); }, refresh: () => { detailRefresh?.(); cityRefresh?.(); }, }); } : undefined } /> ) : ( ); }; export default CityTab;