返回 AiToEarn
CommonUserSelect.tsx
1 import React, { useEffect } from 'react';
2 import { Avatar, Select, SelectProps, Spin } from 'antd';
3 import { IUsersItem } from '@/../electron/main/plat/plat.type';
4 import useDebounceFetcher from '@/views/publish/children/videoPage/components/VideoPubSetModal/components/useDebounceFetcher';
5 import styles from './commonComponents.module.scss';
6 import { icpGetUsers } from '@/icp/publish';
7 import { describeNumber } from '@/utils';
8 import { onAccountLoginFinish } from '@/icp/receiveMsg';
9 import { AccountInfo } from '../../../account/comment';
10 import { accountFailureDispose } from '../../comment';
11
12 export interface CommonUserSelectProps<ValueType = any>
13 extends Omit<SelectProps<ValueType | ValueType[]>, 'options' | 'children'> {
14 account?: AccountInfo;
15 tips?: string;
16 title?: string;
17 children?: React.ReactNode;
18 onAccountChange?: (account: AccountInfo) => void;
19 }
20
21 // 通用用户选择器
22 export default function CommonUserSelect({
23 account,
24 children,
25 onAccountChange,
26 ...props
27 }: CommonUserSelectProps<IUsersItem>) {
28 if (!account || !onAccountChange) return '';
29
30 const { fetching, options, debounceFetcher, setOptions } =
31 useDebounceFetcher<IUsersItem>(async (keywords) => {
32 return await getList(keywords);
33 });
34
35 const getList = async (keywords?: string) => {
36 const res = await icpGetUsers({
37 page: 1,
38 keyword: keywords || '',
39 account: account!,
40 });
41 const data = await accountFailureDispose(res, account!, onAccountChange);
42 setOptions(data);
43 return data;
44 };
45
46 useEffect(() => {
47 if (props.showSearch === false) {
48 getList();
49
50 return onAccountLoginFinish((newAccount) => {
51 account = newAccount;
52 getList();
53 });
54 }
55 }, []);
56
57 return (
58 <>
59 <h1>{props.title || '@用户选择'}</h1>
60 <Select
61 {...props}
62 showSearch={
63 props.hasOwnProperty('showSearch') ? props.showSearch : true
64 }
65 allowClear
66 style={{ width: '100%' }}
67 mode="multiple"
68 placeholder="输入关键词搜索"
69 labelInValue
70 filterOption={false}
71 onSearch={
72 (props.hasOwnProperty('showSearch') ? props.showSearch : true)
73 ? debounceFetcher
74 : undefined
75 }
76 notFoundContent={fetching ? <Spin size="small" /> : null}
77 fieldNames={{
78 label: 'name',
79 value: 'id',
80 }}
81 options={options}
82 optionRender={({ data }) => {
83 return (
84 <div className={styles.usersSelect}>
85 <Avatar src={data.image} />
86 <div className="usersSelect-con">
87 <div className="usersSelect-con-name">{data.name}</div>
88 {(data.unique_id || data.follower_count) && (
89 <div className="usersSelect-con-footer">
90 <div className="usersSelect-con-footer-follower">
91 粉丝数:{describeNumber(data.follower_count || 0)}
92 </div>
93 {data.unique_id && (
94 <div className="usersSelect-con-footer-unique">
95 抖音号:{data.unique_id}
96 </div>
97 )}
98 </div>
99 )}
100 </div>
101 </div>
102 );
103 }}
104 />
105 {children}
106 {props.tips && <p className={styles.tips}>{props.tips}</p>}
107 </>
108 );
109 }
110
110 lines Plain Text