nili 3 years ago
parent
commit
4eae8eb7d9
  1. 22
      src/components/AuthorSelect/index.tsx
  2. 28
      src/components/DebunceSelect/index.tsx
  3. 6
      src/pages/PoemPage/index.tsx

22
src/components/AuthorSelect/index.tsx

@ -1,22 +1,30 @@
import { seekUsingGET } from '@/services/luigi/author'; import { seekUsingGET } from '@/services/luigi/author';
import React from 'react'; import React from 'react';
import type { ValueType } from '../DebunceSelect';
import DebounceSelect from '../DebunceSelect'; import DebounceSelect from '../DebunceSelect';
const AuthorSelect: React.FC<{ const AuthorSelect: React.FC<{
value?: string; value?: string;
onChange?: (value: string) => void; onChange: (value: ValueType) => void;
}> = (props) => { }> = (props) => {
return ( return (
<DebounceSelect <DebounceSelect
initOption={props.value} initOption={props.value}
fetchOptions={seekUsingGET} fetchOptions={async (query) => {
onChange={(newValue) => { const response = await seekUsingGET({
if (typeof newValue == 'string') { name: query,
props.onChange(JSON.parse(newValue)); });
} else { if (response.data?.list) {
props.onChange(newValue); return response.data.list?.map((author) => {
const data: ValueType = { label: author.name, value: author.id, key: author.id };
return data;
});
} }
return undefined;
}}
onChange={(newValue) => {
props.onChange(newValue);
}} }}
style={{ style={{
width: '100%', width: '100%',

28
src/components/DebunceSelect/index.tsx

@ -1,19 +1,23 @@
import { Select, Spin } from 'antd'; import { Select, Spin } from 'antd';
import { SelectProps } from 'antd/es/select'; import type { SelectProps } from 'antd/es/select';
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
import React from 'react'; import React from 'react';
import { useEffect } from '../../.umi/.cache/.mfsu/mf-dep_vendors-node_modules_react_index_js.598bdd42.async';
export interface DebounceSelectProps<ValueType = any> export interface DebounceSelectProps<ValueType>
extends Omit<SelectProps<ValueType>, 'options' | 'children'> { extends Omit<SelectProps<ValueType>, 'options' | 'children'> {
fetchOptions: (search: string) => Promise<ValueType[]>; fetchOptions: (search: string) => Promise<ValueType[] | undefined>;
debounceTimeout?: number; debounceTimeout?: number;
initOption?: string; initOption?: string;
} }
function DebounceSelect< export type ValueType = { key?: number; label?: string; value?: number };
ValueType extends { key?: string; label: React.ReactNode; value: string | number } = any,
>({ fetchOptions, debounceTimeout = 800, initOption, ...props }: DebounceSelectProps) { function DebounceSelect({
fetchOptions,
debounceTimeout = 800,
initOption,
...props
}: DebounceSelectProps<ValueType>) {
const [fetching, setFetching] = React.useState(false); const [fetching, setFetching] = React.useState(false);
const initOptions = []; const initOptions = [];
let defaultValue = null; let defaultValue = null;
@ -27,22 +31,18 @@ function DebounceSelect<
const fetchRef = React.useRef(0); const fetchRef = React.useRef(0);
const debounceFetcher = React.useMemo(() => { const debounceFetcher = React.useMemo(() => {
const loadOptions = (value: string | number) => { const loadOptions = (value: string) => {
fetchRef.current += 1; fetchRef.current += 1;
const fetchId = fetchRef.current; const fetchId = fetchRef.current;
setOptions([]); setOptions([]);
setFetching(true); setFetching(true);
fetchOptions({ query: value }).then((newOptions) => { fetchOptions(value).then((newOptions) => {
if (fetchId !== fetchRef.current) { if (fetchId !== fetchRef.current) {
// for fetch callback order // for fetch callback order
return; return;
} }
const list = newOptions.data.list.map((user: { id: number; name: string }) => ({ setOptions(newOptions);
label: user.name,
value: user.id,
}));
setOptions(list);
setFetching(false); setFetching(false);
}); });
}; };

6
src/pages/PoemPage/index.tsx

@ -3,7 +3,7 @@ import { poemListUsingPOST } from '@/services/luigi/poem';
import { PlusOutlined } from '@ant-design/icons'; import { PlusOutlined } from '@ant-design/icons';
import ProTable from '@ant-design/pro-table'; import ProTable from '@ant-design/pro-table';
import { Button } from 'antd'; import { Button } from 'antd';
import React, { useRef, useState } from 'react'; import { useRef } from 'react';
import type { ProColumns, ActionType } from '@ant-design/pro-table'; import type { ProColumns, ActionType } from '@ant-design/pro-table';
const columns: ProColumns<API.PoemBo>[] = [ const columns: ProColumns<API.PoemBo>[] = [
@ -59,7 +59,7 @@ const columns: ProColumns<API.PoemBo>[] = [
}, },
], ],
}, },
renderFormItem: (item, { type, defaultRender, ...rest }, form) => { renderFormItem: (item, { type, defaultRender, ...rest }) => {
return <AuthorSelect {...rest} />; return <AuthorSelect {...rest} />;
}, },
}, },
@ -78,7 +78,7 @@ export default () => {
columns={columns} columns={columns}
actionRef={actionRef} actionRef={actionRef}
cardBordered cardBordered
request={async (params = {}, sort, filter) => { request={async (params = {}) => {
const query: API.QueryParam[] = []; const query: API.QueryParam[] = [];
if (params.author) { if (params.author) {
let author = params.author; let author = params.author;

Loading…
Cancel
Save