Commit 5d1c5833 by zhaochengxiang

新增订购品规以及走势图

parent 24799db6
......@@ -4,3 +4,4 @@ pc:http://localhost:3000/dashboard/3350a29b8fedcfebe3a40e4d12358626
mobile:http://localhost:3000/m/dashboard/3350a29b8fedcfebe3a40e4d12358626
用户id加密方式 AES(加密模式ECB 填充pkcs7padding 密码A930F2C3ACEA7B5B 偏移量B54480C3A296C334)+hex 参考链接:http://tool.chacuo.net/cryptaes
......@@ -17,7 +17,8 @@
"react-dom": "^16.12.0",
"react-router-dom": "^5.0.1",
"react-scripts": "^3.4.0",
"recharts": "^2.0.0-beta.1"
"recharts": "^2.0.0-beta.1",
"echarts": "^4.6.0"
},
"scripts": {
"start": "react-scripts start",
......
......@@ -13,41 +13,8 @@
}
.degreeContent {
height: 415px;
}
.degreeWrap {
max-height: 415px;
display: flex;
flex-wrap: wrap;
height: 230px;
overflow: auto;
align-self: center;
}
.degreeWrapItem {
margin: 5px;
padding: 5px 10px;
border: 1px solid #d9d9d9;
border-radius: 4px;
}
.checked {
cursor: pointer;
}
.degreeWrapItem svg {
position: relative;
top: 2px;
color: #ff4d4f;
}
.checked svg {
color: #52c41a;
}
.degreeWrapItem .title {
margin-left: 10px;
font-size: .9rem;
}
.radarContent {
......
......@@ -4,10 +4,13 @@ import CryptoJS from "crypto-js";
import { PostJSON } from "../util/axios";
import Basic from './Radar.recharts';
import Pie from './Pie';
import Line from './Line';
import './Dashboard.css';
import { Layout, Row, Col, Card, Tooltip, Spin, Divider } from 'antd';
import { Layout, Row, Col, Card, Spin, Divider, Table, Select } from 'antd';
const { Content } = Layout;
const { Option } = Select;
class Dashboard extends Component {
......@@ -17,7 +20,21 @@ class Dashboard extends Component {
"appid":"SJZT202001150001",
"appSecret":"09E9E259FF6BF30C5F93EC56DA634E59",
loading: false,
loadingOrder: false,
data: null,
orderData: null,
columns: [
{
title: '标签名称',
dataIndex: 'name',
key: 'name',
},
{
title: '标签值',
dataIndex: 'value',
key: 'value',
},
],
cxdDimension: [
{key: "custActiveTimes",name: "累计参加活动的次数"},
{key: "custActivityExpecNums",name: "累计应到活动的次数"},
......@@ -171,10 +188,24 @@ class Dashboard extends Component {
}}).then(function(data) {
if (data.return_code === '00000') {
const { gfdDimension } = this.state;
this.setState({ data: data.data, curDimension: this.curDimensionSort(data.data,gfdDimension), loading: false });
this.setState({ data: data.data, curDimension: this.curDimensionConvert(data.data,gfdDimension), loading: false });
}
}.bind(this));
});
let lastDay = this.getLastDay();
this.setState({ loadingOrder: true}, () => {
PostJSON("/data/json/queryByCriteria",{ payload: {
"userName":"root",
"tableModelId":"5e9024e4ed72724be6c0bbe1",
"whereCriterias":[{"operator":"eq","parameter":"dt","values":[lastDay]},{"operator":"eq","parameter":"lic_no","values":[_custId],"relation":"and"}],
"orderByCriterias":[{"order":"DESC","parameter":"order_num"}],
"pageNo":"1",
"pageSize":"10"
}}).then(function(data) {
this.setState({ loadingOrder: false, orderData: data.data||[] });
}.bind(this));
});
}
getNowTime = () => {
......@@ -187,7 +218,23 @@ class Dashboard extends Component {
this.second = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
this.milliSeconds = date.getMilliseconds();
return `${this.year}${this.month}${this.hour}${this.minute}${this.second}${this.milliSeconds}`;
}
}
getLastDay = () => {
var nowdays = new Date();
var year = nowdays.getFullYear();
var month = nowdays.getMonth();
if(month === 0) {
month = 12;
year = year-1;
}
if (month < 10) {
month = "0" + month;
}
var myDate = new Date(year, month, 0);
return (year + "-" + month + "-" + myDate.getDate());
}
custCredit = data => {
var level = 0;
......@@ -225,34 +272,39 @@ class Dashboard extends Component {
return '';
}
curDimensionSort = (data, dimension) => {
var checkedDimension = [];
var uncheckedDimension = [];
curDimensionConvert = (data, dimension) => {
var validateDimension = [];
dimension.map(item=>{
(data[item.key]!=null)?checkedDimension.push(item):uncheckedDimension.push(item);
if (data[item.key] != null) {
validateDimension.push({key:item.key,name:item.name,value:data[item.key]});
}
return item;
})
return checkedDimension.concat(uncheckedDimension);
return validateDimension;
}
onRadarSelected = (index) => {
const { gfdDimension, yjdDimension, phdDimension, czdDimension, cxdDimension, data} = this.state;
if (index === 0) {
this.setState({ curDegree: '规范度', curDimension: this.curDimensionSort(data,gfdDimension)});
this.setState({ curDegree: '规范度', curDimension: this.curDimensionConvert(data,gfdDimension)});
} else if (index === 1) {
this.setState({ curDegree: '预警度', curDimension: this.curDimensionSort(data,yjdDimension)});
this.setState({ curDegree: '预警度', curDimension: this.curDimensionConvert(data,yjdDimension)});
} else if (index === 2) {
this.setState({ curDegree: '配合度', curDimension: this.curDimensionSort(data,phdDimension)});
this.setState({ curDegree: '配合度', curDimension: this.curDimensionConvert(data,phdDimension)});
} else if (index === 3) {
this.setState({ curDegree: '成长度', curDimension: this.curDimensionSort(data,czdDimension)});
this.setState({ curDegree: '成长度', curDimension: this.curDimensionConvert(data,czdDimension)});
} else if (index === 4) {
this.setState({ curDegree: '诚信度', curDimension: this.curDimensionSort(data,cxdDimension)});
this.setState({ curDegree: '诚信度', curDimension: this.curDimensionConvert(data,cxdDimension)});
}
}
handleTrendChange = (value) => {
}
render() {
const { data, curDegree ,curDimension, loading } = this.state;
const { data, curDegree ,curDimension, loading, columns, loadingOrder, orderData } = this.state;
return (
<React.Fragment>
<Layout>
......@@ -314,6 +366,22 @@ class Dashboard extends Component {
<div className="text-primary">{data.custWorkPort||''}</div>
</Col>
</Row>
<Row className="border-bottom border-light infoContentItem">
<Col md={12}>
<div>所属自律互助小组</div>
<div className="text-primary">{data.custTOSDMAG||''}</div>
</Col>
<Col md={12}>
<div>经营业态</div>
<div className="text-primary">{data.custBaseType||''}</div>
</Col>
</Row>
<Row className="border-bottom border-light infoContentItem">
<Col md={12}>
<div>经营规模</div>
<div className="text-primary">{data.custSaleScope||''}</div>
</Col>
</Row>
</>
)
}
......@@ -321,7 +389,7 @@ class Dashboard extends Component {
</Card>
</Col>
<Col md={8}>
<Card bordered={false}>
<Card bordered={false} style={{marginBottom: '10px'}}>
<h3 className="ant-typography text-primary">客户评级</h3>
<Spin spinning={loading}>
<div className="levelContent">
......@@ -339,43 +407,38 @@ class Dashboard extends Component {
</div>
</Spin>
</Card>
</Col>
<Col md={8}>
<Card bordered={false}>
<h3 className="ant-typography text-primary">{curDegree}</h3>
<Spin spinning={loading}>
<div className="degreeContent">
<div className="degreeWrap">
{
data&&curDimension.map((item,i) => {
if (data[item.key]!=null) {
return (
<div key={i} className="degreeWrapItem checked text-primary">
<Tooltip
placement="top"
overlayClassName="home"
title={data[item.key]}
>
<svg viewBox="64 64 896 896" focusable="false" data-icon="check-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true">
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 0 1-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"></path>
</svg>
<span className="title">{item.name}</span>
</Tooltip>
</div>
)
curDimension&&<Table dataSource={curDimension} columns={columns} pagination={false} />
}
return (
<div key={i} className="degreeWrapItem">
<svg viewBox="64 64 896 896" focusable="false" data-icon="close-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"></path></svg>
<span className="title">{item.name}</span>
</div>
)
})
</Spin>
</Card>
</Col>
<Col md={8}>
<Card bordered={false} style={{marginBottom: '10px'}}>
<h3 className="ant-typography text-primary">订购品规TOP10</h3>
<Spin spinning={loadingOrder}>
{
orderData&&<Pie data={orderData} />
}
</div>
</div>
</Spin>
</Card>
<Card bordered={false}>
<div style={{display: 'flex',justifyContent: 'space-between'}}>
<h3 className="ant-typography text-primary">上季度走势图</h3>
<Select defaultValue="0" style={{ width: 120 }} onChange={this.handleTrendChange}>
<Option value="0">订购数量</Option>
<Option value="1">订购结构</Option>
<Option value="2">省外烟比例</Option>
<Option value="3">月供总量使用率</Option>
</Select>
</div>
<Line />
</Card>
</Col>
</Row>
</Content>
......
import React, { Component } from "react";
import echarts from "echarts";
class Line extends Component {
componentDidMount() {
// const { data } = this.props;
let xAxis = ['一月份订购数量','二月份订购数量','三月份订购数量'];
let series = [1000,800,1300];
var myChart = echarts.init(document.getElementById('line'));
myChart.setOption({
animation: true,
legend: {
show: false,
},
tooltip: {
trigger: 'axis'
},
grid: {
left: '15%',
top: '15%',
bottom: '15%'
},
textStyle:{"color":"#333","fontSize":12},
xAxis: [{
type: 'category',
show: true,
name: '',
nameGap: 8,
nameTextStyle:{
padding: [8, 0, 0, 0],
verticalAlign: 'top'
},
interval:2,
splitLine: {
show: false,
},
axisTick: {show: false},
axisLabel: {
color: '#999999',
showMaxLabel: true
},
axisLine:{
lineStyle:{
color: '#b7b7b7'
}
},
data: xAxis
}],
yAxis: {
type: 'value',
show: true,
axisTick: {show: false},
splitNumber: 3,
splitLine: {
lineStyle:{
color: '#f2f2f2'
}
},
name: '',
nameTextStyle:{
padding: [0, 8, 0, 0],
align: 'right'
},
axisLabel: {
color: '#999999',
},
axisLine:{
lineStyle:{
color: '#b7b7b7'
}
}
},
series: [
{
name: '',
type: 'line',
color: '#4091b0',
symbol: 'circle',
symbolSize: 6,
itemStyle:{
borderColor: '#fff',
borderWidth: 1
},
smooth: false,
data: series,
areaStyle: {}
}
],
});
window.addEventListener("resize", () => {
myChart.resize();
});
}
render() {
return (
<React.Fragment>
<div id={"line"} style={{ width: '100%', height: '300px' }}></div>
</React.Fragment>
);
}
}
export default Line;
import React, { Component } from "react";
import echarts from "echarts";
class Pie extends Component {
componentDidMount() {
const { data } = this.props;
let legendData = [], pieData = [];
data.map((item,i) =>{
legendData.push({
name: item.item_name,
});
pieData.push({
value: item.order_num,
name: item.item_name,
});
return item;
});
var myChart = echarts.init(document.getElementById('pie'));
myChart.setOption({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: [
{
orient: 'vertical',
left: '0',
top: '20%',
data: legendData.slice(0,5)
},
{
orient: 'vertical',
right: '0',
top: '20%',
align: 'right',
data: legendData.slice(5,10)
},
],
series: [
{
name: '访问来源',
type: 'pie',
radius: ['40%', '60%'],
avoidLabelOverlap: false,
label: {
normal: {
show: false,
position: 'center'
},
emphasis: {
show: true,
textStyle: {
fontSize: '12',
fontWeight: 'bold'
}
}
},
labelLine: {
normal: {
show: false
}
},
data: pieData
}
]
});
window.addEventListener("resize", () => {
myChart.resize();
});
}
render() {
return (
<React.Fragment>
<div id='pie' style={{ width: '100%', height: '200px' }}></div>
</React.Fragment>
);
}
}
export default Pie;
......@@ -4,10 +4,13 @@ import CryptoJS from "crypto-js";
import { PostJSON } from "../util/axios";
import Basic from './Radar.recharts';
import Pie from './Pie';
import Line from './Line';
import './Dashboard.css';
import { Layout, Row, Col, Card, Tooltip, Spin, Divider } from 'antd';
import { Layout, Row, Col, Card, Spin, Divider, Table, Select } from 'antd';
const { Content } = Layout;
const { Option } = Select;
class mDashboard extends Component {
......@@ -17,7 +20,21 @@ class mDashboard extends Component {
"appid":"SJZT202001150001",
"appSecret":"09E9E259FF6BF30C5F93EC56DA634E59",
loading: false,
loadingOrder: false,
data: null,
orderData: null,
columns: [
{
title: '标签名称',
dataIndex: 'name',
key: 'name',
},
{
title: '标签值',
dataIndex: 'value',
key: 'value',
},
],
cxdDimension: [
{key: "custActiveTimes",name: "累计参加活动的次数"},
{key: "custActivityExpecNums",name: "累计应到活动的次数"},
......@@ -171,10 +188,24 @@ class mDashboard extends Component {
}}).then(function(data) {
if (data.return_code === '00000') {
const { gfdDimension } = this.state;
this.setState({ data: data.data, curDimension: this.curDimensionSort(data.data,gfdDimension), loading: false });
this.setState({ data: data.data, curDimension: this.curDimensionConvert(data.data,gfdDimension), loading: false });
}
}.bind(this));
});
let lastDay = this.getLastDay();
this.setState({ loadingOrder: true}, () => {
PostJSON("/data/json/queryByCriteria",{ payload: {
"userName":"root",
"tableModelId":"5e9024e4ed72724be6c0bbe1",
"whereCriterias":[{"operator":"eq","parameter":"dt","values":[lastDay]},{"operator":"eq","parameter":"lic_no","values":[_custId],"relation":"and"}],
"orderByCriterias":[{"order":"DESC","parameter":"order_num"}],
"pageNo":"1",
"pageSize":"10"
}}).then(function(data) {
this.setState({ loadingOrder: false, orderData: data.data||[] });
}.bind(this));
});
}
getNowTime = () => {
......@@ -187,7 +218,23 @@ class mDashboard extends Component {
this.second = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
this.milliSeconds = date.getMilliseconds();
return `${this.year}${this.month}${this.hour}${this.minute}${this.second}${this.milliSeconds}`;
}
}
getLastDay = () => {
var nowdays = new Date();
var year = nowdays.getFullYear();
var month = nowdays.getMonth();
if(month === 0) {
month = 12;
year = year-1;
}
if (month < 10) {
month = "0" + month;
}
var myDate = new Date(year, month, 0);
return (year + "-" + month + "-" + myDate.getDate());
}
custCredit = data => {
var level = 0;
......@@ -225,34 +272,39 @@ class mDashboard extends Component {
return '';
}
curDimensionSort = (data, dimension) => {
var checkedDimension = [];
var uncheckedDimension = [];
curDimensionConvert = (data, dimension) => {
var validateDimension = [];
dimension.map(item=>{
(data[item.key]!=null)?checkedDimension.push(item):uncheckedDimension.push(item);
if (data[item.key] != null) {
validateDimension.push({key:item.key,name:item.name,value:data[item.key]});
}
return item;
})
return checkedDimension.concat(uncheckedDimension);
return validateDimension;
}
onRadarSelected = (index) => {
const { gfdDimension, yjdDimension, phdDimension, czdDimension, cxdDimension, data} = this.state;
if (index === 0) {
this.setState({ curDegree: '规范度', curDimension: this.curDimensionSort(data,gfdDimension)});
this.setState({ curDegree: '规范度', curDimension: this.curDimensionConvert(data,gfdDimension)});
} else if (index === 1) {
this.setState({ curDegree: '预警度', curDimension: this.curDimensionSort(data,yjdDimension)});
this.setState({ curDegree: '预警度', curDimension: this.curDimensionConvert(data,yjdDimension)});
} else if (index === 2) {
this.setState({ curDegree: '配合度', curDimension: this.curDimensionSort(data,phdDimension)});
this.setState({ curDegree: '配合度', curDimension: this.curDimensionConvert(data,phdDimension)});
} else if (index === 3) {
this.setState({ curDegree: '成长度', curDimension: this.curDimensionSort(data,czdDimension)});
this.setState({ curDegree: '成长度', curDimension: this.curDimensionConvert(data,czdDimension)});
} else if (index === 4) {
this.setState({ curDegree: '诚信度', curDimension: this.curDimensionSort(data,cxdDimension)});
this.setState({ curDegree: '诚信度', curDimension: this.curDimensionConvert(data,cxdDimension)});
}
}
handleTrendChange = (value) => {
}
render() {
const { data, curDegree ,curDimension, loading } = this.state;
const { data, curDegree ,curDimension, loading, columns, loadingOrder, orderData } = this.state;
return (
<React.Fragment>
<Layout>
......@@ -308,11 +360,27 @@ class mDashboard extends Component {
<div>市管员</div>
<div className="text-primary">{data.custGridPersonName||''}</div>
</Col>
<Col md={12}>
<Col span={12}>
<div>市场类型</div>
<div className="text-primary">{data.custWorkPort||''}</div>
</Col>
</Row>
<Row className="border-bottom border-light infoContentItem">
<Col span={12}>
<div>所属自律互助小组</div>
<div className="text-primary">{data.custTOSDMAG||''}</div>
</Col>
<Col span={12}>
<div>经营业态</div>
<div className="text-primary">{data.custBaseType||''}</div>
</Col>
</Row>
<Row className="border-bottom border-light infoContentItem">
<Col span={12}>
<div>经营规模</div>
<div className="text-primary">{data.custSaleScope||''}</div>
</Col>
</Row>
</>
)
}
......@@ -343,40 +411,38 @@ class mDashboard extends Component {
<Card bordered={false}>
<h3 className="ant-typography text-primary">{curDegree}</h3>
<Spin spinning={loading}>
<div className="degreeContent" style={{height: 'auto'}}>
<div className="degreeWrap" style={{maxHeight: '100%'}}>
<div className="degreeContent">
{
data&&curDimension.map((item,i) => {
if (data[item.key]!=null) {
console.log(data[item.key]);
return (
<div key={i} className="degreeWrapItem checked text-primary">
<Tooltip
placement="top"
overlayClassName="home"
title={data[item.key]}
>
<svg viewBox="64 64 896 896" focusable="false" data-icon="check-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true">
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 0 1-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"></path>
</svg>
<span className="title">{item.name}</span>
</Tooltip>
</div>
)
curDimension&&<Table dataSource={curDimension} columns={columns} pagination={false} />
}
return (
<div key={i} className="degreeWrapItem">
<svg viewBox="64 64 896 896" focusable="false" data-icon="close-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"></path></svg>
<span className="title">{item.name}</span>
</div>
)
})
</Spin>
</Card>
</Row>
<Row style={{marginBottom: '10px'}}>
<Card bordered={false} style={{marginBottom: '10px'}}>
<h3 className="ant-typography text-primary">订购品规TOP10</h3>
<Spin spinning={loadingOrder}>
{
orderData&&<Pie data={orderData} />
}
</div>
</div>
</Spin>
</Card>
</Row>
<Row style={{marginBottom: '10px'}}>
<Card bordered={false}>
<div style={{display: 'flex',justifyContent: 'space-between'}}>
<h3 className="ant-typography text-primary">上季度走势图</h3>
<Select defaultValue="0" style={{ width: 120 }} onChange={this.handleTrendChange}>
<Option value="0">订购数量</Option>
<Option value="1">订购结构</Option>
<Option value="2">省外烟比例</Option>
<Option value="3">月供总量使用率</Option>
</Select>
</div>
<Line />
</Card>
</Row>
</Content>
</Layout>
</React.Fragment>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment