feat: 优化数据管理操作栏均为顶部

This commit is contained in:
licoy 2024-11-12 17:00:06 +08:00
parent cdc02f660b
commit 67d09d68c6
5 changed files with 297 additions and 300 deletions

View File

@ -17,7 +17,7 @@ import {
renderQuota, renderQuota,
} from '../helpers/render'; } from '../helpers/render';
import { import {
Button, Button, Divider,
Dropdown, Dropdown,
Form, Form,
InputNumber, InputNumber,
@ -707,226 +707,217 @@ const ChannelsTable = () => {
}; };
return ( return (
<> <>
<EditChannel <EditChannel
refresh={refresh} refresh={refresh}
visible={showEdit} visible={showEdit}
handleClose={closeEdit} handleClose={closeEdit}
editingChannel={editingChannel} editingChannel={editingChannel}
/> />
<Form <Form
onSubmit={() => { onSubmit={() => {
searchChannels(searchKeyword, searchGroup, searchModel); searchChannels(searchKeyword, searchGroup, searchModel);
}} }}
labelPosition='left' labelPosition='left'
> >
<div style={{ display: 'flex' }}> <div style={{display: 'flex'}}>
<Space> <Space>
<Form.Input <Form.Input
field='search_keyword' field='search_keyword'
label='搜索渠道关键词' label='搜索渠道关键词'
placeholder='ID名称和密钥 ...' placeholder='ID名称和密钥 ...'
value={searchKeyword} value={searchKeyword}
loading={searching} loading={searching}
onChange={(v) => { onChange={(v) => {
setSearchKeyword(v.trim()); setSearchKeyword(v.trim());
}} }}
/> />
<Form.Input <Form.Input
field='search_model' field='search_model'
label='模型' label='模型'
placeholder='模型关键字' placeholder='模型关键字'
value={searchModel} value={searchModel}
loading={searching} loading={searching}
onChange={(v) => { onChange={(v) => {
setSearchModel(v.trim()); setSearchModel(v.trim());
}} }}
/> />
<Form.Select <Form.Select
field='group' field='group'
label='分组' label='分组'
optionList={[{ label: '选择分组', value: null}, ...groupOptions]} optionList={[{label: '选择分组', value: null}, ...groupOptions]}
initValue={null} initValue={null}
onChange={(v) => { onChange={(v) => {
setSearchGroup(v); setSearchGroup(v);
searchChannels(searchKeyword, v, searchModel); 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 <Button
label='查询' theme='light'
type='primary' type='primary'
htmlType='submit' style={{marginRight: 8}}
className='btn-margin-right' onClick={() => {
style={{ marginRight: 8 }} 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> </Button>
</Space> </Space>
</div> </div>
</Form> <div style={{marginTop: 20}}>
<div style={{ marginTop: 10, display: 'flex' }}>
<Space>
<Space> <Space>
<Typography.Text strong>使用ID排序</Typography.Text> <Typography.Text strong>开启批量删除</Typography.Text>
<Switch <Switch
checked={idSort} label='开启批量删除'
label='使用ID排序' uncheckedText='关'
uncheckedText='关' aria-label='是否开启批量删除'
aria-label='是否用ID排序' onChange={(v) => {
onChange={(v) => { setEnableBatchDelete(v);
localStorage.setItem('id-sort', v + ''); }}
setIdSort(v);
loadChannels(0, pageSize, v)
.then()
.catch((reason) => {
showError(reason);
});
}}
></Switch> ></Switch>
</Space> <Popconfirm
</Space> title='确定是否要删除所选通道?'
</div> content='此修改将不可逆'
okType={'danger'}
<Table onConfirm={batchDeleteChannels}
className={'channel-table'} disabled={!enableBatchDelete}
style={{ marginTop: 15 }} position={'top'}
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 }}
> >
删除所选通道 <Button
</Button> disabled={!enableBatchDelete}
</Popconfirm> theme='light'
<Popconfirm type='danger'
title='确定是否要修复数据库一致性?' style={{marginRight: 8}}
content='进行该操作时,可能导致渠道访问错误,请仅在数据库出现问题时使用' >
okType={'warning'} 删除所选通道
onConfirm={fixChannelsAbilities} </Button>
position={'top'} </Popconfirm>
> <Popconfirm
<Button theme='light' type='secondary' style={{ marginRight: 8 }}> title='确定是否要修复数据库一致性?'
修复数据库一致性 content='进行该操作时,可能导致渠道访问错误,请仅在数据库出现问题时使用'
</Button> okType={'warning'}
</Popconfirm> onConfirm={fixChannelsAbilities}
</Space> position={'top'}
</div> >
</> <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
}
/>
</>
); );
}; };

View File

@ -767,6 +767,22 @@ const LogsTable = () => {
<Form.Section></Form.Section> <Form.Section></Form.Section>
</> </>
</Form> </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 <Table
style={{ marginTop: 5 }} style={{ marginTop: 5 }}
columns={columns} columns={columns}
@ -786,20 +802,6 @@ const LogsTable = () => {
onPageChange: handlePageChange, 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> </Layout>
</> </>
); );

View File

@ -10,7 +10,7 @@ import {
import { ITEMS_PER_PAGE } from '../constants'; import { ITEMS_PER_PAGE } from '../constants';
import { renderQuota } from '../helpers/render'; import { renderQuota } from '../helpers/render';
import { import {
Button, Button, Divider,
Form, Form,
Modal, Modal,
Popconfirm, Popconfirm,
@ -391,6 +391,39 @@ const RedemptionsTable = () => {
onChange={handleKeywordChange} onChange={handleKeywordChange}
/> />
</Form> </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 <Table
style={{ marginTop: 20 }} style={{ marginTop: 20 }}
@ -414,36 +447,6 @@ const RedemptionsTable = () => {
rowSelection={rowSelection} rowSelection={rowSelection}
onRow={handleRow} onRow={handleRow}
></Table> ></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>
</> </>
); );
}; };

View File

@ -10,7 +10,7 @@ import {
import { ITEMS_PER_PAGE } from '../constants'; import { ITEMS_PER_PAGE } from '../constants';
import {renderGroup, renderQuota} from '../helpers/render'; import {renderGroup, renderQuota} from '../helpers/render';
import { import {
Button, Button, Divider,
Dropdown, Dropdown,
Form, Form,
Modal, Modal,
@ -596,6 +596,40 @@ const TokensTable = () => {
查询 查询
</Button> </Button>
</Form> </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 <Table
style={{ marginTop: 20 }} style={{ marginTop: 20 }}
@ -619,37 +653,6 @@ const TokensTable = () => {
rowSelection={rowSelection} rowSelection={rowSelection}
onRow={handleRow} onRow={handleRow}
></Table> ></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>
</> </>
); );
}; };

View File

@ -476,10 +476,18 @@ const UsersTable = () => {
type='primary' type='primary'
htmlType='submit' htmlType='submit'
className='btn-margin-right' className='btn-margin-right'
style={{ marginRight: 8 }}
> >
查询 查询
</Button> </Button>
<Button
theme='light'
type='primary'
onClick={() => {
setShowAddUser(true);
}}
>
添加用户
</Button>
</Space> </Space>
</div> </div>
</Form> </Form>
@ -496,16 +504,6 @@ const UsersTable = () => {
}} }}
loading={loading} loading={loading}
/> />
<Button
theme='light'
type='primary'
style={{ marginRight: 8 }}
onClick={() => {
setShowAddUser(true);
}}
>
添加用户
</Button>
</> </>
); );
}; };