系统管理功能完善

This commit is contained in:
zzy 2022-07-30 16:42:08 +08:00
parent 3d6c3b873c
commit 31198544d7
19 changed files with 296 additions and 75 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.1.226:9999',
// 配置了这个可以从 http 代理到 https // 配置了这个可以从 http 代理到 https
// 依赖 origin 的功能可能需要这个,比如 cookie // 依赖 origin 的功能可能需要这个,比如 cookie
changeOrigin: true, changeOrigin: true,

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 '@/pages/Login/components/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,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,4 +1,4 @@
// 创建收款地址弹窗 // 创建弹窗
import React, { useRef } from 'react'; import React, { useRef } from 'react';
import { createForm } from '@formily/core'; import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react'; import { createSchemaField } from '@formily/react';

View File

@ -1,4 +1,4 @@
// 修改收款地址弹窗 // 修改弹窗
import React, { useRef, useEffect } from 'react'; import React, { useRef, useEffect } from 'react';
import { createForm } from '@formily/core'; import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react'; import { createSchemaField } from '@formily/react';

View File

@ -1,4 +1,4 @@
// 修改收款地址弹窗 // 修改弹窗
import React, { useRef, useEffect } from 'react'; import React, { useRef, useEffect } from 'react';
import { createForm } from '@formily/core'; import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react'; import { createSchemaField } from '@formily/react';

View File

@ -59,30 +59,28 @@ const RecordList = () => {
}, },
]; ];
return ( return (
<div> <Table
<Table columns={columns}
columns={columns} rowKey="id"
rowKey="id" actionRef={tableRef}
actionRef={tableRef} request={async (params) => {
request={async (params) => { if ((params.time ?? '') !== '') {
if ((params.time ?? '') !== '') { params.start_time = params.time[0];
params.start_time = params.time[0]; params.end_time = params.time[1];
params.end_time = params.time[1]; }
const res = await fetchTableData(getRecordList, 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();
} }
const res = await fetchTableData(getRecordList, params); }
for (const key in res.data) { return res;
if (Object.prototype.hasOwnProperty.call(res.data, key)) { }}
const element = res.data[key]; />
element.price = getBalanceAmount(
new BigNumber(element.price),
element.decimals,
).toNumber();
}
}
return res;
}}
/>
</div>
); );
}; };

View File

@ -4,9 +4,18 @@ import { getAccountList, deleteUser } from '@/services/System/accountManage';
import { fetchTableData } from '@/utils/table'; import { fetchTableData } from '@/utils/table';
import DeleteButton from '@/components/Table/DeleteButton'; import DeleteButton from '@/components/Table/DeleteButton';
import { Switch } from 'antd'; import { Switch } from 'antd';
import AddAccountModal from '../components/addAccountModal';
const AccountManageList = () => { const AccountManageList = () => {
const handleEdit = (row: any) => {}; const [isModalVisible, setIsModalVisible] = useState(false);
const [isEditModal, setIsEditModal] = useState(false);
const [modalData, setModalData] = useState({});
const handleEdit = (row: any) => {
setModalData(row);
setIsEditModal(true);
setIsModalVisible(true);
};
const handleDelete = async (name: any) => { const handleDelete = async (name: any) => {
await deleteUser({ name: name }); await deleteUser({ name: name });
@ -63,7 +72,9 @@ const AccountManageList = () => {
toolBarActions={[ toolBarActions={[
{ {
type: 'add', type: 'add',
onConfirm: () => {}, onConfirm: () => {
setIsModalVisible(true);
},
}, },
]} ]}
actionRef={tableRef} actionRef={tableRef}
@ -72,6 +83,17 @@ const AccountManageList = () => {
return res; return res;
}} }}
/> />
<AddAccountModal
visible={isModalVisible}
isEdit={isEditModal}
editModalData={modalData}
onCancel={function () {
setIsModalVisible(false);
}}
onOk={async function (): Promise<void> {
setIsModalVisible(false);
}}
/>
</div> </div>
); );
}; };

View File

@ -0,0 +1,81 @@
// 创建弹窗
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 } from '@/services/System/accountManage';
interface AddUserModalPropsType extends ModalProps {
isEdit: boolean;
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();
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-decorator="FormItem"
x-component="Input"
x-component-props={{
placeholder: '请输入密码',
}}
/>
<SchemaField.String
name="role"
title="角色"
required
x-decorator="FormItem"
x-component="Select"
x-component-props={{
placeholder: '请选择角色',
}}
/>
</SchemaField>
</Form>
</Modal>
);
};
export default AddUserModal;

View File

@ -25,23 +25,21 @@ const UserManageList = () => {
}, },
]; ];
return ( return (
<div> <Table
<Table columns={columns}
columns={columns} rowKey="id"
rowKey="id" toolBarActions={[
toolBarActions={[ {
{ type: 'add',
type: 'add', onConfirm: () => {},
onConfirm: () => {}, },
}, ]}
]} actionRef={tableRef}
actionRef={tableRef} request={async (params) => {
request={async (params) => { const res = await fetchTableData(getUserList, params);
const res = await fetchTableData(getUserList, params); return res;
return res; }}
}} />
/>
</div>
); );
}; };

