数据看板完善

This commit is contained in:
vance 2022-08-03 16:16:26 +08:00
parent 43c2cdb98b
commit d2991a5ddd
16 changed files with 13142 additions and 12012 deletions

View File

@ -62,6 +62,8 @@
"axios": "^0.24.0", "axios": "^0.24.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.25.3", "moment": "^2.25.3",
"omit.js": "^2.0.2", "omit.js": "^2.0.2",

View File

@ -0,0 +1,6 @@
export enum TimeType {
DAY = 'day',
WEEK = 'week',
MONTH = 'month',
}
export default TimeType;

View File

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

View File

@ -1,59 +1,97 @@
import React, { useRef, useState } from 'react'; import React, { useRef, useState } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table'; import echarts from 'echarts/lib/echarts'; // 引入 ECharts 主模块
import { fetchTableData } from '@/utils/table'; import { getDwuData } from '@/services/DataBorad';
import moreData from '@/pages/DataBoard/ActiveAnalysis/List/components/moreData';
import { getCoreData } from '@/services/DataBorad';
import ReactEcharts from 'echarts-for-react';
import { Card, Col, Row, Select } from 'antd';
const ActiveAnalysis: React.FC = () => { const ActiveAnalysis: React.FC = () => {
const tableRef = useRef<ActionType>(); const { Option } = Select;
const [visible, setVisible] = useState(false); const [timeType, setTimeType] = useState('day');
const getData = async (func) => {
const res = await func({});
return res.data;
};
const columns: ProColumns<any>[] = [ const [data, setData] = useState(getData(getCoreData));
{ const [oldUserData, setOldUserData] = useState(getData(getCoreData));
title: '日期', const [weekData, setWeekData] = useState(getData(getCoreData));
dataIndex: 'time', const [monthData, setMonthData] = useState(getData(getCoreData));
width: '10%',
hideInSearch: true, const getOption = async (item = 'day') => {
}, const res = await getDwuData({ time_type: item });
{ const xData: any = [];
title: '活跃用户数', const seriesData: any = [];
dataIndex: 'address', res.data.foreach((item: any) => {
hideInSearch: true, xData.push(item.time);
width: '20%', seriesData.push(item.dwn);
}, });
{ const option = {
title: '活跃老玩家数量', xAxis: {
dataIndex: 'address', type: 'category',
hideInSearch: true, data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
width: '20%', // data: xData,
}, },
{ yAxis: {
title: 'MAU', type: 'value',
dataIndex: 'address', },
hideInSearch: true, series: [
width: '20%', {
}, data: [150, 230, 224, 218, 135, 147, 360],
{ // data: seriesData.reverse(),
title: 'WAU', type: 'line',
dataIndex: 'arpu', },
hideInSearch: true, ],
width: '20%', };
}, return option;
{ };
title: 'DAU', const [option, setOption] = useState(getOption);
dataIndex: 'arppu', const setTimeOption = (val: any) => {
hideInSearch: true, setTimeType(val);
width: '20%', setOption(getOption(val));
}, };
];
return ( return (
<div> <div>
<Table <Row gutter={24} justify="space-between" style={{ marginBottom: 10 }}>
columns={columns} <Col span={6}>
rowKey="id" <Card style={{ height: '200px' }}>{moreData(data, '今日活跃用户数')}</Card>
actionRef={tableRef} </Col>
// request={async (params) => { <Col span={6}>
// // return fetchTableData(, params); <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>DAU</h1>
<h3></h3>
{/* <h2>{data}人</h2> */}
<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> </div>
); );
}; };

View File

