修复冲突

This commit is contained in:
vance 2022-08-23 15:45:51 +08:00
commit b1ba349063
45 changed files with 4261 additions and 3752 deletions

View File

@ -9,9 +9,9 @@
export default { export default {
dev: { dev: {
// localhost:8000/api/** -> https://preview.pro.ant.design/api/** // localhost:8000/api/** -> https://preview.pro.ant.design/api/**
'/admin/': { '/tbg/api/v1': {
// 要代理的地址 // 要代理的地址
target: '', target: 'http://192.168.88.224:9999',
// 配置了这个可以从 http 代理到 https // 配置了这个可以从 http 代理到 https
// 依赖 origin 的功能可能需要这个,比如 cookie // 依赖 origin 的功能可能需要这个,比如 cookie
changeOrigin: true, changeOrigin: true,

View File

@ -61,12 +61,13 @@
"ahooks": "^2.10.14", "ahooks": "^2.10.14",
"antd": "^4.17.2", "antd": "^4.17.2",
"axios": "^0.24.0", "axios": "^0.24.0",
"bignumber.js": "^9.0.0",
"braft-editor": "^2.3.9", "braft-editor": "^2.3.9",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"echarts": "^5.3.3", "echarts": "^5.3.3",
"echarts-for-react": "^3.0.2", "echarts-for-react": "^3.0.2",
"lodash": "^4.17.11", "lodash": "^4.17.11",
"moment": "^2.25.3", "moment": "^2.29.4",
"omit.js": "^2.0.2", "omit.js": "^2.0.2",
"rc-menu": "^9.0.13", "rc-menu": "^9.0.13",
"rc-util": "^5.14.0", "rc-util": "^5.14.0",

View File

@ -0,0 +1,65 @@
// 创建弹窗
import React, { useRef } from 'react';
import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, Select } from '@formily/antd';
import { modifyPassword } from '@/services/login';
interface ModifyPasswordModalPropsType extends ModalProps {
onCancel: () => void;
onOk: () => void;
}
const SchemaField = createSchemaField({
components: {
FormItem,
Input,
Select,
},
});
const form = createForm({});
const ModifyPasswordModal = ({ onOk, onCancel, ...rest }: ModifyPasswordModalPropsType) => {
const handleOk = async () => {
onOk();
const formState = form.getFormState();
await modifyPassword(formState.values);
};
const handleCancel = () => {
onCancel();
};
return (
<Modal title="修改密码" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField>
<SchemaField.String
name="password"
title="旧密码"
required
x-decorator="FormItem"
x-component="Input"
x-component-props={{
placeholder: '请输入旧密码',
}}
/>
<SchemaField.String
name="new_password"
title="新密码"
required
x-decorator="FormItem"
x-component="Input"
x-component-props={{
placeholder: '请输入新密码',
}}
/>
</SchemaField>
</Form>
</Modal>
);
};
export default ModifyPasswordModal;

View File

@ -1,5 +1,5 @@
import React, { useCallback } from 'react'; import React, { useState, useCallback } from 'react';
import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons'; import { LogoutOutlined, SettingOutlined, UserOutlined, EditOutlined } from '@ant-design/icons';
import { Avatar, Menu, Spin } from 'antd'; import { Avatar, Menu, Spin } from 'antd';
import { history } from 'umi'; import { history } from 'umi';
import { stringify } from 'querystring'; import { stringify } from 'querystring';
@ -8,6 +8,7 @@ import styles from './index.less';
import type { MenuInfo } from 'rc-menu/lib/interface'; import type { MenuInfo } from 'rc-menu/lib/interface';
import RoutePath from '@/routes/routePath'; import RoutePath from '@/routes/routePath';
import { CACHE_TOKEN } from '@/constants/cacheKey'; import { CACHE_TOKEN } from '@/constants/cacheKey';
import ModifyPasswordModal from '@/components/ModifyPassword/ModifyPasswordModal';
export type GlobalHeaderRightProps = { export type GlobalHeaderRightProps = {
menu?: boolean; menu?: boolean;
@ -32,8 +33,18 @@ const loginOut = async () => {
}; };
const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({ menu }) => { const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({ menu }) => {
const [isModalVisible, setIsModalVisible] = useState(false);
const modifyPassword = async () => {
setIsModalVisible(true);
};
const onMenuClick = useCallback((event: MenuInfo) => { const onMenuClick = useCallback((event: MenuInfo) => {
const { key } = event; const { key } = event;
if (key === 'modify') {
modifyPassword();
return;
}
if (key === 'logout') { if (key === 'logout') {
loginOut(); loginOut();
return; return;
@ -77,7 +88,10 @@ const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({ menu }) => {
</Menu.Item> </Menu.Item>
)} )}
{menu && <Menu.Divider />} {menu && <Menu.Divider />}
<Menu.Item key="modify">
<EditOutlined />
</Menu.Item>
<Menu.Item key="logout"> <Menu.Item key="logout">
<LogoutOutlined /> <LogoutOutlined />
退 退
@ -85,12 +99,24 @@ const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({ menu }) => {
</Menu> </Menu>
); );
return ( return (
<HeaderDropdown overlay={menuHeaderDropdown}> <div>
<span className={`${styles.action} ${styles.account}`}> <HeaderDropdown overlay={menuHeaderDropdown}>
<Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" /> <span className={`${styles.action} ${styles.account}`}>
<span className={`${styles.name} anticon`}>{currentUser.name}</span> <Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" />
</span> <span className={`${styles.name} anticon`}>{currentUser.name}</span>
</HeaderDropdown> </span>
</HeaderDropdown>
<ModifyPasswordModal
visible={isModalVisible}
onCancel={function () {
setIsModalVisible(false);
}}
onOk={function () {
console.log('onOk');
setIsModalVisible(false);
}}
/>
</div>
); );
}; };

View File

@ -0,0 +1,13 @@
.delete-btn {
color: @error-color;
&:hover {
color: @error-color !important;
}
}
.disabled {
color: @disabled-color;
cursor: not-allowed;
&:hover {
color: @disabled-color !important;
}
}

View File

@ -0,0 +1,24 @@
import React from 'react';
import { Popconfirm } from 'antd';
import styles from './index.less';
import classNames from 'classnames';
interface PropsType {
onConfirm: () => void;
title?: string;
buttonName?: string;
disabled?: boolean;
}
const ConfirmButton: React.FC<PropsType> = ({
onConfirm,
disabled = false,
title = '',
buttonName = '',
}) => {
return (
<Popconfirm title={title} disabled={disabled} onConfirm={onConfirm} okText="是" cancelText="否">
<a className={classNames(styles.deleteBtn, disabled ? styles.disabled : '')}>{buttonName}</a>
</Popconfirm>
);
};
export default ConfirmButton;

View File

@ -172,7 +172,7 @@ const Table = <T extends Record<string, any>>(props: PropsType) => {
}} }}
> >
<PlusOutlined /> <PlusOutlined />
{item.text || '新建'} {item.text || '添加'}
</Button>, </Button>,
); );
} else if (item.type === 'batchDelete') { } else if (item.type === 'batchDelete') {

View File

@ -35,7 +35,7 @@ const Login: React.FC = () => {
}} }}
> >
<ProFormText <ProFormText
name="username" name="name"
fieldProps={{ fieldProps={{
size: 'large', size: 'large',
prefix: <UserOutlined className={styles.prefixIcon} />, prefix: <UserOutlined className={styles.prefixIcon} />,

View File

@ -0,0 +1,97 @@
// 创建弹窗
import React, { useRef } from 'react';
import { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core';
import { FormProvider, createSchemaField } from '@formily/react';
import { getCoinTypeList } from '@/services/recharge/coinType';
import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, Select } from '@formily/antd';
import { action } from '@formily/reactive';
interface AddAddressModalPropsType extends ModalProps {
onOk: (val: any) => void;
onCancel: () => void;
}
const SchemaField = createSchemaField({
components: {
FormItem,
Input,
Select,
},
});
const useAsyncDataSource = (
pattern: FormPathPattern,
service: (field: Field) => Promise<{ label: string; value: any }[]>,
) => {
onFieldReact(pattern, (field) => {
service(field).then(
action.bound((data) => {
field.dataSource = data;
}),
);
});
};
const form = createForm({
effects: () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
useAsyncDataSource('bc_name', async (field) => {
const list = await getCoinTypeList({ page: 1, page_size: 10 });
const option = [];
for (let index = 0; index < list.items.length; index++) {
const element = list.items[index];
const item = {
label: element.bc_name,
value: element.bc_name,
};
option.push(item);
}
return option;
});
},
});
const AddAddressModal = ({ onOk, onCancel, ...rest }: AddAddressModalPropsType) => {
const handleOk = () => {
const formState = form.getFormState();
onOk(formState.values);
};
const handleCancel = () => {
onCancel();
};
return (
<Modal title="创建收款地址" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<FormProvider form={form}>
<SchemaField>
<SchemaField.String
name="bc_name"
title="游戏币名称"
required
x-decorator="FormItem"
x-component="Select"
x-component-props={{
placeholder: '',
}}
/>
<SchemaField.String
name="address"
title="收款地址"
x-decorator="FormItem"
x-component="Input"
x-component-props={{
placeholder: '不传则后台生成',
}}
/>
</SchemaField>
</FormProvider>
{/* <Form form={form} labelCol={4} wrapperCol={18}> */}
{/* </Form> */}
</Modal>
);
};
export default AddAddressModal;

View File

@ -0,0 +1,106 @@
// 修改弹窗
import React, { useRef, useEffect } from 'react';
import { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core';
import { getCoinTypeList } from '@/services/recharge/coinType';
import { FormProvider, createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, Select } from '@formily/antd';
import { action } from '@formily/reactive';
interface EditAddressModalPropsType extends ModalProps {
editModalData: any;
onOk: (val: any) => void;
onCancel: () => void;
}
const SchemaField = createSchemaField({
components: {
FormItem,
Input,
Select,
},
});
const EditAddressModal = ({
onOk,
onCancel,
editModalData,
...rest
}: EditAddressModalPropsType) => {
const useAsyncDataSource = (
pattern: FormPathPattern,
service: (field: Field) => Promise<{ label: string; value: any }[]>,
) => {
onFieldReact(pattern, (field) => {
service(field).then(
action.bound((data) => {
field.dataSource = data;
}),
);
});
};
const form = createForm({
effects: () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
useAsyncDataSource('bc_name', async (field) => {
const list = await getCoinTypeList({ page: 1, page_size: 10 });
const option = [];
for (let index = 0; index < list.items.length; index++) {
const element = list.items[index];
const item = {
label: element.bc_name,
value: element.bc_name,
};
option.push(item);
}
return option;
});
},
});
useEffect(() => {
form.setInitialValues(editModalData);
});
const handleOk = () => {
const formState = form.getFormState();
onOk(formState.values);
};
const handleCancel = () => {
onCancel();
};
return (
<Modal title="修改收款地址" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField>
<SchemaField.String
name="address"
title="旧收款地址"
x-disabled
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="bc_name"
title="游戏币名称"
required
x-decorator="FormItem"
x-component="Select"
/>
<SchemaField.String
name="new_address"
title="新收款地址"
required
x-decorator="FormItem"
x-component="Input"
/>
</SchemaField>
</Form>
</Modal>
);
};
export default EditAddressModal;

View File

@ -0,0 +1,114 @@
import React, { useState, useRef } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table';
import {
getAddressList,
deleteAddress,
createAddress,
modifyAddress,
} from '@/services/recharge/address';
import { fetchTableData } from '@/utils/table';
import DeleteButton from '@/components/Table/DeleteButton';
import AddAddressModal from '../Components/AddAddressModal';
import EditAddressModal from '../Components/EditAddressModal';
const CollectionAddressList = () => {
const tableRef = useRef<ActionType>();
const [isModalVisible, setIsModalVisible] = useState(false);
const [isEditModalVisible, setIsEditModalVisible] = useState(false);
const [modalData, setModalData] = useState({});
const handleEdit = (row: any) => {
row.new_address = '';
setModalData(row);
setIsEditModalVisible(true);
};
const handleDelete = async (address: any) => {
await deleteAddress({ address: address });
tableRef.current?.reload();
};
const columns: ProColumns<any>[] = [
{
title: '收款地址',
dataIndex: 'address',
hideInSearch: true,
ellipsis: true,
},
{
title: '收款游戏币名称',
dataIndex: 'bc_name',
hideInSearch: true,
ellipsis: true,
},
{
title: '操作',
valueType: 'option',
width: 150,
render: (_, row) => [
<a
key="edit"
onClick={() => {
handleEdit(row);
}}
>
</a>,
<DeleteButton
key="delete"
onDelete={() => {
handleDelete(row.address);
}}
/>,
],
},
];
return (
<div>
<Table
columns={columns}
rowKey="id"
toolBarActions={[
{
type: 'add',
onConfirm: () => {
setIsModalVisible(true);
},
},
]}
actionRef={tableRef}
request={async (params) => {
const res = await fetchTableData(getAddressList, params);
return res;
}}
/>
<AddAddressModal
visible={isModalVisible}
onCancel={function () {
setIsModalVisible(false);
}}
onOk={async function (val: any): Promise<void> {
await createAddress(val);
setIsModalVisible(false);
tableRef.current?.reload();
}}
/>
<EditAddressModal
visible={isEditModalVisible}
editModalData={modalData}
onCancel={function () {
setIsEditModalVisible(false);
}}
onOk={async function (val: any): Promise<void> {
await modifyAddress(val);
setIsEditModalVisible(false);
tableRef.current?.reload();
}}
/>
</div>
);
};
export default CollectionAddressList;

View File

@ -0,0 +1,71 @@
// 添加代币类型弹窗
import React, { useRef } from 'react';
import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, NumberPicker } from '@formily/antd';
interface AddCoinTypeModalPropsType extends ModalProps {
onOk: (val: any) => void;
onCancel: () => void;
}
const SchemaField = createSchemaField({
components: {
FormItem,
Input,
NumberPicker,
},
});
const form = createForm({});
const AddCoinTypeModal = ({ onOk, onCancel, ...rest }: AddCoinTypeModalPropsType) => {
const handleOk = () => {
const formState = form.getFormState();
onOk(formState.values);
};
const handleCancel = () => {
onCancel();
};
return (
<Modal title="添加代币类型" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField>
<SchemaField.String
name="bc_name"
title="代币名称"
required
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="usdt_price"
title="usdt比例"
required
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="eth_price"
title="eth比例"
required
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.Number
name="num"
title="数量"
required
x-decorator="FormItem"
x-component="NumberPicker"
/>
</SchemaField>
</Form>
</Modal>
);
};
export default AddCoinTypeModal;

View File

@ -0,0 +1,72 @@
// 修改弹窗
import React, { useRef, useEffect } from 'react';
import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, Select } from '@formily/antd';
interface EditCoinTypeModalPropsType extends ModalProps {
editModalData: any;
onOk: (val: any) => void;
onCancel: () => void;
}
const SchemaField = createSchemaField({
components: {
FormItem,
Input,
Select,
},
});
const form = createForm({});
const EditCoinTypeModal = ({
onOk,
onCancel,
editModalData,
...rest
}: EditCoinTypeModalPropsType) => {
useEffect(() => {
form.setInitialValues(editModalData);
});
const handleOk = () => {
const formState = form.getFormState();
onOk(formState.values);
};
const handleCancel = () => {
onCancel();
};
return (
<Modal title="修改代币类型" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField>
<SchemaField.String
name="bc_name"
title="游戏币名称"
x-disabled
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="usdt_price"
title="usdt比例"
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="eth_price"
title="eth比例"
x-decorator="FormItem"
x-component="Input"
/>
</SchemaField>
</Form>
</Modal>
);
};
export default EditCoinTypeModal;

View File

@ -0,0 +1,108 @@
import React, { useState, useRef } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table';
import { addCoinType, getCoinTypeList, modifyCoinType } from '@/services/recharge/coinType';
import { fetchTableData } from '@/utils/table';
import AddCoinTypeModal from '../Components/AddCoinTypeModal';
import EditCoinTypeModal from '../Components/EditCoinTypeModal';
const CoinTypeList = () => {
const tableRef = useRef<ActionType>();
const [isModalVisible, setIsModalVisible] = useState(false);
const [isEditModalVisible, setIsEditModalVisible] = useState(false);
const [modalData, setModalData] = useState({});
const handleEdit = (row: any) => {
setModalData(row);
setIsEditModalVisible(true);
tableRef.current?.reload();
};
const columns: ProColumns<any>[] = [
{
title: '游戏币名称',
dataIndex: 'bc_name',
hideInSearch: true,
ellipsis: true,
},
{
title: 'usdt比例',
dataIndex: 'usdt_price',
hideInSearch: true,
ellipsis: true,
},
{
title: 'eth比例',
dataIndex: 'eth_price',
hideInSearch: true,
ellipsis: true,
},
{
title: '代币发行总量',
dataIndex: 'num',
hideInSearch: true,
ellipsis: true,
},
{
title: '操作',
valueType: 'option',
width: 150,
render: (_, row) => [
<a
key="edit"
onClick={() => {
handleEdit(row);
}}
>
</a>,
],
},
];
return (
<div>
<Table
columns={columns}
rowKey="id"
toolBarActions={[
{
type: 'add',
onConfirm: () => {
setIsModalVisible(true);
},
},
]}
actionRef={tableRef}
request={async (params) => {
const res = await fetchTableData(getCoinTypeList, params);
return res;
}}
/>
<AddCoinTypeModal
visible={isModalVisible}
onCancel={function () {
setIsModalVisible(false);
}}
onOk={async function (val: any): Promise<void> {
await addCoinType(val);
setIsModalVisible(false);
tableRef.current?.reload();
}}
/>
<EditCoinTypeModal
visible={isEditModalVisible}
editModalData={modalData}
onCancel={function () {
setIsEditModalVisible(false);
}}
onOk={async function (val: any): Promise<void> {
await modifyCoinType(val);
setIsEditModalVisible(false);
tableRef.current?.reload();
}}
/>
</div>
);
};
export default CoinTypeList;

View File

@ -0,0 +1,93 @@
import React, { useRef } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table';
import { getRecordList } from '@/services/recharge/record';
import { fetchTableData } from '@/utils/table';
import { getBalanceAmount } from '@/utils/formatBalance';
import BigNumber from 'bignumber.js';
import moment from 'moment';
const RecordList = () => {
const tableRef = useRef<ActionType>();
const columns: ProColumns<any>[] = [
{
title: '时间',
dataIndex: 'time',
hideInTable: true,
valueType: 'dateRange',
ellipsis: true,
},
{
title: '交易哈希',
dataIndex: 'tx_hash',
hideInSearch: true,
ellipsis: true,
},
{
title: '金额',
dataIndex: 'price',
width: '10%',
hideInSearch: true,
},
{
title: '位数',
dataIndex: 'decimals',
width: '10%',
hideInSearch: true,
},
{
title: '游戏币类型',
dataIndex: 'bc_type',
width: '10%',
hideInSearch: true,
},
{
title: '发送地址',
dataIndex: 'from_address',
hideInSearch: true,
ellipsis: true,
},
{
title: '接受地址',
dataIndex: 'to_address',
hideInSearch: true,
ellipsis: true,
},
{
title: '充值时间',
dataIndex: 'time',
hideInSearch: true,
ellipsis: true,
},
];
return (
<Table
columns={columns}
rowKey="id"
actionRef={tableRef}
request={async (params) => {
console.log('params = ', params);
if ((params.time ?? '') !== '') {
const start = Date.parse(params.time[0] + ' 00:00:00');
const end = Date.parse(params.time[1] + ' 23:59:59');
params.start_time = start / 1000;
params.end_time = end / 1000;
}
const res = await fetchTableData(getRecordList, params);
console.log('res = ', res);
for (const key in res.data) {
if (Object.prototype.hasOwnProperty.call(res.data, key)) {
const element = res.data[key];
element.price = getBalanceAmount(
new BigNumber(element.price),
element.decimals,
).toNumber();
element.time = moment(element.time * 1000).format('YYYY-MM-DD hh:mm:ss');
}
}
return res;
}}
/>
);
};
export default RecordList;

View File

@ -0,0 +1,101 @@
import React, { useRef } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table';
import { getWithdrawList, solveWithdraw } from '@/services/recharge/withdraw';
import { fetchTableData } from '@/utils/table';
import { getBalanceAmount } from '@/utils/formatBalance';
import BigNumber from 'bignumber.js';
import ConfirmButton from '@/components/Table/ConfirmButton';
import moment from 'moment';
const WithdrawList = () => {
const handleConfirm = async (uuid) => {
await solveWithdraw({ uuid: uuid });
};
const handlePass = async (row) => {};
const tableRef = useRef<ActionType>();
const columns: ProColumns<any>[] = [
{
title: '提现订单号',
dataIndex: 'uuid',
ellipsis: true,
},
{
title: '金额',
dataIndex: 'price',
width: '10%',
hideInSearch: true,
},
{
title: '接收地址',
dataIndex: 'to_address',
hideInSearch: true,
ellipsis: true,
},
{
title: '游戏币类型',
dataIndex: 'bc_type',
width: '10%',
},
{
title: '类型',
dataIndex: 'type',
width: '10%',
},
{
title: '时间',
dataIndex: 'time',
valueType: 'dateRange',
ellipsis: true,
},
{
title: '操作',
valueType: 'option',
width: 150,
render: (_, row) => [
<ConfirmButton
key="confirm"
title="确认通知已提现?"
buttonName="通知"
onConfirm={() => {
handleConfirm(row.uuid);
}}
/>,
<a
key="pass"
onClick={() => {
handlePass(row);
}}
>
</a>,
],
},
];
return (
<div>
<Table
columns={columns}
rowKey="id"
actionRef={tableRef}
request={async (params) => {
const res = await fetchTableData(getWithdrawList, params);
for (const key in res.data) {
if (Object.prototype.hasOwnProperty.call(res.data, key)) {
const element = res.data[key];
element.price = getBalanceAmount(
new BigNumber(element.price),
element.decimals,
).toNumber();
element.time = moment(element.time * 1000).format('YYYY-MM-DD hh:mm:ss');
}
}
return res;
}}
/>
</div>
);
};
export default WithdrawList;

View File

@ -0,0 +1,84 @@
// 创建弹窗
import React, { useRef } from 'react';
import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, Select } from '@formily/antd';
import { addUser } from '@/services/system/accountManage';
interface AddAccountModalPropsType extends ModalProps {
onCancel: () => void;
onOk: () => void;
}
const SchemaField = createSchemaField({
components: {
FormItem,
Input,
Select,
},
});
const form = createForm({});
const AddAccountModal = ({ onOk, onCancel, ...rest }: AddAccountModalPropsType) => {
const handleOk = async () => {
form.submit(async () => {
onOk();
const formState = form.getFormState();
formState.values.role = parseInt(formState.values.role);
await addUser(formState.values);
});
};
const handleCancel = () => {
onCancel();
};
return (
<Modal title="添加管理账号" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField>
<SchemaField.String
name="name"
title="账号名"
required
x-decorator="FormItem"
x-component="Input"
x-component-props={{
placeholder: '请输入账号名',
}}
/>
<SchemaField.String
name="password"
title="密码"
required
x-validator={{
required: true,
}}
x-decorator="FormItem"
x-component="Input"
x-component-props={{
placeholder: '请输入密码',
}}
/>
<SchemaField.String
name="role"
title="角色"
required
x-validator={{
required: true,
}}
x-decorator="FormItem"
x-component="Input"
x-component-props={{
placeholder: '请选择角色',
}}
/>
</SchemaField>
</Form>
</Modal>
);
};
export default AddAccountModal;

