Commit 0d3ce089 by yuananting

feat:单个学员学习数据'全部'页面

parent a4d52d69
@font-face { @font-face {
font-family: 'iconfont'; /* Project id 2223403 */ font-family: 'iconfont'; /* Project id 2223403 */
src: url('//at.alicdn.com/t/font_2223403_sv3ehwf2rr.woff2?t=1627903518018') format('woff2'), src: url('//at.alicdn.com/t/font_2223403_obblua8v3q.woff2?t=1628151518578') format('woff2'),
url('//at.alicdn.com/t/font_2223403_sv3ehwf2rr.woff?t=1627903518018') format('woff'), url('//at.alicdn.com/t/font_2223403_obblua8v3q.woff?t=1628151518578') format('woff'),
url('//at.alicdn.com/t/font_2223403_sv3ehwf2rr.ttf?t=1627903518018') format('truetype'); url('//at.alicdn.com/t/font_2223403_obblua8v3q.ttf?t=1628151518578') format('truetype');
} }
.iconfont { .iconfont {
font-family: 'iconfont' !important; font-family: 'iconfont' !important;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-08-24 12:20:57 * @Date: 2020-08-24 12:20:57
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-08-03 14:08:12 * @LastEditTime: 2021-08-05 16:19:02
* @Description: * @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
--> -->
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
--> -->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="stylesheet" href="//at.alicdn.com/t/font_2223403_sv3ehwf2rr.css" /> <link rel="stylesheet" href="//at.alicdn.com/t/font_2223403_obblua8v3q.css" />
<!-- <!--
Notice the use of %PUBLIC_URL% in the tags above. Notice the use of %PUBLIC_URL% in the tags above.
......
/*
* @Author: yuananting
* @Date: 2021-08-05 10:55:49
* @LastEditors: yuananting
* @LastEditTime: 2021-08-05 16:10:51
* @Description: 个人学习详情
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React from 'react';
import { Progress, Space, Tabs } from 'antd';
import Breadcrumbs from '@/components/Breadcrumbs';
import WholeData from './components/WholeData';
import ENUM from '../enum';
import './UserLearningData.less';
const { TabPane } = Tabs;
function UserLearningData(props) {
const tabList = [
{
name: '全部',
key: 'whole',
compoment: WholeData,
},
{
name: '考试',
key: 'exam',
compoment: WholeData, // todo
},
];
return (
<div className='page user-learning-data'>
<Breadcrumbs
navList='学员学习数据'
goBack={() => {
props.history.goBack();
}}
/>
<div className='header'>
<div className='train-title'>培训任务全新版本上线啦~🐹🐹</div>
<div className='data-info'>
<div className='user-name'>学员:{'文小小'}</div>
<div className='complete-progress'>
任务完成率:
<div style={{ width: 120 }}>
<Progress size={120} strokeColor='#2966FF' trailColor='#EAEAEA' percent={30} size='small' />
</div>
</div>
<Space size={24}>
<div>
<img src={ENUM.LearningContentIcon['COURSE']} />
课程:{'15/98'}
</div>
<div>
<img src={ENUM.LearningContentIcon['EXAM']} />
考试:{'15/98'}
</div>
</Space>
</div>
</div>
<div className='gap-line'></div>
<div className='content'>
<Tabs defaultActiveKey={'whole'} onChange={() => {}}>
{tabList.map((item) => {
return (
<TabPane tab={item.name} key={item.key}>
{<item.compoment />}
</TabPane>
);
})}
</Tabs>
</div>
</div>
);
}
export default UserLearningData;
.user-learning-data {
.header {
padding: 16px 28px;
.train-title {
font-size: 18px;
font-weight: 500;
color: #333333;
line-height: 25px;
position: relative;
&::before {
content: '';
position: absolute;
left: -8px;
top: 50%;
transform: translateY(-50%);
width: 4px;
height: 10px;
background: #2966ff;
}
&::after {
content: '';
position: absolute;
left: -8px;
top: 75%;
transform: translateY(-50%);
width: 4px;
height: 2px;
background: #0acca4;
}
}
.data-info {
display: flex;
color: #666666;
margin-top: 16px;
margin-bottom: 8px;
.user-name {
margin-right: 32px;
}
.complete-progress {
display: inline-flex;
margin-right: 24px;
}
img {
width: 20px;
height: 20px;
margin-right: 8px;
}
}
}
.gap-line {
height: 10px;
background-color: #f0f2f5;
}
.content {
.ant-tabs-tab {
padding: 20px 20px 14px !important;
// margin-left: 18px;
}
}
}
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { withRouter } from "react-router-dom"; import { Route, withRouter } from "react-router-dom";
import { Row, Input, Select, Tooltip, Col } from 'antd'; import { Row, Input, Select, Tooltip, Col } from 'antd';
import RangePicker from '@/modules/common/DateRangePicker'; import RangePicker from '@/modules/common/DateRangePicker';
import { PageControl, XMTable } from '@/components'; import { PageControl, XMTable } from '@/components';
import ENUM from '../../enum'; import ENUM from '../../enum';
import moment from 'moment'; import moment from 'moment';
import UserLearningData from '../UserLearningData';
const { Search } = Input; const { Search } = Input;
const { Option } = Select; const { Option } = Select;
declare var formatDate: any; declare var formatDate: any;
function StudyTable(props: any) { function StudyTable(props: any) {
const [query, setQuery] = useState<any>({ current: 1, size: 10 }); const [query, setQuery] = useState<any>({ current: 1, size: 10 });
const [list,setList] = useState<any[]>([]); const [list,setList] = useState<any[]>([
{
storeCustomerName: 'yat',
learnState2: '技术部',
learnState1: '前端',
learnState: 'UN_PLAY',
}
]);
const [total,setTotal] = useState<any>(0); const [total,setTotal] = useState<any>(0);
const columns = [ const columns = [
...@@ -50,7 +58,7 @@ function StudyTable(props: any) { ...@@ -50,7 +58,7 @@ function StudyTable(props: any) {
dataIndex: 'learnState', dataIndex: 'learnState',
render: (val: any, record: any) => { render: (val: any, record: any) => {
return <div>{ENUM.LearnState[val].text}</div>; return <div></div>;
}, },
}, },
...@@ -83,7 +91,7 @@ function StudyTable(props: any) { ...@@ -83,7 +91,7 @@ function StudyTable(props: any) {
render: (val: any, record: any) => { render: (val: any, record: any) => {
return ( return (
<div className='operate-area'> <div className='operate-area'>
<span className='operate-item' onClick={() => { }}> <span className='operate-item' onClick={() => {console.log(props.match); props.history.push(`${props.match.path}/user-learning-data`);}}>
查看数据 查看数据
</span> </span>
...@@ -199,7 +207,7 @@ function StudyTable(props: any) { ...@@ -199,7 +207,7 @@ function StudyTable(props: any) {
</div> </div>
)} )}
</div> </div>
<Route path={`${props.match.url}/user-learning-data`} component={UserLearningData} />
</div> </div>
} }
......
/*
* @Author: yuananting
* @Date: 2021-08-05 11:26:25
* @LastEditors: yuananting
* @LastEditTime: 2021-08-05 16:20:07
* @Description: 个人学习详情-全部tab页
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React from 'react';
import { Collapse, Progress } from 'antd';
import './WholeData.less';
import ENUM from '../../enum';
const { Panel } = Collapse;
function WholeData() {
const SortConvert = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'];
const stageList = [
{
stageName: '新手阶段',
finishedCount: 1,
contentSum: 4,
contentList: [
{
contentType: 'LIVE',
contentName: '入门培训任务',
courseState: 'UN_START',
percent: 75,
},
{
contentType: 'LIVE',
contentName: '普通培训任务',
courseState: 'FINISH',
percent: 0,
},
{
contentType: 'VOICE',
contentName: '困难培训任务',
courseChapterNum: 4,
percent: 100,
},
{
contentType: 'PICTURE',
contentName: '困难培训任务',
percent: 23,
},
],
},
{
stageName: '老手阶段',
finishedCount: 3,
contentSum: 5,
contentList: [
{
contentType: 'LIVE',
contentName: '入门培训任务',
courseState: 'UN_START',
percent: 15,
},
{
contentType: 'EXAM',
contentName: '入门考试',
percent: 70,
},
{
contentType: 'EXAM',
contentName: '入门二段考试',
percent: 100,
},
],
},
];
const courseStateShow = {
UN_START: {
title: '待开播',
},
STARTING: {
title: '直播中',
},
FINISH: {
title: '回放',
},
EXPIRED: {
title: '未成功开课',
},
};
// 渲染阶段信息
function renderStageInfo(item, index) {
return (
<div className='stage-info__item'>
<span className='stage-name'>
{SortConvert[index]}{item.stageName}
</span>
<span className='extra-info'>
{item.finishedCount}/{item.contentSum}
</span>
</div>
);
}
// 渲染学习内容信息
function renderContentInfo(contentItem, contentIndex, index) {
const { contentName, contentType, courseChapterNum, courseState, percent } = contentItem;
return (
<div className='content-info__item'>
<div className='basic-info'>
<img src={ENUM.LearningContentIcon[contentType]} />
<span className='content-name'>
{contentIndex + 1}.{index + 1} {contentName}
</span>
{contentType === 'LIVE' && <span className='extra-info'>{courseStateShow[courseState].title}</span>}
{contentType === 'VOICE' && <span className='extra-info'>(共{courseChapterNum || 1}小节)</span>}
</div>
<div className='percent-info'>
{percent === 100 ? (
<span className='icon iconfont'>&#xe621;</span>
) : (
<Progress
width={20}
strokeWidth={12}
type='circle'
trailColor='#EAEAEA'
strokeColor={{
'0%': '#38B7F3',
'100%': '#1A80E2',
}}
percent={percent}
/>
)}
<span className='text'>{percent === 100 ? '已完成' : `${percent}%`}</span>
</div>
</div>
);
}
return (
<div className='whole-data-container'>
<Collapse ghost>
{stageList.map((item, index) => {
return (
<Panel header={renderStageInfo(item, index)} key={index}>
{item.contentList.map((contentItem, contentIndex) => {
return renderContentInfo(contentItem, contentIndex, index);
})}
</Panel>
);
})}
</Collapse>
</div>
);
}
export default WholeData;
.whole-data-container {
.ant-collapse-header {
padding: 15px 16px !important;
background-color: #f7f8f9;
}
.stage-info {
&__item {
width: calc(100% - 24px);
display: inline-flex;
align-items: center;
line-height: 20px;
.stage-name {
color: #333333;
}
.extra-info {
margin-left: 8px;
color: #666666;
}
}
}
.content-info {
&__item {
padding: 14px 16px;
margin-left: 40px;
border-bottom: 1px dotted #e8e8e8;
vertical-align: middle;
display: flex;
justify-content: space-between;
* {
vertical-align: middle;
}
.basic-info {
.content-name {
margin-left: 12px;
color: #333333;
}
.extra-info {
margin-left: 8px;
color: #999999;
}
img {
width: 20px;
height: 20px;
}
}
.percent-info {
width: 70px;
.ant-progress-text {
display: none;
}
.icon {
color: #2966ff;
font-size: 20px;
}
.text {
margin-left: 6px;
color: #666666;
}
}
}
}
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-07-28 11:25:58 * @Date: 2021-07-28 11:25:58
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-07-30 11:58:13 * @LastEditTime: 2021-08-05 16:33:23
* @Description: 任务中心-培训任务 * @Description: 任务中心-培训任务
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -53,7 +53,7 @@ function TrainTaskPage(props) { ...@@ -53,7 +53,7 @@ function TrainTaskPage(props) {
<TrainFilter onChange={queryChange} /> <TrainFilter onChange={queryChange} />
<TrainList trainListData={trainListData} query={query} totalCount={totalCount} onChange={queryChange} /> <TrainList trainListData={trainListData} query={query} totalCount={totalCount} onChange={queryChange} />
</div> </div>
<Route path={`${match.url}/data/:planId`} component={DataCenter} /> <Route path={`${match.url}/data`} component={DataCenter} />
</div> </div>
); );
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-07-30 16:33:58 * @Date: 2021-07-30 16:33:58
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-08-04 19:27:08 * @LastEditTime: 2021-08-05 14:21:19
* @Description: 任务中心-培训任务-新建-培训内容 * @Description: 任务中心-培训任务-新建-培训内容
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
...@@ -44,18 +44,7 @@ const courseStateShow = { ...@@ -44,18 +44,7 @@ const courseStateShow = {
}, },
}; };
const SortConvert = { const SortConvert = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'];
1: '一',
2: '二',
3: '三',
4: '四',
5: '五',
6: '六',
7: '七',
8: '八',
9: '九',
10: '十',
};
// const id = window.getParameterByName('id'); // const id = window.getParameterByName('id');
// const type = window.getParameterByName('type'); // const type = window.getParameterByName('type');
...@@ -286,7 +275,7 @@ class TrainContent extends Component { ...@@ -286,7 +275,7 @@ class TrainContent extends Component {
return ( return (
<div className='sort-stage-item'> <div className='sort-stage-item'>
<div className='item-info'> <div className='item-info'>
<span className='info-number'>{SortConvert[index + 1]}</span> <span className='info-number'>{SortConvert[index]}</span>
<Choose> <Choose>
<When condition={item.type === 'input'}> <When condition={item.type === 'input'}>
<Form> <Form>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-07-28 14:56:52 * @Date: 2021-07-28 14:56:52
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-08-02 15:45:37 * @LastEditTime: 2021-08-05 16:33:02
* @Description: 描述一下咯 * @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -162,7 +162,7 @@ function TrainList(props) { ...@@ -162,7 +162,7 @@ function TrainList(props) {
return ( return (
<div className='operate'> <div className='operate'>
<div className='operate__item' onClick={() => { <div className='operate__item' onClick={() => {
props.history.push(`${match.path}/data/${record.planId}`) props.history.push(`${match.path}/data?planId=${record.planId}`)
}}> }}>
数据 数据
</div> </div>
......
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