返回 AiToEarn
1 import {
2 ForwardedRef,
3 forwardRef,
4 memo,
5 useMemo,
6 useRef,
7 useState,
8 } from 'react';
9 import styles from './proxyManage.module.scss';
10 import { Button, Input, message, Modal, Switch, Table, TableProps } from 'antd';
11 import { AccountGroupItem, useAccountStore } from '@/store/account';
12 import { useShallow } from 'zustand/react/shallow';
13 import { QuestionCircleOutlined, SearchOutlined } from '@ant-design/icons';
14 import accountStyles from '../AccountSidebar.module.scss';
15 import { icpEditDeleteAccountGroup, icpProxyCheck } from '@/icp/account';
16 import { parseProxyString } from '@@/utils';
17
18 export interface IProxyManageRef {}
19
20 export interface IProxyManageProps {
21 open: boolean;
22 onCancel: () => void;
23 onExamineAccountClick: (groupId: number) => void;
24 }
25
26 const ProxyManage = memo(
27 forwardRef(
28 (
29 { open, onCancel, onExamineAccountClick }: IProxyManageProps,
30 ref: ForwardedRef<IProxyManageRef>,
31 ) => {
32 const { accountGroupList, getAccountGroup } = useAccountStore(
33 useShallow((state) => ({
34 accountGroupList: state.accountGroupList,
35 getAccountGroup: state.getAccountGroup,
36 })),
37 );
38 const [proxyOpen, setProxyOpen] = useState(false);
39 const [proxyName, setProxyName] = useState('');
40 const [proxyLoading, setProxyLoading] = useState(false);
41 const [submitLoading, setSubmitLoading] = useState(false);
42 const proxyGroupData = useRef<AccountGroupItem>(undefined);
43 const [proxyCourseOpen, setProxyCourseOpen] = useState(false);
44 const videoRef = useRef<HTMLVideoElement>(null);
45
46 const columns = useMemo(() => {
47 const columns: TableProps<AccountGroupItem>['columns'] = [
48 {
49 title: '分组名称',
50 key: 'name',
51 dataIndex: 'name',
52 },
53 {
54 title: '代理地址',
55 key: 'proxy',
56 dataIndex: 'proxyIp',
57 },
58 {
59 title: '代理启用',
60 width: 90,
61 key: 'proxyOpen',
62 dataIndex: 'proxyOpen',
63 render: (_, gri) => {
64 return (
65 <>
66 {gri.proxyIp && (
67 <Switch
68 value={gri.proxyOpen}
69 onChange={async (v) => {
70 await icpEditDeleteAccountGroup({
71 id: gri.id,
72 proxyOpen: v,
73 });
74 await getAccountGroup();
75 }}
76 />
77 )}
78 </>
79 );
80 },
81 },
82 {
83 title: '账号数量',
84 key: 'accountCount',
85 width: 110,
86 sorter: (a, b) => b.children?.length - a.children?.length,
87 render: (_, gri) => {
88 return (
89 <>
90 <div className={styles.accountCount}>
91 <span className="accountCount-count">
92 {gri.children?.length}
93 </span>
94 {(gri.children?.length || 0) > 0 && (
95 <SearchOutlined
96 title="查看账号"
97 onClick={() => {
98 onExamineAccountClick(gri.id);
99 }}
100 />
101 )}
102 </div>
103 </>
104 );
105 },
106 },
107 {
108 title: '操作',
109 width: 100,
110 render: (_, gri) => {
111 return (
112 <>
113 <Button
114 size="small"
115 type="link"
116 onClick={() => {
117 proxyGroupData.current = gri;
118 setProxyName(gri.proxyIp || '');
119 setProxyOpen(true);
120 }}
121 >
122 设置代理
123 </Button>
124 </>
125 );
126 },
127 },
128 ];
129 return columns;
130 }, []);
131
132 return (
133 <>
134 <Modal
135 title="代理使用教程"
136 open={proxyCourseOpen}
137 footer={null}
138 width={1000}
139 onCancel={() => {
140 setProxyCourseOpen(false);
141 videoRef.current!.pause();
142 }}
143 >
144 <video
145 ref={videoRef}
146 src="https://ylzsfile.yikart.cn/att/ipv.mkv"
147 style={{ width: '100%' }}
148 controls={true}
149 ></video>
150 </Modal>
151
152 <Modal
153 title="设置代理"
154 open={proxyOpen}
155 onCancel={() => setProxyOpen(false)}
156 footer={
157 <>
158 <Button onClick={() => setProxyOpen(false)}>取消</Button>
159 <Button
160 type="primary"
161 loading={submitLoading}
162 onClick={async () => {
163 setSubmitLoading(true);
164 const proxyCheckRes = await icpProxyCheck(proxyName);
165 if (!proxyCheckRes) {
166 setSubmitLoading(false);
167 return message.error('代理地址不可用');
168 }
169 await icpEditDeleteAccountGroup({
170 id: proxyGroupData.current!.id,
171 proxyIp: proxyName,
172 });
173 await getAccountGroup();
174 setProxyOpen(false);
175 setSubmitLoading(false);
176 message.success('代理地址添加成功!');
177 }}
178 >
179 确认
180 </Button>
181 </>
182 }
183 >
184 <div
185 className={`${accountStyles.createGroup} ${styles.proxyInput}`}
186 style={{ marginBottom: '20px' }}
187 >
188 <label>代理地址</label>
189 <Input
190 value={proxyName}
191 placeholder="请输入代理地址"
192 onChange={(e) => setProxyName(e.target.value)}
193 />
194 <Button
195 disabled={proxyName.length === 0}
196 loading={proxyLoading}
197 onClick={async () => {
198 console.log(parseProxyString(proxyName));
199 setProxyLoading(true);
200 const res = await icpProxyCheck(proxyName);
201 setProxyLoading(false);
202 if (res) {
203 message.success('代理地址可用');
204 } else {
205 message.error('代理地址不可用');
206 }
207 }}
208 >
209 验证连接
210 </Button>
211 </div>
212 <div className={styles.proxyHint}>
213 <p>1. 代理类型仅支持HTTP、HTTPS、Socks5;</p>
214 <p>支持以下填写格式</p>
215 <p>192.168.0.1:8000{`{备注}`}</p>
216 <p>192.168.0.1:8000:代理账号:代理密码{`{备注}`}</p>
217 <p>socks5://192.168.0.1:8000:代理账号:代理密码{`{备注}`}</p>
218 </div>
219 </Modal>
220 <Modal
221 open={open}
222 title={
223 <>
224 代理管理器
225 <QuestionCircleOutlined
226 style={{ marginLeft: '6px', cursor: 'pointer' }}
227 onClick={() => {
228 setProxyCourseOpen(true);
229 }}
230 />
231 </>
232 }
233 onCancel={onCancel}
234 width={700}
235 footer={null}
236 >
237 <div className={styles.proxyManage}>
238 <Table<AccountGroupItem>
239 columns={columns}
240 dataSource={accountGroupList}
241 rowKey="id"
242 childrenColumnName="1"
243 scroll={{ y: 500 }}
244 />
245 </div>
246 </Modal>
247 </>
248 );
249 },
250 ),
251 );
252 ProxyManage.displayName = 'ProxyManage';
253
254 export default ProxyManage;
255
255 lines Plain Text