View File

@ -0,0 +1,82 @@
// 创建弹窗
import React, { useRef, useEffect } from 'react';
import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, Select } from '@formily/antd';
import { addUser, updateUser } from '@/services/system/accountManage';
interface AddUserModalPropsType extends ModalProps {
editModalData: any;
onCancel: () => void;
onOk: () => void;
}
const SchemaField = createSchemaField({
components: {
FormItem,
Input,
Select,
},
});
const form = createForm({});
const AddUserModal = ({ onOk, onCancel, editModalData, ...rest }: AddUserModalPropsType) => {
useEffect(() => {
form.setInitialValues(editModalData);
});
const handleOk = async () => {
onOk();
const formState = form.getFormState();
formState.values.role = parseInt(formState.values.role);
await updateUser(formState.values);
};
const handleCancel = () => {
onCancel();
};
return (
<Modal title="编辑管理账号" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField>
<SchemaField.String
name="name"
title="账号名"
required
x-disabled
x-decorator="FormItem"
x-component="Input"
x-component-props={{
placeholder: '请输入账号名',
}}
/>
<SchemaField.String
name="password"
title="密码"
required
x-decorator="FormItem"
x-component="Input"
x-component-props={{
placeholder: '请输入密码',
}}
/>
<SchemaField.String
name="role"
title="角色"
required
x-decorator="FormItem"
x-component="Input"
x-component-props={{
placeholder: '请选择角色',
}}
/>
</SchemaField>
</Form>
</Modal>
);
};
export default AddUserModal;

