Merge branch 'dev' into user-zzy-dev
This commit is contained in:
commit
a5040d8541
|
|
@ -56,6 +56,7 @@
|
||||||
"@formily/antd": "^2.0.7",
|
"@formily/antd": "^2.0.7",
|
||||||
"@formily/core": "^2.0.7",
|
"@formily/core": "^2.0.7",
|
||||||
"@formily/react": "^2.0.7",
|
"@formily/react": "^2.0.7",
|
||||||
|
"@metamask/detect-provider": "^1.2.0",
|
||||||
"@umijs/route-utils": "^2.0.3",
|
"@umijs/route-utils": "^2.0.3",
|
||||||
"ahooks": "^2.10.14",
|
"ahooks": "^2.10.14",
|
||||||
"antd": "^4.17.2",
|
"antd": "^4.17.2",
|
||||||
|
|
@ -63,6 +64,8 @@
|
||||||
"bignumber.js": "^9.0.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-for-react": "^3.0.2",
|
||||||
"lodash": "^4.17.11",
|
"lodash": "^4.17.11",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"omit.js": "^2.0.2",
|
"omit.js": "^2.0.2",
|
||||||
|
|
@ -73,7 +76,8 @@
|
||||||
"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",
|
||||||
|
"web3": "^1.7.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ant-design/pro-cli": "^2.0.2",
|
"@ant-design/pro-cli": "^2.0.2",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
export enum TimeType {
|
||||||
|
DAY = 'day',
|
||||||
|
WEEK = 'week',
|
||||||
|
MONTH = 'month',
|
||||||
|
}
|
||||||
|
export default TimeType;
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
import echarts from 'echarts/lib/echarts';
|
||||||
|
import {
|
||||||
|
getActiveData,
|
||||||
|
getMonthUserData,
|
||||||
|
getOldUserData,
|
||||||
|
getTodayUserData,
|
||||||
|
getWeekUserData,
|
||||||
|
} from '@/services/dataBorad/activeAnalysis';
|
||||||
|
import MoreData from '@/widget/MoreData';
|
||||||
|
import ReactEcharts from 'echarts-for-react';
|
||||||
|
import { Card, Col, Row, Select } from 'antd';
|
||||||
|
const ActiveAnalysis: React.FC = () => {
|
||||||
|
const { Option } = Select;
|
||||||
|
const [timeType, setTimeType] = useState('day');
|
||||||
|
const getData = async (func) => {
|
||||||
|
const res = await func({});
|
||||||
|
return res.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const [data, setData] = useState(getData(getTodayUserData));
|
||||||
|
const [oldUserData, setOldUserData] = useState(getData(getOldUserData));
|
||||||
|
const [weekData, setWeekData] = useState(getData(getWeekUserData));
|
||||||
|
const [monthData, setMonthData] = useState(getData(getMonthUserData));
|
||||||
|
|
||||||
|
const getOption = async (item = 'day') => {
|
||||||
|
const res = await getActiveData({ time_type: item });
|
||||||
|
const xData: any = [];
|
||||||
|
const seriesData: any = [];
|
||||||
|
res.data.foreach((item: any) => {
|
||||||
|
xData.push(item.time);
|
||||||
|
seriesData.push(item.dwn);
|
||||||
|
});
|
||||||
|
const option = {
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
||||||
|
// data: xData,
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
data: [150, 230, 224, 218, 135, 147, 360],
|
||||||
|
// data: seriesData.reverse(),
|
||||||
|
type: 'line',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
};
|
||||||
|
const [option, setOption] = useState(getOption);
|
||||||
|
const setTimeOption = (val: any) => {
|
||||||
|
setTimeType(val);
|
||||||
|
setOption(getOption(val));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Row gutter={24} justify="space-between" style={{ marginBottom: 10 }}>
|
||||||
|
<Col span={6}>
|
||||||
|
<Card style={{ height: '200px' }}>{MoreData(data, '今日活跃用户数')}</Card>
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<Card style={{ height: '200px' }}>{MoreData(oldUserData, '今日登录老用户数')}</Card>
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<Card style={{ height: '200px' }}>{MoreData(weekData, 'WAU(本周去重人数)')}</Card>
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<Card style={{ height: '200px' }}>{MoreData(monthData, 'MAU(本月去重人数)')}</Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Card style={{ width: '100%' }}>
|
||||||
|
<Row gutter={32} style={{ marginBottom: 10 }}>
|
||||||
|
<Col span={6}>
|
||||||
|
<h1>登陆人数数据图</h1>
|
||||||
|
<Select
|
||||||
|
defaultValue="lucy"
|
||||||
|
value={timeType}
|
||||||
|
style={{ width: 100 }}
|
||||||
|
bordered={false}
|
||||||
|
onChange={(val) => {
|
||||||
|
setTimeOption(val);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Option value="day">每日</Option>
|
||||||
|
<Option value="week">每周</Option>
|
||||||
|
<Option value="month">每月</Option>
|
||||||
|
</Select>
|
||||||
|
</Col>
|
||||||
|
<Col span={18}>
|
||||||
|
<ReactEcharts option={option} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ActiveAnalysis;
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
import Table, { ProColumns, ActionType } from '@/components/Table';
|
||||||
|
import moment from 'moment';
|
||||||
|
import TimeType from '@/constants/enum/timeType';
|
||||||
|
import { getData } from '@/utils/getData';
|
||||||
|
import MoreData from '@/widget/MoreData';
|
||||||
|
import {
|
||||||
|
getCoreData,
|
||||||
|
getPayData,
|
||||||
|
getTodayUserData,
|
||||||
|
getMonthPayData,
|
||||||
|
getNewUserData,
|
||||||
|
} from '@/services/dataBorad/coreData';
|
||||||
|
import { Card, Col, Row, Select } from 'antd';
|
||||||
|
const CoreData: React.FC = () => {
|
||||||
|
const tableRef = useRef<ActionType>();
|
||||||
|
const [timeType, setTimeType] = useState(TimeType.DAY);
|
||||||
|
|
||||||
|
// const [date, setDate] = useState(getData);
|
||||||
|
const [userDate, setUserDate] = useState(getData(getTodayUserData));
|
||||||
|
const [newUserdate, setNewUserDate] = useState(getData(getNewUserData));
|
||||||
|
const [payData, setPayDate] = useState(getData(getMonthPayData));
|
||||||
|
const [allPay, setAllPayDate] = useState(getData(getPayData));
|
||||||
|
const columns: ProColumns<any>[] = [
|
||||||
|
{
|
||||||
|
title: '时间类型',
|
||||||
|
dataIndex: 'coinType',
|
||||||
|
hideInTable: true,
|
||||||
|
initialValue: TimeType.DAY,
|
||||||
|
renderFormItem: (item, { type, defaultRender, ...rest }, form) => {
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
label: '每日',
|
||||||
|
value: TimeType.DAY,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '每周',
|
||||||
|
value: TimeType.WEEK,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '每月',
|
||||||
|
value: TimeType.MONTH,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
onChange={(val) => {
|
||||||
|
setTimeType(val);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '日期',
|
||||||
|
dataIndex: 'time',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '10%',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '时间',
|
||||||
|
dataIndex: 'select_time',
|
||||||
|
valueType: 'dateRange',
|
||||||
|
width: '20%',
|
||||||
|
hideInTable: true,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '活跃用户数',
|
||||||
|
dataIndex: 'address',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '20%',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '新用户数量',
|
||||||
|
dataIndex: 'new_user',
|
||||||
|
width: 150,
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '当日充值总额',
|
||||||
|
dataIndex: 'address',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '20%',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '付费用户数',
|
||||||
|
dataIndex: 'address',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '20%',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '付费率',
|
||||||
|
dataIndex: 'address',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '20%',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ARPU',
|
||||||
|
dataIndex: 'arpu',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '20%',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ARPPU',
|
||||||
|
dataIndex: 'arppu',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '20%',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Row gutter={24} style={{ marginBottom: 10 }}>
|
||||||
|
<Col span={6}>
|
||||||
|
<Card style={{ height: '200px' }}>{MoreData(userDate, '今日活跃用户数', '人')}</Card>
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<Card style={{ height: '200px' }}>{MoreData(newUserdate, '今日新增人数', '人')}</Card>
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<Card style={{ height: '200px' }}>{MoreData(payData, '本月充值总额', '万元')}</Card>
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<Card style={{ height: '200px' }}>{MoreData(allPay, '充值总额', '万元')}</Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
rowKey="id"
|
||||||
|
actionRef={tableRef}
|
||||||
|
request={async (params) => {
|
||||||
|
if ((params.select_time ?? '') !== '') {
|
||||||
|
params.start_time = moment(params.select_time[0]).valueOf() / 1000;
|
||||||
|
params.end_time = moment(params.select_time[1]).valueOf() / 1000;
|
||||||
|
}
|
||||||
|
return getCoreData(params);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CoreData;
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
import Table, { ProColumns, ActionType } from '@/components/Table';
|
||||||
|
import { getRententionData } from '@/services/dataBorad/rechargeAnalysis';
|
||||||
|
import { Select } from 'antd';
|
||||||
|
import moment from 'moment';
|
||||||
|
import TimeType from '@/constants/enum/timeType';
|
||||||
|
const Address: React.FC = () => {
|
||||||
|
const tableRef = useRef<ActionType>();
|
||||||
|
const [timeType, setTimeType] = useState(TimeType.DAY);
|
||||||
|
|
||||||
|
const columns: ProColumns<any>[] = [
|
||||||
|
{
|
||||||
|
title: '时间类型',
|
||||||
|
dataIndex: 'time_type',
|
||||||
|
hideInTable: true,
|
||||||
|
initialValue: TimeType.DAY,
|
||||||
|
renderFormItem: (item, { type, defaultRender, ...rest }, form) => {
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
label: '每日',
|
||||||
|
value: TimeType.DAY,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '每周',
|
||||||
|
value: TimeType.WEEK,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '每月',
|
||||||
|
value: TimeType.MONTH,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
onChange={(val) => {
|
||||||
|
setTimeType(val);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '日期',
|
||||||
|
dataIndex: 'time',
|
||||||
|
width: '10%',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '时间筛选',
|
||||||
|
dataIndex: 'timeData',
|
||||||
|
hideInTable: true,
|
||||||
|
width: '20%',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '时间',
|
||||||
|
dataIndex: 'select_time',
|
||||||
|
valueType: 'dateRange',
|
||||||
|
width: '20%',
|
||||||
|
hideInTable: true,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '付费次数',
|
||||||
|
dataIndex: 'pay_num',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '20%',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '付费用户数',
|
||||||
|
dataIndex: 'pay_user',
|
||||||
|
width: 150,
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '付费金额',
|
||||||
|
dataIndex: 'pay_price',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '20%',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '付费率',
|
||||||
|
dataIndex: 'rate',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '20%',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ARPU',
|
||||||
|
dataIndex: 'arpu',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '20%',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ARPPU',
|
||||||
|
dataIndex: 'arppu',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '20%',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
rowKey="id"
|
||||||
|
actionRef={tableRef}
|
||||||
|
// search={false}
|
||||||
|
request={async (params) => {
|
||||||
|
if ((params.select_time ?? '') !== '') {
|
||||||
|
params.start_time = moment(params.select_time[0]).valueOf() / 1000;
|
||||||
|
params.end_time = moment(params.select_time[1]).valueOf() / 1000;
|
||||||
|
}
|
||||||
|
return getRententionData(params);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Address;
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
import React, { useRef } from 'react';
|
||||||
|
import Modal, { ModalProps } from '@/components/Modal';
|
||||||
|
import { fetchTableData } from '@/utils/table';
|
||||||
|
import Table, { ProColumns, ActionType } from '@/components/Table';
|
||||||
|
import TimeText from '@/components/Typography/TimeText';
|
||||||
|
import { getChannelData } from '@/services/dataBorad/retentionAnalysis';
|
||||||
|
|
||||||
|
interface TableModalPropsType extends ModalProps {
|
||||||
|
modalData: any;
|
||||||
|
onCancel: () => void;
|
||||||
|
}
|
||||||
|
const TableModal = ({ onCancel, modalData, ...rest }: TableModalPropsType) => {
|
||||||
|
const tableRef = useRef<ActionType>();
|
||||||
|
const columns: ProColumns<any>[] = [
|
||||||
|
{
|
||||||
|
title: '时间',
|
||||||
|
dataIndex: 'time',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '20%',
|
||||||
|
render: (_, row) => [<TimeText value={row} format={'YYYY-MM-DD'} />],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '渠道类型',
|
||||||
|
dataIndex: 'channel_name',
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '登录用户数',
|
||||||
|
dataIndex: 'login_user',
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '第一日',
|
||||||
|
dataIndex: 'day_one',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '第二日',
|
||||||
|
dataIndex: 'day_two',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '第四日',
|
||||||
|
dataIndex: 'day_three',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '第五日',
|
||||||
|
dataIndex: 'day_four',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '第六日',
|
||||||
|
dataIndex: 'day_five',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '第七日',
|
||||||
|
dataIndex: 'day_seven',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
onCancel();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal title="渠道活跃分析" onCancel={handleCancel} width={800} {...rest}>
|
||||||
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
rowKey="id"
|
||||||
|
search={false}
|
||||||
|
actionRef={tableRef}
|
||||||
|
request={async (params) => {
|
||||||
|
params.time = modalData;
|
||||||
|
return fetchTableData(getChannelData, params);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TableModal;
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
import Table, { ProColumns, ActionType } from '@/components/Table';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { fetchTableData } from '@/utils/table';
|
||||||
|
import { getRententionData } from '@/services/dataBorad/retentionAnalysis';
|
||||||
|
import TableModal from './components/TableModal';
|
||||||
|
|
||||||
|
const RetentionAnalysis = () => {
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
const [requestData, setRequestData] = useState();
|
||||||
|
const sendData = (row: any) => {
|
||||||
|
setVisible(true);
|
||||||
|
setRequestData(row.time);
|
||||||
|
};
|
||||||
|
|
||||||
|
const tableRef = useRef<ActionType>();
|
||||||
|
const columns: ProColumns<any>[] = [
|
||||||
|
{
|
||||||
|
title: '时间',
|
||||||
|
dataIndex: 'time',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '时间',
|
||||||
|
dataIndex: 'select_time',
|
||||||
|
valueType: 'dateRange',
|
||||||
|
width: '20%',
|
||||||
|
hideInTable: true,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '登录用户数',
|
||||||
|
dataIndex: 'login_user',
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '第一日',
|
||||||
|
dataIndex: 'day_one',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '第二日',
|
||||||
|
dataIndex: 'day_two',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '第四日',
|
||||||
|
dataIndex: 'day_three',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '第五日',
|
||||||
|
dataIndex: 'day_four',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '第六日',
|
||||||
|
dataIndex: 'day_five',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '第七日',
|
||||||
|
dataIndex: 'day_seven',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
valueType: 'option',
|
||||||
|
width: 150,
|
||||||
|
render: (_, row) => [
|
||||||
|
<button
|
||||||
|
key="edit"
|
||||||
|
onClick={() => {
|
||||||
|
sendData(row);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
查看
|
||||||
|
</button>,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
rowKey="id"
|
||||||
|
actionRef={tableRef}
|
||||||
|
request={async (params) => {
|
||||||
|
if ((params.select_time ?? '') !== '') {
|
||||||
|
params.start_time = moment(params.select_time[0]).valueOf() / 1000;
|
||||||
|
params.end_time = moment(params.select_time[1]).valueOf() / 1000;
|
||||||
|
}
|
||||||
|
return await fetchTableData(getRententionData, params);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<TableModal
|
||||||
|
visible={visible}
|
||||||
|
modalData={requestData}
|
||||||
|
onCancel={function () {
|
||||||
|
setVisible(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RetentionAnalysis;
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
import React, { useRef } from 'react';
|
||||||
|
import { createForm } from '@formily/core';
|
||||||
|
import { createSchemaField } from '@formily/react';
|
||||||
|
import Modal, { ModalProps } from '@/components/Modal';
|
||||||
|
// import { fetchTableData } from '@/utils/table';
|
||||||
|
import { Form, FormItem, Input, NumberPicker } from '@formily/antd';
|
||||||
|
|
||||||
|
interface AddNftContractModalPropsType extends ModalProps {
|
||||||
|
onOk: (val: any) => void;
|
||||||
|
onCancel: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SchemaField = createSchemaField({
|
||||||
|
components: {
|
||||||
|
FormItem,
|
||||||
|
Input,
|
||||||
|
NumberPicker,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const form = createForm({});
|
||||||
|
|
||||||
|
const AddNftContractModal = ({ onOk, onCancel, ...rest }: AddNftContractModalPropsType) => {
|
||||||
|
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="contract_name"
|
||||||
|
title="名称"
|
||||||
|
required
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="Input"
|
||||||
|
/>
|
||||||
|
<SchemaField.Number
|
||||||
|
name="contract_address"
|
||||||
|
title="合约"
|
||||||
|
required
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="NumberPicker"
|
||||||
|
/>
|
||||||
|
<SchemaField.Number
|
||||||
|
name="description"
|
||||||
|
title=""
|
||||||
|
required
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="NumberPicker"
|
||||||
|
/>
|
||||||
|
</SchemaField>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddNftContractModal;
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
import Table, { ProColumns, ActionType } from '@/components/Table';
|
||||||
|
import { message } from 'antd';
|
||||||
|
// import { fetchTableData } from '@/utils/table';
|
||||||
|
import AddNftContractModal from './components/AddNftContract';
|
||||||
|
|
||||||
|
const Address: React.FC = () => {
|
||||||
|
const tableRef = useRef<ActionType>();
|
||||||
|
const [NftModal, setNftModal] = useState(false);
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
|
||||||
|
const columns: ProColumns<any>[] = [
|
||||||
|
{
|
||||||
|
title: '合约名称',
|
||||||
|
dataIndex: 'time',
|
||||||
|
width: '10%',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '合约地址',
|
||||||
|
dataIndex: 'address',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '20%',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'NFT数量',
|
||||||
|
dataIndex: 'nft_num',
|
||||||
|
width: 150,
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
rowKey="id"
|
||||||
|
actionRef={tableRef}
|
||||||
|
toolBarActions={[
|
||||||
|
{
|
||||||
|
type: 'add',
|
||||||
|
text: '新建NFT合约',
|
||||||
|
onConfirm: () => {
|
||||||
|
setVisible(true);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
// request={async (params) => {
|
||||||
|
// // return fetchTableData(, params);
|
||||||
|
// }}
|
||||||
|
/>
|
||||||
|
<AddNftContractModal
|
||||||
|
visible={NftModal}
|
||||||
|
onCancel={function () {
|
||||||
|
setNftModal(false);
|
||||||
|
}}
|
||||||
|
onOk={async function (val: any): Promise<void> {
|
||||||
|
try {
|
||||||
|
const params = { ...val };
|
||||||
|
// await creatNftAddress(params);
|
||||||
|
message.success('添加成功');
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
message.success('发生错误');
|
||||||
|
setVisible(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Address;
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
import React, { useRef } from 'react';
|
||||||
|
import { createForm } from '@formily/core';
|
||||||
|
import { createSchemaField } from '@formily/react';
|
||||||
|
import Modal, { ModalProps } from '@/components/Modal';
|
||||||
|
// import { fetchTableData } from '@/utils/table';
|
||||||
|
import { Form, FormItem, Input, NumberPicker } from '@formily/antd';
|
||||||
|
|
||||||
|
interface AddNftModalPropsType extends ModalProps {
|
||||||
|
onOk: (val: any) => void;
|
||||||
|
onCancel: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SchemaField = createSchemaField({
|
||||||
|
components: {
|
||||||
|
FormItem,
|
||||||
|
Input,
|
||||||
|
NumberPicker,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const form = createForm({});
|
||||||
|
|
||||||
|
const AddNftModal = ({ onOk, onCancel, ...rest }: AddNftModalPropsType) => {
|
||||||
|
const handleOk = () => {
|
||||||
|
const formState = form.getFormState();
|
||||||
|
onOk(formState.values);
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
onCancel();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal title="添加NFT" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
|
||||||
|
<Form form={form} labelCol={4} wrapperCol={18}>
|
||||||
|
<SchemaField>
|
||||||
|
<SchemaField.String
|
||||||
|
name="nft_name"
|
||||||
|
title="名称"
|
||||||
|
required
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="Input"
|
||||||
|
/>
|
||||||
|
<SchemaField.Number
|
||||||
|
name="contract"
|
||||||
|
title="合约"
|
||||||
|
required
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="NumberPicker"
|
||||||
|
/>
|
||||||
|
<SchemaField.Number
|
||||||
|
name="description"
|
||||||
|
title="描述"
|
||||||
|
required
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="NumberPicker"
|
||||||
|
/>
|
||||||
|
<SchemaField.Number
|
||||||
|
name="img"
|
||||||
|
title="图片"
|
||||||
|
required
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="NumberPicker"
|
||||||
|
/>
|
||||||
|
</SchemaField>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddNftModal;
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
import Table, { ProColumns, ActionType } from '@/components/Table';
|
||||||
|
import { message } from 'antd';
|
||||||
|
// import { fetchTableData } from '@/utils/table';
|
||||||
|
|
||||||
|
import AddNftModal from './components/AddNftModel';
|
||||||
|
import PaySelectModal from '@/widget/PaySelectModal';
|
||||||
|
|
||||||
|
const Address: React.FC = () => {
|
||||||
|
const tableRef = useRef<ActionType>();
|
||||||
|
const [NftModal, setNftModal] = useState(false);
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
const [payVisible, setPayVisible] = useState(false);
|
||||||
|
|
||||||
|
const columns: ProColumns<any>[] = [
|
||||||
|
{
|
||||||
|
title: '合约名称',
|
||||||
|
dataIndex: 'time',
|
||||||
|
width: '10%',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'NFT名称',
|
||||||
|
dataIndex: 'address',
|
||||||
|
hideInSearch: true,
|
||||||
|
width: '20%',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'TokenId',
|
||||||
|
dataIndex: 'token_id',
|
||||||
|
width: 150,
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
rowKey="id"
|
||||||
|
actionRef={tableRef}
|
||||||
|
toolBarActions={[
|
||||||
|
{
|
||||||
|
type: 'add',
|
||||||
|
text: '添加NFT',
|
||||||
|
onConfirm: () => {
|
||||||
|
setVisible(true);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'add',
|
||||||
|
text: '分发NFT',
|
||||||
|
onConfirm: () => {
|
||||||
|
setNftModal(true);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
// request={async (params) => {
|
||||||
|
// // return fetchTableData(, params);
|
||||||
|
// }}
|
||||||
|
/>
|
||||||
|
<AddNftModal
|
||||||
|
visible={visible}
|
||||||
|
onCancel={function () {
|
||||||
|
setVisible(false);
|
||||||
|
}}
|
||||||
|
onOk={async function (val: any): Promise<void> {
|
||||||
|
try {
|
||||||
|
const params = { ...val };
|
||||||
|
// await creatNftAddress(params);
|
||||||
|
message.success('添加成功');
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
message.success('发生错误');
|
||||||
|
setVisible(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<PaySelectModal
|
||||||
|
visible={payVisible}
|
||||||
|
onCancel={function () {
|
||||||
|
setVisible(false);
|
||||||
|
}}
|
||||||
|
onOk={async function (val: any): Promise<void> {
|
||||||
|
try {
|
||||||
|
const params = { ...val };
|
||||||
|
// await creatNftAddress(params);
|
||||||
|
console.log(params);
|
||||||
|
message.success('添加成功');
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
message.success('发生错误');
|
||||||
|
setVisible(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Address;
|
||||||
|
|
@ -93,33 +93,62 @@ export default [
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// name: '设置',
|
name: '数据看板',
|
||||||
// path: RoutePath.SETTING,
|
path: RoutePath.DATABOARD,
|
||||||
// routes: [
|
routes: [
|
||||||
// {
|
{
|
||||||
// path: RoutePath.SETTING,
|
path: RoutePath.DATABOARD,
|
||||||
// redirect: RoutePath.WORK.LIST,
|
redirect: RoutePath.COREDATA.LIST,
|
||||||
// hideInMenu: true,
|
hideInMenu: true,
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// name: '作品',
|
name: '核心看板',
|
||||||
// path: RoutePath.WORK.LIST,
|
path: RoutePath.COREDATA.LIST,
|
||||||
// component: './Work/List',
|
component: './DataBoard/CoreData/List',
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// name: '作品详情',
|
name: '活跃分析',
|
||||||
// path: RoutePath.WORK.EDIT,
|
path: RoutePath.ACTIVEANALYSIS.LIST,
|
||||||
// hideInMenu: true,
|
component: './DataBoard/ActiveAnalysis/List',
|
||||||
// component: './Work/Edit',
|
},
|
||||||
// },
|
{
|
||||||
// ],
|
name: '留存分析',
|
||||||
// },
|
path: RoutePath.RETENTIONANALYSIS.LIST,
|
||||||
|
component: './DataBoard/RetentionAnalysis/List',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '用户充值分析',
|
||||||
|
path: RoutePath.RECHARGEANALYSIS.LIST,
|
||||||
|
component: './DataBoard/RechargeAnalysis/List',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'NFT',
|
||||||
|
path: RoutePath.NFT,
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: RoutePath.NFT,
|
||||||
|
redirect: RoutePath.NFTCONTRACT.LIST,
|
||||||
|
hideInMenu: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'NFT合约管理',
|
||||||
|
path: RoutePath.NFTCONTRACT.LIST,
|
||||||
|
component: './NFT/NftContract/List',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'NFT管理',
|
||||||
|
path: RoutePath.NFTTOKEN.LIST,
|
||||||
|
component: './NFT/NftToken/List',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
redirect: RoutePath.RECORD.LIST,
|
redirect: RoutePath.RECORD.LIST,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
component: './404',
|
component: './404',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ const SETTING = '/setting';
|
||||||
const RECHARGE = '/recharge';
|
const RECHARGE = '/recharge';
|
||||||
const USER = '/user';
|
const USER = '/user';
|
||||||
const SYSTEM = '/system';
|
const SYSTEM = '/system';
|
||||||
|
const DATABOARD = '/databoard';
|
||||||
|
const NFT = '/nft';
|
||||||
const RoutePath = {
|
const RoutePath = {
|
||||||
LOGIN: '/login',
|
LOGIN: '/login',
|
||||||
RECHARGE: RECHARGE,
|
RECHARGE: RECHARGE,
|
||||||
|
|
@ -34,6 +36,26 @@ const RoutePath = {
|
||||||
NOTICE: {
|
NOTICE: {
|
||||||
LIST: `${SYSTEM}/notice`,
|
LIST: `${SYSTEM}/notice`,
|
||||||
},
|
},
|
||||||
|
NFT: NFT,
|
||||||
|
NFTCONTRACT: {
|
||||||
|
LIST: `${NFT}/nftcontract`,
|
||||||
|
},
|
||||||
|
NFTTOKEN: {
|
||||||
|
LIST: `${NFT}/nfttoken`,
|
||||||
|
},
|
||||||
|
DATABOARD: DATABOARD,
|
||||||
|
COREDATA: {
|
||||||
|
LIST: `${DATABOARD}/coredata`,
|
||||||
|
},
|
||||||
|
ACTIVEANALYSIS: {
|
||||||
|
LIST: `${DATABOARD}/activeanalysis`,
|
||||||
|
},
|
||||||
|
RETENTIONANALYSIS: {
|
||||||
|
LIST: `${DATABOARD}/retentionanalysis`,
|
||||||
|
},
|
||||||
|
RECHARGEANALYSIS: {
|
||||||
|
LIST: `${DATABOARD}/rechargeanalysis`,
|
||||||
|
},
|
||||||
SECRET_KEY: `${SYSTEM}/secret_key`,
|
SECRET_KEY: `${SYSTEM}/secret_key`,
|
||||||
// SETTING: SETTING,
|
// SETTING: SETTING,
|
||||||
// WORK: {
|
// WORK: {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
import request from '@/utils/request';
|
||||||
|
//获取基础数据报表
|
||||||
|
export const getActiveData = (data) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/tgb/api/v1/data/get',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 获取今日登陆人数接口
|
||||||
|
export const getTodayUserData = (params) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/tgb/api/v1/data/user/today',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//获取本日新用户人数
|
||||||
|
export const getMonthUserData = (params) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/tgb/api/v1/data/user/month',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 获取本周登录人数
|
||||||
|
export const getWeekUserData = (params) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/tgb/api/v1/data/user/week',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 获取本日老用户登录人数
|
||||||
|
export const getOldUserData = (params) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/tgb/api/v1/data/user/old',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
import request from '@/utils/request';
|
||||||
|
//获取基础数据报表
|
||||||
|
export const getCoreData = (data) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/tgb/api/v1/data/get',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 获取今日登陆人数接口
|
||||||
|
export const getTodayUserData = (params) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/tgb/api/v1/data/user/today',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//获取今日新用户
|
||||||
|
export const getNewUserData = (params) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/tgb/api/v1/data/user/new',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 获取充值总额
|
||||||
|
export const getPayData = (params) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/tgb/api/v1/data/pay/all',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 获取本月充值总额
|
||||||
|
export const getMonthPayData = (params) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/tgb/api/v1/data/pay/month',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import request from '@/utils/request';
|
||||||
|
//获取基础数据报表
|
||||||
|
export const getRententionData = (data) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/tgb/api/v1/data/get',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import request from '@/utils/request';
|
||||||
|
//获取基础数据报表
|
||||||
|
export const getRententionData = (data) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/tgb/api/v1/data/get',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//获取渠道
|
||||||
|
export const getChannelData = (data) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/tgb/api/v1/data/get',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
import Web3 from 'web3';
|
||||||
|
import detectEthereumProvider from '@metamask/detect-provider';
|
||||||
|
import { message } from 'antd';
|
||||||
|
|
||||||
|
let provider: any;
|
||||||
|
|
||||||
|
export const web3 = new Web3();
|
||||||
|
if (typeof window.ethereum !== 'undefined') {
|
||||||
|
web3.eth.defaultAccount = window.ethereum.selectedAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function initWeb3() {
|
||||||
|
provider = await detectEthereumProvider();
|
||||||
|
|
||||||
|
if (!provider) {
|
||||||
|
console.log('请安装MetaMask');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
web3.setProvider(provider);
|
||||||
|
const accounts = await provider.request({
|
||||||
|
method: 'eth_requestAccounts',
|
||||||
|
});
|
||||||
|
web3.eth.defaultAccount = accounts[0];
|
||||||
|
return true;
|
||||||
|
} catch (reason) {
|
||||||
|
switch (reason) {
|
||||||
|
case 'Already processing eth_requestAccounts. Please wait.': // 已有请求存在
|
||||||
|
message.warning('请打开MetaMask完成授权');
|
||||||
|
break;
|
||||||
|
case 'User rejected provider access': //如果用户拒绝了登录请求
|
||||||
|
message.warning('请同意登录请求');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// 本不该执行到这里,但是真到这里了,说明发生了意外
|
||||||
|
message.warning('登录出错!err:' + reason);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
export const getData = async (fetch: any) => {
|
||||||
|
const res = (await fetch()) || {};
|
||||||
|
return res.data;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
import { Col, Row, Statistic } from 'antd';
|
||||||
|
import { ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons';
|
||||||
|
const MoreData = (props: any, title: string, company = '人') => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>{title}</p>
|
||||||
|
<h2>{props.time}</h2>
|
||||||
|
<h1>
|
||||||
|
{props.mon_user}
|
||||||
|
{company}
|
||||||
|
</h1>
|
||||||
|
<div>
|
||||||
|
<Row>
|
||||||
|
<Col span={12}>
|
||||||
|
<Statistic
|
||||||
|
title="较环比"
|
||||||
|
value={props.day_proportion}
|
||||||
|
valueStyle={
|
||||||
|
props.week_proportion > 0
|
||||||
|
? { color: '#3f8600', fontSize: 15 }
|
||||||
|
: { color: '#cf1322', fontSize: 15 }
|
||||||
|
}
|
||||||
|
prefix={props.week_proportion > 0 ? <ArrowDownOutlined /> : <ArrowUpOutlined />}
|
||||||
|
suffix="%"
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Statistic
|
||||||
|
title="较同比"
|
||||||
|
value={Math.abs(props.week_proportion)}
|
||||||
|
valueStyle={
|
||||||
|
props.week_proportion > 0
|
||||||
|
? { color: '#3f8600', fontSize: 15 }
|
||||||
|
: { color: '#cf1322', fontSize: 15 }
|
||||||
|
}
|
||||||
|
prefix={props.week_proportion > 0 ? <ArrowDownOutlined /> : <ArrowUpOutlined />}
|
||||||
|
suffix="%"
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default MoreData;
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
import { createForm, onFieldChange } from '@formily/core';
|
||||||
|
import { createSchemaField } from '@formily/react';
|
||||||
|
import Modal, { ModalProps } from '@/components/Modal';
|
||||||
|
// import { fetchTableData } from '@/utils/table';
|
||||||
|
import { Form, FormItem, Input, Select, Radio, Switch } from '@formily/antd';
|
||||||
|
|
||||||
|
interface PaySelectModalPropsType extends ModalProps {
|
||||||
|
onOk: (val: any) => void;
|
||||||
|
onCancel: () => void;
|
||||||
|
// modalData: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SchemaField = createSchemaField({
|
||||||
|
components: {
|
||||||
|
FormItem,
|
||||||
|
Input,
|
||||||
|
Select,
|
||||||
|
Radio,
|
||||||
|
Switch,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const form = createForm({});
|
||||||
|
|
||||||
|
const PaySelectModal = ({ onOk, onCancel, ...rest }: PaySelectModalPropsType) => {
|
||||||
|
const [send, useSend] = useState(true);
|
||||||
|
|
||||||
|
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.Number
|
||||||
|
name="type"
|
||||||
|
title="支付方式"
|
||||||
|
required
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="Radio.Group"
|
||||||
|
enum={[
|
||||||
|
{ label: '秘钥支付', value: 1 },
|
||||||
|
{ label: '小狐狸钱包支付', value: 2 },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<SchemaField.String
|
||||||
|
name="key"
|
||||||
|
title="秘钥"
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="Input"
|
||||||
|
x-component-props={{
|
||||||
|
placeholder: '请输入秘钥,若使用小狐狸支付则不需要输入',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</SchemaField>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PaySelectModal;
|
||||||
Loading…
Reference in New Issue