WIP: user-zzy-dev #1

Closed
Ghost wants to merge 12 commits from user-zzy-dev into master
26 changed files with 12674 additions and 11957 deletions
Showing only changes of commit 65c09c20e6 - Show all commits

View File

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

View File

@ -60,10 +60,11 @@
"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",
"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",
@ -72,8 +73,7 @@
"react-dom": "^17.0.0", "react-dom": "^17.0.0",
"react-helmet-async": "^1.0.4", "react-helmet-async": "^1.0.4",
"umi": "^3.5.0", "umi": "^3.5.0",
"umi-serve": "^1.9.10", "umi-serve": "^1.9.10"
"bignumber.js": "^9.0.0"
}, },
"devDependencies": { "devDependencies": {
"@ant-design/pro-cli": "^2.0.2", "@ant-design/pro-cli": "^2.0.2",

View File

@ -6,25 +6,30 @@ import {
createAddress, createAddress,
modifyAddress, modifyAddress,
} from '@/services/Recharge/address'; } from '@/services/Recharge/address';
import { fetchTableData } from '@/utils/table'; import { fetchTableData } from '@/utils/table';
import DeleteButton from '@/components/Table/DeleteButton'; import DeleteButton from '@/components/Table/DeleteButton';
import AddAddressModal from './components/addAddressModal'; import AddAddressModal from '../components/addAddressModal';
import EditAddressModal from './components/editAddressModal'; import EditAddressModal from '../components/editAddressModal';
const CollectionAddressList = () => { const CollectionAddressList = () => {
const tableRef = useRef<ActionType>();
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
const [isEditModalVisible, setIsEditModalVisible] = useState(false); const [isEditModalVisible, setIsEditModalVisible] = useState(false);
const [modalData, setModalData] = useState({}); const [modalData, setModalData] = useState({});
const handleEdit = (row: any) => { const handleEdit = (row: any) => {
row.new_address = '';
setModalData(row); setModalData(row);
setIsEditModalVisible(true); setIsEditModalVisible(true);
}; };
const handleDelete = async (address: any) => { const handleDelete = async (address: any) => {
await deleteAddress({ address: address }); await deleteAddress({ address: address });
tableRef.current?.reload();
}; };
const tableRef = useRef<ActionType>();
const columns: ProColumns<any>[] = [ const columns: ProColumns<any>[] = [
{ {
title: '收款地址', title: '收款地址',
@ -33,8 +38,8 @@ const CollectionAddressList = () => {
ellipsis: true, ellipsis: true,
}, },
{ {
title: '收款游戏币类型', title: '收款游戏币名称',
dataIndex: 'bc_type', dataIndex: 'bc_name',
hideInSearch: true, hideInSearch: true,
ellipsis: true, ellipsis: true,
}, },
@ -87,6 +92,7 @@ const CollectionAddressList = () => {
onOk={async function (val: any): Promise<void> { onOk={async function (val: any): Promise<void> {
await createAddress(val); await createAddress(val);
setIsModalVisible(false); setIsModalVisible(false);
tableRef.current?.reload();
}} }}
/> />
<EditAddressModal <EditAddressModal
@ -98,6 +104,7 @@ const CollectionAddressList = () => {
onOk={async function (val: any): Promise<void> { onOk={async function (val: any): Promise<void> {
await modifyAddress(val); await modifyAddress(val);
setIsEditModalVisible(false); setIsEditModalVisible(false);
tableRef.current?.reload();
}} }}
/> />
</div> </div>

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

@ -2,10 +2,12 @@ import React, { useState, useRef } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table'; import Table, { ProColumns, ActionType } from '@/components/Table';
import { addCoinType, getCoinTypeList, modifyCoinType } from '@/services/Recharge/coinType'; import { addCoinType, getCoinTypeList, modifyCoinType } from '@/services/Recharge/coinType';
import { fetchTableData } from '@/utils/table'; import { fetchTableData } from '@/utils/table';
import AddCoinTypeModal from './components/addCoinTypeModal'; import AddCoinTypeModal from '../components/addCoinTypeModal';
import EditCoinTypeModal from './components/editCoinTypeModal'; import EditCoinTypeModal from '../components/editCoinTypeModal';
const CoinTypeList = () => { const CoinTypeList = () => {
const tableRef = useRef<ActionType>();
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
const [isEditModalVisible, setIsEditModalVisible] = useState(false); const [isEditModalVisible, setIsEditModalVisible] = useState(false);
const [modalData, setModalData] = useState({}); const [modalData, setModalData] = useState({});
@ -13,9 +15,9 @@ const CoinTypeList = () => {
const handleEdit = (row: any) => { const handleEdit = (row: any) => {
setModalData(row); setModalData(row);
setIsEditModalVisible(true); setIsEditModalVisible(true);
tableRef.current?.reload();
}; };
const tableRef = useRef<ActionType>();
const columns: ProColumns<any>[] = [ const columns: ProColumns<any>[] = [
{ {
title: '游戏币名称', title: '游戏币名称',
@ -23,12 +25,6 @@ const CoinTypeList = () => {
hideInSearch: true, hideInSearch: true,
ellipsis: true, ellipsis: true,
}, },
{
title: '游戏币类型',
dataIndex: 'bc_type',
width: '10%',
hideInSearch: true,
},
{ {
title: 'usdt比例', title: 'usdt比例',
dataIndex: 'usdt_price', dataIndex: 'usdt_price',
@ -41,6 +37,12 @@ const CoinTypeList = () => {
hideInSearch: true, hideInSearch: true,
ellipsis: true, ellipsis: true,
}, },
{
title: '代币发行总量',
dataIndex: 'num',
hideInSearch: true,
ellipsis: true,
},
{ {
title: '操作', title: '操作',
valueType: 'option', valueType: 'option',
@ -84,6 +86,7 @@ const CoinTypeList = () => {
onOk={async function (val: any): Promise<void> { onOk={async function (val: any): Promise<void> {
await addCoinType(val); await addCoinType(val);
setIsModalVisible(false); setIsModalVisible(false);
tableRef.current?.reload();
}} }}
/> />
<EditCoinTypeModal <EditCoinTypeModal
@ -95,6 +98,7 @@ const CoinTypeList = () => {
onOk={async function (val: any): Promise<void> { onOk={async function (val: any): Promise<void> {
await modifyCoinType(val); await modifyCoinType(val);
setIsEditModalVisible(false); setIsEditModalVisible(false);
tableRef.current?.reload();
}} }}
/> />
</div> </div>

View File

@ -35,8 +35,9 @@ const AddCoinTypeModal = ({ onOk, onCancel, ...rest }: AddCoinTypeModalPropsType
<Form form={form} labelCol={4} wrapperCol={18}> <Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField> <SchemaField>
<SchemaField.String <SchemaField.String
name="name" name="bc_name"
title="代币名称" title="代币名称"
required
x-decorator="FormItem" x-decorator="FormItem"
x-component="Input" x-component="Input"
/> />
@ -50,12 +51,14 @@ const AddCoinTypeModal = ({ onOk, onCancel, ...rest }: AddCoinTypeModalPropsType
<SchemaField.String <SchemaField.String
name="eth_price" name="eth_price"
title="eth比例" title="eth比例"
required
x-decorator="FormItem" x-decorator="FormItem"
x-component="Input" x-component="Input"
/> />
<SchemaField.Number <SchemaField.Number
name="num" name="num"
title="数量" title="数量"
required
x-decorator="FormItem" x-decorator="FormItem"
x-component="NumberPicker" x-component="NumberPicker"
/> />

View File

@ -47,16 +47,10 @@ const EditCoinTypeModal = ({
<SchemaField.String <SchemaField.String
name="bc_name" name="bc_name"
title="游戏币名称" title="游戏币名称"
x-disabled
x-decorator="FormItem" x-decorator="FormItem"
x-component="Input" x-component="Input"
/> />
<SchemaField.String
name="bc_type"
title="游戏币类型"
required
x-decorator="FormItem"
x-component="Select"
/>
<SchemaField.String <SchemaField.String
name="usdt_price" name="usdt_price"
title="usdt比例" title="usdt比例"

View File

@ -4,6 +4,7 @@ import { getRecordList } from '@/services/Recharge/record';
import { fetchTableData } from '@/utils/table'; import { fetchTableData } from '@/utils/table';
import { getBalanceAmount } from '@/utils/formatBalance'; import { getBalanceAmount } from '@/utils/formatBalance';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import moment from 'moment';
const RecordList = () => { const RecordList = () => {
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
@ -41,7 +42,7 @@ const RecordList = () => {
}, },
{ {
title: '发送地址', title: '发送地址',
dataIndex: 'form_address', dataIndex: 'from_address',
hideInSearch: true, hideInSearch: true,
ellipsis: true, ellipsis: true,
}, },
@ -64,11 +65,15 @@ const RecordList = () => {
rowKey="id" rowKey="id"
actionRef={tableRef} actionRef={tableRef}
request={async (params) => { request={async (params) => {
console.log('params = ', params);
if ((params.time ?? '') !== '') { if ((params.time ?? '') !== '') {
params.start_time = params.time[0]; const start = Date.parse(params.time[0] + ' 00:00:00');
params.end_time = params.time[1]; 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); const res = await fetchTableData(getRecordList, params);
console.log('res = ', res);
for (const key in res.data) { for (const key in res.data) {
if (Object.prototype.hasOwnProperty.call(res.data, key)) { if (Object.prototype.hasOwnProperty.call(res.data, key)) {
const element = res.data[key]; const element = res.data[key];
@ -76,6 +81,7 @@ const RecordList = () => {
new BigNumber(element.price), new BigNumber(element.price),
element.decimals, element.decimals,
).toNumber(); ).toNumber();
element.time = moment(element.time * 1000).format('YYYY-MM-DD hh:mm:ss');
} }
} }
return res; return res;

View File

@ -5,12 +5,15 @@ import { fetchTableData } from '@/utils/table';
import { getBalanceAmount } from '@/utils/formatBalance'; import { getBalanceAmount } from '@/utils/formatBalance';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import ConfirmButton from '@/components/Table/ConfirmButton'; import ConfirmButton from '@/components/Table/ConfirmButton';
import moment from 'moment';
const WithdrawList = () => { const WithdrawList = () => {
const handleConfirm = async (uuid) => { const handleConfirm = async (uuid) => {
await solveWithdraw({ uuid: uuid }); await solveWithdraw({ uuid: uuid });
}; };
const handlePass = async (row) => {};
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
const columns: ProColumns<any>[] = [ const columns: ProColumns<any>[] = [
{ {
@ -25,19 +28,7 @@ const WithdrawList = () => {
hideInSearch: true, hideInSearch: true,
}, },
{ {
title: '位数', title: '接收地址',
dataIndex: 'decimals',
width: '10%',
hideInSearch: true,
},
{
title: '发送地址',
dataIndex: 'form_address',
hideInSearch: true,
ellipsis: true,
},
{
title: '接受地址',
dataIndex: 'to_address', dataIndex: 'to_address',
hideInSearch: true, hideInSearch: true,
ellipsis: true, ellipsis: true,
@ -47,6 +38,11 @@ const WithdrawList = () => {
dataIndex: 'bc_type', dataIndex: 'bc_type',
width: '10%', width: '10%',
}, },
{
title: '类型',
dataIndex: 'type',
width: '10%',
},
{ {
title: '时间', title: '时间',
dataIndex: 'time', dataIndex: 'time',
@ -66,6 +62,14 @@ const WithdrawList = () => {
handleConfirm(row.uuid); handleConfirm(row.uuid);
}} }}
/>, />,
<a
key="pass"
onClick={() => {
handlePass(row);
}}
>
</a>,
], ],
}, },
]; ];
@ -76,7 +80,6 @@ const WithdrawList = () => {
rowKey="id" rowKey="id"
actionRef={tableRef} actionRef={tableRef}
request={async (params) => { request={async (params) => {
console.log('params = ', params);
const res = await fetchTableData(getWithdrawList, params); const res = await fetchTableData(getWithdrawList, params);
for (const key in res.data) { for (const key in res.data) {
if (Object.prototype.hasOwnProperty.call(res.data, key)) { if (Object.prototype.hasOwnProperty.call(res.data, key)) {
@ -85,6 +88,7 @@ const WithdrawList = () => {
new BigNumber(element.price), new BigNumber(element.price),
element.decimals, element.decimals,
).toNumber(); ).toNumber();
element.time = moment(element.time * 1000).format('YYYY-MM-DD hh:mm:ss');
} }
} }
return res; return res;

View File

@ -1,10 +1,16 @@
import React, { useState, useRef } from 'react'; import React, { useState, useRef } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table'; import Table, { ProColumns, ActionType } from '@/components/Table';
import { getAccountList, deleteUser } from '@/services/System/accountManage'; import {
getAccountList,
deleteUser,
updateUser,
changeUserStatus,
} 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'; import AddAccountModal from '../components/addAccountModal';
import EditAccountModal from '../components/editAccountModal';
const AccountManageList = () => { const AccountManageList = () => {
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
@ -14,13 +20,11 @@ const AccountManageList = () => {
const handleEdit = (row: any) => { const handleEdit = (row: any) => {
setModalData(row); setModalData(row);
setIsEditModal(true); setIsEditModal(true);
setIsModalVisible(true);
}; };
const handleDelete = async (name: any) => { const handleDelete = async (name: any) => {
await deleteUser({ name: name }); await deleteUser({ name: name });
}; };
const onChange = (checked: boolean) => {};
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
const columns: ProColumns<any>[] = [ const columns: ProColumns<any>[] = [
{ {
@ -35,12 +39,6 @@ const AccountManageList = () => {
hideInSearch: true, hideInSearch: true,
ellipsis: true, ellipsis: true,
}, },
{
title: '用户状态',
dataIndex: 'status',
hideInSearch: true,
ellipsis: true,
},
{ {
title: '操作', title: '操作',
valueType: 'option', valueType: 'option',
@ -54,11 +52,19 @@ const AccountManageList = () => {
> >
</a>, </a>,
<Switch key="switch" defaultChecked={row.status} size="small" onChange={onChange} />, <Switch
key="switch"
defaultChecked={row.status}
size="small"
onChange={async (checked) => {
await changeUserStatus({ name: row.name, status: checked });
}}
/>,
<DeleteButton <DeleteButton
key="delete" key="delete"
onDelete={() => { onDelete={() => {
handleDelete(row.name); handleDelete(row.name);
tableRef.current?.reload();
}} }}
/>, />,
], ],
@ -85,13 +91,23 @@ const AccountManageList = () => {
/> />
<AddAccountModal <AddAccountModal
visible={isModalVisible} visible={isModalVisible}
isEdit={isEditModal}
editModalData={modalData}
onCancel={function () { onCancel={function () {
setIsModalVisible(false); setIsModalVisible(false);
}} }}
onOk={async function (): Promise<void> { onOk={async function (): Promise<void> {
setIsModalVisible(false); 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> </div>

View File

@ -1,14 +1,12 @@
// 创建弹窗 // 创建弹窗
import React, { useRef, useEffect } 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';
import Modal, { ModalProps } from '@/components/Modal'; import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, Select } from '@formily/antd'; import { Form, FormItem, Input, Select } from '@formily/antd';
import { addUser } from '@/services/System/accountManage'; import { addUser } from '@/services/System/accountManage';
interface AddUserModalPropsType extends ModalProps { interface AddAccountModalPropsType extends ModalProps {
isEdit: boolean;
editModalData: any;
onCancel: () => void; onCancel: () => void;
onOk: () => void; onOk: () => void;
} }
@ -23,15 +21,14 @@ const SchemaField = createSchemaField({
const form = createForm({}); const form = createForm({});
const AddUserModal = ({ onOk, onCancel, editModalData, ...rest }: AddUserModalPropsType) => { const AddAccountModal = ({ onOk, onCancel, ...rest }: AddAccountModalPropsType) => {
useEffect(() => {
form.setInitialValues(editModalData);
});
const handleOk = async () => { const handleOk = async () => {
form.submit(async () => {
onOk(); onOk();
const formState = form.getFormState(); const formState = form.getFormState();
formState.values.role = parseInt(formState.values.role);
await addUser(formState.values); await addUser(formState.values);
});
}; };
const handleCancel = () => { const handleCancel = () => {
@ -56,6 +53,9 @@ const AddUserModal = ({ onOk, onCancel, editModalData, ...rest }: AddUserModalPr
name="password" name="password"
title="密码" title="密码"
required required
x-validator={{
required: true,
}}
x-decorator="FormItem" x-decorator="FormItem"
x-component="Input" x-component="Input"
x-component-props={{ x-component-props={{
@ -66,8 +66,11 @@ const AddUserModal = ({ onOk, onCancel, editModalData, ...rest }: AddUserModalPr
name="role" name="role"
title="角色" title="角色"
required required
x-validator={{
required: true,
}}
x-decorator="FormItem" x-decorator="FormItem"
x-component="Select" x-component="Input"
x-component-props={{ x-component-props={{
placeholder: '请选择角色', placeholder: '请选择角色',
}} }}
@ -78,4 +81,4 @@ const AddUserModal = ({ onOk, onCancel, editModalData, ...rest }: AddUserModalPr
); );
}; };
export default AddUserModal; 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,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

@ -1,11 +1,11 @@
// 创建弹窗 // 添加代币类型弹窗
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';
import Modal, { ModalProps } from '@/components/Modal'; import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, Select } from '@formily/antd'; import { Form, FormItem, Input, Select } from '@formily/antd';
interface AddAddressModalPropsType extends ModalProps { interface AddNoticeModalPropsType extends ModalProps {
onOk: (val: any) => void; onOk: (val: any) => void;
onCancel: () => void; onCancel: () => void;
} }
@ -20,9 +20,10 @@ const SchemaField = createSchemaField({
const form = createForm({}); const form = createForm({});
const AddAddressModal = ({ onOk, onCancel, ...rest }: AddAddressModalPropsType) => { const AddNoticeModal = ({ onOk, onCancel, ...rest }: AddNoticeModalPropsType) => {
const handleOk = () => { const handleOk = () => {
const formState = form.getFormState(); const formState = form.getFormState();
formState.values.code = parseInt(formState.values.code);
onOk(formState.values); onOk(formState.values);
}; };
@ -31,27 +32,33 @@ const AddAddressModal = ({ onOk, onCancel, ...rest }: AddAddressModalPropsType)
}; };
return ( return (
<Modal title="创建收款地址" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}> <Modal title="添加通知" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}> <Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField> <SchemaField>
<SchemaField.String <SchemaField.String
name="bc_type" name="code"
title="游戏币类型" 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 required
x-decorator="FormItem" x-decorator="FormItem"
x-component="Select" x-component="Select"
x-component-props={{ enum={[
placeholder: '', { label: '启用', value: true },
}} { label: '禁用', value: false },
/> ]}
<SchemaField.String
name="address"
title="收款地址"
x-decorator="FormItem"
x-component="Input"
x-component-props={{
placeholder: '不传则后台生成',
}}
/> />
</SchemaField> </SchemaField>
</Form> </Form>
@ -59,4 +66,4 @@ const AddAddressModal = ({ onOk, onCancel, ...rest }: AddAddressModalPropsType)
); );
}; };
export default AddAddressModal; export default AddNoticeModal;

View File

@ -5,7 +5,7 @@ import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal'; import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, Select } from '@formily/antd'; import { Form, FormItem, Input, Select } from '@formily/antd';
interface EditAddressModalPropsType extends ModalProps { interface EditNoticeModalPropsType extends ModalProps {
editModalData: any; editModalData: any;
onOk: (val: any) => void; onOk: (val: any) => void;
onCancel: () => void; onCancel: () => void;
@ -21,12 +21,7 @@ const SchemaField = createSchemaField({
const form = createForm({}); const form = createForm({});
const EditAddressModal = ({ const EditNoticeModal = ({ onOk, onCancel, editModalData, ...rest }: EditNoticeModalPropsType) => {
onOk,
onCancel,
editModalData,
...rest
}: EditAddressModalPropsType) => {
useEffect(() => { useEffect(() => {
form.setInitialValues(editModalData); form.setInitialValues(editModalData);
}); });
@ -41,26 +36,22 @@ const EditAddressModal = ({
}; };
return ( return (
<Modal title="修改收款地址" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}> <Modal title="修改通知" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}> <Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField> <SchemaField>
<SchemaField.String <SchemaField.String
name="address" name="code"
title="旧收款地址" title="通知码"
x-disabled
required
x-decorator="FormItem" x-decorator="FormItem"
x-component="Input" x-component="Input"
/> />
<SchemaField.String <SchemaField.String
name="bc_type" name="addr"
title="游戏币类型" title="通知地址"
required required
x-decorator="FormItem" x-decorator="FormItem"
x-component="Select"
/>
<SchemaField.String
name="new_address"
title="新收款地址"
x-decorator="FormItem"
x-component="Input" x-component="Input"
/> />
</SchemaField> </SchemaField>
@ -69,4 +60,4 @@ const EditAddressModal = ({
); );
}; };
export default EditAddressModal; export default EditNoticeModal;

View File

@ -9,7 +9,8 @@ const SecretKey: React.FC = () => {
const [secretKey, setSecretKey] = useState(''); const [secretKey, setSecretKey] = useState('');
const create = async () => { const create = async () => {
await createSecretKey({}); const data = await createSecretKey({});
setSecretKey(data + '');
}; };
const getUserSecretKey = async () => { const getUserSecretKey = async () => {

View File

@ -65,6 +65,11 @@ export default [
path: RoutePath.PERMISSIONS.LIST, path: RoutePath.PERMISSIONS.LIST,
component: './System/Permissions/List', component: './System/Permissions/List',
}, },
{
name: '通知管理',
path: RoutePath.NOTICE.LIST,
component: './System/Notice/List',
},
{ {
name: '密钥管理', name: '密钥管理',
path: RoutePath.SECRET_KEY, path: RoutePath.SECRET_KEY,
@ -72,31 +77,31 @@ export default [
}, },
], ],
}, },
{ // {
name: '设置', // name: '设置',
path: RoutePath.SETTING, // path: RoutePath.SETTING,
routes: [ // routes: [
{ // {
path: RoutePath.SETTING, // path: RoutePath.SETTING,
redirect: RoutePath.WORK.LIST, // redirect: RoutePath.WORK.LIST,
hideInMenu: true, // hideInMenu: true,
}, // },
{ // {
name: '作品', // name: '作品',
path: RoutePath.WORK.LIST, // path: RoutePath.WORK.LIST,
component: './Work/List', // component: './Work/List',
}, // },
{ // {
name: '作品详情', // name: '作品详情',
path: RoutePath.WORK.EDIT, // path: RoutePath.WORK.EDIT,
hideInMenu: true, // hideInMenu: true,
component: './Work/Edit', // component: './Work/Edit',
}, // },
], // ],
}, // },
{ {
path: '/', path: '/',
redirect: RoutePath.WORK.LIST, redirect: RoutePath.RECORD.LIST,
}, },
{ {

View File

@ -26,12 +26,15 @@ const RoutePath = {
PERMISSIONS: { PERMISSIONS: {
LIST: `${SYSTEM}/permissions`, LIST: `${SYSTEM}/permissions`,
}, },
SECRET_KEY: `${SYSTEM}/secret_key`, NOTICE: {
SETTING: SETTING, LIST: `${SYSTEM}/notice`,
WORK: {
LIST: `${SETTING}/work`,
EDIT: `${SETTING}/work/edit`,
}, },
SECRET_KEY: `${SYSTEM}/secret_key`,
// SETTING: SETTING,
// WORK: {
// LIST: `${SETTING}/work`,
// EDIT: `${SETTING}/work/edit`,
// },
}; };
export default RoutePath; export default RoutePath;

View File

@ -24,7 +24,7 @@ export const getAddressList = (params) => {
*/ */
export const createAddress = (data) => { export const createAddress = (data) => {
return request.request({ return request.request({
url: '/address/make', url: '/address/create',
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: '/address/del', url: '/address/delete',
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: '/address/del', url: '/address/update',
method: 'post', method: 'post',
data, data,
}); });

View File

@ -29,7 +29,7 @@ export const getCoinTypeList = (params) => {
*/ */
export const addCoinType = (data) => { export const addCoinType = (data) => {
return request.request({ return request.request({
url: '/token/make', url: '/token/create',
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: '/token/chg', url: '/token/update',
method: 'post', method: 'post',
data, data,
}); });

View File

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

View File

@ -29,6 +29,37 @@ export const addUser = (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 * @param {object} data
@ -37,7 +68,7 @@ export const addUser = (data) => {
*/ */
export const deleteUser = (data) => { export const deleteUser = (data) => {
return request.request({ return request.request({
url: '/user/get', url: '/user/delete',
method: 'post', method: 'post',
data, 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

@ -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]];

23793
yarn.lock

File diff suppressed because it is too large Load Diff