View File

@ -0,0 +1,117 @@
import React, { useState, useRef } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table';
import {
getAccountList,
deleteUser,
updateUser,
changeUserStatus,
} from '@/services/system/accountManage';
import { fetchTableData } from '@/utils/table';
import DeleteButton from '@/components/Table/DeleteButton';
import { Switch } from 'antd';
import AddAccountModal from '../Components/AddAccountModal';
import EditAccountModal from '../Components/EditAccountModal';
const AccountManageList = () => {
const [isModalVisible, setIsModalVisible] = useState(false);
const [isEditModal, setIsEditModal] = useState(false);
const [modalData, setModalData] = useState({});
const handleEdit = (row: any) => {
setModalData(row);
setIsEditModal(true);
};
const handleDelete = async (name: any) => {
await deleteUser({ name: name });
};
const tableRef = useRef<ActionType>();
const columns: ProColumns<any>[] = [
{
title: '账号',
dataIndex: 'name',
hideInSearch: true,
ellipsis: true,
},
{
title: '角色',
dataIndex: 'role',
hideInSearch: true,
ellipsis: true,
},
{
title: '操作',
valueType: 'option',
width: 180,
render: (_, row) => [
<a
key="edit"
onClick={() => {
handleEdit(row);
}}
>
</a>,
<Switch
key="switch"
defaultChecked={row.status}
size="small"
onChange={async (checked) => {
await changeUserStatus({ name: row.name, status: checked });
}}
/>,
<DeleteButton
key="delete"
onDelete={() => {
handleDelete(row.name);
tableRef.current?.reload();
}}
/>,
],
},
];
return (
<div>
<Table
columns={columns}
rowKey="id"
toolBarActions={[
{
type: 'add',
onConfirm: () => {
setIsModalVisible(true);
},
},
]}
actionRef={tableRef}
request={async (params) => {
const res = await fetchTableData(getAccountList, params);
return res;
}}
/>
<AddAccountModal
visible={isModalVisible}
onCancel={function () {
setIsModalVisible(false);
}}
onOk={async function (): Promise<void> {
setIsModalVisible(false);
tableRef.current?.reload();
}}
/>
<EditAccountModal
visible={isEditModal}
editModalData={modalData}
onCancel={function () {
setIsEditModal(false);
}}
onOk={async function (): Promise<void> {
setIsEditModal(false);
tableRef.current?.reload();
}}
/>
</div>
);
};
export default AccountManageList;

