import useAhookUrlState from '@ahooksjs/use-url-state'; import _ from 'lodash'; import { createContext, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'; import { useHistory, useLocation, useModel, useRequest } from 'umi'; export const useQuery = (): T => { // @ts-ignore const { query } = useLocation(); return query; }; export const useUrlState = () => { const [query, setQuery] = useState>({}); const history = useHistory(); const location = useLocation>(); const tempData = useRef(false); useEffect(() => { if (!tempData?.current) { tempData.current = true; // eslint-disable-next-line @typescript-eslint/dot-notation setQuery(location['query']); } }, [location]); useEffect(() => { if (_.isEmpty(query) && location.search !== '') { history.push({ pathname: location.pathname, search: '', }); return; } // 如果query变化,那么生成search,如果serch变化,那么生成url const search = new URLSearchParams({ // eslint-disable-next-line @typescript-eslint/dot-notation ..._.omit(location['query'], _.keys(query)), ...query, }).toString(); if (`?${search}` !== location.search && search !== location.search) { history.push({ pathname: location.pathname, search: search, }); } }, [query, location, history]); return { query, setQuery }; }; export const useGetAppId = (): number => { // @ts-ignore const { appId: id } = useQuery<{ appId: number }>(); const appId = parseInt(id + '', 10); return appId; }; interface useBatchSetExpiresProps { selectIdMap: Record; onChange?: (val: any) => void; value: any; oldData: any; } export const useBatchSetExpires = ({ selectIdMap, onChange, value, oldData, }: useBatchSetExpiresProps) => { const applyAll = useCallback( (val) => { const selectIdMapValues = Object.values(selectIdMap); onChange?.({ ...value, data: selectIdMapValues?.map((item) => ({ ...item, expiredAt: val })), }); }, // eslint-disable-next-line react-hooks/exhaustive-deps [selectIdMap], ); const applyNew = useCallback( (val) => { const selectIdMapValues = Object.values(selectIdMap); const oldDataMap = _.keyBy(oldData, 'id'); onChange?.({ ...value, data: selectIdMapValues?.map((item) => ({ ...item, expiredAt: oldDataMap[item?.id] ? item.expiredAt : val, })), }); }, // eslint-disable-next-line react-hooks/exhaustive-deps [oldData, selectIdMap], ); return { applyAll, applyNew }; }; /** 页面是否只读 */ export function usePageReadOnly() { const { initialState } = useModel('@@initialState'); return Boolean(initialState?.settings?.pageReadOnly); } /** 监听页面是否只读 */ export function useWatchPageReadOnly() { const pageReadOnly = usePageReadOnly(); const [urlState, setUrlState] = useAhookUrlState(undefined, { navigateMode: 'replace', }); useEffect(() => { if (pageReadOnly && !urlState?.pageReadOnly) { setUrlState({ pageReadOnly: '1' }); } }, [pageReadOnly, setUrlState, urlState]); } export interface AppDetailType { isAllowApplyFeature?: boolean; isAllowApplyFlag?: boolean; isAllowApplyPolicy?: boolean; isAllowApplyRole?: boolean; isAllowApplyCity?: boolean; applyOrder?: number[]; roleApprovalForData?: number; [k: string]: any; } export const AppDetailContext = createContext({}); export default function useAppDetail(parentAppId?: number | string) { const { data: appDetail, loading, refresh, } = useRequest( () => ({ url: '/goapi/app/detail', method: 'POST', data: { appId: parentAppId }, }), { refreshDeps: [parentAppId], ready: Boolean(parentAppId), }, ); return { appDetail: appDetail ?? {}, loading, refresh }; } export function useRoleList(parentAppId?: number | string, isAllowApply?: number) { const { data, loading, refresh } = useRequest( () => ({ url: '/goapi/role/list', method: 'POST', data: { condition: { appId: parentAppId, isAllowApply, }, fromApply: isAllowApply, pagination: { page: 0, size: 0, }, }, }), { refreshDeps: [parentAppId, isAllowApply], ready: Boolean(parentAppId), }, ); return { roleList: data?.list, loading, refresh }; } export function useFeatureTree(parentAppId?: number | string, isAllowApply?: number) { const { data: featureTreeData, loading, refresh, } = useRequest( () => ({ url: '/goapi/feature/tree', method: 'POST', data: { appId: parentAppId, fromApply: isAllowApply }, }), { refreshDeps: [parentAppId, isAllowApply], ready: Boolean(parentAppId), }, ); return { featureTreeData, loading, refresh }; } export function usePolicyList(parentAppId?: number | string, isAllowApply?: number) { const { data, loading, refresh } = useRequest( () => ({ url: '/goapi/policy/list', method: 'POST', data: { condition: { appId: parentAppId, isAllowApply, }, fromApply: isAllowApply, pagination: { page: 0, size: 0, }, }, }), { refreshDeps: [parentAppId, isAllowApply], ready: Boolean(parentAppId), }, ); return { policyList: data?.list, loading, refresh }; } export function useCityList(parentAppId?: number | string) { const { data, loading, refresh } = useRequest( () => ({ url: '/goapi/app/city', method: 'POST', data: { appId: parentAppId, version: 2, }, }), { refreshDeps: [parentAppId], ready: Boolean(parentAppId), }, ); return { cityList: data, loading, refresh }; } export function useFlagList(parentAppId?: number | string, isAllowApply?: number) { const { data, refresh, loading } = useRequest( () => ({ url: '/goapi/flag/all', method: 'POST', data: { appId: parentAppId, fromApply: isAllowApply, }, }), { refreshDeps: [parentAppId], ready: Boolean(parentAppId), }, ); return { flagList: data, loading, refresh }; } export function useDomLayoutEffect(handler: () => void, deps: any[]) { const timerRef = useRef(); useLayoutEffect(() => { clearTimeout(timerRef.current); timerRef.current = setTimeout(() => { handler?.(); }, 300); return () => clearTimeout(timerRef.current); // eslint-disable-next-line react-hooks/exhaustive-deps }, [...(deps || [])]); } export function useUserData() { const { data: currentUser, loading, refresh: userRefresh, } = useRequest( { url: `/goapi/user/homeInfo`, method: 'post' }, { cacheKey: 'currentUser', }, ); return { currentUser, loading, userRefresh }; }