Commit 3f0a9d28 by guomingpang

feat:首页新增学员周活跃模块

parent f803fff4
import React from 'react'; import Service from '@/common/js/service';
import { Select, Tooltip } from 'antd';
import DataSet from "@antv/data-set";
import { Chart as G2Chart } from '@antv/g2';
import {
G2,
Chart,
Geom,
Axis,
Tooltip as G2Tooltip,
Coord,
Label,
Legend,
View,
Guide,
Shape,
Facet,
Util
} from "bizcharts";
import moment from 'moment'
import Service from "@/common/js/service";
import User from '@/common/js/user'; import User from '@/common/js/user';
import DataSet from '@antv/data-set';
import { Chart as G2Chart } from '@antv/g2';
import { Select, Tooltip } from 'antd';
import { Axis, Chart, Coord, Geom, Guide, Tooltip as G2Tooltip } from 'bizcharts';
import moment from 'moment';
import React from 'react';
import './Home.less'; import './Home.less';
const Option = Select.Option; const Option = Select.Option;
...@@ -42,7 +28,9 @@ class Home extends React.Component { ...@@ -42,7 +28,9 @@ class Home extends React.Component {
studyTimeRange: '7', studyTimeRange: '7',
completeNum: 0, completeNum: 0,
unfinishedNum: 0, unfinishedNum: 0,
} weekVisitCustomerNum: 0,
incWeekVisitCustomerNum: 0,
};
this._chart = null; this._chart = null;
} }
...@@ -56,7 +44,7 @@ class Home extends React.Component { ...@@ -56,7 +44,7 @@ class Home extends React.Component {
getTrainingInfo() { getTrainingInfo() {
Service.Hades('public/hades/planOverview', { storeId: User.getStoreId() }).then((res) => { Service.Hades('public/hades/planOverview', { storeId: User.getStoreId() }).then((res) => {
if (res.success) { if (res.success) {
this.setState(res.result) this.setState(res.result);
} }
}); });
} }
...@@ -68,25 +56,25 @@ class Home extends React.Component { ...@@ -68,25 +56,25 @@ class Home extends React.Component {
scheduleType, scheduleType,
storeId: User.getStoreId(), storeId: User.getStoreId(),
timeRange, timeRange,
} };
Service.Hades('public/courseCloud/hotCourse', data).then((res) => { Service.Hades('public/courseCloud/hotCourse', data).then((res) => {
if (res.success) { if (res.success) {
this.setState({ this.setState({
list: res.result list: res.result,
}) });
} }
}) });
} }
getStudyInfo() { getStudyInfo() {
const { studyTimeRange } = this.state; const { studyTimeRange } = this.state;
Service.Hades('public/hades/studyInfo', { storeId: User.getStoreId(), timeRange: studyTimeRange }).then((res) => { Service.Hades('public/hades/studyInfo', { storeId: User.getStoreId(), timeRange: studyTimeRange }).then((res) => {
if (res.success) { if (res.success) {
const dataList = res.result.map(item => ({ const dataList = res.result.map((item) => ({
time: moment(item.dateline).format('MM-DD'), time: moment(item.dateline).format('MM-DD'),
studyNum: item.studyNum, studyNum: item.studyNum,
studyTime: Math.round(item.studyTime / 6) / 10, studyTime: Math.round(item.studyTime / 6) / 10,
})) }));
this.createChart(dataList); this.createChart(dataList);
} }
}); });
...@@ -110,9 +98,11 @@ class Home extends React.Component { ...@@ -110,9 +98,11 @@ class Home extends React.Component {
pictureCourseNum: res.result.pictureCourseNum, pictureCourseNum: res.result.pictureCourseNum,
offlineCourseNum: res.result.offlineCourseNum, offlineCourseNum: res.result.offlineCourseNum,
trainingPlanNum: res.result.trainingPlanNum, trainingPlanNum: res.result.trainingPlanNum,
}) weekVisitCustomerNum: res.result.weekVisitCustomerNum,
incWeekVisitCustomerNum: res.result.incWeekVisitCustomerNum,
});
} }
}) });
} }
showNumber(index) { showNumber(index) {
...@@ -135,82 +125,92 @@ class Home extends React.Component { ...@@ -135,82 +125,92 @@ class Home extends React.Component {
container: 'chart-id', container: 'chart-id',
forceFit: true, forceFit: true,
height: 290, height: 290,
padding: [48, 64] padding: [48, 64],
}) });
} }
this._chart.clear(); this._chart.clear();
this._chart.source(data, { this._chart.source(data, {
studyTime: { studyTime: {
formatter: (val) => { formatter: (val) => {
return val return val;
}, },
tickCount: 5, tickCount: 5,
}, },
time: { time: {
formatter: (val) => { formatter: (val) => {
return `${val}` return `${val}`;
}, },
}, },
studyNum: { studyNum: {
formatter: (val) => { formatter: (val) => {
return val return val;
}, },
tickCount: 5, tickCount: 5,
} },
}); });
this._chart.axis('time', { this._chart.axis('time', {
label: { label: {
offset: 20, offset: 20,
textStyle: { textStyle: {
fill: '#666666', fill: '#666666',
fontSize: 14 fontSize: 14,
} },
}, },
line: { line: {
stroke: '#E8E8E8' stroke: '#E8E8E8',
}, },
tickLine: { tickLine: {
stroke: '#E8E8E8' stroke: '#E8E8E8',
} },
}) });
this._chart.axis('submitCount', { this._chart.axis('submitCount', {
label: { label: {
textStyle: { textStyle: {
fill: '#666666', fill: '#666666',
fontSize: 14 fontSize: 14,
} },
} },
}) });
this._chart.axis('studyTime', { this._chart.axis('studyTime', {
label: { label: {
textStyle: { textStyle: {
fill: '#666666', fill: '#666666',
fontSize: 14 fontSize: 14,
} },
} },
}) });
this._chart.line().position('time*studyNum').color('#2966FF').tooltip('time*studyNum', function( time, studyNum){ this._chart
.line()
.position('time*studyNum')
.color('#2966FF')
.tooltip('time*studyNum', function (time, studyNum) {
return { return {
name: '学习人数', name: '学习人数',
value: studyNum + '人' value: studyNum + '人',
} };
}); });
this._chart.line().position('time*studyTime').color('#FFBB54').tooltip('time*studyTime', function( time, studyTime){ this._chart
.line()
.position('time*studyTime')
.color('#FFBB54')
.tooltip('time*studyTime', function (time, studyTime) {
return { return {
name: '人均学习时长', name: '人均学习时长',
value: studyTime + '分钟' value: studyTime + '分钟',
} };
}); });
this._chart.legend(false); this._chart.legend(false);
this._chart.tooltip({ this._chart.tooltip({
containerTpl: '<div class="g2-tooltip" style="background: #fff !important;">' containerTpl:
+ '<div class="g2-tooltip-title" style="margin:10px 0;"></div>' '<div class="g2-tooltip" style="background: #fff !important;">' +
+ '<ul class="g2-tooltip-list"></ul></div>', // tooltip 容器模板 '<div class="g2-tooltip-title" style="margin:10px 0;"></div>' +
itemTpl: '<li data-index={index}><span style="background-color:{color};width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:8px;"></span>{name}<span style="display: inline-block; float: right; margin-left: 30px;">{value}</span></li>', // tooltip 每项记录的默认模板 '<ul class="g2-tooltip-list"></ul></div>', // tooltip 容器模板
}) itemTpl:
'<li data-index={index}><span style="background-color:{color};width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:8px;"></span>{name}<span style="display: inline-block; float: right; margin-left: 30px;">{value}</span></li>', // tooltip 每项记录的默认模板
});
this._chart.render(); this._chart.render();
} };
render() { render() {
const { const {
...@@ -235,313 +235,344 @@ class Home extends React.Component { ...@@ -235,313 +235,344 @@ class Home extends React.Component {
planCustomerNum, planCustomerNum,
incOfflineCourseNum, incOfflineCourseNum,
offlineCourseNum, offlineCourseNum,
weekVisitCustomerNum,
incWeekVisitCustomerNum,
} = this.state; } = this.state;
const data = [ const data = [
{ {
item: '已完成培训', item: '已完成培训',
count: completeNum, count: completeNum,
}, { },
{
item: '未完成培训', item: '未完成培训',
count: unfinishedNum, count: unfinishedNum,
} },
]; ];
const { DataView } = DataSet; const { DataView } = DataSet;
const { Html } = Guide; const { Html } = Guide;
const sum = data[0].count + data[1].count; const sum = data[0].count + data[1].count;
const dv = new DataView(); const dv = new DataView();
sum && dv.source(data).transform({ sum &&
type: "percent", dv.source(data).transform({
field: "count", type: 'percent',
dimension: "item", field: 'count',
as: "percent" dimension: 'item',
as: 'percent',
}); });
const cols = { const cols = {
percent: { percent: {
formatter: val => { formatter: (val) => {
val = val * 100 + "%"; val = val * 100 + '%';
return val; return val;
} },
} },
}; };
return ( return (
<div className="home-page"> <div className='home-page'>
<div className="data-wrap"> <div className='data-wrap'>
<div className="home-title">数据概况</div> <div className='home-title'>数据概况</div>
<div className="data-box"> <div className='data-box'>
<div className="data-item"> <div className='data-item'>
<div className="header"> <div className='header'>
<img className="header-icon" src="https://image.xiaomaiketang.com/xm/wAaFtjeRsM.png" /> <img className='header-icon' src='https://image.xiaomaiketang.com/xm/wAaFtjeRsM.png' alt='' />
<span className="header-word">学员总数 (人)</span> <span className='header-word'>学员总数 (人)</span>
</div> </div>
<div className="data-number">{totalCustomerNum}</div> <div className='data-number'>{totalCustomerNum}</div>
<div className="data-footer"> <div className='data-footer'>
<span className="footer-word">本月新增</span> <span className='footer-word'>本月新增</span>
{incCustomerNum > 0 && {incCustomerNum > 0 && <span className='icon iconfont'>&#xe635;</span>}
<span className="icon iconfont">&#xe635;</span> <span className='footer-number'>{incCustomerNum}</span>
} </div>
<span className="footer-number">{incCustomerNum}</span> </div>
</div> <div className='data-item'>
</div> <div className='header'>
<div className="data-item course-data"> <img className='header-icon' src='https://image.xiaomaiketang.com/xm/nXYAHExPrX.png' alt='' />
<div className="header"> <span className='header-word'>学员周活跃 (人)</span>
<img className="header-icon" src="https://image.xiaomaiketang.com/xm/jPrRhw8EMF.png" /> </div>
<span className="header-word">课程总数 (个)</span> <div className='data-number'>{weekVisitCustomerNum || 0}</div>
</div> <div className='data-footer'>
<div className="data-number">{videoCourseNum + liveCourseNum + pictureCourseNum}</div> <span className='footer-word'>本月新增</span>
<div className="course-box"> {incWeekVisitCustomerNum > 0 && <span className='icon iconfont'>&#xe635;</span>}
<div className="course-item"> <span className='footer-number'>{incWeekVisitCustomerNum || 0}</span>
<div className="course-title">直播课</div>
<div className="data">
<span className="course-number">{liveCourseNum}</span>
<span className="course-word">本月新增</span>
{incLiveCourseNum > 0 &&
<span className="icon iconfont">&#xe635;</span>
}
<span className="add-number">{incLiveCourseNum}</span>
</div> </div>
</div> </div>
<div className="course-item">
<div className="course-title">视频课</div> <div className='data-item course-data'>
<div className="data"> <div className='header'>
<span className="course-number">{videoCourseNum}</span> <img className='header-icon' src='https://image.xiaomaiketang.com/xm/jPrRhw8EMF.png' alt='' />
<span className="course-word">本月新增</span> <span className='header-word'>课程总数 (个)</span>
{incVideoCourseNum > 0 &&
<span className="icon iconfont">&#xe635;</span>
}
<span className="add-number">{incVideoCourseNum}</span>
</div> </div>
<div className='data-number'>{videoCourseNum + liveCourseNum + pictureCourseNum}</div>
<div className='data-footer'>
<span className='footer-word'>本月新增</span>
{incCustomerNum > 0 && <span className='icon iconfont'>&#xe635;</span>}
<span className='footer-number'>{incCustomerNum}</span>
</div> </div>
<div className="course-item"> <div className='course-box'>
<div className="course-title">图文课</div> <div className='course-item'>
<div className="data"> <div className='course-title'>直播课</div>
<span className="course-number">{pictureCourseNum}</span> <div className='data'>
<span className="course-word">本月新增</span> <span className='course-number'>{liveCourseNum}</span>
{incPictureCourseNum > 0 && {incLiveCourseNum > 0 && <span className='icon iconfont'>&#xe635;</span>}
<span className="icon iconfont">&#xe635;</span> <span className='add-number'>{incLiveCourseNum}</span>
}
<span className="add-number">{incPictureCourseNum}</span>
</div> </div>
</div> </div>
<div className="course-item"> <div className='course-item'>
<div className="course-title">线下课</div> <div className='course-title'>视频课</div>
<div className="data"> <div className='data'>
<span className="course-number">{offlineCourseNum}</span> <span className='course-number'>{videoCourseNum}</span>
<span className="course-word">本月新增</span> {incVideoCourseNum > 0 && <span className='icon iconfont'>&#xe635;</span>}
{incOfflineCourseNum > 0 && <span className='add-number'>{incVideoCourseNum}</span>
<span className="icon iconfont">&#xe635;</span>
}
<span className="add-number">{incOfflineCourseNum}</span>
</div> </div>
</div> </div>
<div className='course-item'>
<div className='course-title'>图文课</div>
<div className='data'>
<span className='course-number'>{pictureCourseNum}</span>
{incPictureCourseNum > 0 && <span className='icon iconfont'>&#xe635;</span>}
<span className='add-number'>{incPictureCourseNum}</span>
</div> </div>
</div> </div>
<div className="data-item"> <div className='course-item'>
<div className="header"> <div className='course-title'>线下课</div>
<img className="header-icon" src="https://image.xiaomaiketang.com/xm/jZf3GNY5tY.png" /> <div className='data'>
<span className="header-word">培训计划总数 (个)</span> <span className='course-number'>{offlineCourseNum}</span>
{incOfflineCourseNum > 0 && <span className='icon iconfont'>&#xe635;</span>}
<span className='add-number'>{incOfflineCourseNum}</span>
</div> </div>
<div className="data-number">{trainingPlanNum}</div> </div>
<div className="data-footer"> </div>
<span className="footer-word">本月新增</span> </div>
{incTrainingPlanNum > 0 && <div className='data-item'>
<span className="icon iconfont">&#xe635;</span> <div className='header'>
} <img className='header-icon' src='https://image.xiaomaiketang.com/xm/jZf3GNY5tY.png' alt='' />
<span className="footer-number">{incTrainingPlanNum}</span> <span className='header-word'>培训计划总数 (个)</span>
</div>
<div className='data-number'>{trainingPlanNum}</div>
<div className='data-footer'>
<span className='footer-word'>本月新增</span>
{incTrainingPlanNum > 0 && <span className='icon iconfont'>&#xe635;</span>}
<span className='footer-number'>{incTrainingPlanNum}</span>
</div> </div>
</div> </div>
<div className="data-item"> <div className='data-item'>
<div className="header"> <div className='header'>
<img className="header-icon" src="https://image.xiaomaiketang.com/xm/3CfrPs23Re.png" /> <img className='header-icon' src='https://image.xiaomaiketang.com/xm/3CfrPs23Re.png' alt='' />
<span className="header-word">考试总数 (个)</span> <span className='header-word'>考试总数 (个)</span>
</div> </div>
<div className="data-number">{examNum}</div> <div className='data-number'>{examNum}</div>
<div className="data-footer"> <div className='data-footer'>
<span className="footer-word">本月新增</span> <span className='footer-word'>本月新增</span>
{incExamNum > 0 && {incExamNum > 0 && <span className='icon iconfont'>&#xe635;</span>}
<span className="icon iconfont">&#xe635;</span> <span className='footer-number'>{incExamNum}</span>
}
<span className="footer-number">{incExamNum}</span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div className="study-wrap"> <div className='study-wrap'>
<div className="home-title">学习概况</div> <div className='home-title'>学习概况</div>
<div className="study-box"> <div className='study-box'>
<div className="study-item"> <div className='study-item'>
<div className="study-title">课程学习排行榜</div> <div className='study-title'>课程学习排行榜</div>
<div className="study-header"> <div className='study-header'>
<div className="study-tab"> <div className='study-tab'>
<span <span
className={`tab${scheduleType === 'LIVE' ? ' selected' : ''}`} className={`tab${scheduleType === 'LIVE' ? ' selected' : ''}`}
onClick={() => this.setState({ scheduleType: 'LIVE' }, () => this.getHotCourse())} onClick={() => this.setState({ scheduleType: 'LIVE' }, () => this.getHotCourse())}>
>直播课</span> 直播课
</span>
<span <span
className={`tab${scheduleType === 'VOICE' ? ' selected' : ''}`} className={`tab${scheduleType === 'VOICE' ? ' selected' : ''}`}
onClick={() => this.setState({ scheduleType: 'VOICE' }, () => this.getHotCourse())} onClick={() => this.setState({ scheduleType: 'VOICE' }, () => this.getHotCourse())}>
>视频课</span> 视频课
</span>
<span <span
className={`tab${scheduleType === 'PICTURE' ? ' selected' : ''}`} className={`tab${scheduleType === 'PICTURE' ? ' selected' : ''}`}
onClick={() => this.setState({ scheduleType: 'PICTURE' }, () => this.getHotCourse())} onClick={() => this.setState({ scheduleType: 'PICTURE' }, () => this.getHotCourse())}>
>图文课</span> 图文课
</div> </span>
<div className="study-select"> </div>
<span className="select-word">{moment().subtract(timeRange - 1, 'day').format('MM.DD')} ~ {moment().format('MM.DD')}</span> <div className='study-select'>
<span className='select-word'>
{moment()
.subtract(timeRange - 1, 'day')
.format('MM.DD')}{' '}
~ {moment().format('MM.DD')}
</span>
<Select <Select
style={{ width: 88 }} style={{ width: 88 }}
value={timeRange} value={timeRange}
onChange={(value) => { onChange={(value) => {
this.setState({ timeRange: value }, () => this.getHotCourse()); this.setState({ timeRange: value }, () => this.getHotCourse());
}} }}>
> <Option value='7'>近7天</Option>
<Option value="7">近7天</Option> <Option value='15'>近15天</Option>
<Option value="15">近15天</Option> <Option value='30'>近30天</Option>
<Option value="30">近30天</Option>
</Select> </Select>
</div> </div>
</div> </div>
{_.isEmpty(list) ? <Choose>
<div className="study-empty"> <When condition={_.isEmpty(list)}>
<img src="https://image.xiaomaiketang.com/xm/52dmait5Bx.png" /> <div className='study-empty'>
<img src='https://image.xiaomaiketang.com/xm/52dmait5Bx.png' />
<div>暂无课程上榜</div> <div>暂无课程上榜</div>
</div> </div>
: list.map((item, index) => ( </When>
<Otherwise>
{list.map((item, index) => (
<div className={`table-item${index % 2 ? '' : ' odd'}`} key={item.id}> <div className={`table-item${index % 2 ? '' : ' odd'}`} key={item.id}>
{index < 3 ? <Choose>
<span className="table-number"><img src={this.showNumber(index)} className="table-image" /></span> <When condition={index < 3}>
: <span className="table-number">{index + 1}</span> <span className='table-number'>
} <img src={this.showNumber(index)} className='table-image' alt='' />
<div className="table-data"> </span>
<div className="table-name"> </When>
<Tooltip title={item.courseName}> <Otherwise>
{item.courseName} <span className='table-number'>{index + 1}</span>
</Tooltip> </Otherwise>
</Choose>
<div className='table-data'>
<div className='table-name'>
<Tooltip title={item.courseName}>{item.courseName}</Tooltip>
</div> </div>
<div className="table-tag">{item.categoryName}</div> <div className='table-tag'>{item.categoryName}</div>
</div> </div>
<span className="table-study">{item.studyNum || 0}人已学习</span> <span className='table-study'>{item.studyNum || 0}人已学习</span>
</div> </div>
)) ))}
} </Otherwise>
</Choose>
</div> </div>
<div className="study-item"> <div className='study-item'>
<div className="study-title">培训计划完成情况 <div className='study-title'>
<Tooltip overlayClassName="data-plan-tooltip" title="若某人加入多个培训计划,则需完成所有已加入的培训计划后,才视为已完成培训"> 培训计划完成情况
<span className="iconfont icon">&#xe61d;</span> <Tooltip overlayClassName='data-plan-tooltip' title='若某人加入多个培训计划,则需完成所有已加入的培训计划后,才视为已完成培训'>
<span className='iconfont icon'>&#xe61d;</span>
</Tooltip> </Tooltip>
<span className="tip">(本月)</span> <span className='tip'>(本月)</span>
</div> </div>
{(unfinishedNum || completeNum) ? <Choose>
<When condition={unfinishedNum || completeNum}>
<div <div
className="left-graph-container" className='left-graph-container'
id="mountNode" id='mountNode'
style={{ width: '100%', marginLeft: '-20%', marginTop: -30 }} style={{ width: '100%', marginLeft: '-20%', marginTop: -30 }}
ref={e => e && (this.width = e.clientWidth)} ref={(e) => e && (this.width = e.clientWidth)}>
> {this.width && (
{this.width && <div> <div>
<Chart <Chart height={400} width={this.width} data={dv} scale={cols} padding={20}>
height={400} <Coord type={'theta'} radius={0.75} innerRadius={0.6} />
width={this.width} <Axis name='percent' />
data={dv}
scale={cols}
padding={20}
>
<Coord type={"theta"} radius={0.75} innerRadius={0.6} />
<Axis name="percent" />
<G2Tooltip <G2Tooltip
showTitle={false} showTitle={false}
itemTpl="<li><span style=&quot;background-color:{color};&quot; class=&quot;g2-tooltip-marker&quot;></span>{name}: {value}</li>" itemTpl='<li><span style="background-color:{color};" class="g2-tooltip-marker"></span>{name}: {value}</li>'
/> />
<Guide> <Guide>
<Html <Html
position={['50%', "50%"]} position={['50%', '50%']}
html={`<div style="color:#8c8c8c;font-size:14px;text-align: center;width: ${this.width}px;"><span style="color:#333;font-size:20px">${planCustomerNum}人</span><br>新增培训人数</div>`} html={`<div style="color:#8c8c8c;font-size:14px;text-align: center;width: ${this.width}px;"><span style="color:#333;font-size:20px">${planCustomerNum}人</span><br>新增培训人数</div>`}
alignX="middle" alignX='middle'
alignY="middle" alignY='middle'
/> />
</Guide> </Guide>
<Geom <Geom
type="intervalStack" type='intervalStack'
position="percent" position='percent'
color={['item', ['#FFBB54', '#2966FF']]} color={['item', ['#FFBB54', '#2966FF']]}
tooltip={[ tooltip={[
"item*percent", 'item*percent',
(item, percent) => { (item, percent) => {
percent = Math.round(percent * 100) + "%"; percent = Math.round(percent * 100) + '%';
return { return {
name: item, name: item,
value: percent, value: percent,
}; };
} },
]} ]}
style={{ style={{
lineWidth: 1, lineWidth: 1,
stroke: "#fff" stroke: '#fff',
}} }}></Geom>
>
</Geom>
</Chart> </Chart>
</div> </div>
} )}
</div> </div>
: <div className="circle-box"> </When>
<div className="big-circle"> <Otherwise>
<div className="small-circle"> <div className='circle-box'>
<div className="tip-box"> <div className='big-circle'>
<div className='small-circle'>
<div className='tip-box'>
<div style={{ color: '#333', fontSize: '20px', marginBottom: 4 }}>{planCustomerNum}</div> <div style={{ color: '#333', fontSize: '20px', marginBottom: 4 }}>{planCustomerNum}</div>
<div style={{ color: '#999' }}>新增培训人数</div> <div style={{ color: '#999' }}>新增培训人数</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
} </Otherwise>
<div className="circle-tip unfinished"> </Choose>
<div className="spot"></div>
<div className="number">{unfinishedNum}</div> <div className='circle-tip unfinished'>
<div className="word">未完成培训</div> <div className='spot'></div>
</div> <div className='number'>{unfinishedNum}</div>
<div className="circle-tip finished"> <div className='word'>未完成培训</div>
<div className="spot"></div> </div>
<div className="number">{completeNum}</div> <div className='circle-tip finished'>
<div className="word">完成培训</div> <div className='spot'></div>
</div> <div className='number'>{completeNum}</div>
</div> <div className='word'>完成培训</div>
</div> </div>
</div> </div>
<div className="study-chart"> </div>
<div className="study-title">学习人数与时长 </div>
<div className="study-select"> <div className='study-chart'>
<span className="select-word">{moment().subtract(studyTimeRange - 1, 'day').format('MM.DD')} ~ {moment().format('MM.DD')}</span> <div className='study-title'>
学习人数与时长
<div className='study-select'>
<span className='select-word'>
{moment()
.subtract(studyTimeRange - 1, 'day')
.format('MM.DD')}{' '}
~ {moment().format('MM.DD')}
</span>
<Select <Select
style={{ width: 88 }} style={{ width: 88 }}
value={studyTimeRange} value={studyTimeRange}
onChange={(value) => { onChange={(value) => {
this.setState({ studyTimeRange: value }, () => this.getStudyInfo()); this.setState({ studyTimeRange: value }, () => this.getStudyInfo());
}} }}>
> <Option value='7'>近7天</Option>
<Option value="7">近7天</Option> <Option value='15'>近15天</Option>
<Option value="15">近15天</Option> <Option value='30'>近30天</Option>
<Option value="30">近30天</Option>
</Select> </Select>
</div> </div>
</div> </div>
<div className="chart-tip"> <div className='chart-tip'>
<div>学习人数(人) <div>
<Tooltip title="参与任意课程进行学习的人数"> 学习人数(人)
<span className="iconfont icon">&#xe61d;</span> <Tooltip title='参与任意课程进行学习的人数'>
<span className='iconfont icon'>&#xe61d;</span>
</Tooltip> </Tooltip>
</div> </div>
<div>人均学习时长(分钟)</div> <div>人均学习时长(分钟)</div>
</div> </div>
<div id="chart-id"></div> <div id='chart-id'></div>
<div className="chart-bottom-tip"> <div className='chart-bottom-tip'>
<div className="tip-item" style={{ marginRight: 100 }}><span className="student-dot"></span>学习人数</div> <div className='tip-item' style={{ marginRight: 100 }}>
<div className="tip-item"><span className="time-dot"></span>人均学习时长</div> <span className='student-dot'></span>学习人数
</div>
<div className='tip-item'>
<span className='time-dot'></span>人均学习时长
</div>
</div> </div>
</div> </div>
</div> </div>
) );
} }
} }
......
...@@ -2,34 +2,34 @@ ...@@ -2,34 +2,34 @@
// padding: 0 16px 16px; // padding: 0 16px 16px;
min-width: 1100px; min-width: 1100px;
position: relative; position: relative;
z-index:3; z-index: 3;
.g2-tooltip-marker { .g2-tooltip-marker {
border-radius: 50% !important; border-radius: 50% !important;
} }
.home-title { .home-title {
color: #333; color: #333;
padding-left:28px; padding-left: 28px;
font-size:16px; font-size: 16px;
font-weight:bold; font-weight: bold;
position: relative; position: relative;
padding-top:16px; padding-top: 16px;
&::before{ &::before {
width:4px; width: 4px;
height:12px; height: 12px;
content:''; content: '';
background-image: linear-gradient(#2966FF 83.5%, #0ACCA4 16.5%); background-image: linear-gradient(#2966ff 83.5%, #0acca4 16.5%);
display:inline-block; display: inline-block;
position: absolute; position: absolute;
left:16px; left: 16px;
top:22px; top: 22px;
} }
} }
@font-face { @font-face {
font-family: 'number'; font-family: 'number';
src: url('https://image.xiaomaiketang.com/xm/n2sADd2jY6.TTF'); src: url('https://image.xiaomaiketang.com/xm/n2sADd2jY6.TTF');
} }
.data-wrap{ .data-wrap {
background: #FFF; background: #fff;
.data-box { .data-box {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
width: ~'calc(16.67% - 8px)'; width: ~'calc(16.67% - 8px)';
padding: 16px; padding: 16px;
&.course-data { &.course-data {
width: ~'calc(50% - 24px)'; width: ~'calc(33% - 24px)';
} }
.header { .header {
display: flex; display: flex;
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
font-size: 14px; font-size: 14px;
line-height: 18px; line-height: 18px;
color: #333; color: #333;
font-weight:500; font-weight: 500;
} }
} }
.data-number { .data-number {
...@@ -74,7 +74,7 @@ ...@@ -74,7 +74,7 @@
.iconfont { .iconfont {
font-size: 12px; font-size: 12px;
margin-right: 4px; margin-right: 4px;
color: #EC4B35; color: #ec4b35;
} }
.footer-number { .footer-number {
font-size: 12px; font-size: 12px;
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
} }
.course-box { .course-box {
border-radius: 4px; border-radius: 4px;
background: #FAFAFA; background: #fafafa;
height: 124px; height: 124px;
width: 66%; width: 66%;
position: absolute; position: absolute;
...@@ -114,7 +114,7 @@ ...@@ -114,7 +114,7 @@
.iconfont { .iconfont {
font-size: 12px; font-size: 12px;
margin-right: 4px; margin-right: 4px;
color: #EC4B35; color: #ec4b35;
} }
.add-number { .add-number {
font-size: 12px; font-size: 12px;
...@@ -126,9 +126,9 @@ ...@@ -126,9 +126,9 @@
} }
} }
} }
.study-wrap{ .study-wrap {
background: #FFF; background: #fff;
margin-top:16px; margin-top: 16px;
.study-box { .study-box {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
...@@ -148,7 +148,7 @@ ...@@ -148,7 +148,7 @@
margin-bottom: 12px; margin-bottom: 12px;
.iconfont { .iconfont {
font-size: 14px; font-size: 14px;
color: #BFBFBF; color: #bfbfbf;
margin-left: 4px; margin-left: 4px;
} }
.tip { .tip {
...@@ -169,13 +169,13 @@ ...@@ -169,13 +169,13 @@
color: #666; color: #666;
cursor: pointer; cursor: pointer;
&.selected { &.selected {
color: #2966FF; color: #2966ff;
&::after { &::after {
position: absolute; position: absolute;
width: 24px; width: 24px;
height: 2px; height: 2px;
content: ''; content: '';
background: #2966FF; background: #2966ff;
border-radius: 1px; border-radius: 1px;
left: 9px; left: 9px;
bottom: -4px; bottom: -4px;
...@@ -196,7 +196,7 @@ ...@@ -196,7 +196,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
&.odd { &.odd {
background: #FAFAFA; background: #fafafa;
} }
.table-image { .table-image {
width: 24px; width: 24px;
...@@ -257,7 +257,7 @@ ...@@ -257,7 +257,7 @@
width: 204px; width: 204px;
height: 204px; height: 204px;
border-radius: 102px; border-radius: 102px;
background: #F1F3F6; background: #f1f3f6;
margin-top: -20px; margin-top: -20px;
.small-circle { .small-circle {
display: flex; display: flex;
...@@ -280,13 +280,13 @@ ...@@ -280,13 +280,13 @@
&.unfinished { &.unfinished {
top: 152px; top: 152px;
.spot { .spot {
background: #2966FF; background: #2966ff;
} }
} }
&.finished { &.finished {
top: 232px; top: 232px;
.spot { .spot {
background: #FFBB54; background: #ffbb54;
} }
} }
.spot { .spot {
...@@ -352,14 +352,14 @@ ...@@ -352,14 +352,14 @@
align-items: center; align-items: center;
color: #666; color: #666;
.student-dot { .student-dot {
background: #2966FF; background: #2966ff;
height: 8px; height: 8px;
width: 8px; width: 8px;
border-radius: 50%; border-radius: 50%;
margin-right: 8px; margin-right: 8px;
} }
.time-dot { .time-dot {
background: #FEB613; background: #feb613;
height: 8px; height: 8px;
width: 8px; width: 8px;
border-radius: 50%; border-radius: 50%;
...@@ -382,7 +382,8 @@ ...@@ -382,7 +382,8 @@
font-size: 14px; font-size: 14px;
} }
.g2-tooltip-list { .g2-tooltip-list {
li,span { li,
span {
display: flex; display: flex;
align-items: center; align-items: center;
font-size: 14px; font-size: 14px;
......
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