View File

@ -0,0 +1,69 @@
// 添加代币类型弹窗
import React, { useRef } from 'react';
import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, Select } from '@formily/antd';
interface AddNoticeModalPropsType extends ModalProps {
onOk: (val: any) => void;
onCancel: () => void;
}
const SchemaField = createSchemaField({
components: {
FormItem,
Input,
Select,
},
});
const form = createForm({});
const AddNoticeModal = ({ onOk, onCancel, ...rest }: AddNoticeModalPropsType) => {
const handleOk = () => {
const formState = form.getFormState();
formState.values.code = parseInt(formState.values.code);
onOk(formState.values);
};
const handleCancel = () => {
onCancel();
};
return (
<Modal title="添加通知" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField>
<SchemaField.String
name="code"
title="通知码"
required
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="addr"
title="通知地址"
required
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.Boolean
name="status"
title="状态"
required
x-decorator="FormItem"
x-component="Select"
enum={[
{ label: '启用', value: true },
{ label: '禁用', value: false },
]}
/>
</SchemaField>
</Form>
</Modal>
);
};
export default AddNoticeModal;

View File

@ -0,0 +1,63 @@
// 修改弹窗
import React, { useRef, useEffect } from 'react';
import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, Select } from '@formily/antd';
interface EditNoticeModalPropsType extends ModalProps {
editModalData: any;
onOk: (val: any) => void;
onCancel: () => void;
}
const SchemaField = createSchemaField({
components: {
FormItem,
Input,
Select,
},
});
const form = createForm({});
const EditNoticeModal = ({ onOk, onCancel, editModalData, ...rest }: EditNoticeModalPropsType) => {
useEffect(() => {
form.setInitialValues(editModalData);
});
const handleOk = () => {
const formState = form.getFormState();
onOk(formState.values);
};
const handleCancel = () => {
onCancel();
};
return (
<Modal title="修改通知" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField>
<SchemaField.String
name="code"
title="通知码"
x-disabled
required
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="addr"
title="通知地址"
required
x-decorator="FormItem"
x-component="Input"
/>
</SchemaField>
</Form>
</Modal>
);
};
export default EditNoticeModal;