@ -1,27 +1,55 @@
import React, { useRef, useState } from 'react'; import React, { useRef, useState } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table'; import Table, { ProColumns, ActionType } from '@/components/Table';
import { getCoreData } from '@/services/DataBorad'; import { getCoreData } from '@/services/DataBorad';
import { RedoOutlined } from '@ant-design/icons';
import moment from 'moment'; import moment from 'moment';
import { Card, Col, Row, DatePicker, Button } from 'antd'; import TimeType from '@/constants/enum/timeType';
// import TimeText from '@/components/Typography/TimeText'; import moreData from '@/pages/DataBoard/ActiveAnalysis/List/components/moreData';
import { Card, Col, Row, DatePicker, Select } from 'antd';
const CoreData: React.FC = () => { const CoreData: React.FC = () => {
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
const [startTimeValue, setStartTimeValue] = useState(Number); const [startTimeValue, setStartTimeValue] = useState(Number);
const [endTimeValue, setEndTimeValue] = useState(Number); const [endTimeValue, setEndTimeValue] = useState(Number);
const [timeType, setTimeType] = useState(TimeType.DAY);
const getTimedata = (data: any) => { const getTimedata = (data: any) => {
setStartTimeValue(moment(data[0]).valueOf()); setStartTimeValue(moment(data[0]).valueOf());
setEndTimeValue(moment(data[1]).valueOf()); setEndTimeValue(moment(data[1]).valueOf());
console.log(startTimeValue, endTimeValue);
}; };
const carddata = { const getData = async () => {
name: 1, const res = await getCoreData({});
time: 2, return res.data;
user_num: 2,
}; };
const [date, setDate] = useState(carddata); // const [date, setDate] = useState(getData);
const [date, setDate] = useState(getData);
const columns: ProColumns<any>[] = [ 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: '日期', title: '日期',
dataIndex: 'time', dataIndex: 'time',
@ -85,75 +113,16 @@ const CoreData: React.FC = () => {
<div> <div>
<Row gutter={24} style={{ marginBottom: 10 }}> <Row gutter={24} style={{ marginBottom: 10 }}>
<Col span={6}> <Col span={6}>
<Card style={{ height: '140px' }}> <Card style={{ height: '200px' }}>{moreData(2, '今日活跃用户数', '人')}</Card>
<div>
<p>
<Button
type="link"
icon={
<RedoOutlined
onClick={async () => {
const res = await getCoreData({});
setDate(res.data);
}}
/>
}
/>
</p>
<p>{date.user_num}</p>
</div>
</Card>
</Col> </Col>
<Col span={6}> <Col span={6}>
<Card style={{ height: '140px' }}> <Card style={{ height: '200px' }}>{moreData(2, '今日新增人数', '人')}</Card>
<div>
<p>
<Button
type="link"
icon={
<RedoOutlined
onClick={async () => {
const res = await getCoreData({});
setDate(res.data);
}}
/>
}
/>
</p>
<p>{date.user_num}</p>
</div>
</Card>
</Col> </Col>
<Col span={6}> <Col span={6}>
<Card style={{ height: '140px' }}> <Card style={{ height: '200px' }}>{moreData(2, '本月充值总额', '万元')}</Card>
<div>
<p>
<Button
type="link"
icon={
<RedoOutlined
onClick={async () => {
const res = await getCoreData({});
setDate(res.data);
}}
/>
}
/>
</p>
<p>{date.name}</p>
</div>
</Card>
</Col> </Col>
<Col span={6}> <Col span={6}>
<Card style={{ height: '140px' }}> <Card style={{ height: '200px' }}>{moreData(2, '充值总额', '万元')}</Card>
<div>
<p></p>
<p>{date.user_num}</p>
</div>
</Card>
</Col> </Col>
</Row> </Row>

View File

@ -1,44 +1,88 @@
import React, { useRef, useState } from 'react'; import React, { useRef, useState } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table'; import Table, { ProColumns, ActionType } from '@/components/Table';
import { getCoreData } from '@/services/DataBorad'; import { getCoreData } from '@/services/DataBorad';
import { DatePicker, Select } from 'antd';
import moment from 'moment';
import TimeType from '@/constants/enum/timeType';
const Address: React.FC = () => { const Address: React.FC = () => {
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
const [visible, setVisible] = useState(false); const [startTimeValue, setStartTimeValue] = useState(Number);
const [endTimeValue, setEndTimeValue] = useState(Number);
const [timeType, setTimeType] = useState(TimeType.DAY);
const getTimedata = (data: any) => {
setStartTimeValue(moment(data[0]).valueOf());
setEndTimeValue(moment(data[1]).valueOf());
};
const columns: ProColumns<any>[] = [ 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: '日期', title: '日期',
dataIndex: 'time', dataIndex: 'time',
width: '10%', width: '10%',
hideInSearch: true, // hideInSearch: true,
renderFormItem: (item, { type, defaultRender, ...rest }, form) => {
return (
<div>
<DatePicker.RangePicker
style={{ width: '300px' }}
defaultValue={[moment(), moment()]}
format={'YYYY-MM-DD'}
onChange={getTimedata}
/>
</div>
);
},
}, },
{ {
title: '活跃用户数', title: '付费次数',
dataIndex: 'address', dataIndex: 'pay_num',
hideInSearch: true,
width: '20%',
},
{
title: '新用户数量',
dataIndex: 'new_user',
width: 150,
hideInSearch: true,
},
{
title: '当日充值总额',
dataIndex: 'address',
hideInSearch: true, hideInSearch: true,
width: '20%', width: '20%',
}, },
{ {
title: '付费用户数', title: '付费用户数',
dataIndex: 'address', dataIndex: 'pay_user',
width: 150,
hideInSearch: true,
},
{
title: '付费金额',
dataIndex: 'pay_price',
hideInSearch: true, hideInSearch: true,
width: '20%', width: '20%',
}, },
{ {
title: '付费率', title: '付费率',
dataIndex: 'address', dataIndex: 'rate',
hideInSearch: true, hideInSearch: true,
width: '20%', width: '20%',
}, },
@ -57,34 +101,27 @@ const Address: React.FC = () => {
]; ];
return ( return (
<div> // <div>
<Table // <Table
columns={columns} // columns={columns}
rowKey="id" // rowKey="id"
actionRef={tableRef} // actionRef={tableRef}
search={false} // // search={false}
request={async (params) => { // request={async (params) => {
return getCoreData(params); // return getCoreData(params);
}} // }}
/> // />
<Table <Table
columns={columns} columns={columns}
rowKey="id" rowKey="id"
actionRef={tableRef} actionRef={tableRef}
search={false} // search={false}
toolBarActions={[ request={async (params) => {
{ params.start_time = startTimeValue;
type: 'add', params.end_time = endTimeValue;
onConfirm: () => { return getCoreData(params);
setVisible(true); }}
}, />
},
]}
request={async (params) => {
return getCoreData(params);
}}
/>
</div>
); );
}; };

View File

@ -26,38 +26,39 @@ const TableModal = ({ onCancel, modalData, ...rest }: TableModalPropsType) => {
ellipsis: true, ellipsis: true,
}, },
{ {
title: '当日', title: '登录用户数',
dataIndex: 'key', dataIndex: 'login_user',
hideInSearch: true, hideInSearch: true,
ellipsis: true,
}, },
{ {
title: '第一日', title: '第一日',
dataIndex: 'key', dataIndex: 'day_one',
hideInSearch: true, hideInSearch: true,
}, },
{ {
title: '第二日', title: '第二日',
dataIndex: 'key', dataIndex: 'day_two',
hideInSearch: true, hideInSearch: true,
}, },
{ {
title: '第四日', title: '第四日',
dataIndex: 'key', dataIndex: 'day_three',
hideInSearch: true, hideInSearch: true,
}, },
{ {
title: '第五日', title: '第五日',
dataIndex: 'key', dataIndex: 'day_four',
hideInSearch: true, hideInSearch: true,
}, },
{ {
title: '第六日', title: '第六日',
dataIndex: 'key', dataIndex: 'day_five',
hideInSearch: true, hideInSearch: true,
}, },
{ {
title: '第七日', title: '第七日',
dataIndex: 'key', dataIndex: 'day_seven',
hideInSearch: true, hideInSearch: true,
}, },
]; ];

