diff --git a/config/proxy.ts b/config/proxy.ts index 4f407c4..6244356 100644 --- a/config/proxy.ts +++ b/config/proxy.ts @@ -9,9 +9,9 @@ export default { dev: { // localhost:8000/api/** -> https://preview.pro.ant.design/api/** - '/admin/': { + '/tbg/api/v1': { // 要代理的地址 - target: '', + target: 'http://192.168.88.224:9999', // 配置了这个可以从 http 代理到 https // 依赖 origin 的功能可能需要这个,比如 cookie changeOrigin: true, diff --git a/package.json b/package.json index aed6a00..14d9265 100644 --- a/package.json +++ b/package.json @@ -61,12 +61,13 @@ "ahooks": "^2.10.14", "antd": "^4.17.2", "axios": "^0.24.0", + "bignumber.js": "^9.0.0", "braft-editor": "^2.3.9", "classnames": "^2.2.6", "echarts": "^5.3.3", "echarts-for-react": "^3.0.2", "lodash": "^4.17.11", - "moment": "^2.25.3", + "moment": "^2.29.4", "omit.js": "^2.0.2", "rc-menu": "^9.0.13", "rc-util": "^5.14.0", diff --git a/src/components/ModifyPassword/ModifyPasswordModal.tsx b/src/components/ModifyPassword/ModifyPasswordModal.tsx new file mode 100644 index 0000000..a373f38 --- /dev/null +++ b/src/components/ModifyPassword/ModifyPasswordModal.tsx @@ -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 ( + +
+ + + + +
+
+ ); +}; + +export default ModifyPasswordModal; diff --git a/src/components/RightContent/AvatarDropdown.tsx b/src/components/RightContent/AvatarDropdown.tsx index 150cbce..b7a6994 100644 --- a/src/components/RightContent/AvatarDropdown.tsx +++ b/src/components/RightContent/AvatarDropdown.tsx @@ -1,5 +1,5 @@ -import React, { useCallback } from 'react'; -import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons'; +import React, { useState, useCallback } from 'react'; +import { LogoutOutlined, SettingOutlined, UserOutlined, EditOutlined } from '@ant-design/icons'; import { Avatar, Menu, Spin } from 'antd'; import { history } from 'umi'; import { stringify } from 'querystring'; @@ -8,6 +8,7 @@ import styles from './index.less'; import type { MenuInfo } from 'rc-menu/lib/interface'; import RoutePath from '@/routes/routePath'; import { CACHE_TOKEN } from '@/constants/cacheKey'; +import ModifyPasswordModal from '@/components/ModifyPassword/ModifyPasswordModal'; export type GlobalHeaderRightProps = { menu?: boolean; @@ -32,8 +33,18 @@ const loginOut = async () => { }; const AvatarDropdown: React.FC = ({ menu }) => { + const [isModalVisible, setIsModalVisible] = useState(false); + + const modifyPassword = async () => { + setIsModalVisible(true); + }; + const onMenuClick = useCallback((event: MenuInfo) => { const { key } = event; + if (key === 'modify') { + modifyPassword(); + return; + } if (key === 'logout') { loginOut(); return; @@ -77,7 +88,10 @@ const AvatarDropdown: React.FC = ({ menu }) => { )} {menu && } - + + + 修改密码 + 退出登录 @@ -85,12 +99,24 @@ const AvatarDropdown: React.FC = ({ menu }) => { ); return ( - - - - {currentUser.name} - - +
+ + + + {currentUser.name} + + + +
); }; diff --git a/src/components/Table/ConfirmButton/index.less b/src/components/Table/ConfirmButton/index.less new file mode 100644 index 0000000..61897f7 --- /dev/null +++ b/src/components/Table/ConfirmButton/index.less @@ -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; + } +} diff --git a/src/components/Table/ConfirmButton/index.tsx b/src/components/Table/ConfirmButton/index.tsx new file mode 100644 index 0000000..f1b19ec --- /dev/null +++ b/src/components/Table/ConfirmButton/index.tsx @@ -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 = ({ + onConfirm, + disabled = false, + title = '', + buttonName = '', +}) => { + return ( + + {buttonName} + + ); +}; +export default ConfirmButton; diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx index 1873c46..d4f2fda 100644 --- a/src/components/Table/index.tsx +++ b/src/components/Table/index.tsx @@ -172,7 +172,7 @@ const Table = >(props: PropsType) => { }} > - {item.text || '新建'} + {item.text || '添加'} , ); } else if (item.type === 'batchDelete') { diff --git a/src/pages/Login/index.tsx b/src/pages/Login/index.tsx index a06865a..f876e6e 100644 --- a/src/pages/Login/index.tsx +++ b/src/pages/Login/index.tsx @@ -35,7 +35,7 @@ const Login: React.FC = () => { }} > , diff --git a/src/pages/Recharge/Address/Components/AddAddressModal.tsx b/src/pages/Recharge/Address/Components/AddAddressModal.tsx new file mode 100644 index 0000000..dbd4a9d --- /dev/null +++ b/src/pages/Recharge/Address/Components/AddAddressModal.tsx @@ -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 ( + + + + + + + + {/*
*/} + + {/*
*/} +
+ ); +}; + +export default AddAddressModal; diff --git a/src/pages/Recharge/Address/Components/EditAddressModal.tsx b/src/pages/Recharge/Address/Components/EditAddressModal.tsx new file mode 100644 index 0000000..ca55c75 --- /dev/null +++ b/src/pages/Recharge/Address/Components/EditAddressModal.tsx @@ -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 ( + +
+ + + + + +
+
+ ); +}; + +export default EditAddressModal; diff --git a/src/pages/Recharge/Address/List/index.tsx b/src/pages/Recharge/Address/List/index.tsx new file mode 100644 index 0000000..33ff914 --- /dev/null +++ b/src/pages/Recharge/Address/List/index.tsx @@ -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(); + + 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[] = [ + { + title: '收款地址', + dataIndex: 'address', + hideInSearch: true, + ellipsis: true, + }, + { + title: '收款游戏币名称', + dataIndex: 'bc_name', + hideInSearch: true, + ellipsis: true, + }, + { + title: '操作', + valueType: 'option', + width: 150, + render: (_, row) => [ + { + handleEdit(row); + }} + > + 编辑 + , + { + handleDelete(row.address); + }} + />, + ], + }, + ]; + return ( +
+ { + setIsModalVisible(true); + }, + }, + ]} + actionRef={tableRef} + request={async (params) => { + const res = await fetchTableData(getAddressList, params); + return res; + }} + /> + { + await createAddress(val); + setIsModalVisible(false); + tableRef.current?.reload(); + }} + /> + { + await modifyAddress(val); + setIsEditModalVisible(false); + tableRef.current?.reload(); + }} + /> + + ); +}; + +export default CollectionAddressList; diff --git a/src/pages/Recharge/CoinType/Components/AddCoinTypeModal.tsx b/src/pages/Recharge/CoinType/Components/AddCoinTypeModal.tsx new file mode 100644 index 0000000..798c15a --- /dev/null +++ b/src/pages/Recharge/CoinType/Components/AddCoinTypeModal.tsx @@ -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 ( + +
+ + + + + + + +
+ ); +}; + +export default AddCoinTypeModal; diff --git a/src/pages/Recharge/CoinType/Components/EditCoinTypeModal.tsx b/src/pages/Recharge/CoinType/Components/EditCoinTypeModal.tsx new file mode 100644 index 0000000..e61e366 --- /dev/null +++ b/src/pages/Recharge/CoinType/Components/EditCoinTypeModal.tsx @@ -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 ( + +
+ + + + + + +
+ ); +}; + +export default EditCoinTypeModal; diff --git a/src/pages/Recharge/CoinType/List/index.tsx b/src/pages/Recharge/CoinType/List/index.tsx new file mode 100644 index 0000000..aa661b1 --- /dev/null +++ b/src/pages/Recharge/CoinType/List/index.tsx @@ -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(); + + 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[] = [ + { + 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) => [ + { + handleEdit(row); + }} + > + 编辑 + , + ], + }, + ]; + return ( +
+
{ + setIsModalVisible(true); + }, + }, + ]} + actionRef={tableRef} + request={async (params) => { + const res = await fetchTableData(getCoinTypeList, params); + return res; + }} + /> + { + await addCoinType(val); + setIsModalVisible(false); + tableRef.current?.reload(); + }} + /> + { + await modifyCoinType(val); + setIsEditModalVisible(false); + tableRef.current?.reload(); + }} + /> + + ); +}; + +export default CoinTypeList; diff --git a/src/pages/Recharge/Record/List/index.tsx b/src/pages/Recharge/Record/List/index.tsx new file mode 100644 index 0000000..2688bac --- /dev/null +++ b/src/pages/Recharge/Record/List/index.tsx @@ -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(); + const columns: ProColumns[] = [ + { + 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 ( +
{ + 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; diff --git a/src/pages/Recharge/Withdraw/List/index.tsx b/src/pages/Recharge/Withdraw/List/index.tsx new file mode 100644 index 0000000..44d233d --- /dev/null +++ b/src/pages/Recharge/Withdraw/List/index.tsx @@ -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(); + const columns: ProColumns[] = [ + { + 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) => [ + { + handleConfirm(row.uuid); + }} + />, + { + handlePass(row); + }} + > + 通过 + , + ], + }, + ]; + return ( +
+
{ + 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; + }} + /> + + ); +}; + +export default WithdrawList; diff --git a/src/pages/System/Account/Components/AddAccountModal.tsx b/src/pages/System/Account/Components/AddAccountModal.tsx new file mode 100644 index 0000000..9b07a1e --- /dev/null +++ b/src/pages/System/Account/Components/AddAccountModal.tsx @@ -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 ( + +
+ + + + + + +
+ ); +}; + +export default AddAccountModal; diff --git a/src/pages/System/Account/Components/EditAccountModal.tsx b/src/pages/System/Account/Components/EditAccountModal.tsx new file mode 100644 index 0000000..44f66ba --- /dev/null +++ b/src/pages/System/Account/Components/EditAccountModal.tsx @@ -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 ( + +
+ + + + + + +
+ ); +}; + +export default AddUserModal; diff --git a/src/pages/System/Account/List/index.tsx b/src/pages/System/Account/List/index.tsx new file mode 100644 index 0000000..537d19d --- /dev/null +++ b/src/pages/System/Account/List/index.tsx @@ -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(); + const columns: ProColumns[] = [ + { + title: '账号', + dataIndex: 'name', + hideInSearch: true, + ellipsis: true, + }, + { + title: '角色', + dataIndex: 'role', + hideInSearch: true, + ellipsis: true, + }, + { + title: '操作', + valueType: 'option', + width: 180, + render: (_, row) => [ + { + handleEdit(row); + }} + > + 编辑 + , + { + await changeUserStatus({ name: row.name, status: checked }); + }} + />, + { + handleDelete(row.name); + tableRef.current?.reload(); + }} + />, + ], + }, + ]; + return ( +
+
{ + setIsModalVisible(true); + }, + }, + ]} + actionRef={tableRef} + request={async (params) => { + const res = await fetchTableData(getAccountList, params); + return res; + }} + /> + { + setIsModalVisible(false); + tableRef.current?.reload(); + }} + /> + { + setIsEditModal(false); + tableRef.current?.reload(); + }} + /> + + ); +}; + +export default AccountManageList; diff --git a/src/pages/System/Notice/Components/AddNoticeModal.tsx b/src/pages/System/Notice/Components/AddNoticeModal.tsx new file mode 100644 index 0000000..da5cb75 --- /dev/null +++ b/src/pages/System/Notice/Components/AddNoticeModal.tsx @@ -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 ( + +
+ + + + + + +
+ ); +}; + +export default AddNoticeModal; diff --git a/src/pages/System/Notice/Components/EditNoticeModal.tsx b/src/pages/System/Notice/Components/EditNoticeModal.tsx new file mode 100644 index 0000000..7713f06 --- /dev/null +++ b/src/pages/System/Notice/Components/EditNoticeModal.tsx @@ -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 ( + +
+ + + + + +
+ ); +}; + +export default EditNoticeModal; diff --git a/src/pages/System/Notice/List/index.tsx b/src/pages/System/Notice/List/index.tsx new file mode 100644 index 0000000..593fec3 --- /dev/null +++ b/src/pages/System/Notice/List/index.tsx @@ -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(); + + 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[] = [ + { + title: '通知码', + dataIndex: 'code', + hideInSearch: true, + ellipsis: true, + }, + { + title: '通知地址', + dataIndex: 'addr', + hideInSearch: true, + ellipsis: true, + }, + { + title: '操作', + valueType: 'option', + width: 180, + render: (_, row) => [ + { + handleEdit(row); + }} + > + 编辑 + , + { + row.status = checked; + await updateNotice(row); + }} + />, + { + handleDelete(row.code); + }} + />, + ], + }, + ]; + return ( +
+
{ + setIsModalVisible(true); + }, + }, + ]} + actionRef={tableRef} + request={async (params) => { + const res = await fetchTableData(getNoticeList, params); + return res; + }} + /> + { + await createNotice(val); + setIsModalVisible(false); + tableRef.current?.reload(); + }} + /> + { + await updateNotice(val); + setIsEditModalVisible(false); + tableRef.current?.reload(); + }} + /> + + ); +}; + +export default NoticeList; diff --git a/src/pages/System/Permissions/List/index.tsx b/src/pages/System/Permissions/List/index.tsx new file mode 100644 index 0000000..0e90276 --- /dev/null +++ b/src/pages/System/Permissions/List/index.tsx @@ -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(); + const columns: ProColumns[] = [ + { + title: '收款地址', + dataIndex: 'address', + hideInSearch: true, + ellipsis: true, + }, + { + title: '收款游戏币类型', + dataIndex: 'bc_type', + hideInSearch: true, + ellipsis: true, + }, + { + title: '操作', + valueType: 'option', + width: 150, + render: (_, row) => [ + { + handleEdit(row); + }} + > + 编辑 + , + { + handleDelete(row.name); + }} + />, + ], + }, + ]; + return ( +
+
{}, + }, + ]} + actionRef={tableRef} + request={async (params) => { + return {}; + }} + /> + + ); +}; + +export default PermissionsList; diff --git a/src/pages/System/Role/List/index.tsx b/src/pages/System/Role/List/index.tsx new file mode 100644 index 0000000..c9c4d14 --- /dev/null +++ b/src/pages/System/Role/List/index.tsx @@ -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(); + const columns: ProColumns[] = [ + { + title: '角色名称', + dataIndex: 'role_name', + hideInSearch: true, + ellipsis: true, + }, + { + title: '用户类型', + dataIndex: 'role', + hideInSearch: true, + ellipsis: true, + }, + { + title: '操作', + valueType: 'option', + width: 180, + render: (_, row) => [ + { + handleEdit(row); + }} + > + 编辑 + , + { + handleAuth(row); + }} + > + 授权 + , + { + handleDelete(row.role); + }} + />, + ], + }, + ]; + return ( +
+
{}, + }, + ]} + actionRef={tableRef} + request={async (params) => { + const res = await fetchTableData(getRoleList, params); + return res; + }} + /> + + ); +}; + +export default RoleList; diff --git a/src/pages/System/SecretKey/index.less b/src/pages/System/SecretKey/index.less new file mode 100644 index 0000000..1565eba --- /dev/null +++ b/src/pages/System/SecretKey/index.less @@ -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; +} diff --git a/src/pages/System/SecretKey/index.tsx b/src/pages/System/SecretKey/index.tsx new file mode 100644 index 0000000..95edc1f --- /dev/null +++ b/src/pages/System/SecretKey/index.tsx @@ -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 ( +
+ +