mirror of
https://github.com/linux-do/new-api.git
synced 2025-09-18 00:16:37 +08:00
feat: 优化数据管理操作栏均为顶部
This commit is contained in:
parent
cdc02f660b
commit
67d09d68c6
@ -17,7 +17,7 @@ import {
|
||||
renderQuota,
|
||||
} from '../helpers/render';
|
||||
import {
|
||||
Button,
|
||||
Button, Divider,
|
||||
Dropdown,
|
||||
Form,
|
||||
InputNumber,
|
||||
@ -707,226 +707,217 @@ const ChannelsTable = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<EditChannel
|
||||
refresh={refresh}
|
||||
visible={showEdit}
|
||||
handleClose={closeEdit}
|
||||
editingChannel={editingChannel}
|
||||
/>
|
||||
<Form
|
||||
onSubmit={() => {
|
||||
searchChannels(searchKeyword, searchGroup, searchModel);
|
||||
}}
|
||||
labelPosition='left'
|
||||
>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<Space>
|
||||
<Form.Input
|
||||
field='search_keyword'
|
||||
label='搜索渠道关键词'
|
||||
placeholder='ID,名称和密钥 ...'
|
||||
value={searchKeyword}
|
||||
loading={searching}
|
||||
onChange={(v) => {
|
||||
setSearchKeyword(v.trim());
|
||||
}}
|
||||
/>
|
||||
<Form.Input
|
||||
field='search_model'
|
||||
label='模型'
|
||||
placeholder='模型关键字'
|
||||
value={searchModel}
|
||||
loading={searching}
|
||||
onChange={(v) => {
|
||||
setSearchModel(v.trim());
|
||||
}}
|
||||
/>
|
||||
<Form.Select
|
||||
field='group'
|
||||
label='分组'
|
||||
optionList={[{ label: '选择分组', value: null}, ...groupOptions]}
|
||||
initValue={null}
|
||||
onChange={(v) => {
|
||||
setSearchGroup(v);
|
||||
searchChannels(searchKeyword, v, searchModel);
|
||||
}}
|
||||
/>
|
||||
<>
|
||||
<EditChannel
|
||||
refresh={refresh}
|
||||
visible={showEdit}
|
||||
handleClose={closeEdit}
|
||||
editingChannel={editingChannel}
|
||||
/>
|
||||
<Form
|
||||
onSubmit={() => {
|
||||
searchChannels(searchKeyword, searchGroup, searchModel);
|
||||
}}
|
||||
labelPosition='left'
|
||||
>
|
||||
<div style={{display: 'flex'}}>
|
||||
<Space>
|
||||
<Form.Input
|
||||
field='search_keyword'
|
||||
label='搜索渠道关键词'
|
||||
placeholder='ID,名称和密钥 ...'
|
||||
value={searchKeyword}
|
||||
loading={searching}
|
||||
onChange={(v) => {
|
||||
setSearchKeyword(v.trim());
|
||||
}}
|
||||
/>
|
||||
<Form.Input
|
||||
field='search_model'
|
||||
label='模型'
|
||||
placeholder='模型关键字'
|
||||
value={searchModel}
|
||||
loading={searching}
|
||||
onChange={(v) => {
|
||||
setSearchModel(v.trim());
|
||||
}}
|
||||
/>
|
||||
<Form.Select
|
||||
field='group'
|
||||
label='分组'
|
||||
optionList={[{label: '选择分组', value: null}, ...groupOptions]}
|
||||
initValue={null}
|
||||
onChange={(v) => {
|
||||
setSearchGroup(v);
|
||||
searchChannels(searchKeyword, v, searchModel);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
label='查询'
|
||||
type='primary'
|
||||
htmlType='submit'
|
||||
className='btn-margin-right'
|
||||
style={{marginRight: 8}}
|
||||
>
|
||||
查询
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</Form>
|
||||
<Divider style={{marginBottom:15}}/>
|
||||
<div
|
||||
style={{
|
||||
display: isMobile() ? '' : 'flex',
|
||||
marginTop: isMobile() ? 0 : -45,
|
||||
zIndex: 999,
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
>
|
||||
<Space
|
||||
style={{pointerEvents: 'auto', marginTop: isMobile() ? 0 : 45}}
|
||||
>
|
||||
<Typography.Text strong>使用ID排序</Typography.Text>
|
||||
<Switch
|
||||
checked={idSort}
|
||||
label='使用ID排序'
|
||||
uncheckedText='关'
|
||||
aria-label='是否用ID排序'
|
||||
onChange={(v) => {
|
||||
localStorage.setItem('id-sort', v + '');
|
||||
setIdSort(v);
|
||||
loadChannels(0, pageSize, v)
|
||||
.then()
|
||||
.catch((reason) => {
|
||||
showError(reason);
|
||||
});
|
||||
}}
|
||||
></Switch>
|
||||
<Button
|
||||
label='查询'
|
||||
type='primary'
|
||||
htmlType='submit'
|
||||
className='btn-margin-right'
|
||||
style={{ marginRight: 8 }}
|
||||
theme='light'
|
||||
type='primary'
|
||||
style={{marginRight: 8}}
|
||||
onClick={() => {
|
||||
setEditingChannel({
|
||||
id: undefined,
|
||||
});
|
||||
setShowEdit(true);
|
||||
}}
|
||||
>
|
||||
查询
|
||||
添加渠道
|
||||
</Button>
|
||||
<Popconfirm
|
||||
title='确定?'
|
||||
okType={'warning'}
|
||||
onConfirm={testAllChannels}
|
||||
position={isMobile() ? 'top' : 'top'}
|
||||
>
|
||||
<Button theme='light' type='warning' style={{marginRight: 8}}>
|
||||
测试所有通道
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
<Popconfirm
|
||||
title='确定?'
|
||||
okType={'secondary'}
|
||||
onConfirm={updateAllChannelsBalance}
|
||||
>
|
||||
<Button theme='light' type='secondary' style={{marginRight: 8}}>
|
||||
更新所有已启用通道余额
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
<Popconfirm
|
||||
title='确定是否要删除禁用通道?'
|
||||
content='此修改将不可逆'
|
||||
okType={'danger'}
|
||||
onConfirm={deleteAllDisabledChannels}
|
||||
>
|
||||
<Button theme='light' type='danger' style={{marginRight: 8}}>
|
||||
删除禁用通道
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
|
||||
<Button
|
||||
theme='light'
|
||||
type='primary'
|
||||
style={{marginRight: 8}}
|
||||
onClick={refresh}
|
||||
>
|
||||
刷新
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</Form>
|
||||
<div style={{ marginTop: 10, display: 'flex' }}>
|
||||
<Space>
|
||||
<div style={{marginTop: 20}}>
|
||||
<Space>
|
||||
<Typography.Text strong>使用ID排序</Typography.Text>
|
||||
<Typography.Text strong>开启批量删除</Typography.Text>
|
||||
<Switch
|
||||
checked={idSort}
|
||||
label='使用ID排序'
|
||||
uncheckedText='关'
|
||||
aria-label='是否用ID排序'
|
||||
onChange={(v) => {
|
||||
localStorage.setItem('id-sort', v + '');
|
||||
setIdSort(v);
|
||||
loadChannels(0, pageSize, v)
|
||||
.then()
|
||||
.catch((reason) => {
|
||||
showError(reason);
|
||||
});
|
||||
}}
|
||||
label='开启批量删除'
|
||||
uncheckedText='关'
|
||||
aria-label='是否开启批量删除'
|
||||
onChange={(v) => {
|
||||
setEnableBatchDelete(v);
|
||||
}}
|
||||
></Switch>
|
||||
</Space>
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
className={'channel-table'}
|
||||
style={{ marginTop: 15 }}
|
||||
columns={columns}
|
||||
dataSource={pageData}
|
||||
pagination={{
|
||||
currentPage: activePage,
|
||||
pageSize: pageSize,
|
||||
total: channelCount,
|
||||
pageSizeOpts: [10, 20, 50, 100],
|
||||
showSizeChanger: true,
|
||||
formatPageText: (page) => '',
|
||||
onPageSizeChange: (size) => {
|
||||
handlePageSizeChange(size).then();
|
||||
},
|
||||
onPageChange: handlePageChange,
|
||||
}}
|
||||
loading={loading}
|
||||
onRow={handleRow}
|
||||
rowSelection={
|
||||
enableBatchDelete
|
||||
? {
|
||||
onChange: (selectedRowKeys, selectedRows) => {
|
||||
// console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
|
||||
setSelectedChannels(selectedRows);
|
||||
},
|
||||
}
|
||||
: null
|
||||
}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
display: isMobile() ? '' : 'flex',
|
||||
marginTop: isMobile() ? 0 : -45,
|
||||
zIndex: 999,
|
||||
position: 'relative',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
>
|
||||
<Space
|
||||
style={{ pointerEvents: 'auto', marginTop: isMobile() ? 0 : 45 }}
|
||||
>
|
||||
<Button
|
||||
theme='light'
|
||||
type='primary'
|
||||
style={{ marginRight: 8 }}
|
||||
onClick={() => {
|
||||
setEditingChannel({
|
||||
id: undefined,
|
||||
});
|
||||
setShowEdit(true);
|
||||
}}
|
||||
>
|
||||
添加渠道
|
||||
</Button>
|
||||
<Popconfirm
|
||||
title='确定?'
|
||||
okType={'warning'}
|
||||
onConfirm={testAllChannels}
|
||||
position={isMobile() ? 'top' : 'top'}
|
||||
>
|
||||
<Button theme='light' type='warning' style={{ marginRight: 8 }}>
|
||||
测试所有通道
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
<Popconfirm
|
||||
title='确定?'
|
||||
okType={'secondary'}
|
||||
onConfirm={updateAllChannelsBalance}
|
||||
>
|
||||
<Button theme='light' type='secondary' style={{ marginRight: 8 }}>
|
||||
更新所有已启用通道余额
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
<Popconfirm
|
||||
title='确定是否要删除禁用通道?'
|
||||
content='此修改将不可逆'
|
||||
okType={'danger'}
|
||||
onConfirm={deleteAllDisabledChannels}
|
||||
>
|
||||
<Button theme='light' type='danger' style={{ marginRight: 8 }}>
|
||||
删除禁用通道
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
|
||||
<Button
|
||||
theme='light'
|
||||
type='primary'
|
||||
style={{ marginRight: 8 }}
|
||||
onClick={refresh}
|
||||
>
|
||||
刷新
|
||||
</Button>
|
||||
</Space>
|
||||
{/*<div style={{width: '100%', pointerEvents: 'none', position: 'absolute'}}>*/}
|
||||
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
<div style={{ marginTop: 20 }}>
|
||||
<Space>
|
||||
<Typography.Text strong>开启批量删除</Typography.Text>
|
||||
<Switch
|
||||
label='开启批量删除'
|
||||
uncheckedText='关'
|
||||
aria-label='是否开启批量删除'
|
||||
onChange={(v) => {
|
||||
setEnableBatchDelete(v);
|
||||
}}
|
||||
></Switch>
|
||||
<Popconfirm
|
||||
title='确定是否要删除所选通道?'
|
||||
content='此修改将不可逆'
|
||||
okType={'danger'}
|
||||
onConfirm={batchDeleteChannels}
|
||||
disabled={!enableBatchDelete}
|
||||
position={'top'}
|
||||
>
|
||||
<Button
|
||||
disabled={!enableBatchDelete}
|
||||
theme='light'
|
||||
type='danger'
|
||||
style={{ marginRight: 8 }}
|
||||
<Popconfirm
|
||||
title='确定是否要删除所选通道?'
|
||||
content='此修改将不可逆'
|
||||
okType={'danger'}
|
||||
onConfirm={batchDeleteChannels}
|
||||
disabled={!enableBatchDelete}
|
||||
position={'top'}
|
||||
>
|
||||
删除所选通道
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
<Popconfirm
|
||||
title='确定是否要修复数据库一致性?'
|
||||
content='进行该操作时,可能导致渠道访问错误,请仅在数据库出现问题时使用'
|
||||
okType={'warning'}
|
||||
onConfirm={fixChannelsAbilities}
|
||||
position={'top'}
|
||||
>
|
||||
<Button theme='light' type='secondary' style={{ marginRight: 8 }}>
|
||||
修复数据库一致性
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
</Space>
|
||||
</div>
|
||||
</>
|
||||
<Button
|
||||
disabled={!enableBatchDelete}
|
||||
theme='light'
|
||||
type='danger'
|
||||
style={{marginRight: 8}}
|
||||
>
|
||||
删除所选通道
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
<Popconfirm
|
||||
title='确定是否要修复数据库一致性?'
|
||||
content='进行该操作时,可能导致渠道访问错误,请仅在数据库出现问题时使用'
|
||||
okType={'warning'}
|
||||
onConfirm={fixChannelsAbilities}
|
||||
position={'top'}
|
||||
>
|
||||
<Button theme='light' type='secondary' style={{marginRight: 8}}>
|
||||
修复数据库一致性
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
className={'channel-table'}
|
||||
style={{marginTop: 15}}
|
||||
columns={columns}
|
||||
dataSource={pageData}
|
||||
pagination={{
|
||||
currentPage: activePage,
|
||||
pageSize: pageSize,
|
||||
total: channelCount,
|
||||
pageSizeOpts: [10, 20, 50, 100],
|
||||
showSizeChanger: true,
|
||||
formatPageText: (page) => '',
|
||||
onPageSizeChange: (size) => {
|
||||
handlePageSizeChange(size).then();
|
||||
},
|
||||
onPageChange: handlePageChange,
|
||||
}}
|
||||
loading={loading}
|
||||
onRow={handleRow}
|
||||
rowSelection={
|
||||
enableBatchDelete
|
||||
? {
|
||||
onChange: (selectedRowKeys, selectedRows) => {
|
||||
// console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
|
||||
setSelectedChannels(selectedRows);
|
||||
},
|
||||
}
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -767,6 +767,22 @@ const LogsTable = () => {
|
||||
<Form.Section></Form.Section>
|
||||
</>
|
||||
</Form>
|
||||
<div style={{marginTop:10}}>
|
||||
<Select
|
||||
defaultValue='0'
|
||||
style={{ width: 120 }}
|
||||
onChange={(value) => {
|
||||
setLogType(parseInt(value));
|
||||
loadLogs(0, pageSize, parseInt(value));
|
||||
}}
|
||||
>
|
||||
<Select.Option value='0'>全部</Select.Option>
|
||||
<Select.Option value='1'>充值</Select.Option>
|
||||
<Select.Option value='2'>消费</Select.Option>
|
||||
<Select.Option value='3'>管理</Select.Option>
|
||||
<Select.Option value='4'>系统</Select.Option>
|
||||
</Select>
|
||||
</div>
|
||||
<Table
|
||||
style={{ marginTop: 5 }}
|
||||
columns={columns}
|
||||
@ -786,20 +802,6 @@ const LogsTable = () => {
|
||||
onPageChange: handlePageChange,
|
||||
}}
|
||||
/>
|
||||
<Select
|
||||
defaultValue='0'
|
||||
style={{ width: 120 }}
|
||||
onChange={(value) => {
|
||||
setLogType(parseInt(value));
|
||||
loadLogs(0, pageSize, parseInt(value));
|
||||
}}
|
||||
>
|
||||
<Select.Option value='0'>全部</Select.Option>
|
||||
<Select.Option value='1'>充值</Select.Option>
|
||||
<Select.Option value='2'>消费</Select.Option>
|
||||
<Select.Option value='3'>管理</Select.Option>
|
||||
<Select.Option value='4'>系统</Select.Option>
|
||||
</Select>
|
||||
</Layout>
|
||||
</>
|
||||
);
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
import { ITEMS_PER_PAGE } from '../constants';
|
||||
import { renderQuota } from '../helpers/render';
|
||||
import {
|
||||
Button,
|
||||
Button, Divider,
|
||||
Form,
|
||||
Modal,
|
||||
Popconfirm,
|
||||
@ -391,6 +391,39 @@ const RedemptionsTable = () => {
|
||||
onChange={handleKeywordChange}
|
||||
/>
|
||||
</Form>
|
||||
<Divider style={{margin:'5px 0 15px 0'}}/>
|
||||
<div>
|
||||
<Button
|
||||
theme='light'
|
||||
type='primary'
|
||||
style={{ marginRight: 8 }}
|
||||
onClick={() => {
|
||||
setEditingRedemption({
|
||||
id: undefined,
|
||||
});
|
||||
setShowEdit(true);
|
||||
}}
|
||||
>
|
||||
添加兑换码
|
||||
</Button>
|
||||
<Button
|
||||
label='复制所选兑换码'
|
||||
type='warning'
|
||||
onClick={async () => {
|
||||
if (selectedKeys.length === 0) {
|
||||
showError('请至少选择一个兑换码!');
|
||||
return;
|
||||
}
|
||||
let keys = '';
|
||||
for (let i = 0; i < selectedKeys.length; i++) {
|
||||
keys += selectedKeys[i].name + ' ' + selectedKeys[i].key + '\n';
|
||||
}
|
||||
await copyText(keys);
|
||||
}}
|
||||
>
|
||||
复制所选兑换码到剪贴板
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
style={{ marginTop: 20 }}
|
||||
@ -414,36 +447,6 @@ const RedemptionsTable = () => {
|
||||
rowSelection={rowSelection}
|
||||
onRow={handleRow}
|
||||
></Table>
|
||||
<Button
|
||||
theme='light'
|
||||
type='primary'
|
||||
style={{ marginRight: 8 }}
|
||||
onClick={() => {
|
||||
setEditingRedemption({
|
||||
id: undefined,
|
||||
});
|
||||
setShowEdit(true);
|
||||
}}
|
||||
>
|
||||
添加兑换码
|
||||
</Button>
|
||||
<Button
|
||||
label='复制所选兑换码'
|
||||
type='warning'
|
||||
onClick={async () => {
|
||||
if (selectedKeys.length === 0) {
|
||||
showError('请至少选择一个兑换码!');
|
||||
return;
|
||||
}
|
||||
let keys = '';
|
||||
for (let i = 0; i < selectedKeys.length; i++) {
|
||||
keys += selectedKeys[i].name + ' ' + selectedKeys[i].key + '\n';
|
||||
}
|
||||
await copyText(keys);
|
||||
}}
|
||||
>
|
||||
复制所选兑换码到剪贴板
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
import { ITEMS_PER_PAGE } from '../constants';
|
||||
import {renderGroup, renderQuota} from '../helpers/render';
|
||||
import {
|
||||
Button,
|
||||
Button, Divider,
|
||||
Dropdown,
|
||||
Form,
|
||||
Modal,
|
||||
@ -596,6 +596,40 @@ const TokensTable = () => {
|
||||
查询
|
||||
</Button>
|
||||
</Form>
|
||||
<Divider style={{margin:'15px 0'}}/>
|
||||
<div>
|
||||
<Button
|
||||
theme='light'
|
||||
type='primary'
|
||||
style={{ marginRight: 8 }}
|
||||
onClick={() => {
|
||||
setEditingToken({
|
||||
id: undefined,
|
||||
});
|
||||
setShowEdit(true);
|
||||
}}
|
||||
>
|
||||
添加令牌
|
||||
</Button>
|
||||
<Button
|
||||
label='复制所选令牌'
|
||||
type='warning'
|
||||
onClick={async () => {
|
||||
if (selectedKeys.length === 0) {
|
||||
showError('请至少选择一个令牌!');
|
||||
return;
|
||||
}
|
||||
let keys = '';
|
||||
for (let i = 0; i < selectedKeys.length; i++) {
|
||||
keys +=
|
||||
selectedKeys[i].name + ' sk-' + selectedKeys[i].key + '\n';
|
||||
}
|
||||
await copyText(keys);
|
||||
}}
|
||||
>
|
||||
复制所选令牌到剪贴板
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
style={{ marginTop: 20 }}
|
||||
@ -619,37 +653,6 @@ const TokensTable = () => {
|
||||
rowSelection={rowSelection}
|
||||
onRow={handleRow}
|
||||
></Table>
|
||||
<Button
|
||||
theme='light'
|
||||
type='primary'
|
||||
style={{ marginRight: 8 }}
|
||||
onClick={() => {
|
||||
setEditingToken({
|
||||
id: undefined,
|
||||
});
|
||||
setShowEdit(true);
|
||||
}}
|
||||
>
|
||||
添加令牌
|
||||
</Button>
|
||||
<Button
|
||||
label='复制所选令牌'
|
||||
type='warning'
|
||||
onClick={async () => {
|
||||
if (selectedKeys.length === 0) {
|
||||
showError('请至少选择一个令牌!');
|
||||
return;
|
||||
}
|
||||
let keys = '';
|
||||
for (let i = 0; i < selectedKeys.length; i++) {
|
||||
keys +=
|
||||
selectedKeys[i].name + ' sk-' + selectedKeys[i].key + '\n';
|
||||
}
|
||||
await copyText(keys);
|
||||
}}
|
||||
>
|
||||
复制所选令牌到剪贴板
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -476,10 +476,18 @@ const UsersTable = () => {
|
||||
type='primary'
|
||||
htmlType='submit'
|
||||
className='btn-margin-right'
|
||||
style={{ marginRight: 8 }}
|
||||
>
|
||||
查询
|
||||
</Button>
|
||||
<Button
|
||||
theme='light'
|
||||
type='primary'
|
||||
onClick={() => {
|
||||
setShowAddUser(true);
|
||||
}}
|
||||
>
|
||||
添加用户
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</Form>
|
||||
@ -496,16 +504,6 @@ const UsersTable = () => {
|
||||
}}
|
||||
loading={loading}
|
||||
/>
|
||||
<Button
|
||||
theme='light'
|
||||
type='primary'
|
||||
style={{ marginRight: 8 }}
|
||||
onClick={() => {
|
||||
setShowAddUser(true);
|
||||
}}
|
||||
>
|
||||
添加用户
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user