View File

@ -11,11 +11,12 @@ const RetentionAnalysis = () => {
const [endTimeValue, setEndTimeValue] = useState(Number); const [endTimeValue, setEndTimeValue] = useState(Number);
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const [requestData, setRequestData] = useState({}); const [requestData, setRequestData] = useState();
const getTimedata = (data) => { const getTimedata = (data) => {
setStartTimeValue(moment(data[0]).valueOf()); setStartTimeValue(moment(data[0]).valueOf());
setEndTimeValue(moment(data[1]).valueOf()); setEndTimeValue(moment(data[1]).valueOf());
console.log(startTimeValue, endTimeValue); console.log(startTimeValue, endTimeValue);
console.log(visible);
}; };
const sendData = (row: any) => { const sendData = (row: any) => {
setVisible(true); setVisible(true);
@ -27,10 +28,11 @@ const RetentionAnalysis = () => {
{ {
title: '时间', title: '时间',
dataIndex: 'time', dataIndex: 'time',
width: '20%', // width: '20%',
renderFormItem: (item, { type, defaultRender, ...rest }, form) => { renderFormItem: (item, { type, defaultRender, ...rest }, form) => {
return ( return (
<DatePicker.RangePicker <DatePicker.RangePicker
value={requestData}
style={{ width: '200px' }} style={{ width: '200px' }}
defaultValue={[moment(), moment()]} defaultValue={[moment(), moment()]}
format={'YYYY-MM-DD'} format={'YYYY-MM-DD'}
@ -45,39 +47,34 @@ const RetentionAnalysis = () => {
hideInSearch: true, hideInSearch: true,
ellipsis: true, ellipsis: true,
}, },
{
title: '当日',
dataIndex: 'key',
hideInSearch: true,
},
{ {
title: '第一日', title: '第一日',
dataIndex: 'key', dataIndex: 'day_one',
hideInSearch: true, hideInSearch: true,
}, },
{ {
title: '第二日', title: '第二日',
dataIndex: 'key', dataIndex: 'day_two',
hideInSearch: true, hideInSearch: true,
}, },
{ {
title: '第四日', title: '第四日',
dataIndex: 'key', dataIndex: 'day_three',
hideInSearch: true, hideInSearch: true,
}, },
{ {
title: '第五日', title: '第五日',
dataIndex: 'key', dataIndex: 'day_four',
hideInSearch: true, hideInSearch: true,
}, },
{ {
title: '第六日', title: '第六日',
dataIndex: 'key', dataIndex: 'day_five',
hideInSearch: true, hideInSearch: true,
}, },
{ {
title: '第七日', title: '第七日',
dataIndex: 'key', dataIndex: 'day_seven',
hideInSearch: true, hideInSearch: true,
}, },
{ {
@ -105,7 +102,7 @@ const RetentionAnalysis = () => {
request={async (params) => { request={async (params) => {
params.start_time = startTimeValue; params.start_time = startTimeValue;
params.end_time = endTimeValue; params.end_time = endTimeValue;
return fetchTableData(getRetentionData, params); return await fetchTableData(getRetentionData, params);
}} }}
/> />
<TableModal <TableModal

View File

@ -30,7 +30,7 @@ const AddNftContractModal = ({ onOk, onCancel, ...rest }: AddNftContractModalPro
}; };
return ( return (
<Modal title="添加地址" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}> <Modal title="创建NFT" 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

View File

@ -30,7 +30,7 @@ const AddNftModal = ({ onOk, onCancel, ...rest }: AddNftModalPropsType) => {
}; };
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

View File

@ -23,3 +23,11 @@ export const getchannelRetentionData = (data) => {
data, data,
}); });
}; };
export const getDwuData = (data) => {
return request.request({
url: '/tgb/api/v1/data/get',
method: 'post',
data,
});
};

View File

View File

@ -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 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,
});
};

24624
yarn.lock

File diff suppressed because it is too large Load Diff