View File

@ -9,7 +9,7 @@ import request from '@/utils/request';
*/ */
export const getAddressList = (params) => { export const getAddressList = (params) => {
return request.request({ return request.request({
url: '/api/v1/address/get', url: '/address/get',
method: 'get', method: 'get',
params, params,
}); });
@ -24,7 +24,7 @@ export const getAddressList = (params) => {
*/ */
export const createAddress = (data) => { export const createAddress = (data) => {
return request.request({ return request.request({
url: '/api/v1/address/make', url: '/address/make',
method: 'post', method: 'post',
data, data,
}); });
@ -38,7 +38,7 @@ export const createAddress = (data) => {
*/ */
export const deleteAddress = (data) => { export const deleteAddress = (data) => {
return request.request({ return request.request({
url: '/api/v1/address/del', url: '/address/del',
method: 'post', method: 'post',
data, data,
}); });
@ -54,7 +54,7 @@ export const deleteAddress = (data) => {
*/ */
export const modifyAddress = (data) => { export const modifyAddress = (data) => {
return request.request({ return request.request({
url: '/api/v1/address/del', url: '/address/del',
method: 'post', method: 'post',
data, data,
}); });

View File

@ -12,7 +12,7 @@ import request from '@/utils/request';
*/ */
export const getCoinTypeList = (params) => { export const getCoinTypeList = (params) => {
return request.request({ return request.request({
url: '/api/v1/token/get', url: '/token/get',
method: 'get', method: 'get',
params, params,
}); });
@ -29,7 +29,7 @@ export const getCoinTypeList = (params) => {
*/ */
export const addCoinType = (data) => { export const addCoinType = (data) => {
return request.request({ return request.request({
url: '/api/v1/token/make', url: '/token/make',
method: 'post', method: 'post',
data, data,
}); });
@ -46,7 +46,7 @@ export const addCoinType = (data) => {
*/ */
export const modifyCoinType = (data) => { export const modifyCoinType = (data) => {
return request.request({ return request.request({
url: '/api/v1/token/chg', url: '/token/chg',
method: 'post', method: 'post',
data, data,
}); });

View File

@ -13,7 +13,7 @@ import request from '@/utils/request';
*/ */
export const getRecordList = (data) => { export const getRecordList = (data) => {
return request.request({ return request.request({
url: '/tgb/api/v1/recharge/record', url: '/recharge/record',
method: 'post', method: 'post',
data, data,
}); });

View File

@ -13,7 +13,7 @@ import request from '@/utils/request';
*/ */
export const getWithdrawList = (params) => { export const getWithdrawList = (params) => {
return request.request({ return request.request({
url: '/tgb/api/v1/withdrawal/get', url: '/withdrawal/get',
method: 'get', method: 'get',
params, params,
}); });
@ -27,7 +27,7 @@ export const getWithdrawList = (params) => {
*/ */
export const solveWithdraw = (params) => { export const solveWithdraw = (params) => {
return request.request({ return request.request({
url: '/tgb/api/v1/withdrawal/solve', url: '/withdrawal/solve',
method: 'get', method: 'get',
params, params,
}); });

View File

@ -7,12 +7,28 @@ import request from '@/utils/request';
*/ */
export const getAccountList = (params) => { export const getAccountList = (params) => {
return request.request({ return request.request({
url: '/tgb/api/v1/user/get', url: '/user/get',
method: 'get', method: 'get',
params, 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 * @param {object} data
@ -21,7 +37,7 @@ export const getAccountList = (params) => {
*/ */
export const deleteUser = (data) => { export const deleteUser = (data) => {
return request.request({ return request.request({
url: '/tgb/api/v1/user/get', url: '/user/get',
method: 'post', method: 'post',
data, data,
}); });

View File

@ -9,7 +9,7 @@ import request from '@/utils/request';
*/ */
export const getRoleList = (params) => { export const getRoleList = (params) => {
return request.request({ return request.request({
url: '/tgb/api/v1/user/role', url: '/user/role',
method: 'get', method: 'get',
params, params,
}); });
@ -23,7 +23,7 @@ export const getRoleList = (params) => {
*/ */
export const deleteRole = (data) => { export const deleteRole = (data) => {
return request.request({ return request.request({
url: '/tgb/api/v1/user/role/delete', url: '/user/role/delete',
method: 'post', method: 'post',
data, data,
}); });

View File

@ -9,7 +9,7 @@ import request from '@/utils/request';
*/ */
export const getUserList = (params) => { export const getUserList = (params) => {
return request.request({ return request.request({
url: '/tgb/api/v1/account/get', url: '/account/get',
method: 'get', method: 'get',
params, params,
}); });

View File

@ -2,7 +2,22 @@ import request from '@/utils/request';
export const login = (data) => { export const login = (data) => {
return request.request({ return request.request({
url: '/tbg/api/v1/admin/login', url: '/admin/login',
method: 'post',
data,
});
};
/**
*
* @param data
* password
* new_password
* @returns
*/
export const modifyPassword = (data) => {
return request.request({
url: '/admin/update',
method: 'post', method: 'post',
data, data,
}); });

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: '登录失效',