View File

@ -0,0 +1,118 @@
import React, { useState, useRef } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table';
import { getNoticeList, createNotice, updateNotice, deleteNotice } from '@/services/system/notice';
import { fetchTableData } from '@/utils/table';
import AddNoticeModal from '../Components/AddNoticeModal';
import DeleteButton from '@/components/Table/DeleteButton';
import { Switch } from 'antd';
import EditNoticeModal from '../Components/EditNoticeModal';
const NoticeList = () => {
const tableRef = useRef<ActionType>();
const [isModalVisible, setIsModalVisible] = useState(false);
const [isEditModalVisible, setIsEditModalVisible] = useState(false);
const [modalData, setModalData] = useState({});
const handleEdit = (row: any) => {
setModalData(row);
setIsEditModalVisible(true);
tableRef.current?.reload();
};
const handleDelete = async (code: any) => {
await deleteNotice({ code: code });
tableRef.current?.reload();
};
const columns: ProColumns<any>[] = [
{
title: '通知码',
dataIndex: 'code',
hideInSearch: true,
ellipsis: true,
},
{
title: '通知地址',
dataIndex: 'addr',
hideInSearch: true,
ellipsis: true,
},
{
title: '操作',
valueType: 'option',
width: 180,
render: (_, row) => [
<a
key="edit"
onClick={() => {
handleEdit(row);
}}
>
</a>,
<Switch
key="switch"
defaultChecked={row.status}
size="small"
onChange={async (checked) => {
row.status = checked;
await updateNotice(row);
}}
/>,
<DeleteButton
key="delete"
onDelete={() => {
handleDelete(row.code);
}}
/>,
],
},
];
return (
<div>
<Table
columns={columns}
rowKey="id"
toolBarActions={[
{
type: 'add',
onConfirm: () => {
setIsModalVisible(true);
},
},
]}
actionRef={tableRef}
request={async (params) => {
const res = await fetchTableData(getNoticeList, params);
return res;
}}
/>
<AddNoticeModal
visible={isModalVisible}
onCancel={function () {
setIsModalVisible(false);
}}
onOk={async function (val: any): Promise<void> {
await createNotice(val);
setIsModalVisible(false);
tableRef.current?.reload();
}}
/>
<EditNoticeModal
visible={isEditModalVisible}
editModalData={modalData}
onCancel={function () {
setIsEditModalVisible(false);
}}
onOk={async function (val: any): Promise<void> {
await updateNotice(val);
setIsEditModalVisible(false);
tableRef.current?.reload();
}}
/>
</div>
);
};
export default NoticeList;

View File

@ -0,0 +1,66 @@
import React, { useState, useRef } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table';
import { fetchTableData } from '@/utils/table';
import DeleteButton from '@/components/Table/DeleteButton';
const PermissionsList = () => {
const handleEdit = (row: any) => {};
const handleDelete = async (name: any) => {};
const tableRef = useRef<ActionType>();
const columns: ProColumns<any>[] = [
{
title: '收款地址',
dataIndex: 'address',
hideInSearch: true,
ellipsis: true,
},
{
title: '收款游戏币类型',
dataIndex: 'bc_type',
hideInSearch: true,
ellipsis: true,
},
{
title: '操作',
valueType: 'option',
width: 150,
render: (_, row) => [
<a
key="edit"
onClick={() => {
handleEdit(row);
}}
>
</a>,
<DeleteButton
key="delete"
onDelete={() => {
handleDelete(row.name);
}}
/>,
],
},
];
return (
<div>
<Table
columns={columns}
rowKey="id"
toolBarActions={[
{
type: 'add',
onConfirm: () => {},
},
]}
actionRef={tableRef}
request={async (params) => {
return {};
}}
/>
</div>
);
};
export default PermissionsList;

View File

@ -0,0 +1,78 @@
import React, { useRef } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table';
import { getRoleList, deleteRole } from '@/services/system/role';
import { fetchTableData } from '@/utils/table';
import DeleteButton from '@/components/Table/DeleteButton';
const RoleList = () => {
const handleEdit = (row: any) => {};
const handleAuth = (row: any) => {};
const handleDelete = async (role: any) => {
await deleteRole({ role: role });
};
const tableRef = useRef<ActionType>();
const columns: ProColumns<any>[] = [
{
title: '角色名称',
dataIndex: 'role_name',
hideInSearch: true,
ellipsis: true,
},
{
title: '用户类型',
dataIndex: 'role',
hideInSearch: true,
ellipsis: true,
},
{
title: '操作',
valueType: 'option',
width: 180,
render: (_, row) => [
<a
key="edit"
onClick={() => {
handleEdit(row);
}}
>
</a>,
<a
key="auth"
onClick={() => {
handleAuth(row);
}}
>
</a>,
<DeleteButton
key="delete"
onDelete={() => {
handleDelete(row.role);
}}
/>,
],
},
];
return (
<div>
<Table
columns={columns}
rowKey="id"
toolBarActions={[
{
type: 'add',
onConfirm: () => {},
},
]}
actionRef={tableRef}
request={async (params) => {
const res = await fetchTableData(getRoleList, params);
return res;
}}
/>
</div>
);
};
export default RoleList;

View File

@ -0,0 +1,24 @@
@import '~antd/es/style/themes/default.less';
.container {
display: flex;
flex-direction: column;
height: 100vh;
padding: 20px;
overflow: auto;
background: white;
:global {
.ant-pro-form-login-header {
margin-bottom: 40px;
}
}
}
.button {
width: 150px;
}
.textarea {
width: 600px;
margin-top: 20px;
}

View File

@ -0,0 +1,35 @@
import React, { useState, useEffect } from 'react';
import { Button, Input } from 'antd';
import styles from './index.less';
import { createSecretKey, getSecretKey } from '@/services/system/secretKey';
const { TextArea } = Input;
const SecretKey: React.FC = () => {
const [secretKey, setSecretKey] = useState('');
const create = async () => {
const data = await createSecretKey({});
setSecretKey(data + '');
};
const getUserSecretKey = async () => {
const data = await getSecretKey();
setSecretKey(data + '');
};
useEffect(() => {
getUserSecretKey();
}, []);
return (
<div className={styles.container}>
<Button className={styles.button} type="primary" onClick={create}>
</Button>
<TextArea className={styles.textarea} rows={16} value={secretKey} />
</div>
);
};
export default SecretKey;

View File

@ -0,0 +1,46 @@
import React, { useState, useRef } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table';
import { getUserList } from '@/services/user/user';
import { fetchTableData } from '@/utils/table';
const UserManageList = () => {
const tableRef = useRef<ActionType>();
const columns: ProColumns<any>[] = [
{
title: '用户钱包地址',
dataIndex: 'address',
ellipsis: true,
},
{
title: '登陆时间',
dataIndex: 'last_time',
hideInSearch: true,
ellipsis: true,
},
{
title: '注册时间',
dataIndex: 'first_time',
hideInSearch: true,
ellipsis: true,
},
];
return (
<Table
columns={columns}
rowKey="id"
toolBarActions={[
{
type: 'add',
onConfirm: () => {},
},
]}
actionRef={tableRef}
request={async (params) => {
const res = await fetchTableData(getUserList, params);
return res;
}}
/>
);
};
export default UserManageList;

View File

@ -11,25 +11,69 @@ export default [
component: './Login', component: './Login',
}, },
{ {
name: '设置', name: '充值系统',
path: RoutePath.SETTING, path: RoutePath.RECHARGE,
routes: [ routes: [
{ {
path: RoutePath.SETTING, path: RoutePath.RECHARGE,
redirect: RoutePath.WORK.LIST, redirect: RoutePath.RECORD.LIST,
hideInMenu: true, hideInMenu: true,
}, },
{ {
name: '作品', name: '充值订单',
path: RoutePath.WORK.LIST, path: RoutePath.RECORD.LIST,
component: './Work/List', component: './Recharge/Record/List',
}, },
{ {
name: '作品详情', name: '收款地址',
path: RoutePath.WORK.EDIT, path: RoutePath.ADDRESS.LIST,
component: './Recharge/Address/List',
},
{
name: '代币种类',
path: RoutePath.COIN_TYPE.LIST,
component: './Recharge/CoinType/List',
},
{
name: '提现管理',
path: RoutePath.WITHDRAW.LIST,
component: './Recharge/Withdraw/List',
},
],
},
{
name: '系统设置',
path: RoutePath.SYSTEM,
routes: [
{
path: RoutePath.SYSTEM,
redirect: RoutePath.ACCOUNT.LIST,
hideInMenu: true, hideInMenu: true,
component: './Work/Edit', },
{
name: '账号管理',
path: RoutePath.ACCOUNT.LIST,
component: './System/Account/List',
},
{
name: '角色管理',
path: RoutePath.ROLE.LIST,
component: './System/Role/List',
},
{
name: '权限管理',
path: RoutePath.PERMISSIONS.LIST,
component: './System/Permissions/List',
},
{
name: '通知管理',
path: RoutePath.NOTICE.LIST,
component: './System/Notice/List',
},
{
name: '密钥管理',
path: RoutePath.SECRET_KEY,
component: './System/SecretKey',
}, },
], ],
}, },
@ -87,9 +131,8 @@ export default [
}, },
{ {
path: '/', path: '/',
redirect: RoutePath.WORK.LIST, redirect: RoutePath.RECORD.LIST,
}, },
{ {
component: './404', component: './404',
}, },

View File

@ -1,10 +1,36 @@
const SETTING = '/setting'; const SETTING = '/setting';
const RECHARGE = '/recharge';
const SYSTEM = '/system';
const DATABOARD = '/databoard'; const DATABOARD = '/databoard';
const NFT = '/nft'; const NFT = '/nft';
const RoutePath = { const RoutePath = {
LOGIN: '/login', LOGIN: '/login',
SETTING: SETTING, RECHARGE: RECHARGE,
DATABOARD: DATABOARD, RECORD: {
LIST: `${RECHARGE}/record`,
},
ADDRESS: {
LIST: `${RECHARGE}/address`,
},
COIN_TYPE: {
LIST: `${RECHARGE}/coin_type`,
},
WITHDRAW: {
LIST: `${RECHARGE}/withdraw`,
},
SYSTEM: SYSTEM,
ACCOUNT: {
LIST: `${SYSTEM}/account`,
},
ROLE: {
LIST: `${SYSTEM}/role`,
},
PERMISSIONS: {
LIST: `${SYSTEM}/permissions`,
},
NOTICE: {
LIST: `${SYSTEM}/notice`,
},
NFT: NFT, NFT: NFT,
NFTCONTRACT: { NFTCONTRACT: {
LIST: `${NFT}/nftcontract`, LIST: `${NFT}/nftcontract`,
@ -12,6 +38,7 @@ const RoutePath = {
NFTTOKEN: { NFTTOKEN: {
LIST: `${NFT}/nfttoken`, LIST: `${NFT}/nfttoken`,
}, },
DATABOARD: DATABOARD,
COREDATA: { COREDATA: {
LIST: `${DATABOARD}/coredata`, LIST: `${DATABOARD}/coredata`,
}, },
@ -24,10 +51,12 @@ const RoutePath = {
RECHARGEANALYSIS: { RECHARGEANALYSIS: {
LIST: `${DATABOARD}/rechargeanalysis`, LIST: `${DATABOARD}/rechargeanalysis`,
}, },
WORK: { SECRET_KEY: `${SYSTEM}/secret_key`,
LIST: `${SETTING}/work`, // SETTING: SETTING,
EDIT: `${SETTING}/work/edit`, // WORK: {
}, // LIST: `${SETTING}/work`,
// EDIT: `${SETTING}/work/edit`,
// },
}; };
export default RoutePath; export default RoutePath;

View File

@ -7,3 +7,18 @@ export const login = (data) => {
data, data,
}); });
}; };
/**
*
* @param data
* password
* new_password
* @returns
*/
export const modifyPassword = (data) => {
return request.request({
url: '/admin/update',
method: 'post',
data,
});
};

View File

@ -0,0 +1,61 @@
import request from '@/utils/request';
/**
*
* @param {object} params
* @returns {array} data
* bc_type
* address
*/
export const getAddressList = (params) => {
return request.request({
url: '/address/get',
method: 'get',
params,
});
};
/**
*
* @param {Object} data
* bc_type
* address ()
* @returns
*/
export const createAddress = (data) => {
return request.request({
url: '/address/create',
method: 'post',
data,
});
};
/**
*
* @param {Object} data
* address
* @returns
*/
export const deleteAddress = (data) => {
return request.request({
url: '/address/delete',
method: 'post',
data,
});
};
/**
*
* @param {Object} data
* address
* bc_type
* new_address
* @returns
*/
export const modifyAddress = (data) => {
return request.request({
url: '/address/update',
method: 'post',
data,
});
};

View File

@ -0,0 +1,53 @@
import request from '@/utils/request';
/**
*
* @param {object} params
* type
* @returns {array} data
* bc_name
* bc_type
* usdt_price usdt的比例
* eth_price eth的比例
*/
export const getCoinTypeList = (params) => {
return request.request({
url: '/token/get',
method: 'get',
params,
});
};
/**
*
* @param {object} params
* bc_name
* usdt_price usdt的比例
* eth_price eth的比例
* num
* @returns {object} data
*/
export const addCoinType = (data) => {
return request.request({
url: '/token/create',
method: 'post',
data,
});
};
/**
*
* @param {object} params
* bc_name
* bc_type
* usdt_price usdt的比例
* eth_price eth的比例
* @returns {object} data
*/
export const modifyCoinType = (data) => {
return request.request({
url: '/token/update',
method: 'post',
data,
});
};

View File

@ -0,0 +1,20 @@
import request from '@/utils/request';
/**
*
* @param {object} data
* page
* pageSize
* start_time
* end_time
* @returns {array} data
* bc_type
* address
*/
export const getRecordList = (data) => {
return request.request({
url: '/recharge/record',
method: 'post',
data,
});
};

View File

@ -0,0 +1,34 @@
import request from '@/utils/request';
/**
*
* @param {object} params
*
* @returns {array} data
* uuid id
* to_addrss
* from_address
* time
* price
*/
export const getWithdrawList = (data) => {
return request.request({
url: '/withdrawal/get',
method: 'post',
data,
});
};
/**
*
* @param {object} params
* uuid id
* @returns {object} data
*/
export const solveWithdraw = (data) => {
return request.request({
url: 'withdrawal/update',
method: 'post',
data,
});
};

View File

@ -0,0 +1,75 @@
import request from '@/utils/request';
/**
*
* @param {object} params
* @returns {array} data
*/
export const getAccountList = (params) => {
return request.request({
url: '/user/get',
method: 'get',
params,
});
};
/**
*
* @param {object} data
* name
* password
* role
* @returns {array} data
*/
export const addUser = (data) => {
return request.request({
url: '/user/create',
method: 'post',
data,
});
};
/**
*
* @param {object} data
* name
* password
* role
* @returns {array} data
*/
export const updateUser = (data) => {
return request.request({
url: '/user/update',
method: 'post',
data,
});
};
/**
*
* @param {object} data
* name
* status
* @returns {array} data
*/
export const changeUserStatus = (data) => {
return request.request({
url: '/user/status',
method: 'post',
data,
});
};
/**
*
* @param {object} data
* name
* @returns {array} data
*/
export const deleteUser = (data) => {
return request.request({
url: '/user/delete',
method: 'post',
data,
});
};

View File

@ -0,0 +1,53 @@
import request from '@/utils/request';
/**
*
* @param {object} params
* @returns {array} data
*/
export const getNoticeList = (params) => {
return request.request({
url: '/notice/get',
method: 'get',
params,
});
};
/**
*
* @param {object} params
* @returns {array} data
*/
export const createNotice = (data) => {
return request.request({
url: '/notice/create',
method: 'post',
data,
});
};
/**
*
* @param {object} params
* @returns {array} data
*/
export const updateNotice = (data) => {
return request.request({
url: '/notice/update',
method: 'post',
data,
});
};
/**
*
* @param {object} params
* @returns {array} data
*/
export const deleteNotice = (data) => {
return request.request({
url: '/notice/delete',
method: 'post',
data,
});
};

View File

@ -0,0 +1,30 @@
import request from '@/utils/request';
/**
*
* @param {object} params
* @returns {array} data
* role_name
* role
*/
export const getRoleList = (params) => {
return request.request({
url: '/user/role',
method: 'get',
params,
});
};
/**
*
* @param {object} params
* role
* @returns {array} data
*/
export const deleteRole = (data) => {
return request.request({
url: '/user/role/delete',
method: 'post',
data,
});
};

View File

@ -0,0 +1,26 @@
import request from '@/utils/request';
/**
*
* @param {object} params
* @returns {array} data
*/
export const getSecretKey = () => {
return request.request({
url: '/key/get',
method: 'get',
});
};
/**
*
* @param {object} data
* @returns {array} data
*/
export const createSecretKey = (data) => {
return request.request({
url: '/key/create',
method: 'post',
data,
});
};

16
src/services/user/user.ts Normal file
View File

@ -0,0 +1,16 @@
import request from '@/utils/request';
/**
*
* @param {object} params
* @returns {array} data
* role_name
* role
*/
export const getUserList = (params) => {
return request.request({
url: '/account/get',
method: 'get',
params,
});
};

View File

@ -176,7 +176,7 @@
.ant-pro-table-list-toolbar-container { .ant-pro-table-list-toolbar-container {
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
padding: 0 0 20px 0; padding: 20px 0 20px 0;
.ant-pro-table-list-toolbar-left { .ant-pro-table-list-toolbar-left {
.ant-space-item { .ant-space-item {
margin-bottom: 16px; margin-bottom: 16px;

6
src/utils/bigNumber.ts Normal file
View File

@ -0,0 +1,6 @@
import BigNumber from 'bignumber.js';
export const BIG_ZERO = new BigNumber(0);
export const BIG_ONE = new BigNumber(1);
export const BIG_NINE = new BigNumber(9);
export const BIG_TEN = new BigNumber(10);

View File

@ -0,0 +1,6 @@
import BigNumber from 'bignumber.js';
import { BIG_TEN } from './bigNumber';
export const getBalanceAmount = (amount: BigNumber, decimals = 18) => {
return new BigNumber(amount).dividedBy(BIG_TEN.pow(decimals));
};

View File

@ -6,13 +6,13 @@ import { CACHE_TOKEN } from '@/constants/cacheKey';
// create an axios instance // create an axios instance
const request = axios.create({ const request = axios.create({
baseURL: '', // baseURL: '/tbg/api/v1', //
timeout: 10000, // request timeout timeout: 10000, // request timeout
}); });
// request interceptor // request interceptor
request.interceptors.request.use( request.interceptors.request.use(
(memo: any) => { (memo: any) => {
memo.headers.token = localStorage.getItem(CACHE_TOKEN); memo.headers.Authorization = localStorage.getItem(CACHE_TOKEN);
return memo; return memo;
}, },
(error) => { (error) => {
@ -24,7 +24,7 @@ request.interceptors.response.use(
(response) => { (response) => {
const res: any = response.data; const res: any = response.data;
if (res.code !== 200) { if (res.code !== 200) {
if (res.code === 401) { if (res.code === 401 || res.code === 10001) {
notification.error({ notification.error({
message: '错误信息', message: '错误信息',
description: '登录失效', description: '登录失效',

View File

@ -5,12 +5,11 @@ export const fetchTableData = async (
formatObj: any = {}, formatObj: any = {},
) => { ) => {
params.page = params.current; params.page = params.current;
params.num = params.pageSize; params.page_size = params.pageSize;
delete params.current; delete params.current;
delete params.pageSize; delete params.pageSize;
const res = (await fetch(params)) || {}; const res = (await fetch(params)) || {};
const data = res.data; const data = res.items;
data?.forEach((n: any) => { data?.forEach((n: any) => {
for (const key in formatObj) { for (const key in formatObj) {
n[key] = n[formatObj[key]]; n[key] = n[formatObj[key]];

5794
yarn.lock

File diff suppressed because it is too large Load Diff