Commit 9f343476 by guomingpang

Merge branch 'dev' of…

Merge branch 'dev' of ssh://xmgit.ixm5.cn:10022/xiaomai-cloud-class/xiaomai-cloud-class-web into dev
parents 04a98954 3f74ea5d
@font-face { @font-face {
font-family: 'iconfont'; /* Project id 2223403 */ font-family: 'iconfont'; /* Project id 2223403 */
src: url('//at.alicdn.com/t/font_2223403_2digpsfgq8l.woff2?t=1628853864698') format('woff2'), src: url('//at.alicdn.com/t/font_2223403_0b87tvtysw45.woff2?t=1629025918841') format('woff2'),
url('//at.alicdn.com/t/font_2223403_2digpsfgq8l.woff?t=1628853864698') format('woff'), url('//at.alicdn.com/t/font_2223403_0b87tvtysw45.woff?t=1629025918841') format('woff'),
url('//at.alicdn.com/t/font_2223403_2digpsfgq8l.ttf?t=1628853864698') format('truetype'); url('//at.alicdn.com/t/font_2223403_0b87tvtysw45.ttf?t=1629025918841') format('truetype');
} }
.iconfont { .iconfont {
font-family: 'iconfont' !important; font-family: 'iconfont' !important;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-08-06 17:35:35 * @Date: 2021-08-06 17:35:35
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-08-14 09:51:12 * @LastEditTime: 2021-08-16 20:52:16
* @Description: 任务中心接口 * @Description: 任务中心接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
...@@ -52,3 +52,15 @@ export function updateTrainingTaskAssign(params: object) { ...@@ -52,3 +52,15 @@ export function updateTrainingTaskAssign(params: object) {
export function getTrainingCourseAutoCancel(params: object) { export function getTrainingCourseAutoCancel(params: object) {
return Service.Hades('public/hades/getTrainingCourseAutoCancel', params); return Service.Hades('public/hades/getTrainingCourseAutoCancel', params);
} }
export function delTaskCancelContent(params: object) {
return Service.Hades('public/hades/delTaskCancelContent', params);
}
export function getStoreTaskAll(params: object) {
return Service.Hades('public/hades/getStoreTaskAll', params);
}
export function relatedCourseToTask(params: object) {
return Service.Hades('public/hades/relatedCourseToTask', params);
}
/* /*
* @Author: 陈剑宇 * @Author: 陈剑宇
* @Date: 2020-05-07 14:43:01 * @Date: 2020-05-07 14:43:01
* @LastEditTime: 2021-08-09 15:52:49 * @LastEditTime: 2021-08-16 16:39:13
* @LastEditors: wufan * @LastEditors: yuananting
* @Description: * @Description:
* @FilePath: /wheat-web-demo/src/domains/basic-domain/constants.ts * @FilePath: /wheat-web-demo/src/domains/basic-domain/constants.ts
*/ */
import { MapInterface } from '@/domains/basic-domain/interface' import { MapInterface } from '@/domains/basic-domain/interface';
import { path, live } from '@/domains/brand/constants' import { path, live } from '@/domains/brand/constants';
// 默认是 dev 环境 // 默认是 dev 环境
const ENV: string = process.env.DEPLOY_ENV || 'dev' const ENV: string = process.env.DEPLOY_ENV || 'dev';
console.log('process.env.DEPLOY_ENV', process.env, ENV, 'hjkkkk') console.log('process.env.DEPLOY_ENV', process.env, ENV, 'hjkkkk');
console.log('process.env.DEPLOY_ENV', process);
const BASIC_HOST_MAP: MapInterface = { const BASIC_HOST_MAP: MapInterface = {
dev: 'https://dev-heimdall.xiaomai5.com/', dev: 'https://dev-heimdall.xiaomai5.com/',
dev1: 'https://dev-heimdall.xiaomai5.com/', dev1: 'https://dev-heimdall.xiaomai5.com/',
rc: 'https://rc-heimdall.xiaomai5.com/', rc: 'https://rc-heimdall.xiaomai5.com/',
gray: 'https://gray-heimdall.xiaomai5.com/', gray: 'https://gray-heimdall.xiaomai5.com/',
prod: 'https://gateway.xiaomai5.com/', prod: 'https://gateway.xiaomai5.com/',
} };
const PATH_MAP: MapInterface = { const PATH_MAP: MapInterface = {
dev: 'https://dev.xiaomai5.com/xiaomai-cloud-class-web/h5.html', dev: 'https://dev.xiaomai5.com/xiaomai-cloud-class-web/h5.html',
dev1: 'https://dev.xiaomai5.com/dev1/xiaomai-cloud-class-web/h5.html', dev1: 'https://dev.xiaomai5.com/dev1/xiaomai-cloud-class-web/h5.html',
rc: 'https://rc.xiaomai5.com/xiaomai-cloud-class-web/h5.html', rc: 'https://rc.xiaomai5.com/xiaomai-cloud-class-web/h5.html',
gray: path + '/gray/h5.html', gray: path + '/gray/h5.html',
prod: path + '/h5.html', prod: path + '/h5.html',
} };
export const YZ_APPId = "yozoqvpO2Hvz8346"; export const YZ_APPId = 'yozoqvpO2Hvz8346';
export const YZ_PREVIEW_URL: string = 'http://eic.yozocloud.cn/api/view/file' export const YZ_PREVIEW_URL: string = 'http://eic.yozocloud.cn/api/view/file';
export const OFFICE_PREVIEW_URL: string = 'https://view.officeapps.live.com/op/view.aspx' export const OFFICE_PREVIEW_URL: string = 'https://view.officeapps.live.com/op/view.aspx';
// axios headers config // axios headers config
export const TIME_OUT: number = 20000 export const TIME_OUT: number = 20000;
export const USER_TYPE: string = 'B' export const USER_TYPE: string = 'B';
export const PROJECT = 'xmzj-web-b' export const PROJECT = 'xmzj-web-b';
export const VERSION = '5.4.8' export const VERSION = '5.4.8';
export const PREFIX = 'cloud-class' export const PREFIX = 'cloud-class';
export const USER_PREFIX = 'store-live' export const USER_PREFIX = 'store-live';
// host // host
export const BASIC_HOST: string = BASIC_HOST_MAP[ENV] export const BASIC_HOST: string = BASIC_HOST_MAP[ENV];
export const PATH: string = PATH_MAP[ENV] export const PATH: string = PATH_MAP[ENV];
/* /*
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-08-20 09:21:40 * @Date: 2020-08-20 09:21:40
* @LastEditors: Please set LastEditors * @LastEditors: yuananting
* @LastEditTime: 2021-08-11 22:50:48 * @LastEditTime: 2021-08-16 16:38:55
* @Description: * @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
*/ */
import { MapInterface } from '@/domains/basic-domain/interface' import { MapInterface } from '@/domains/basic-domain/interface';
import { path, live } from '@/domains/brand/constants' import { path, live } from '@/domains/brand/constants';
const ENV: string = process.env.DEPLOY_ENV || 'dev'; const ENV: string = process.env.DEPLOY_ENV || 'dev';
const appIdMap: MapInterface = { const appIdMap: MapInterface = {
dev: 'wx3ea60e78ddfa277e', dev: 'wx3ea60e78ddfa277e',
dev1: 'wx3ea60e78ddfa277e', dev1: 'wx3ea60e78ddfa277e',
rc: 'wx5c5a1fb71ecab7bc', rc: 'wx5c5a1fb71ecab7bc',
gray: "wx3dda02036493ada6", // 小麦校讯通 gray: 'wx3dda02036493ada6', // 小麦校讯通
prod: 'wx3dda02036493ada6', prod: 'wx3dda02036493ada6',
} };
const shareUrlMap: MapInterface = { const shareUrlMap: MapInterface = {
'dev': 'https://dev.xiaomai5.com/share/show?appid=', dev: 'https://dev.xiaomai5.com/share/show?appid=',
'dev1': 'https://dev.xiaomai5.com/share/show?appid=', dev1: 'https://dev.xiaomai5.com/share/show?appid=',
'rc': 'https://rc.xiaomai5.com/share/show?appid=', rc: 'https://rc.xiaomai5.com/share/show?appid=',
'prod': 'https://prod.xiaomai5.com/share/show?appid=', prod: 'https://prod.xiaomai5.com/share/show?appid=',
'gray': 'https://prod.xiaomai5.com/share/show?appid=', gray: 'https://prod.xiaomai5.com/share/show?appid=',
} };
const LIVE_SHARE_MAP: MapInterface = { const LIVE_SHARE_MAP: MapInterface = {
dev: 'https://dev.xiaomai5.com/store-live/index.html#/', dev: 'https://dev.xiaomai5.com/store-live/index.html#/',
dev1: 'https://dev.xiaomai5.com/dev1/store-live/index.html#/', dev1: 'https://dev.xiaomai5.com/dev1/store-live/index.html#/',
rc: 'https://rc.xiaomai5.com/store-live/index.html#/', rc: 'https://rc.xiaomai5.com/store-live/index.html#/',
gray: live+'/gray/index.html#/', gray: live + '/gray/index.html#/',
prod: live+'/index.html#/', prod: live + '/index.html#/',
} };
export const appId: string = appIdMap[ENV]; export const appId: string = appIdMap[ENV];
export const shareUrl: string = shareUrlMap[ENV]; export const shareUrl: string = shareUrlMap[ENV];
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-08-06 17:32:41 * @Date: 2021-08-06 17:32:41
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-08-14 09:52:00 * @LastEditTime: 2021-08-16 20:56:36
* @Description: 任务中心-培训任务接口 * @Description: 任务中心-培训任务接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
...@@ -19,6 +19,9 @@ import { ...@@ -19,6 +19,9 @@ import {
getTaskCustomerDetail, getTaskCustomerDetail,
updateTrainingTaskAssign, updateTrainingTaskAssign,
getTrainingCourseAutoCancel, getTrainingCourseAutoCancel,
delTaskCancelContent,
getStoreTaskAll,
relatedCourseToTask,
} from '@/data-source/taskCenter/request-apis'; } from '@/data-source/taskCenter/request-apis';
export default class TaskCenterService { export default class TaskCenterService {
...@@ -76,4 +79,19 @@ export default class TaskCenterService { ...@@ -76,4 +79,19 @@ export default class TaskCenterService {
static getTrainingCourseAutoCancel(params: any) { static getTrainingCourseAutoCancel(params: any) {
return getTrainingCourseAutoCancel(params); return getTrainingCourseAutoCancel(params);
} }
// 删除失效课程
static delTaskCancelContent(params: any) {
return delTaskCancelContent(params);
}
// 获取培训任务学习基本信息
static getStoreTaskAll(params: any) {
return getStoreTaskAll(params);
}
// 课程关联培训任务
static relatedCourseToTask(params: any) {
return relatedCourseToTask(params);
}
} }
...@@ -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: wufan * @LastEditors: wufan
* @LastEditTime: 2021-08-13 19:25:12 * @LastEditTime: 2021-08-15 19:12:48
* @Description: * @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
--> -->
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,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_2digpsfgq8l.css"> <link rel="stylesheet" href="//at.alicdn.com/t/font_2223403_0b87tvtysw45.css">
<!-- <!--
Notice the use of %PUBLIC_URL% in the tags above. Notice the use of %PUBLIC_URL% in the tags above.
......
...@@ -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: wufan * @LastEditors: wufan
* @LastEditTime: 2021-08-13 19:25:18 * @LastEditTime: 2021-08-15 19:12:55
* @Description: * @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
--> -->
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,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_2digpsfgq8l.css" /> <link rel="stylesheet" href="//at.alicdn.com/t/font_2223403_0b87tvtysw45.css" />
<!-- <!--
Notice the use of %PUBLIC_URL% in the tags above. Notice the use of %PUBLIC_URL% in the tags above.
......
...@@ -28,7 +28,7 @@ import Bus from '@/core/bus'; ...@@ -28,7 +28,7 @@ import Bus from '@/core/bus';
import './LiveCourseList.less'; import './LiveCourseList.less';
import { brandLiveName } from '@/domains/brand/constants'; import { brandLiveName } from '@/domains/brand/constants';
const { confirm } = Modal const { confirm } = Modal;
const courseStateShow = { const courseStateShow = {
UN_START: { UN_START: {
code: 1, code: 1,
...@@ -50,20 +50,20 @@ const courseStateShow = { ...@@ -50,20 +50,20 @@ const courseStateShow = {
title: '未成功开课', title: '未成功开课',
color: '#999', color: '#999',
}, },
} };
class LiveCourseList extends React.Component { class LiveCourseList extends React.Component {
constructor(props) { constructor(props) {
super(props) super(props);
this.state = { this.state = {
columns: [], columns: [],
openDownloadModal: false, openDownloadModal: false,
url: '', url: '',
RelatedPlanModalVisible: false, RelatedPlanModalVisible: false,
selectPlanList: {}, selectPlanList: {},
} };
} }
componentWillMount() { componentWillMount() {
this.parseColumns() this.parseColumns();
} }
componentDidMount() { componentDidMount() {
this.getDownloadVersion() this.getDownloadVersion()
...@@ -73,13 +73,12 @@ class LiveCourseList extends React.Component { ...@@ -73,13 +73,12 @@ class LiveCourseList extends React.Component {
} }
// 显示分享弹窗 // 显示分享弹窗
handleShowShareModal = (item, needStr = false) => { handleShowShareModal = (item, needStr = false) => {
const { liveCourseId } = item const { liveCourseId } = item;
const htmlUrl = `${LIVE_SHARE}live_detail/${liveCourseId}?id=${User.getStoreId()}` const htmlUrl = `${LIVE_SHARE}live_detail/${liveCourseId}?id=${User.getStoreId()}`;
const longUrl = htmlUrl const longUrl = htmlUrl;
console.log('htmlUrl', htmlUrl, longUrl)
const shareData = { ...item, longUrl } const shareData = { ...item, longUrl };
const shareLiveModal = ( const shareLiveModal = (
<ShareLiveModal <ShareLiveModal
needStr={needStr} needStr={needStr}
...@@ -89,33 +88,33 @@ class LiveCourseList extends React.Component { ...@@ -89,33 +88,33 @@ class LiveCourseList extends React.Component {
close={() => { close={() => {
this.setState({ this.setState({
shareLiveModal: null, shareLiveModal: null,
}) });
localStorage.setItem('largeLiveCourseItem', '') localStorage.setItem('largeLiveCourseItem', '');
}} }}
/> />
) );
this.setState({ shareLiveModal }) this.setState({ shareLiveModal });
} };
//改变上架状态 //改变上架状态
changeShelfState = (index, item, checked) => { changeShelfState = (index, item, checked) => {
let _shelfState = checked ? 'YES' : 'NO' let _shelfState = checked ? 'YES' : 'NO';
const params = { const params = {
liveCourseId: item.liveCourseId, liveCourseId: item.liveCourseId,
shelfState: _shelfState, shelfState: _shelfState,
} };
CourseService.turnOnOrOffLiveCloudCourse(params).then((res) => { CourseService.turnOnOrOffLiveCloudCourse(params).then((res) => {
if (res.success) { if (res.success) {
if (_shelfState === 'YES') { if (_shelfState === 'YES') {
message.success('已开启展示') message.success('已开启展示');
} else { } else {
message.success('已取消展示') message.success('已取消展示');
} }
this.props.changeShelfState(index, _shelfState) this.props.changeShelfState(index, _shelfState);
} }
}) });
} };
// 前往上课数据页面 // 前往上课数据页面
handleLinkToClassData = (item) => { handleLinkToClassData = (item) => {
...@@ -126,8 +125,8 @@ class LiveCourseList extends React.Component { ...@@ -126,8 +125,8 @@ class LiveCourseList extends React.Component {
}); });
}; };
parseColumns = () => { parseColumns = () => {
let columns let columns;
const userRole = User.getUserRole() const userRole = User.getUserRole();
if (userRole !== 'CloudLecturer') { if (userRole !== 'CloudLecturer') {
columns = [ columns = [
{ {
...@@ -137,15 +136,15 @@ class LiveCourseList extends React.Component { ...@@ -137,15 +136,15 @@ class LiveCourseList extends React.Component {
fixed: 'left', fixed: 'left',
dataIndex: 'courseName', dataIndex: 'courseName',
render: (val, record) => { render: (val, record) => {
let hasCover = false let hasCover = false;
return ( return (
<div className='record__item'> <div className='record__item'>
{record.courseMediaVOS.map((item, index) => { {record.courseMediaVOS.map((item, index) => {
if (item.contentType === 'COVER') { if (item.contentType === 'COVER') {
hasCover = true hasCover = true;
return <img key={item.mediaContent + index} className='course-cover' src={item.mediaUrl} alt='' /> return <img key={item.mediaContent + index} className='course-cover' src={item.mediaUrl} alt='' />;
} else { } else {
return null return null;
} }
})} })}
{!hasCover && <img className='course-cover' src={'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'} alt='' />} {!hasCover && <img className='course-cover' src={'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'} alt='' />}
...@@ -191,7 +190,7 @@ class LiveCourseList extends React.Component { ...@@ -191,7 +190,7 @@ class LiveCourseList extends React.Component {
<span key={item.adminId + index}> <span key={item.adminId + index}>
{item.adminName} {index < record.admins.length - 1 && <span></span>}{' '} {item.adminName} {index < record.admins.length - 1 && <span></span>}{' '}
</span> </span>
) );
})} })}
</span> </span>
</Tooltip> </Tooltip>
...@@ -204,7 +203,7 @@ class LiveCourseList extends React.Component { ...@@ -204,7 +203,7 @@ class LiveCourseList extends React.Component {
<span> <span>
{item.adminName} {index < record.admins.length - 1 && <span></span>}{' '} {item.adminName} {index < record.admins.length - 1 && <span></span>}{' '}
</span> </span>
) );
})} })}
</span> </span>
</Otherwise> </Otherwise>
...@@ -213,7 +212,7 @@ class LiveCourseList extends React.Component { ...@@ -213,7 +212,7 @@ class LiveCourseList extends React.Component {
</div> </div>
</div> </div>
</div> </div>
) );
}, },
}, },
{ {
...@@ -244,7 +243,7 @@ class LiveCourseList extends React.Component { ...@@ -244,7 +243,7 @@ class LiveCourseList extends React.Component {
key: 'couseCatalog', key: 'couseCatalog',
dataIndex: 'couseCatalog', dataIndex: 'couseCatalog',
render: (val, item) => { render: (val, item) => {
return <div className='categoryName'>{item.categorySonName}</div> return <div className='categoryName'>{item.categorySonName}</div>;
}, },
}, },
{ {
...@@ -260,11 +259,11 @@ class LiveCourseList extends React.Component { ...@@ -260,11 +259,11 @@ class LiveCourseList extends React.Component {
this.setState({ this.setState({
editData: item, editData: item,
openCoursewareModal: true, openCoursewareModal: true,
}) });
}}> }}>
{item.courseDocumentCount} {item.courseDocumentCount}
</span> </span>
) );
}, },
}, },
{ {
...@@ -277,11 +276,11 @@ class LiveCourseList extends React.Component { ...@@ -277,11 +276,11 @@ class LiveCourseList extends React.Component {
<span <span
className='iconfont icon quota-icon' className='iconfont icon quota-icon'
onClick={() => { onClick={() => {
this.handleLinkToClassData(item) this.handleLinkToClassData(item);
}}> }}>
&#xe7d6; &#xe7d6;
</span> </span>
) );
}, },
}, },
{ {
...@@ -313,7 +312,7 @@ class LiveCourseList extends React.Component { ...@@ -313,7 +312,7 @@ class LiveCourseList extends React.Component {
defaultChecked={item.shelfState === 'YES' ? true : false} defaultChecked={item.shelfState === 'YES' ? true : false}
onChange={(checked) => this.changeShelfState(index, item, checked)} onChange={(checked) => this.changeShelfState(index, item, checked)}
/> />
) );
}, },
}, },
{ {
...@@ -324,7 +323,7 @@ class LiveCourseList extends React.Component { ...@@ -324,7 +323,7 @@ class LiveCourseList extends React.Component {
sorter: true, sorter: true,
render: (val, item) => { render: (val, item) => {
// -29000:与后端约定 在初始化学院时,创建时间(标志位-29000)默认展示为'-' // -29000:与后端约定 在初始化学院时,创建时间(标志位-29000)默认展示为'-'
return <span style={{ whiteSpace: 'nowrap' }}>{val === -29000 ? '-' : window.formatDate('YYYY-MM-DD H:i', val)}</span> return <span style={{ whiteSpace: 'nowrap' }}>{val === -29000 ? '-' : window.formatDate('YYYY-MM-DD H:i', val)}</span>;
}, },
}, },
{ {
...@@ -343,7 +342,7 @@ class LiveCourseList extends React.Component { ...@@ -343,7 +342,7 @@ class LiveCourseList extends React.Component {
<span key={index}> <span key={index}>
{item.planName} {index < record.relatedPlanList.length - 1 && <span></span>}{' '} {item.planName} {index < record.relatedPlanList.length - 1 && <span></span>}{' '}
</span> </span>
) );
})} })}
</Tooltip> </Tooltip>
</When> </When>
...@@ -352,7 +351,7 @@ class LiveCourseList extends React.Component { ...@@ -352,7 +351,7 @@ class LiveCourseList extends React.Component {
</Otherwise> </Otherwise>
</Choose> </Choose>
</div> </div>
) );
}, },
}, },
{ {
...@@ -426,7 +425,7 @@ class LiveCourseList extends React.Component { ...@@ -426,7 +425,7 @@ class LiveCourseList extends React.Component {
key='share' key='share'
className='operate__item' className='operate__item'
onClick={() => { onClick={() => {
this.handleShowShareModal(item) this.handleShowShareModal(item);
}}> }}>
分享 分享
</div> </div>
...@@ -456,10 +455,10 @@ class LiveCourseList extends React.Component { ...@@ -456,10 +455,10 @@ class LiveCourseList extends React.Component {
</div> </div>
)} )}
</div> </div>
) );
}, },
}, },
] ];
} else { } else {
columns = [ columns = [
{ {
...@@ -468,13 +467,13 @@ class LiveCourseList extends React.Component { ...@@ -468,13 +467,13 @@ class LiveCourseList extends React.Component {
key: 'course', key: 'course',
dataIndex: 'courseName', dataIndex: 'courseName',
render: (val, record) => { render: (val, record) => {
let hasCover = false let hasCover = false;
return ( return (
<div className='record__item'> <div className='record__item'>
{record.courseMediaVOS.map((item, index) => { {record.courseMediaVOS.map((item, index) => {
if (item.contentType === 'COVER') { if (item.contentType === 'COVER') {
hasCover = true hasCover = true;
return <img className='course-cover' src={item.mediaUrl} alt='' /> return <img className='course-cover' src={item.mediaUrl} alt='' />;
} }
})} })}
{!hasCover && <img className='course-cover' src={'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'} alt='' />} {!hasCover && <img className='course-cover' src={'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'} alt='' />}
...@@ -519,7 +518,7 @@ class LiveCourseList extends React.Component { ...@@ -519,7 +518,7 @@ class LiveCourseList extends React.Component {
<span> <span>
{item.adminName} {index < record.admins.length - 1 && <span></span>}{' '} {item.adminName} {index < record.admins.length - 1 && <span></span>}{' '}
</span> </span>
) );
})} })}
</span> </span>
</Tooltip> </Tooltip>
...@@ -532,7 +531,7 @@ class LiveCourseList extends React.Component { ...@@ -532,7 +531,7 @@ class LiveCourseList extends React.Component {
<span> <span>
{item.adminName} {index < record.admins.length - 1 && <span></span>}{' '} {item.adminName} {index < record.admins.length - 1 && <span></span>}{' '}
</span> </span>
) );
})} })}
</span> </span>
</Otherwise> </Otherwise>
...@@ -541,7 +540,7 @@ class LiveCourseList extends React.Component { ...@@ -541,7 +540,7 @@ class LiveCourseList extends React.Component {
</div> </div>
</div> </div>
</div> </div>
) );
}, },
}, },
{ {
...@@ -550,7 +549,7 @@ class LiveCourseList extends React.Component { ...@@ -550,7 +549,7 @@ class LiveCourseList extends React.Component {
key: 'couseCatalog', key: 'couseCatalog',
dataIndex: 'couseCatalog', dataIndex: 'couseCatalog',
render: (val, item) => { render: (val, item) => {
return <div className='categoryName'>{item.categorySonName}</div> return <div className='categoryName'>{item.categorySonName}</div>;
}, },
}, },
{ {
...@@ -566,11 +565,11 @@ class LiveCourseList extends React.Component { ...@@ -566,11 +565,11 @@ class LiveCourseList extends React.Component {
this.setState({ this.setState({
editData: item, editData: item,
openCoursewareModal: true, openCoursewareModal: true,
}) });
}}> }}>
{item.courseDocumentCount} {item.courseDocumentCount}
</span> </span>
) );
}, },
}, },
{ {
...@@ -583,11 +582,11 @@ class LiveCourseList extends React.Component { ...@@ -583,11 +582,11 @@ class LiveCourseList extends React.Component {
<span <span
className='iconfont icon quota-icon' className='iconfont icon quota-icon'
onClick={() => { onClick={() => {
this.handleLinkToClassData(item) this.handleLinkToClassData(item);
}}> }}>
&#xe7d6; &#xe7d6;
</span> </span>
) );
}, },
}, },
{ {
...@@ -597,7 +596,7 @@ class LiveCourseList extends React.Component { ...@@ -597,7 +596,7 @@ class LiveCourseList extends React.Component {
dataIndex: 'created', dataIndex: 'created',
sorter: true, sorter: true,
render: (val, item) => { render: (val, item) => {
return <span>{window.formatDate('YYYY-MM-DD H:i', val)}</span> return <span>{window.formatDate('YYYY-MM-DD H:i', val)}</span>;
}, },
}, },
{ {
...@@ -616,7 +615,7 @@ class LiveCourseList extends React.Component { ...@@ -616,7 +615,7 @@ class LiveCourseList extends React.Component {
<span> <span>
{item.planName} {index < record.relatedPlanList.length - 1 && <span></span>}{' '} {item.planName} {index < record.relatedPlanList.length - 1 && <span></span>}{' '}
</span> </span>
) );
})} })}
</Tooltip> </Tooltip>
</When> </When>
...@@ -625,36 +624,36 @@ class LiveCourseList extends React.Component { ...@@ -625,36 +624,36 @@ class LiveCourseList extends React.Component {
</Otherwise> </Otherwise>
</Choose> </Choose>
</div> </div>
) );
}, },
}, },
] ];
} }
this.setState({ columns }) this.setState({ columns });
} };
handleAdminName = (adminArray) => { handleAdminName = (adminArray) => {
let adminStr = '' let adminStr = '';
adminArray.forEach((item, index) => { adminArray.forEach((item, index) => {
if (index < adminArray.length - 1) { if (index < adminArray.length - 1) {
adminStr = adminStr + item.adminName + '、' adminStr = adminStr + item.adminName + '、';
} else { } else {
adminStr = adminStr + item.adminName adminStr = adminStr + item.adminName;
} }
}) });
return adminStr return adminStr;
} };
handlePlanName = (planArray) => { handlePlanName = (planArray) => {
let planStr = '' let planStr = '';
planArray.forEach((item, index) => { planArray.forEach((item, index) => {
if (index < planArray.length - 1) { if (index < planArray.length - 1) {
planStr = planStr + item.planName + '、' planStr = planStr + item.planName + '、';
} else { } else {
planStr = planStr + item.planName planStr = planStr + item.planName;
} }
}) });
return planStr return planStr;
} };
renderMoreOperate = (item) => { renderMoreOperate = (item) => {
let now = new Date().getTime() let now = new Date().getTime()
...@@ -746,10 +745,10 @@ class LiveCourseList extends React.Component { ...@@ -746,10 +745,10 @@ class LiveCourseList extends React.Component {
width: 440, width: 440,
height: 188, height: 188,
onOk: () => { onOk: () => {
this.deleteConfirm(record) this.deleteConfirm(record);
}, },
}) });
} };
deleteConfirm = (item) => { deleteConfirm = (item) => {
const params = { const params = {
liveCourseId: item.liveCourseId, liveCourseId: item.liveCourseId,
...@@ -785,8 +784,8 @@ class LiveCourseList extends React.Component { ...@@ -785,8 +784,8 @@ class LiveCourseList extends React.Component {
}; };
refreshCourseList = () => { refreshCourseList = () => {
this.props.onChange(this.props.query) this.props.onChange(this.props.query);
} };
//进入直播间 //进入直播间
handleEnterLiveRoom = (item) => { handleEnterLiveRoom = (item) => {
if (item.thirdPartType === "WECHAT") { if (item.thirdPartType === "WECHAT") {
...@@ -844,48 +843,48 @@ class LiveCourseList extends React.Component { ...@@ -844,48 +843,48 @@ class LiveCourseList extends React.Component {
&#xe834; &#xe834;
</span> </span>
), ),
}) });
} else { } else {
CourseService.getLiveCloudCourseDetail({ CourseService.getLiveCloudCourseDetail({
liveCourseId: item.liveCourseId, liveCourseId: item.liveCourseId,
}).then((res) => { }).then((res) => {
const url = `xmqx://liveCourseId=${item.liveCourseId}` const url = `xmqx://liveCourseId=${item.liveCourseId}`;
if (res.result.courseState === 'FINISH') { if (res.result.courseState === 'FINISH') {
Modal.warning({ Modal.warning({
title: '刷新页面', title: '刷新页面',
icon: <QuestionCircleOutlined />, icon: <QuestionCircleOutlined />,
content: '课次已结束,请刷新一下', content: '课次已结束,请刷新一下',
onOk: () => { onOk: () => {
this.refreshCourseList() this.refreshCourseList();
}, },
}) });
} else { } else {
this.setState({ url, openDownloadModal: true }) this.setState({ url, openDownloadModal: true });
} }
}) });
} }
} };
onShowSizeChange = (current, size) => { onShowSizeChange = (current, size) => {
if (current === size) { if (current === size) {
return return;
} }
let _query = this.props.query let _query = this.props.query;
_query.size = size _query.size = size;
this.props.onChange(_query) this.props.onChange(_query);
} };
getDownloadVersion() { getDownloadVersion() {
const isMac = /macintosh|mac os x/i.test(navigator.userAgent) const isMac = /macintosh|mac os x/i.test(navigator.userAgent);
// 判断学员系统 // 判断学员系统
let platform let platform;
if (!isMac) { if (!isMac) {
platform = 1 platform = 1;
} else { } else {
platform = 4 platform = 4;
} }
BaseService.getLastedVersion({ model: 5, platform }).then((res) => { BaseService.getLastedVersion({ model: 5, platform }).then((res) => {
const { result = {} } = res const { result = {} } = res;
this.setState({ downloadUrl: result.releaseUrl }) this.setState({ downloadUrl: result.releaseUrl });
}) });
} }
handleViewPlayBack = (item) => { handleViewPlayBack = (item) => {
if (item.thirdPartType === "WECHAT") { if (item.thirdPartType === "WECHAT") {
...@@ -917,78 +916,79 @@ class LiveCourseList extends React.Component { ...@@ -917,78 +916,79 @@ class LiveCourseList extends React.Component {
} }
let htmlUrl; let htmlUrl;
if (item.teacherId === User.getUserId()) { if (item.teacherId === User.getUserId()) {
htmlUrl = `${LIVE_SHARE}replay/${item.liveCourseId}?teacherId=${User.getUserId()}&id=${User.getStoreId()}` htmlUrl = `${LIVE_SHARE}replay/${item.liveCourseId}?teacherId=${User.getUserId()}&id=${User.getStoreId()}`;
} else if (_.pluck(item.admins, 'adminId').includes(User.getUserId())) { } else if (_.pluck(item.admins, 'adminId').includes(User.getUserId())) {
htmlUrl = `${LIVE_SHARE}replay/${item.liveCourseId}?userId=${User.getUserId()}&id=${User.getStoreId()}` htmlUrl = `${LIVE_SHARE}replay/${item.liveCourseId}?userId=${User.getUserId()}&id=${User.getStoreId()}`;
} else { } else {
htmlUrl = `${LIVE_SHARE}replay/${item.liveCourseId}?id=${User.getStoreId()}` htmlUrl = `${LIVE_SHARE}replay/${item.liveCourseId}?id=${User.getStoreId()}`;
} }
window.open(htmlUrl) window.open(htmlUrl);
} };
handleRelatedModalShow = (item) => { handleRelatedModalShow = (item) => {
const selectPlanList = {} const selectPlanList = {};
if (item.relatedPlanList) { if (item.relatedPlanList) {
item.relatedPlanList.map((item, index) => { item.relatedPlanList.map((childItem, index) => {
selectPlanList[item.planId] = {} selectPlanList[childItem.taskId] = {};
selectPlanList[item.planId].planId = item.planId selectPlanList[childItem.taskId].taskId = childItem.taskId;
selectPlanList[item.planId].taskBaseVOList = [{ taskId: item.taskId }] selectPlanList[childItem.taskId].taskBaseVOList = [{ stageId: childItem.stageId }];
return item return item;
}) });
} }
this.setState({ this.setState({
RelatedPlanModalVisible: true, RelatedPlanModalVisible: true,
selectCourseId: item.liveCourseId, selectCourseId: item.liveCourseId,
selectPlanList: selectPlanList, selectPlanList: selectPlanList,
}) });
} };
closeRelatedPlanModalVisible = () => { closeRelatedPlanModalVisible = () => {
this.setState({ this.setState({
RelatedPlanModalVisible: false, RelatedPlanModalVisible: false,
}) });
} };
onChangeSelectPlanList = (selectPlanList) => { onChangeSelectPlanList = (selectPlanList) => {
console.log('selectPlanList', selectPlanList);
this.setState({ this.setState({
selectPlanList: selectPlanList, selectPlanList: selectPlanList,
}) });
} };
onConfirmSelectPlanList = () => { onConfirmSelectPlanList = () => {
this.setState( this.setState(
{ {
RelatedPlanModalVisible: false, RelatedPlanModalVisible: false,
}, },
() => { () => {
this.props.onChange() this.props.onChange();
} }
) );
} };
handleChangeTable = (pagination, filters, sorter) => { handleChangeTable = (pagination, filters, sorter) => {
const { columnKey, order } = sorter const { columnKey, order } = sorter;
const { query } = this.props const { query } = this.props;
let _columnKey let _columnKey;
let _order let _order;
// 按创建时间升序排序 // 按创建时间升序排序
if (columnKey === 'created' && order === 'ascend') { if (columnKey === 'created' && order === 'ascend') {
_columnKey = 'CREATED' _columnKey = 'CREATED';
_order = 'SORT_ASC' _order = 'SORT_ASC';
} }
// 按创建时间降序排序 // 按创建时间降序排序
if (columnKey === 'created' && order === 'descend') { if (columnKey === 'created' && order === 'descend') {
_columnKey = 'CREATED' _columnKey = 'CREATED';
_order = 'SORT_DESC' _order = 'SORT_DESC';
} }
const _query = { const _query = {
...query, ...query,
sortMap: {}, sortMap: {},
} };
_query.sortMap[_columnKey] = _order _query.sortMap[_columnKey] = _order;
this.props.onChange(_query) this.props.onChange(_query);
} };
render() { render() {
const { total, query, courseList, loading } = this.props const { total, query, courseList, loading } = this.props;
const { current, size } = query const { current, size } = query;
const { openDownloadModal, downloadUrl, url, columns, openCoursewareModal, editData, RelatedPlanModalVisible, selectCourseId, selectPlanList } = this.state const { openDownloadModal, downloadUrl, url, columns, openCoursewareModal, editData, RelatedPlanModalVisible, selectCourseId, selectPlanList } = this.state;
const { match } = this.props const { match } = this.props;
return ( return (
<div className='live-course-list'> <div className='live-course-list'>
...@@ -1014,8 +1014,8 @@ class LiveCourseList extends React.Component { ...@@ -1014,8 +1014,8 @@ class LiveCourseList extends React.Component {
pageSize={size} pageSize={size}
total={parseInt(total)} total={parseInt(total)}
toPage={(page) => { toPage={(page) => {
const _query = { ...query, current: page + 1 } const _query = { ...query, current: page + 1 };
this.props.onChange(_query) this.props.onChange(_query);
}} }}
onShowSizeChange={this.onShowSizeChange} onShowSizeChange={this.onShowSizeChange}
/> />
...@@ -1026,8 +1026,8 @@ class LiveCourseList extends React.Component { ...@@ -1026,8 +1026,8 @@ class LiveCourseList extends React.Component {
<ManageCoursewareModal <ManageCoursewareModal
data={editData} data={editData}
onCancel={() => { onCancel={() => {
this.props.onChange() this.props.onChange();
this.setState({ openCoursewareModal: false }) this.setState({ openCoursewareModal: false });
}} }}
/> />
)} )}
...@@ -1038,7 +1038,7 @@ class LiveCourseList extends React.Component { ...@@ -1038,7 +1038,7 @@ class LiveCourseList extends React.Component {
this.setState({ this.setState({
url: '', url: '',
openDownloadModal: false, openDownloadModal: false,
}) });
}} }}
/> />
)} )}
...@@ -1055,8 +1055,8 @@ class LiveCourseList extends React.Component { ...@@ -1055,8 +1055,8 @@ class LiveCourseList extends React.Component {
<iframe src={url} style={{ display: 'none' }} title='navigation' /> <iframe src={url} style={{ display: 'none' }} title='navigation' />
<Route path={`${match.url}/live-course-data`} component={DataList} /> <Route path={`${match.url}/live-course-data`} component={DataList} />
</div> </div>
) );
} }
} }
export default withRouter(LiveCourseList) export default withRouter(LiveCourseList);
/* /*
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-08-05 10:12:45 * @Date: 2020-08-05 10:12:45
* @LastEditors: wufan * @LastEditors: yuananting
* @LastEditTime: 2021-08-06 17:42:37 * @LastEditTime: 2021-08-16 23:34:03
* @Description: 线上课-列表模块 * @Description: 线上课-列表模块
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -194,7 +194,7 @@ class GraphicsCourseList extends React.Component { ...@@ -194,7 +194,7 @@ class GraphicsCourseList extends React.Component {
<Tooltip title={this.handlePlanName(record.relatedPlanList)} placement='top' arrowPointAtCenter> <Tooltip title={this.handlePlanName(record.relatedPlanList)} placement='top' arrowPointAtCenter>
{record.relatedPlanList.map((item, index) => { {record.relatedPlanList.map((item, index) => {
return ( return (
<span key={item.planId}> <span key={item.taskId}>
{item.planName} {index < record.relatedPlanList.length - 1 && <span></span>}{' '} {item.planName} {index < record.relatedPlanList.length - 1 && <span></span>}{' '}
</span> </span>
); );
...@@ -245,10 +245,10 @@ class GraphicsCourseList extends React.Component { ...@@ -245,10 +245,10 @@ class GraphicsCourseList extends React.Component {
handleRelatedModalShow = (item) => { handleRelatedModalShow = (item) => {
const selectPlanList = {}; const selectPlanList = {};
if (item.relatedPlanList) { if (item.relatedPlanList) {
item.relatedPlanList.map((item, index) => { item.relatedPlanList.map((childItem, index) => {
selectPlanList[item.planId] = {}; selectPlanList[childItem.taskId] = {};
selectPlanList[item.planId].planId = item.planId; selectPlanList[childItem.taskId].taskId = childItem.taskId;
selectPlanList[item.planId].taskBaseVOList = [{ taskId: item.taskId }]; selectPlanList[childItem.taskId].taskBaseVOList = [{ stageId: childItem.stageId }];
return item; return item;
}); });
} }
...@@ -408,22 +408,7 @@ class GraphicsCourseList extends React.Component { ...@@ -408,22 +408,7 @@ class GraphicsCourseList extends React.Component {
}; };
this.props.onChange(_query); this.props.onChange(_query);
}; };
handleRelatedModalShow = (item) => {
const selectPlanList = {};
if (item.relatedPlanList) {
item.relatedPlanList.map((item, index) => {
selectPlanList[item.planId] = {};
selectPlanList[item.planId].planId = item.planId;
selectPlanList[item.planId].taskBaseVOList = [{ taskId: item.taskId }];
return item;
});
}
this.setState({
RelatedPlanModalVisible: true,
selectCourseId: item.id,
selectPlanList: selectPlanList,
});
};
closeRelatedPlanModalVisible = () => { closeRelatedPlanModalVisible = () => {
this.setState({ this.setState({
RelatedPlanModalVisible: false, RelatedPlanModalVisible: false,
...@@ -487,16 +472,6 @@ class GraphicsCourseList extends React.Component { ...@@ -487,16 +472,6 @@ class GraphicsCourseList extends React.Component {
onConfirm={this.onConfirmSelectPlanList} onConfirm={this.onConfirmSelectPlanList}
/> />
)} )}
{RelatedPlanModalVisible && (
<RelatedPlanModal
onClose={this.closeRelatedPlanModalVisible}
visible={RelatedPlanModalVisible}
selectCourseId={selectCourseId}
selectPlanList={selectPlanList}
onChange={this.onChangeSelectPlanList}
onConfirm={this.onConfirmSelectPlanList}
/>
)}
{this.state.shareLiveModal} {this.state.shareLiveModal}
{this.state.watchDataModal} {this.state.watchDataModal}
</div> </div>
......
...@@ -2,7 +2,7 @@ import User from '@/common/js/user'; ...@@ -2,7 +2,7 @@ import User from '@/common/js/user';
import college from '@/common/lottie/college'; import college from '@/common/lottie/college';
import { PageControl, XMTable } from '@/components'; import { PageControl, XMTable } from '@/components';
import CourseService from '@/domains/course-domain/CourseService'; import CourseService from '@/domains/course-domain/CourseService';
import PlanService from '@/domains/plan-domain/planService'; import TaskCenterService from '@/domains/task-center-domain/TaskCenterService';
import { Input, Modal, Tooltip } from 'antd'; import { Input, Modal, Tooltip } from 'antd';
import React from 'react'; import React from 'react';
import _ from 'underscore'; import _ from 'underscore';
...@@ -33,7 +33,7 @@ class RelatedPlanModal extends React.Component { ...@@ -33,7 +33,7 @@ class RelatedPlanModal extends React.Component {
size, size,
storeId: User.getStoreId(), storeId: User.getStoreId(),
}; };
PlanService.getStorePlanAll(params).then((res) => { TaskCenterService.getStoreTaskAll(params).then((res) => {
const { result = {} } = res; const { result = {} } = res;
const { records = [], total = 0 } = result; const { records = [], total = 0 } = result;
this.setState({ this.setState({
...@@ -66,20 +66,24 @@ class RelatedPlanModal extends React.Component { ...@@ -66,20 +66,24 @@ class RelatedPlanModal extends React.Component {
}; };
renderTitle = () => { renderTitle = () => {
return <div className="tip-title"> return (
<p>为了不影响学员学习,系统已对数据进行筛选</p> <div className='tip-title'>
<p>1、课程不能直接关联「已发布」的培训任务筛选;</p> <p>为了不影响学员学习,系统已对数据进行筛选</p>
<p>2、一个课程不能重复出现在同一培训任务中</p> <p>1、课程不能直接关联「已发布」的培训任务筛选;</p>
</div> <p>2、一个课程不能重复出现在同一培训任务中</p>
} </div>
);
};
renderTableTitle = ()=> { renderTableTitle = () => {
return <div> return (
<Tooltip title={this.renderTitle()} overlayClassName="table-title-tooltip"> <div>
培训任务<span className='icon iconfont table-title'>&#xe6f2;</span> <Tooltip title={this.renderTitle()} overlayClassName='table-title-tooltip'>
</Tooltip> 培训任务<span className='icon iconfont table-title'>&#xe6f2;</span>
</div> </Tooltip>
} </div>
);
};
// 请求表头 // 请求表头
parsePlanColumns = () => { parsePlanColumns = () => {
...@@ -89,9 +93,7 @@ class RelatedPlanModal extends React.Component { ...@@ -89,9 +93,7 @@ class RelatedPlanModal extends React.Component {
key: 'planName', key: 'planName',
dataIndex: 'planName', dataIndex: 'planName',
render: (val, record) => { render: (val, record) => {
return <span>{val} return <span>{val}</span>;
</span>;
}, },
}, },
]; ];
...@@ -111,38 +113,37 @@ class RelatedPlanModal extends React.Component { ...@@ -111,38 +113,37 @@ class RelatedPlanModal extends React.Component {
]; ];
return columns; return columns;
}; };
selectPlanList = (record, selected, planId) => { selectPlanList = (record, selected, taskId) => {
const { selectPlanList } = this.props; const { selectPlanList } = this.props;
let _selectPlanList = { ...selectPlanList }; let _selectPlanList = { ...selectPlanList };
if (selected) { if (selected) {
if (!_selectPlanList[planId]) { if (!_selectPlanList[taskId]) {
_selectPlanList[planId] = {}; _selectPlanList[taskId] = {};
} }
_selectPlanList[planId].taskBaseVOList = []; _selectPlanList[taskId].taskBaseVOList = [];
_selectPlanList[planId].planId = planId; _selectPlanList[taskId].taskId = taskId;
_selectPlanList[planId].taskBaseVOList.push(record); _selectPlanList[taskId].taskBaseVOList.push({ ...record, stageId: record.taskId });
} else { } else {
if (!_selectPlanList[planId]) { if (!_selectPlanList[taskId]) {
_selectPlanList[planId] = {}; _selectPlanList[taskId] = {};
} }
_selectPlanList[planId].taskBaseVOList = []; _selectPlanList[taskId].taskBaseVOList = [];
_selectPlanList[planId].planId = planId; _selectPlanList[taskId].taskId = taskId;
} }
this.props.onChange(_selectPlanList); this.props.onChange(_selectPlanList);
// this.setState({selectPlanList:_selectPlanList});
}; };
handleSelectPlanListData(selectPlanList) { handleSelectPlanListData(selectPlanList) {
let _selectPlanList = []; let _selectPlanList = [];
for (let key in selectPlanList) { for (let key in selectPlanList) {
let item = {}; let item = {};
if (selectPlanList[key].taskBaseVOList) { if (selectPlanList[key].taskBaseVOList) {
item.planId = selectPlanList[key].planId; item.taskId = selectPlanList[key].taskId;
if (selectPlanList[key].taskBaseVOList[0]) { if (selectPlanList[key].taskBaseVOList[0]) {
item.taskId = selectPlanList[key].taskBaseVOList[0].taskId; item.stageId = selectPlanList[key].taskBaseVOList[0].stageId;
} }
} }
if (item.taskId) { if (item.stageId) {
_selectPlanList.push(item); _selectPlanList.push(item);
} }
} }
...@@ -152,10 +153,10 @@ class RelatedPlanModal extends React.Component { ...@@ -152,10 +153,10 @@ class RelatedPlanModal extends React.Component {
const { selectPlanList } = this.props; const { selectPlanList } = this.props;
const params = { const params = {
courseId: this.props.selectCourseId, courseId: this.props.selectCourseId,
relatedPlanList: this.handleSelectPlanListData(selectPlanList), relatedTaskList: this.handleSelectPlanListData(selectPlanList),
storeId: User.getStoreId(), storeId: User.getStoreId(),
}; };
CourseService.relatedCourseToPlan(params).then((res) => { TaskCenterService.relatedCourseToTask(params).then((res) => {
this.props.onConfirm(); this.props.onConfirm();
}); });
}; };
...@@ -218,7 +219,7 @@ class RelatedPlanModal extends React.Component { ...@@ -218,7 +219,7 @@ class RelatedPlanModal extends React.Component {
image: college, image: college,
description: '暂无数据', description: '暂无数据',
}} }}
rowKey={(record) => record.planId} rowKey={(record) => record.taskId}
className='plan-table' className='plan-table'
dataSource={dataSource} dataSource={dataSource}
columns={this.parsePlanColumns()} columns={this.parsePlanColumns()}
...@@ -228,7 +229,7 @@ class RelatedPlanModal extends React.Component { ...@@ -228,7 +229,7 @@ class RelatedPlanModal extends React.Component {
return; return;
} }
if (_record.taskBaseVOList.length !== 0) { if (_record.taskBaseVOList.length !== 0) {
const selectPlan = selectPlanList[_record.planId]; const selectPlan = selectPlanList[_record.taskId];
let taskBaseVOList = []; let taskBaseVOList = [];
if (selectPlan) { if (selectPlan) {
taskBaseVOList = selectPlan.taskBaseVOList; taskBaseVOList = selectPlan.taskBaseVOList;
...@@ -248,9 +249,9 @@ class RelatedPlanModal extends React.Component { ...@@ -248,9 +249,9 @@ class RelatedPlanModal extends React.Component {
className='child-table' className='child-table'
rowSelection={{ rowSelection={{
type: 'checkbox', type: 'checkbox',
selectedRowKeys: _.pluck(taskBaseVOList, 'taskId'), selectedRowKeys: _.pluck(taskBaseVOList, 'stageId'),
onSelect: (record, selected) => { onSelect: (record, selected) => {
this.selectPlanList(record, selected, _record.planId); this.selectPlanList(record, selected, _record.taskId);
}, },
onSelectAll: (selected, _selectedRows, changeRows) => {}, onSelectAll: (selected, _selectedRows, changeRows) => {},
}} }}
......
import React from 'react' import React from 'react';
import { Modal, message, Tooltip, Switch, Dropdown } from 'antd' import { Modal, message, Tooltip, Switch, Dropdown } from 'antd';
import _ from 'underscore' import _ from 'underscore';
import { PageControl } from '@/components' import { PageControl } from '@/components';
import { LIVE_SHARE } from '@/domains/course-domain/constants' import { LIVE_SHARE } from '@/domains/course-domain/constants';
import { Route, withRouter } from 'react-router-dom' import { Route, withRouter } from 'react-router-dom';
import ShareLiveModal from '@/modules/course-manage/modal/ShareLiveModal' import ShareLiveModal from '@/modules/course-manage/modal/ShareLiveModal';
import CourseService from '@/domains/course-domain/CourseService' import CourseService from '@/domains/course-domain/CourseService';
import RelatedPlanModal from '../../modal/RelatedPlanModal' import RelatedPlanModal from '../../modal/RelatedPlanModal';
import User from '@/common/js/user' import User from '@/common/js/user';
import VideoCourseDetail from '../VideoCourseDetail' import VideoCourseDetail from '../VideoCourseDetail';
import WatchData from './WatchData' import WatchData from './WatchData';
import { XMTable } from '@/components' import { XMTable } from '@/components';
import college from '@/common/lottie/college' import college from '@/common/lottie/college';
import './VideoCourseList.less' import './VideoCourseList.less';
class VideoCourseList extends React.Component { class VideoCourseList extends React.Component {
constructor(props) { constructor(props) {
super(props) super(props);
this.state = { this.state = {
id: '', // 视频课ID id: '', // 视频课ID
studentIds: [], studentIds: [],
...@@ -24,36 +24,36 @@ class VideoCourseList extends React.Component { ...@@ -24,36 +24,36 @@ class VideoCourseList extends React.Component {
selectPlanList: {}, selectPlanList: {},
ShelfLoading: false, ShelfLoading: false,
// dataSource: [], // dataSource: [],
} };
} }
componentDidMount() { componentDidMount() {
const videoCourseItem = localStorage.getItem('videoCourseItem') const videoCourseItem = localStorage.getItem('videoCourseItem');
if (videoCourseItem) { if (videoCourseItem) {
const _videoCourseItem = JSON.parse(videoCourseItem) const _videoCourseItem = JSON.parse(videoCourseItem);
this.handleShowShareModal(_videoCourseItem, true) this.handleShowShareModal(_videoCourseItem, true);
} }
} }
// 跳转课程详情页 // 跳转课程详情页
handleLinkToCourseDetail = (courseId) => { handleLinkToCourseDetail = (courseId) => {
const { match } = this.props const { match } = this.props;
window.RCHistory.push(`${match.url}/video-course-detail?courseId=${courseId}`) window.RCHistory.push(`${match.url}/video-course-detail?courseId=${courseId}`);
} };
// 观看数据弹窗 // 观看数据弹窗
handleShowWatchDataModal = (item) => { handleShowWatchDataModal = (item) => {
const { match } = this.props const { match } = this.props;
window.RCHistory.push({ window.RCHistory.push({
pathname: `${match.url}/course-data?courseName=${item.courseName}&courseId=${item.id}`, pathname: `${match.url}/course-data?courseName=${item.courseName}&courseId=${item.id}`,
}) });
} };
// 请求表头 // 请求表头
parseColumns = () => { parseColumns = () => {
const { type } = this.props const { type } = this.props;
const { ShelfLoading } = this.state const { ShelfLoading } = this.state;
const columns = [ const columns = [
{ {
title: '线上课', title: '线上课',
...@@ -62,7 +62,7 @@ class VideoCourseList extends React.Component { ...@@ -62,7 +62,7 @@ class VideoCourseList extends React.Component {
width: 321, width: 321,
fixed: 'left', fixed: 'left',
render: (val, record) => { render: (val, record) => {
const { coverUrl } = record const { coverUrl } = record;
return ( return (
<div className='record__item'> <div className='record__item'>
<img className='course-cover' src={coverUrl || 'https://image.xiaomaiketang.com/xm/TwtGPQGE4K.png'} alt='封面图' /> <img className='course-cover' src={coverUrl || 'https://image.xiaomaiketang.com/xm/TwtGPQGE4K.png'} alt='封面图' />
...@@ -77,7 +77,7 @@ class VideoCourseList extends React.Component { ...@@ -77,7 +77,7 @@ class VideoCourseList extends React.Component {
</Otherwise> </Otherwise>
</Choose> </Choose>
</div> </div>
) );
}, },
}, },
{ {
...@@ -97,7 +97,7 @@ class VideoCourseList extends React.Component { ...@@ -97,7 +97,7 @@ class VideoCourseList extends React.Component {
dataIndex: 'categoryName', dataIndex: 'categoryName',
width: 150, width: 150,
render: (val, record) => { render: (val, record) => {
return <div className='record__item'>{record.categorySonName}</div> return <div className='record__item'>{record.categorySonName}</div>;
}, },
}, },
{ {
...@@ -108,7 +108,7 @@ class VideoCourseList extends React.Component { ...@@ -108,7 +108,7 @@ class VideoCourseList extends React.Component {
width: 100, width: 100,
align: 'right', align: 'right',
render: (val, item) => { render: (val, item) => {
return <div onClick={() => this.handleLinkToCourseDetail(item.id)}>{val || 1}</div> return <div onClick={() => this.handleLinkToCourseDetail(item.id)}>{val || 1}</div>;
}, },
}, },
{ {
...@@ -140,10 +140,10 @@ class VideoCourseList extends React.Component { ...@@ -140,10 +140,10 @@ class VideoCourseList extends React.Component {
checked={item.shelfState === 'YES'} checked={item.shelfState === 'YES'}
defaultChecked={item.shelfState} defaultChecked={item.shelfState}
onClick={(checked) => { onClick={(checked) => {
this.changeShelfState(checked, item, index) this.changeShelfState(checked, item, index);
}} }}
/> />
) );
}, },
}, },
{ {
...@@ -157,7 +157,7 @@ class VideoCourseList extends React.Component { ...@@ -157,7 +157,7 @@ class VideoCourseList extends React.Component {
<div className='watchUserCount' onClick={() => this.handleShowWatchDataModal(item)}> <div className='watchUserCount' onClick={() => this.handleShowWatchDataModal(item)}>
{val || 0} {val || 0}
</div> </div>
) );
}, },
}, },
{ {
...@@ -174,7 +174,7 @@ class VideoCourseList extends React.Component { ...@@ -174,7 +174,7 @@ class VideoCourseList extends React.Component {
</Tooltip> </Tooltip>
)} )}
</div> </div>
) );
}, },
}, },
{ {
...@@ -184,7 +184,7 @@ class VideoCourseList extends React.Component { ...@@ -184,7 +184,7 @@ class VideoCourseList extends React.Component {
dataIndex: 'created', dataIndex: 'created',
sorter: true, sorter: true,
render: (val) => { render: (val) => {
return window.formatDate('YYYY-MM-DD H:i', val) return window.formatDate('YYYY-MM-DD H:i', val);
}, },
}, },
{ {
...@@ -194,7 +194,7 @@ class VideoCourseList extends React.Component { ...@@ -194,7 +194,7 @@ class VideoCourseList extends React.Component {
dataIndex: 'updated', dataIndex: 'updated',
sorter: true, sorter: true,
render: (val) => { render: (val) => {
return window.formatDate('YYYY-MM-DD H:i', val) return window.formatDate('YYYY-MM-DD H:i', val);
}, },
}, },
{ {
...@@ -210,10 +210,10 @@ class VideoCourseList extends React.Component { ...@@ -210,10 +210,10 @@ class VideoCourseList extends React.Component {
<Tooltip title={this.handlePlanName(record.relatedPlanList)} placement='top' arrowPointAtCenter> <Tooltip title={this.handlePlanName(record.relatedPlanList)} placement='top' arrowPointAtCenter>
{record.relatedPlanList.map((item, index) => { {record.relatedPlanList.map((item, index) => {
return ( return (
<span key={item.planId}> <span key={item.taskId}>
{item.planName} {index < record.relatedPlanList.length - 1 && <span></span>} {item.planName} {index < record.relatedPlanList.length - 1 && <span></span>}
</span> </span>
) );
})} })}
</Tooltip> </Tooltip>
</When> </When>
...@@ -222,7 +222,7 @@ class VideoCourseList extends React.Component { ...@@ -222,7 +222,7 @@ class VideoCourseList extends React.Component {
</Otherwise> </Otherwise>
</Choose> </Choose>
</div> </div>
) );
}, },
}, },
{ {
...@@ -249,17 +249,17 @@ class VideoCourseList extends React.Component { ...@@ -249,17 +249,17 @@ class VideoCourseList extends React.Component {
</span> </span>
</Dropdown> </Dropdown>
</div> </div>
) );
}, },
}, },
] ];
type !== 'internal' && columns.splice(5, 1) type !== 'internal' && columns.splice(5, 1);
return columns return columns;
} };
renderMoreOperate = (item) => { renderMoreOperate = (item) => {
const { type } = this.props const { type } = this.props;
return ( return (
<div className='live-course-more-menu'> <div className='live-course-more-menu'>
<If condition={type !== 'internal'}> <If condition={type !== 'internal'}>
...@@ -276,7 +276,7 @@ class VideoCourseList extends React.Component { ...@@ -276,7 +276,7 @@ class VideoCourseList extends React.Component {
<div <div
className='operate__item' className='operate__item'
onClick={() => { onClick={() => {
window.RCHistory.push(`/create-video-course?type=edit&id=${item.id}`) window.RCHistory.push(`/create-video-course?type=edit&id=${item.id}`);
}}> }}>
编辑 编辑
</div> </div>
...@@ -285,41 +285,41 @@ class VideoCourseList extends React.Component { ...@@ -285,41 +285,41 @@ class VideoCourseList extends React.Component {
</div> </div>
</If> </If>
</div> </div>
) );
} };
handlePlanName = (planArray) => { handlePlanName = (planArray) => {
let planStr = '' let planStr = '';
planArray.forEach((item, index) => { planArray.forEach((item, index) => {
if (index < planArray.length - 1) { if (index < planArray.length - 1) {
planStr = planStr + item.planName + '、' planStr = planStr + item.planName + '、';
} else { } else {
planStr = planStr + item.planName planStr = planStr + item.planName;
} }
}) });
return planStr return planStr;
} };
//改变上架状态 //改变上架状态
changeShelfState = (checked, item, index) => { changeShelfState = (checked, item, index) => {
let _shelfState = checked ? 'YES' : 'NO' let _shelfState = checked ? 'YES' : 'NO';
if (checked) { if (checked) {
_shelfState = 'YES' _shelfState = 'YES';
} else { } else {
_shelfState = 'NO' _shelfState = 'NO';
} }
const params = { const params = {
courseId: item.id, courseId: item.id,
shelfState: _shelfState, shelfState: _shelfState,
} };
CourseService.changeVideoShelfState(params).then(() => { CourseService.changeVideoShelfState(params).then(() => {
if (_shelfState === 'YES') { if (_shelfState === 'YES') {
message.success('已开启展示') message.success('已开启展示');
} else { } else {
message.success('已取消展示') message.success('已取消展示');
} }
this.props.changeShelfState(index, _shelfState) this.props.changeShelfState(index, _shelfState);
}) });
} };
// 删除线上课 // 删除线上课
handleDeleteVideoCourse = (scheduleId) => { handleDeleteVideoCourse = (scheduleId) => {
...@@ -334,28 +334,28 @@ class VideoCourseList extends React.Component { ...@@ -334,28 +334,28 @@ class VideoCourseList extends React.Component {
const param = { const param = {
courseId: scheduleId, courseId: scheduleId,
storeId: User.getStoreId(), storeId: User.getStoreId(),
} };
CourseService.delVideoSchedule(param).then(() => { CourseService.delVideoSchedule(param).then(() => {
message.success('删除成功') message.success('删除成功');
this.props.onChange() this.props.onChange();
}) });
}, },
}) });
} };
// 显示分享弹窗 // 显示分享弹窗
handleShowShareModal = (record, needStr = false) => { handleShowShareModal = (record, needStr = false) => {
const { type } = this.props const { type } = this.props;
const { id, scheduleVideoUrl, chapterNum } = record const { id, scheduleVideoUrl, chapterNum } = record;
const htmlUrl = chapterNum > 1 ? `${LIVE_SHARE}course_detail/${id}?id=${User.getStoreId()}` : `${LIVE_SHARE}video_detail/${id}?id=${User.getStoreId()}` const htmlUrl = chapterNum > 1 ? `${LIVE_SHARE}course_detail/${id}?id=${User.getStoreId()}` : `${LIVE_SHARE}video_detail/${id}?id=${User.getStoreId()}`;
const longUrl = htmlUrl const longUrl = htmlUrl;
const { coverUrl, courseName } = record const { coverUrl, courseName } = record;
const shareData = { const shareData = {
longUrl, longUrl,
coverUrl, coverUrl,
scheduleVideoUrl, scheduleVideoUrl,
courseName, courseName,
} };
const shareLiveModal = ( const shareLiveModal = (
<ShareLiveModal <ShareLiveModal
...@@ -367,82 +367,82 @@ class VideoCourseList extends React.Component { ...@@ -367,82 +367,82 @@ class VideoCourseList extends React.Component {
close={() => { close={() => {
this.setState({ this.setState({
shareLiveModal: null, shareLiveModal: null,
}) });
localStorage.setItem('videoCourseItem', '') localStorage.setItem('videoCourseItem', '');
}} }}
/> />
) );
this.setState({ shareLiveModal }) this.setState({ shareLiveModal });
} };
handleChangeTable = (pagination, filters, sorter) => { handleChangeTable = (pagination, filters, sorter) => {
const { columnKey, order } = sorter const { columnKey, order } = sorter;
const { query } = this.props const { query } = this.props;
let { order: _order } = query let { order: _order } = query;
// 按创建时间升序排序 // 按创建时间升序排序
if (columnKey === 'created' && order === 'ascend') { if (columnKey === 'created' && order === 'ascend') {
_order = 'CREATED_ASC' _order = 'CREATED_ASC';
} }
// 按创建时间降序排序 // 按创建时间降序排序
if (columnKey === 'created' && order === 'descend') { if (columnKey === 'created' && order === 'descend') {
_order = 'CREATED_DESC' _order = 'CREATED_DESC';
} }
// 按更新时间升序排序 // 按更新时间升序排序
if (columnKey === 'updated' && order === 'ascend') { if (columnKey === 'updated' && order === 'ascend') {
_order = 'UPDATED_ASC' _order = 'UPDATED_ASC';
} }
// 按更新时间降序排序 // 按更新时间降序排序
if (columnKey === 'updated' && order === 'descend') { if (columnKey === 'updated' && order === 'descend') {
_order = 'UPDATED_DESC' _order = 'UPDATED_DESC';
} }
const _query = { const _query = {
...query, ...query,
orderEnum: _order, orderEnum: _order,
} };
this.props.onChange(_query) this.props.onChange(_query);
} };
handleRelatedModalShow = (item) => { handleRelatedModalShow = (item) => {
const selectPlanList = {} const selectPlanList = {};
if (item.relatedPlanList) { if (item.relatedPlanList) {
item.relatedPlanList.map((item, index) => { item.relatedPlanList.map((childItem, index) => {
selectPlanList[item.planId] = {} selectPlanList[childItem.taskId] = {};
selectPlanList[item.planId].planId = item.planId selectPlanList[childItem.taskId].taskId = childItem.taskId;
selectPlanList[item.planId].taskBaseVOList = [{ taskId: item.taskId }] selectPlanList[childItem.taskId].taskBaseVOList = [{ stageId: childItem.stageId }];
return item return item;
}) });
} }
this.setState({ this.setState({
RelatedPlanModalVisible: true, RelatedPlanModalVisible: true,
selectCourseId: item.id, selectCourseId: item.id,
selectPlanList: selectPlanList, selectPlanList: selectPlanList,
}) });
} };
closeRelatedPlanModalVisible = () => { closeRelatedPlanModalVisible = () => {
this.setState({ this.setState({
RelatedPlanModalVisible: false, RelatedPlanModalVisible: false,
}) });
} };
onChangeSelectPlanList = (selectPlanList) => { onChangeSelectPlanList = (selectPlanList) => {
this.setState({ this.setState({
selectPlanList: selectPlanList, selectPlanList: selectPlanList,
}) });
} };
onConfirmSelectPlanList = () => { onConfirmSelectPlanList = () => {
this.setState( this.setState(
{ {
RelatedPlanModalVisible: false, RelatedPlanModalVisible: false,
}, },
() => { () => {
this.props.onChange() this.props.onChange();
} }
) );
} };
render() { render() {
const { dataSource = [], totalCount, query, type, match } = this.props const { dataSource = [], totalCount, query, type, match } = this.props;
const { current, size } = query const { current, size } = query;
const { RelatedPlanModalVisible, selectPlanList, selectCourseId } = this.state const { RelatedPlanModalVisible, selectPlanList, selectCourseId } = this.state;
return ( return (
<div className={`video-course-list ${type !== 'internal' ? 'video-course-list-mt' : ''}`}> <div className={`video-course-list ${type !== 'internal' ? 'video-course-list-mt' : ''}`}>
<XMTable <XMTable
...@@ -466,8 +466,8 @@ class VideoCourseList extends React.Component { ...@@ -466,8 +466,8 @@ class VideoCourseList extends React.Component {
pageSize={size} pageSize={size}
total={totalCount} total={totalCount}
toPage={(page) => { toPage={(page) => {
const _query = { ...query, current: page + 1 } const _query = { ...query, current: page + 1 };
this.props.onChange(_query) this.props.onChange(_query);
}} }}
/> />
</div> </div>
...@@ -486,8 +486,8 @@ class VideoCourseList extends React.Component { ...@@ -486,8 +486,8 @@ class VideoCourseList extends React.Component {
<Route path={`${match.url}/video-course-detail`} component={VideoCourseDetail} /> <Route path={`${match.url}/video-course-detail`} component={VideoCourseDetail} />
<Route path={`${match.url}/course-data`} component={WatchData} /> <Route path={`${match.url}/course-data`} component={WatchData} />
</div> </div>
) );
} }
} }
export default withRouter(VideoCourseList) export default withRouter(VideoCourseList);
...@@ -3,198 +3,199 @@ ...@@ -3,198 +3,199 @@
* @Author: zangsuyun * @Author: zangsuyun
* @Date: 2021-03-12 14:49:40 * @Date: 2021-03-12 14:49:40
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-07-18 16:58:23 * @LastEditTime: 2021-08-16 16:38:44
* @Copyright: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyright: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React from "react"; import React from 'react';
import { Modal, message, Tooltip, Switch, Dropdown, Button } from "antd"; import { Modal, message, Tooltip, Switch, Dropdown, Button } from 'antd';
import { FileTypeIcon, FileVerifyMap } from '@/common/constants/academic/lessonEnum'; import { FileTypeIcon, FileVerifyMap } from '@/common/constants/academic/lessonEnum';
import { Route, withRouter } from "react-router-dom"; import { Route, withRouter } from 'react-router-dom';
import { PageControl, XMTable } from "@/components"; import { PageControl, XMTable } from '@/components';
import { LIVE_SHARE_MAP } from "@/common/constants/academic/cloudClass"; import { LIVE_SHARE_MAP } from '@/common/constants/academic/cloudClass';
import { appId, shareUrl, LIVE_SHARE } from "@/domains/course-domain/constants"; import { appId, shareUrl, LIVE_SHARE } from '@/domains/course-domain/constants';
import ScanFileModal from "../../resource-disk/modal/ScanFileModal"; import ScanFileModal from '../../resource-disk/modal/ScanFileModal';
import WatchData from "./WatchData"; import WatchData from './WatchData';
import KnowledgeAPI from "@/data-source/knowledge/request-api"; import KnowledgeAPI from '@/data-source/knowledge/request-api';
import ENUM from "../ENUM.js"; import ENUM from '../ENUM.js';
import "./KnowledgeBaseList.less"; import './KnowledgeBaseList.less';
const DEFAULT_SIZE_UNIT = 1000 * 1000 // 将B转换成M const DEFAULT_SIZE_UNIT = 1000 * 1000; // 将B转换成M
const { confirm } = Modal const { confirm } = Modal;
const ENV = process.env.DEPLOY_ENV || 'dev';
class KnowledgeBaseList extends React.Component { class KnowledgeBaseList extends React.Component {
constructor(props) { constructor(props) {
super(props) super(props);
this.state = { this.state = {
id: "", id: '',
scanFileModal: null scanFileModal: null,
} };
} }
handleAdminName = (adminArray) => { handleAdminName = (adminArray) => {
let adminStr = "" let adminStr = '';
adminArray.map((item, index) => { adminArray.map((item, index) => {
if (index < adminArray.length - 1) { if (index < adminArray.length - 1) {
adminStr = adminStr + item.adminName + "、" adminStr = adminStr + item.adminName + '、';
} else { } else {
adminStr = adminStr + item.adminName adminStr = adminStr + item.adminName;
} }
}) });
return adminStr return adminStr;
} };
handleUp = (index, record) => { handleUp = (index, record) => {
if (index === 0 && this.props.query.current === 1) { if (index === 0 && this.props.query.current === 1) {
return return;
} }
const params = { const params = {
direction: "UP", direction: 'UP',
id: record.id, id: record.id,
storeId: record.storeId storeId: record.storeId,
} };
KnowledgeAPI.moveKnowledge(params).then((res) => { KnowledgeAPI.moveKnowledge(params).then((res) => {
if (res.success) { if (res.success) {
message.success("更新成功") message.success('更新成功');
this.props.onChange() this.props.onChange();
} }
}) });
} };
handleDown = (record, index) => { handleDown = (record, index) => {
const { query, totalCount } = this.props const { query, totalCount } = this.props;
const { current, size } = query const { current, size } = query;
if (totalCount === size * (current - 1) + index + 1) { if (totalCount === size * (current - 1) + index + 1) {
return return;
} }
const params = { const params = {
direction: "DOWN", direction: 'DOWN',
id: record.id, id: record.id,
storeId: record.storeId storeId: record.storeId,
} };
KnowledgeAPI.moveKnowledge(params).then((res) => { KnowledgeAPI.moveKnowledge(params).then((res) => {
if (res.success) { if (res.success) {
message.success("更新成功") message.success('更新成功');
this.props.onChange() this.props.onChange();
} }
}) });
} };
getBlob = (url) => { getBlob = (url) => {
return new Promise((resolve) => { return new Promise((resolve) => {
const xhr = new XMLHttpRequest() const xhr = new XMLHttpRequest();
xhr.open("GET", url, true) xhr.open('GET', url, true);
xhr.responseType = "blob" xhr.responseType = 'blob';
xhr.onload = () => { xhr.onload = () => {
if (xhr.status === 200) { if (xhr.status === 200) {
resolve(xhr.response) resolve(xhr.response);
} }
} };
xhr.send() xhr.send();
}) });
} };
saveAs = (blob, filename) => { saveAs = (blob, filename) => {
if (window.navigator.msSaveOrOpenBlob) { if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, filename) navigator.msSaveBlob(blob, filename);
} else { } else {
const link = document.createElement("a") const link = document.createElement('a');
const body = document.querySelector("body") const body = document.querySelector('body');
// 创建对象url // 创建对象url
link.href = window.URL.createObjectURL(blob) link.href = window.URL.createObjectURL(blob);
link.download = filename link.download = filename;
body.appendChild(link) body.appendChild(link);
link.click() link.click();
body.removeChild(link) body.removeChild(link);
// 通过调用 URL.createObjectURL() 创建的 URL 对象 // 通过调用 URL.createObjectURL() 创建的 URL 对象
window.URL.revokeObjectURL(link.href) window.URL.revokeObjectURL(link.href);
} }
} };
// 下载文件 // 下载文件
handleDownload = (folder) => { handleDownload = (folder) => {
this.getBlob(folder.ossUrl).then((blob) => { this.getBlob(folder.ossUrl).then((blob) => {
this.saveAs(blob, folder.folderName) this.saveAs(blob, folder.folderName);
}) });
} };
// 预览文件 // 预览文件
handleScanFile = (folder) => { handleScanFile = (folder) => {
const { folderFormat, folderSize, ossUrl } = folder; const { folderFormat, folderSize, ossUrl } = folder;
switch (folderFormat) { switch (folderFormat) {
case "PDF": case 'PDF':
window.open(ossUrl, "_blank") window.open(ossUrl, '_blank');
break break;
case "WORD": case 'WORD':
case "DOCX": case 'DOCX':
case "DOC": case 'DOC':
case "EXCEL": case 'EXCEL':
case "PPT": case 'PPT':
case "PPTX": case 'PPTX':
case "PDF": case 'PDF':
if ( if (
((folderFormat === "PPT" || folderFormat === "PPTX" || folderFormat === "DOCX" || folderFormat === "WORD" || folderFormat === "DOC") && ((folderFormat === 'PPT' || folderFormat === 'PPTX' || folderFormat === 'DOCX' || folderFormat === 'WORD' || folderFormat === 'DOC') &&
folderSize > 10 * DEFAULT_SIZE_UNIT) || folderSize > 10 * DEFAULT_SIZE_UNIT) ||
(folderFormat === "EXCEL" && folderSize > 5 * DEFAULT_SIZE_UNIT) (folderFormat === 'EXCEL' && folderSize > 5 * DEFAULT_SIZE_UNIT)
) { ) {
Modal.confirm({ Modal.confirm({
title: "抱歉,不能在线预览", title: '抱歉,不能在线预览',
content: "由于文件较大,不支持在线预览,请下载后再查看", content: '由于文件较大,不支持在线预览,请下载后再查看',
// icon: <Icon type="question-circle" theme="filled" style={{ color: '#FF8534' }}></Icon>, // icon: <Icon type="question-circle" theme="filled" style={{ color: '#FF8534' }}></Icon>,
cancelText: "取消", cancelText: '取消',
okText: "下载", okText: '下载',
onOk: () => { onOk: () => {
this.handleDownload(folder) this.handleDownload(folder);
} },
}) });
break break;
} }
const prefixUrl = "https://view.officeapps.live.com/op/view.aspx?src=" const prefixUrl = 'https://view.officeapps.live.com/op/view.aspx?src=';
const scanUrl = `${prefixUrl}${encodeURIComponent(ossUrl)}` const scanUrl = `${prefixUrl}${encodeURIComponent(ossUrl)}`;
window.open(scanUrl, "_blank") window.open(scanUrl, '_blank');
break break;
default: default:
const scanFileModal = ( const scanFileModal = (
<ScanFileModal <ScanFileModal
fileType={folderFormat} fileType={folderFormat}
item={folder} item={folder}
close={() => { close={() => {
this.setState({ scanFileModal: null }) this.setState({ scanFileModal: null });
}} }}
/> />
) );
this.setState({ scanFileModal }) this.setState({ scanFileModal });
break break;
} }
} };
// 请求表头 // 请求表头
parseColumns = () => { parseColumns = () => {
const { query, totalCount } = this.props const { query, totalCount } = this.props;
const { current, size } = query const { current, size } = query;
const columns = [ const columns = [
{ {
title: "名称", title: '名称',
key: "name", key: 'name',
dataIndex: "name", dataIndex: 'name',
render: (val, record) => { render: (val, record) => {
const { coverUrl, mediaCourseUrl, courseDivision } = record.source const { coverUrl, mediaCourseUrl, courseDivision } = record.source;
let hasCover = false let hasCover = false;
const type = record.type const type = record.type;
return ( return (
<div <div
className='record__item' className='record__item'
onClick={() => { onClick={() => {
this.handleScanFile(record.source) this.handleScanFile(record.source);
}}> }}>
<img src={FileTypeIcon[record.source.folderFormat] } style={{width:24,height:24}} alt='' className='item-img' /> <img src={FileTypeIcon[record.source.folderFormat]} style={{ width: 24, height: 24 }} alt='' className='item-img' />
{val.length > 25 ? ( {val.length > 25 ? (
<Tooltip title={val}> <Tooltip title={val}>
<div className='course-name clamp'>{val}</div> <div className='course-name clamp'>{val}</div>
...@@ -203,15 +204,14 @@ class KnowledgeBaseList extends React.Component { ...@@ -203,15 +204,14 @@ class KnowledgeBaseList extends React.Component {
<div className='course-name clamp'>{val}</div> <div className='course-name clamp'>{val}</div>
)} )}
</div> </div>
);
) },
}
}, },
{ {
title: "创建人", title: '创建人',
key: "createName", key: 'createName',
dataIndex: "createName", dataIndex: 'createName',
align: "center", align: 'center',
render: (val) => { render: (val) => {
return ( return (
<div> <div>
...@@ -221,36 +221,35 @@ class KnowledgeBaseList extends React.Component { ...@@ -221,36 +221,35 @@ class KnowledgeBaseList extends React.Component {
</Tooltip> </Tooltip>
)} )}
</div> </div>
) );
} },
}, },
{ {
title: "观看学员数", title: '观看学员数',
key: "watchUserCount", key: 'watchUserCount',
dataIndex: "watchUserCount", dataIndex: 'watchUserCount',
align: "right", align: 'right',
render: (val, item) => { render: (val, item) => {
return val ? ( return val ? (
<div className='operate' style={{ display: "block" }} onClick={() => this.handleLinkToClassData(item)}> <div className='operate' style={{ display: 'block' }} onClick={() => this.handleLinkToClassData(item)}>
<span className='operate__item'>{val}</span> <span className='operate__item'>{val}</span>
</div> </div>
) : ( ) : (
0 0
) );
} },
}, },
{ {
title: "", title: '',
}, },
{ {
title: "操作", title: '操作',
key: "operate", key: 'operate',
dataIndex: "operate", dataIndex: 'operate',
width: 160, width: 160,
fixed: "right", fixed: 'right',
render: (val, record, index) => { render: (val, record, index) => {
return this.props.categoryId === "0" ? ( return this.props.categoryId === '0' ? (
<div className='operate'> <div className='operate'>
<div className='operate__item' onClick={() => this.handleDelete(record)}> <div className='operate__item' onClick={() => this.handleDelete(record)}>
移出 移出
...@@ -258,12 +257,12 @@ class KnowledgeBaseList extends React.Component { ...@@ -258,12 +257,12 @@ class KnowledgeBaseList extends React.Component {
</div> </div>
) : ( ) : (
<div className='operate'> <div className='operate'>
<div className={index === 0 && current === 1 ? "operate__item disable" : "operate__item"} onClick={() => this.handleUp(index, record)}> <div className={index === 0 && current === 1 ? 'operate__item disable' : 'operate__item'} onClick={() => this.handleUp(index, record)}>
上移 上移
</div> </div>
<span className='operate__item split'> | </span> <span className='operate__item split'> | </span>
<div <div
className={totalCount === size * (current - 1) + index + 1 ? "operate__item disable" : "operate__item"} className={totalCount === size * (current - 1) + index + 1 ? 'operate__item disable' : 'operate__item'}
onClick={() => this.handleDown(record, index)}> onClick={() => this.handleDown(record, index)}>
下移 下移
</div> </div>
...@@ -272,64 +271,64 @@ class KnowledgeBaseList extends React.Component { ...@@ -272,64 +271,64 @@ class KnowledgeBaseList extends React.Component {
移出 移出
</div> </div>
</div> </div>
) );
} },
} },
] ];
return columns return columns;
} };
handleDelete = (record) => { handleDelete = (record) => {
return confirm({ return confirm({
title: "移出知识", title: '移出知识',
content: "确定将分类中此知识移出吗?", content: '确定将分类中此知识移出吗?',
icon: <span className='icon iconfont default-confirm-icon'>&#xe839; </span>, icon: <span className='icon iconfont default-confirm-icon'>&#xe839; </span>,
okText: "删除", okText: '删除',
okType: "danger", okType: 'danger',
cancelText: "取消", cancelText: '取消',
width: 440, width: 440,
height: 188, height: 188,
onOk: () => { onOk: () => {
this.deleteConfirm(record) this.deleteConfirm(record);
} },
}) });
} };
// 前往上课数据页面 // 前往上课数据页面
handleLinkToClassData = (item) => { handleLinkToClassData = (item) => {
const { match } = this.props; const { match } = this.props;
localStorage.setItem("WatchData_CourseName", item.name); localStorage.setItem('WatchData_CourseName', item.name);
window.RCHistory.push({ window.RCHistory.push({
pathname: `${match.url}/course-data?type=${item.type}&id=${item.id}` pathname: `${match.url}/course-data?type=${item.type}&id=${item.id}`,
}) });
} };
deleteConfirm = (item) => { deleteConfirm = (item) => {
const params = { const params = {
id: item.id, id: item.id,
storeId: item.storeId storeId: item.storeId,
} };
KnowledgeAPI.delKnowledge(params).then((res) => { KnowledgeAPI.delKnowledge(params).then((res) => {
if (res.success) { if (res.success) {
const { onChange, updateCategoryTree, selectedRowKeys, onSelectChange } = this.props; const { onChange, updateCategoryTree, selectedRowKeys, onSelectChange } = this.props;
message.success("移出成功"); message.success('移出成功');
onChange(); onChange();
updateCategoryTree(); updateCategoryTree();
if (selectedRowKeys.includes(item.id)) { if (selectedRowKeys.includes(item.id)) {
onSelectChange(_.reject(selectedRowKeys, value => value === item.id)); onSelectChange(_.reject(selectedRowKeys, (value) => value === item.id));
} }
} }
}) });
} };
onShowSizeChange = (current, size) => { onShowSizeChange = (current, size) => {
if (current == size) { if (current == size) {
return return;
} }
let _query = this.props.query let _query = this.props.query;
_query.size = size _query.size = size;
this.props.onChange(_query) this.props.onChange(_query);
} };
render() { render() {
const { dataSource = [], totalCount, query, match, selectedRowKeys, onSelectChange } = this.props; const { dataSource = [], totalCount, query, match, selectedRowKeys, onSelectChange } = this.props;
...@@ -338,21 +337,20 @@ class KnowledgeBaseList extends React.Component { ...@@ -338,21 +337,20 @@ class KnowledgeBaseList extends React.Component {
selectedRowKeys, selectedRowKeys,
preserveSelectedRowKeys: true, preserveSelectedRowKeys: true,
onChange: onSelectChange, onChange: onSelectChange,
} };
return ( return (
<div className="knowledge-base-list"> <div className='knowledge-base-list'>
<XMTable <XMTable
rowKey={(record) => record.id} rowKey={(record) => record.id}
rowSelection={rowSelection} rowSelection={rowSelection}
size="middle" size='middle'
dataSource={dataSource} dataSource={dataSource}
columns={this.parseColumns()} columns={this.parseColumns()}
pagination={false} pagination={false}
bordered bordered
className="knowledge-list-table" className='knowledge-list-table'
renderEmpty={{ renderEmpty={{
description: <span style={{ display: 'block', paddingBottom: 24 }}>暂无数据</span> description: <span style={{ display: 'block', paddingBottom: 24 }}>暂无数据</span>,
}} }}
/> />
...@@ -363,8 +361,8 @@ class KnowledgeBaseList extends React.Component { ...@@ -363,8 +361,8 @@ class KnowledgeBaseList extends React.Component {
pageSize={size} pageSize={size}
total={totalCount} total={totalCount}
toPage={(page) => { toPage={(page) => {
const _query = { ...query, current: page + 1 } const _query = { ...query, current: page + 1 };
this.props.onChange(_query) this.props.onChange(_query);
}} }}
onShowSizeChange={this.onShowSizeChange} onShowSizeChange={this.onShowSizeChange}
/> />
...@@ -375,8 +373,8 @@ class KnowledgeBaseList extends React.Component { ...@@ -375,8 +373,8 @@ class KnowledgeBaseList extends React.Component {
{this.state.scanFileModal} {this.state.scanFileModal}
</div> </div>
) );
} }
} }
export default withRouter(KnowledgeBaseList) export default withRouter(KnowledgeBaseList);
...@@ -2,29 +2,30 @@ ...@@ -2,29 +2,30 @@
* @Description: * @Description:
* @Author: zangsuyun * @Author: zangsuyun
* @Date: 2021-03-13 11:48:24 * @Date: 2021-03-13 11:48:24
* @LastEditors: wufan * @LastEditors: yuananting
* @LastEditTime: 2021-08-09 15:53:08 * @LastEditTime: 2021-08-16 16:38:20
* @Copyright: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyright: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React from "react"; import React from 'react';
import { Table, Modal, message, Tooltip, Switch, Dropdown } from "antd"; import { Table, Modal, message, Tooltip, Switch, Dropdown } from 'antd';
import { PageControl } from "@/components"; import { PageControl } from '@/components';
import _ from "underscore"; import _ from 'underscore';
import { LIVE_SHARE_MAP } from "@/common/constants/academic/cloudClass"; import { LIVE_SHARE_MAP } from '@/common/constants/academic/cloudClass';
import { appId, shareUrl, LIVE_SHARE } from "@/domains/course-domain/constants"; import { appId, shareUrl, LIVE_SHARE } from '@/domains/course-domain/constants';
import TableSelectedData from "@/components/TableSelectedData"; import TableSelectedData from '@/components/TableSelectedData';
import "./LiveList.less"; import './LiveList.less';
import CourseService from "@/domains/course-domain/CourseService"; import CourseService from '@/domains/course-domain/CourseService';
import User from "@/common/js/user"; import User from '@/common/js/user';
const ENV = process.env.DEPLOY_ENV || 'dev';
class VideoList extends React.Component { class VideoList extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
id: "", // 线上课ID id: '', // 线上课ID
studentIds: [], studentIds: [],
selectedRowKeys: [], selectedRowKeys: [],
query: { query: {
...@@ -40,8 +41,7 @@ class VideoList extends React.Component { ...@@ -40,8 +41,7 @@ class VideoList extends React.Component {
componentDidUpdate(prevProps, prevState) { componentDidUpdate(prevProps, prevState) {
//必须写在if里面并且重新进行一次this.props !== prevProps的判断 //必须写在if里面并且重新进行一次this.props !== prevProps的判断
if ( if (
((this.props.courseName || this.props.courseType) && ((this.props.courseName || this.props.courseType) && this.props.courseName !== prevProps.courseName) ||
this.props.courseName !== prevProps.courseName) ||
this.props.courseType !== prevProps.courseType this.props.courseType !== prevProps.courseType
) { ) {
this.handleFetchScheduleList(this.props); this.handleFetchScheduleList(this.props);
...@@ -78,10 +78,10 @@ class VideoList extends React.Component { ...@@ -78,10 +78,10 @@ class VideoList extends React.Component {
let hours = Math.floor(time / 3600); let hours = Math.floor(time / 3600);
let mins = Math.floor(diff / 60); let mins = Math.floor(diff / 60);
let seconds = Math.floor(time % 60); let seconds = Math.floor(time % 60);
hours = hours < 10 ? "0" + hours : hours; hours = hours < 10 ? '0' + hours : hours;
mins = mins < 10 ? "0" + mins : mins; mins = mins < 10 ? '0' + mins : mins;
seconds = seconds < 10 ? "0" + seconds : seconds; seconds = seconds < 10 ? '0' + seconds : seconds;
return hours + ":" + mins + ":" + seconds; return hours + ':' + mins + ':' + seconds;
}; };
// 请求表头 // 请求表头
parseColumns = () => { parseColumns = () => {
...@@ -90,71 +90,58 @@ class VideoList extends React.Component { ...@@ -90,71 +90,58 @@ class VideoList extends React.Component {
title: ( title: (
<span> <span>
<span>课程信息</span> <span>课程信息</span>
<Tooltip <Tooltip title={<div>已加入该分类的课程不支持重复选择,因此不显示。</div>}>
title={
<div>
已加入该分类的课程不支持重复选择,因此不显示。
</div>
}
>
<i <i
className="icon iconfont" className='icon iconfont'
style={{ style={{
marginLeft: "5px", marginLeft: '5px',
cursor: "pointer", cursor: 'pointer',
color: "#bfbfbf", color: '#bfbfbf',
fontSize: "14px", fontSize: '14px',
fontWeight:"400" fontWeight: '400',
}} }}>
>
&#xe61d; &#xe61d;
</i> </i>
</Tooltip> </Tooltip>
</span> </span>
), ),
key: "scheduleName", key: 'scheduleName',
dataIndex: "scheduleName", dataIndex: 'scheduleName',
width: 371, width: 371,
render: (val, record) => { render: (val, record) => {
const { coverUrl, scheduleVideoUrl } = record; const { coverUrl, scheduleVideoUrl } = record;
return ( return (
<div className="record__item"> <div className='record__item'>
{/* 上传了封面的话就用上传的封面, 没有的话就取视频的第一帧 */} {/* 上传了封面的话就用上传的封面, 没有的话就取视频的第一帧 */}
<img <img className='course-cover' src={coverUrl || `${scheduleVideoUrl}?x-oss-process=video/snapshot,t_0,m_fast`} />
className="course-cover"
src={
coverUrl ||
`${scheduleVideoUrl}?x-oss-process=video/snapshot,t_0,m_fast`
}
/>
{record.courseName.length > 25 ? ( {record.courseName.length > 25 ? (
<Tooltip title={record.courseName}> <Tooltip title={record.courseName}>
<div className="course-name">{record.courseName}</div> <div className='course-name'>{record.courseName}</div>
</Tooltip> </Tooltip>
) : ( ) : (
<div className="course-name">{record.courseName}</div> <div className='course-name'>{record.courseName}</div>
)} )}
</div> </div>
); );
}, },
}, },
{ {
title: "课程时长", title: '课程时长',
key: "videoDuration", key: 'videoDuration',
dataIndex: "videoDuration", dataIndex: 'videoDuration',
render: (text, item) => { render: (text, item) => {
return <span>{text ? this.dealTimeDuration(text) : "-"}</span>; return <span>{text ? this.dealTimeDuration(text) : '-'}</span>;
}, },
}, },
{ {
title: "课程分类", title: '课程分类',
key: "categoryName", key: 'categoryName',
dataIndex: "categoryName", dataIndex: 'categoryName',
render: (val, record) => { render: (val, record) => {
return ( return (
<div className="record__item"> <div className='record__item'>
{record.categoryOneName} {record.categoryOneName}
{record.categoryTwoName ? `-${record.categoryTwoName}` : ""} {record.categoryTwoName ? `-${record.categoryTwoName}` : ''}
</div> </div>
); );
}, },
...@@ -167,11 +154,7 @@ class VideoList extends React.Component { ...@@ -167,11 +154,7 @@ class VideoList extends React.Component {
let { selectedRowKeys } = this.state; let { selectedRowKeys } = this.state;
let _list = []; let _list = [];
if (selected || !_.find(selectedRowKeys, (item) => item.id == record.id)) { if (selected || !_.find(selectedRowKeys, (item) => item.id == record.id)) {
_list = _.uniq( _list = _.uniq(selectedRowKeys.concat([record]), false, (item) => item.id);
selectedRowKeys.concat([record]),
false,
(item) => item.id
);
} else { } else {
_list = _.reject(selectedRowKeys, (item) => item.id === record.id); _list = _.reject(selectedRowKeys, (item) => item.id === record.id);
} }
...@@ -182,27 +165,21 @@ class VideoList extends React.Component { ...@@ -182,27 +165,21 @@ class VideoList extends React.Component {
const { dataSource = [], totalCount, query, selectedRowKeys } = this.state; const { dataSource = [], totalCount, query, selectedRowKeys } = this.state;
const { current, size } = query; const { current, size } = query;
const rowSelection = { const rowSelection = {
selectedRowKeys: _.pluck(selectedRowKeys, "id"), selectedRowKeys: _.pluck(selectedRowKeys, 'id'),
onSelect: this.selectLiveList, onSelect: this.selectLiveList,
onSelectAll: (selected, _selectedRows, changeRows) => { onSelectAll: (selected, _selectedRows, changeRows) => {
let _list = []; let _list = [];
if (selected) { if (selected) {
_list = _.uniq( _list = _.uniq(selectedRowKeys.concat(changeRows), false, (item) => item.id);
selectedRowKeys.concat(changeRows),
false,
(item) => item.id
);
} else { } else {
_list = _.reject(selectedRowKeys, (item) => _list = _.reject(selectedRowKeys, (item) => _.find(changeRows, (data) => data.id === item.id));
_.find(changeRows, (data) => data.id === item.id)
);
} }
this.setState({ selectedRowKeys: _list }); this.setState({ selectedRowKeys: _list });
}, },
}; };
return ( return (
<div className="live-list"> <div className='live-list'>
<TableSelectedData <TableSelectedData
selectedNum={selectedRowKeys.length} selectedNum={selectedRowKeys.length}
clearSelectedData={() => { clearSelectedData={() => {
...@@ -215,14 +192,14 @@ class VideoList extends React.Component { ...@@ -215,14 +192,14 @@ class VideoList extends React.Component {
rowKey={(record) => record.id} rowKey={(record) => record.id}
dataSource={dataSource} dataSource={dataSource}
columns={this.parseColumns()} columns={this.parseColumns()}
size="middle" size='middle'
rowSelection={rowSelection} rowSelection={rowSelection}
pagination={false} pagination={false}
bordered bordered
className="video-list-table" className='video-list-table'
/> />
<div className="box-footer"> <div className='box-footer'>
{totalCount > 0 && ( {totalCount > 0 && (
<PageControl <PageControl
current={current - 1} current={current - 1}
......
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { withRouter } from "react-router-dom";
import { Tabs } from 'antd'; import { Tabs } from 'antd';
import { Route, withRouter } from 'react-router-dom';
import Service from '@/common/js/service'; import Service from '@/common/js/service';
import Breadcrumbs from "@/components/Breadcrumbs"; import Breadcrumbs from "@/components/Breadcrumbs";
import UserLearningData from './UserLearningData';
import DataInfo from './components/DataInfo' import DataInfo from './components/DataInfo'
import CourseTable from './components/CourseTable'; import CourseTable from './components/CourseTable';
import DataAnalysic from './components/DataAnalysic';
import ExamTable from './components/ExamTable'; import ExamTable from './components/ExamTable';
import StudyTable from './components/StudyTable'; import StudyTable from './components/StudyTable';
import './index.less' import './index.less'
const { TabPane } = Tabs; const { TabPane } = Tabs;
function DataCenter(props: any) { function DataCenter(props: any) {
const { match: { params: { taskId } } } = props; const { match } = props;
const { params: { taskId } } = match;
const [info, setInfo] = useState<any>({}) const [info, setInfo] = useState<any>({})
const [tabKey, setTabKey] = useState<any>('') const [tabKey, setTabKey] = useState<any>('')
...@@ -21,16 +24,25 @@ function DataCenter(props: any) { ...@@ -21,16 +24,25 @@ function DataCenter(props: any) {
name: '课程目录', name: '课程目录',
key: 'course', key: 'course',
compoment: CourseTable, compoment: CourseTable,
show:()=>{
return true
}
}, },
{ {
name: '学习详情', name: '学习详情',
key: 'study', key: 'study',
compoment: StudyTable, compoment: StudyTable,
show:()=>{
return info.courseNum
}
}, },
{ {
name: '考试详情', name: '考试详情',
key: 'exam', key: 'exam',
compoment: ExamTable, compoment: ExamTable,
show:()=>{
return info.examNum
}
}, },
] ]
...@@ -44,8 +56,8 @@ function DataCenter(props: any) { ...@@ -44,8 +56,8 @@ function DataCenter(props: any) {
res.result.trainingStageList.map((item: any) => { res.result.trainingStageList.map((item: any) => {
item.open = true item.open = true
}) })
res.result.cover =res.result.courseMediaVOS.filter((item:any) => item.contentType === 'COVER')[0] || {}; res.result.cover = res.result.courseMediaVOS.filter((item: any) => item.contentType === 'COVER')[0] || {};
res.result.intro =res.result.courseMediaVOS.filter((item:any) => item.contentType === 'INTRO')[0] || {}; res.result.intro = res.result.courseMediaVOS.filter((item: any) => item.contentType === 'INTRO')[0] || {};
setInfo(res.result) setInfo(res.result)
}) })
} }
...@@ -62,7 +74,7 @@ function DataCenter(props: any) { ...@@ -62,7 +74,7 @@ function DataCenter(props: any) {
<Tabs defaultActiveKey={'course'} onChange={() => { }}> <Tabs defaultActiveKey={'course'} onChange={() => { }}>
{ {
tabList.map((item: any) => { tabList.map((item: any) => {
return <TabPane tab={item.name} key={item.key}> return item.show() && <TabPane tab={item.name} key={item.key}>
{ {
<item.compoment info={info} taskId={taskId} /> <item.compoment info={info} taskId={taskId} />
} }
...@@ -72,7 +84,13 @@ function DataCenter(props: any) { ...@@ -72,7 +84,13 @@ function DataCenter(props: any) {
</Tabs> </Tabs>
</div> </div>
<Route
path={`${match.url}/analysic/:id`}
render={() => {
return <DataAnalysic />;
}}
/>
<Route path={`${props.match.url}/user-learning-data/:storeCustomerId`} render={() => <UserLearningData taskId={taskId} />} />
</div> </div>
} }
......
/*
* @Author: yuananting
* @Date: 2021-08-16 17:35:15
* @LastEditors: yuananting
* @LastEditTime: 2021-08-16 22:06:40
* @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { withRouter } from "react-router-dom"; import { withRouter } from 'react-router-dom';
import RichText from '@/components/RichText' import RichText from '@/components/RichText';
import ExpiredCourseList from '../../train-task/components/ExpiredCourseList'; import ExpiredCourseList from '../../train-task/components/ExpiredCourseList';
import ENUM from '../../enum'; import ENUM from '../../enum';
import './course.less' import './course.less';
function CourseTable(props: any) { function CourseTable(props: any) {
const IndexText = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'] const taskId = props.match.params.taskId.replace(/\?.+/, '');
const [list, setList] = useState<any[]>([]); const IndexText = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'];
useEffect(() => { const [list, setList] = useState<any[]>([]);
console.log(props.info, 'rtyuio') useEffect(() => {
setList(props.info.trainingStageList || []) setList(props.info.trainingStageList || []);
}, [props.info.trainingStageList]) }, [props.info.trainingStageList]);
return (
<div className='courseTabContent'>
<div className='tips'>
{`培训目的:`}
<RichText url={props.info?.intro?.mediaUrl} />
</div>
return <div className="courseTabContent"> <div className='coursecontent'>
<div className="tips"> {list?.map((item: any, index: number) => {
{`培训目的:`} return (
<div className='task'>
<RichText url={props.info?.intro?.mediaUrl} /> <div
className='title'
onClick={() => {
const _list = [...list];
_list[index].open = !_list[index].open;
setList(_list);
}}>
{item.open ? <span className='icon iconfont open'>&#xe614;</span> : <span className='icon iconfont'>&#xe614;</span>}
{`${IndexText[index]}、 `}
{item.stageName}
</div>
{item.open && (
<div className='taskItemList'>
{item.contentVOList.map((_item: any, _index: number) => {
return (
<div className={_index == item.contentVOList.length - 1 ? 'item noBorder' : 'item'}>
<div className='name'>
<img className='type-option-icon' src={ENUM.LearningContentIcon[_item.courseType || _item.contentType]} />
<span style={{ marginRight: 4 }}> {`${index + 1}.${_index + 1}`}</span>
</div> {_item.contentName}
{_item.courseType == 'LIVE' && <span className='desc'>{ENUM.courseStateShow[_item.courseState].title}</span>}
<div className="coursecontent"> {_item.courseType == 'VOICE' && <span className='desc'>{`(共${_item.courseChapterNum}节)`}</span>}
{
list?.map((item: any, index: number) => {
return <div className="task">
<div className="title" onClick={() => {
const _list = [...list];
_list[index].open = !_list[index].open;
setList(_list)
}}>
{
item.open ? <span className="icon iconfont open">&#xe614;</span> : <span className="icon iconfont">&#xe614;</span>
}
{
`${IndexText[index]}、 `
}
{item.stageName}
</div> </div>
{ </div>
item.open && <div className="taskItemList"> );
{ })}
item.contentVOList.map((_item: any, _index: number) => { </div>
return <div className={_index == item.contentVOList.length - 1 ? "item noBorder" : "item"}> )}
<div className="name">
<img className='type-option-icon' src={ENUM.LearningContentIcon[_item.courseType || _item.contentType]} />
<span style={{ marginRight: 4 }}> {`${index + 1}.${_index + 1}`}</span>
{
_item.contentName
}
{
(_item.courseType == 'LIVE') && <span className='desc'>{ENUM.courseStateShow[_item.courseState].title}</span>
}
{
_item.courseType == 'VOICE' && <span className='desc'>{`(共${_item.courseChapterNum}节)`}</span>
}
</div>
</div>
})
}
</div>
}
</div>
})
}
</div>
<div className="expired">
<div className="title">失效课程</div>
<div className="list">
<ExpiredCourseList expiredCourseList={list} />
</div> </div>
</div> );
})}
</div>
<div className='expired'>
<ExpiredCourseList taskId={taskId} />
</div>
</div> </div>
);
} }
export default withRouter(CourseTable) export default withRouter(CourseTable);
\ No newline at end of file
import React, { useState, useRef, useEffect, useContext } from 'react'
import { Route, withRouter } from 'react-router-dom';
import Breadcrumbs from "@/components/Breadcrumbs";
import UserData from './UserData';
import ExamData from './ExamData'
import Service from "@/common/js/service";
import { Tabs } from 'antd';
import User from "@/common/js/user";
import './dataAnalysic.less'
const { TabPane } = Tabs;
function DataAnalysic(props: any) {
const examDetailInit: any = {};
const [selectKey, setSelectKey] = useState('user')
const [examDetail, setExamDetail] = useState(examDetailInit);
const { match } = props;
const examId =match.params.id;
useEffect(() => {
queryExamDetail();
}, [])
function queryExamDetail() {
Service.Hades("public/hades/queryExamDetail", {
examId:examId,
tenantId: User.getStoreId(),
userId: User.getStoreUserId(),
source: 0
}).then((res) => {
const { result } = res
setExamDetail(result)
})
}
return <div className="page dataAnalysic">
<Breadcrumbs navList={"考试数据"} goBack={props.history.goBack} />
<div className="box">
<div className="titleBox ">
考试名称:{examDetail.examName}
</div>
</div>
<div className="box" style={{ paddingTop: 0 }}>
<Tabs activeKey={selectKey} onChange={(key: any) => {
setSelectKey(key)
}}>
<TabPane tab="考试人员数据" key="user">
<UserData examDetail ={examDetail } examId={examId} />
</TabPane>
<TabPane tab="题目数据" key="exam">
<ExamData examDetail ={examDetail } examId={examId}></ExamData>
</TabPane>
</Tabs>
</div>
</div>
}
export default withRouter(DataAnalysic);
\ No newline at end of file
...@@ -22,7 +22,7 @@ function DataInfo(props: any) { ...@@ -22,7 +22,7 @@ function DataInfo(props: any) {
<span style={{ marginLeft: 24 }}> {`培训时间:${moment(props.info.startTime).format('YYYY-MM-DD HH:mm')} 至 ${moment(props.info.endTime).format('YYYY-MM-DD HH:mm')}`}</span> <span style={{ marginLeft: 24 }}> {`培训时间:${moment(props.info.startTime).format('YYYY-MM-DD HH:mm')} 至 ${moment(props.info.endTime).format('YYYY-MM-DD HH:mm')}`}</span>
</div> </div>
<div className="info"> <div className="info">
<div className="item">{`任务数:${props.info.contentNum}`}</div> <div className="item">{`任务数: ${props.info.contentNum}`}</div>
{ {
!!props.info.courseNum && <div className="item"><span className="icon"><img src="https://image.xiaomaiketang.com/xm/6C2GjSpnDp.png" alt="" /></span>{`课程:${props.info.courseNum}`}</div> !!props.info.courseNum && <div className="item"><span className="icon"><img src="https://image.xiaomaiketang.com/xm/6C2GjSpnDp.png" alt="" /></span>{`课程:${props.info.courseNum}`}</div>
} }
...@@ -39,7 +39,18 @@ function DataInfo(props: any) { ...@@ -39,7 +39,18 @@ function DataInfo(props: any) {
</div> </div>
<div className="right"> <div className="right">
<div className="prog"> <div className="prog">
<Progress type="circle" width={85} percent={parseInt(props.info.finishCustomerNum /(props.info.cultureCustomerNum)*100 as any)} strokeWidth={10} format={percent => <div className='wcl'>{`${(parseInt(props.info.finishCustomerNum /(props.info.cultureCustomerNum)*100 as any))}% `} <div>完成率</div></div>} /> <Progress type="circle" width={85} percent={parseInt(props.info.finishCustomerNum /(props.info.cultureCustomerNum)*100 as any)} strokeWidth={10}
format={percent => <div className='wcl'>
{`${(parseInt(props.info.finishCustomerNum /(props.info.cultureCustomerNum)*100 as any))}% `}
<div>完成率</div>
</div>} />
{/* <div className='wcl'> */}
{/* {`${(parseInt(props.info.finishCustomerNum /(props.info.cultureCustomerNum)*100 as any))}% `} */}
{/* <div>完成率</div> */}
{/* </div> */}
</div> </div>
<div className="num"> <div className="num">
<div className="item"> {`指派人数:${props.info.cultureCustomerNum}`}</div> <div className="item"> {`指派人数:${props.info.cultureCustomerNum}`}</div>
......
import React, { useState, useRef, useEffect } from "react";
import Service from "@/common/js/service";
import { PageControl } from "@/components";
import { Input, Select, Tooltip, Button } from "antd";
import User from "@/common/js/user";
import { XMTable } from "@/components";
import college from "@/common/lottie/college.json";
import "./userData.less";
interface sortType {
type: "ascend" | "descend" | null | undefined;
}
function ExamData(props: any) {
const sortStatus: sortType = {
type: undefined,
};
const examDataInit: any = {};
const queryInit: any = { current: 1, size: 10, order: "SORT_ASC" };
const [examData, setUserData] = useState(examDataInit);
const [list, setList] = useState([]);
const [query, setQuery] = useState(queryInit);
const [total, setTotal] = useState(0);
const [field, setfield] = useState("");
const [allData, setAllData] = useState(0);
const [order, setOrder] = useState(sortStatus.type);
const questionTypeList = {
SINGLE_CHOICE: "单选题",
MULTI_CHOICE: "多选题",
JUDGE: "判断题",
GAP_FILLING: "填空题",
INDEFINITE_CHOICE: "不定项选择题",
};
const userTypeEnum = {
WORK_WE_CHAT: "企业微信",
WE_CHAT: "微信",
};
const userExamStateEnum = {
EXAM: "进行中",
LACK_EXAM: "缺考",
FINISH_EXAM: "已考试",
};
const orderEnum = {
currentAccuracy: {
ascend: "ACCURACY_ASC",
descend: "ACCURACY_DESC",
},
};
const queryRef = useRef({});
useEffect(() => {
queryExamUserData();
}, []);
useEffect(() => {
queryRef.current = query;
queryExamUserDataList();
}, [query]);
function queryExamUserData() {
Service.Hades("public/hades/queryExamQuestionData", {
examId: props.examId,
tenantId: User.getStoreId(),
userId: User.getStoreUserId(),
source: 0,
}).then((res) => {
setUserData(res.result);
});
}
function queryExamUserDataList() {
Service.Hades("public/hades/queryExamQuestionDataList", {
...query,
examId: props.examId,
tenantId: User.getStoreId(),
userId: User.getStoreUserId(),
source: 0,
}).then((res) => {
setList(res.result.records);
setTotal(parseInt(res.result.total));
if (!allData) {
setAllData(parseInt(res.result.total));
}
});
}
const columns = [
{
title: "序号",
dataIndex: "sort",
width: 60,
render: (text: any, record: any, index: any) => <span>{index + 1}</span>,
},
{
title: "题目",
dataIndex: "questionStem",
ellipsis: true,
width: 350,
render: (val: any) => {
var handleVal = val;
handleVal = handleVal.replace(/<(?!img|input).*?>/g, "");
handleVal = handleVal.replace(/<\s?input[^>]*>/gi, "_、");
handleVal = handleVal.replace(/\&nbsp\;/gi, " ");
return (
<Tooltip
overlayClassName="aid-tool-list"
title={
<div style={{ maxWidth: 700, width: "auto" }}>{handleVal}</div>
}
placement="topLeft"
overlayStyle={{ maxWidth: 700 }}
>
{handleVal}
</Tooltip>
);
},
},
{
title: "题型",
dataIndex: "questionType",
render: (text: any) => <span>{(questionTypeList as any)[text]}</span>,
filters: Object.keys(questionTypeList).map((key) => {
return {
text: (questionTypeList as any)[key],
value: key,
};
}),
},
{
title: "本次正确率",
dataIndex: "currentAccuracy",
sorter: true,
sortOrder: field === "currentAccuracy" ? order : sortStatus.type,
render: (text: any) => <span>{parseInt((text * 100) as any)}%</span>,
},
{
title: (
<div>
历史正确率{" "}
<Tooltip
overlayClassName="tool-list"
title="包含本次考试正确率"
placement="top"
overlayStyle={{ maxWidth: 700 }}
>
{" "}
<span
style={{ color: "rgba(191, 191, 191, 1)",fontWeight: 400 }}
className="icon iconfont"
>
&#xe61d;
</span>
</Tooltip>
</div>
),
dataIndex: "totalAccuracy",
render: (text: any) => <span>{parseInt((text * 100) as any)}%</span>,
},
];
function onChange(pagination: any, filters: any, sorter: any, extra: any) {
console.log(filters, sorter);
setfield(sorter.field);
setOrder(sorter.order);
console.log(sorter.field, sorter.order, (orderEnum as any)[sorter.field]);
let _query: any = { ...queryRef.current };
console.log(filters.questionType);
if (filters.questionType) {
console.log(233232);
_query.questionType = filters.questionType;
_query.current = 1;
} else {
delete _query.questionType;
}
_query.order = (orderEnum as any)[sorter.field][sorter.order];
setQuery(_query);
}
function download() {
Service.Hades("public/hades/exportExamData", {
// ...query,
examId: props.examId,
exportDataType: "EXAM_QUESTION_DATA",
tenantId: User.getStoreId(),
userId: User.getStoreUserId(),
source: 0,
}).then((res) => {
const dom = (document as any).getElementById("load-play-back-excel");
dom.setAttribute("href", res.result);
dom.click();
});
}
return (
<div className="rr">
<a
download
id="load-play-back-excel"
style={{ position: "absolute", left: "-10000px" }}
></a>
<div className="dataPanal">
{!!examData.singleChoiceCnt && (
<div className="item">
<div className="num">
{Math.round((examData.singleChoiceAccuracy || 0) * 100)}%
</div>
<div className="percent">正确率</div>
<div className="subTitle">
<div className="type">
<span className="icon iconfont">&#xe7fa;</span>单选题{" "}
<span>(共{examData.singleChoiceCnt}题)</span>
</div>
</div>
</div>
)}
{!!examData.multiChoiceCnt && (
<div className="item">
<div className="num">
{Math.round((examData.multiChoiceAccuracy || 0) * 100)}%
</div>
<div className="percent">正确率</div>
<div className="subTitle">
<div className="type">
<span className="icon iconfont">&#xe7fb;</span>多选题
<span>(共{examData.multiChoiceCnt}题)</span>
</div>
</div>
</div>
)}
{!!examData.judgeCnt && (
<div className="item">
<div className="num">
{Math.round((examData.judgeAccuracy || 0) * 100)}%
</div>
<div className="percent">正确率</div>
<div className="subTitle">
<div className="type">
<span className="icon iconfont">&#xe7fc;</span>判断题
<span>(共{examData.judgeCnt}题)</span>
</div>
</div>
</div>
)}
{!!examData.gapFillingCnt && (
<div className="item">
<div className="num">
{Math.round((examData.gapFillingAccuracy || 0) * 100)}%
</div>
<div className="percent">正确率</div>
<div className="subTitle">
<div className="type">
<span className="icon iconfont">&#xe7fd;</span>填空题
<span>(共{examData.gapFillingCnt}题)</span>
</div>
</div>
</div>
)}
{!!examData.indefiniteChoiceCnt && (
<div className="item">
<div className="num">
{Math.round((examData.indefiniteChoiceAccuracy || 0) * 100)}%
</div>
<div className="percent">正确率</div>
<div className="subTitle">
<div className="type">
<span className="icon iconfont">&#xe7fe;</span>不定项选择题{" "}
<span>(共{examData.indefiniteChoiceCnt}题)</span>
</div>
</div>
</div>
)}
</div>
{!!allData && (
<Button style={{ marginBottom: 12, marginTop: 12 }} onClick={download}>
导出
</Button>
)}
<div className="content">
<XMTable
renderEmpty={{
image: college,
description: '暂无数据'
}}
bordered
size="small"
columns={columns}
dataSource={list}
onChange={onChange}
pagination={false}
></XMTable>
{total > 0 && (
<PageControl
size="small"
current={query.current - 1}
pageSize={query.size}
total={total}
toPage={(page: any) => {
console.log(page);
let _query: any = { ...queryRef.current };
_query.current = page + 1;
setQuery(_query);
}}
/>
)}
</div>
</div>
);
}
export default ExamData;
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 { PageControl, XMTable } from '@/components'; import { PageControl, XMTable } from '@/components';
import Service from '@/common/js/service'; import Service from '@/common/js/service';
import User from '@/common/js/user'; import User from '@/common/js/user';
function ExamTable(props: any) { function ExamTable(props: any) {
const { match } = props;
console.log(match)
const [query, setQuery] = useState<any>({ const [query, setQuery] = useState<any>({
current: 1, size: 10, current: 1, size: 10,
taskId: props.taskId, taskId: props.taskId,
...@@ -22,8 +25,8 @@ function ExamTable(props: any) { ...@@ -22,8 +25,8 @@ function ExamTable(props: any) {
function getList() { function getList() {
Service.Hades('public/hades/queryTrainingExamUserData', query).then((res: any) => { Service.Hades('public/hades/queryTrainingExamUserData', query).then((res: any) => {
setList(res.result.records) setList(res.result.records);
setTotal(res.result.tatal) setTotal(res.result.total);
}) })
} }
...@@ -79,7 +82,11 @@ function ExamTable(props: any) { ...@@ -79,7 +82,11 @@ function ExamTable(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' style={{ color: 'rgba(41, 102, 255, 1)', cursor: 'pointer' }} onClick={() => {
props.history.push({
pathname: `${match.url}/analysic/${record.examId}`,
});
}}>
查看数据 查看数据
</span> </span>
...@@ -90,6 +97,7 @@ function ExamTable(props: any) { ...@@ -90,6 +97,7 @@ function ExamTable(props: any) {
]; ];
return <div className="study_Table"> return <div className="study_Table">
<div style={{ marginTop: 12 }}> <div style={{ marginTop: 12 }}>
...@@ -121,7 +129,7 @@ function ExamTable(props: any) { ...@@ -121,7 +129,7 @@ function ExamTable(props: any) {
</div> </div>
)} )}
</div> </div>
</div> </div>
} }
......
...@@ -31,12 +31,12 @@ function LeftStageList(props) { ...@@ -31,12 +31,12 @@ function LeftStageList(props) {
> >
<div className="icon"> <div className="icon">
{item.isShowMoreCourse ? ( {item.isShowMoreCourse ? (
<span className="icon iconfont edit-icon">&#xe6b2;</span> <span className="icon iconfont edit-icon">&#xe677;</span>
) : ( ) : (
<span className="icon iconfont edit-icon">&#xe600;</span> <span className="icon iconfont edit-icon">&#xe600;</span>
)} )}
</div> </div>
<div className="stage-name"> <div className="stage-name oneLineText">
{ENUM.IndexToSort[index + 1]}{item.stageName} {ENUM.IndexToSort[index + 1]}{item.stageName}
</div> </div>
</div> </div>
......
...@@ -8,8 +8,7 @@ import Service from '@/common/js/service'; ...@@ -8,8 +8,7 @@ import Service from '@/common/js/service';
import ENUM from '../../enum'; import ENUM from '../../enum';
import User from '@/common/js/user'; import User from '@/common/js/user';
import moment from 'moment'; import moment from 'moment';
import UserLearningData from '../UserLearningData';
import { timers } from 'jquery';
const { Search } = Input; const { Search } = Input;
const { Option } = Select; const { Option } = Select;
declare var formatDate: any; declare var formatDate: any;
...@@ -27,34 +26,46 @@ function StudyTable(props: any) { ...@@ -27,34 +26,46 @@ function StudyTable(props: any) {
const [list, setList] = useState<any[]>([]); const [list, setList] = useState<any[]>([]);
const [total, setTotal] = useState<any>(0); const [total, setTotal] = useState<any>(0);
const [name, setName] = useState<any>(''); const [name, setName] = useState<any>('');
const timer = useRef<any>(null) const [orderFiled, setOrderFiled] = useState<any>(null);
const [sort, setSort] = useState<any>(null);
const timer = useRef<any>(null);
const sortNameMap: any = {
learnPercentage: 'LEARN_NUM',
latelyLearnTime: 'LATE_LEARN_TIME',
startLearnTime: 'START_LEARN_TIME',
}
useEffect(() => { useEffect(() => {
getList() getList()
}, [query]) }, [query, orderFiled, sort])
function getList() { function getList() {
Service.Hades('public/hades/getTaskCustomerRecordPage', query).then((res: any) => { const _query = { ...query };
delete _query.sortMap;
if (sort) {
_query.sortMap = {
[sortNameMap[orderFiled]]: sort === "ascend" ? 'SORT_ASC' : 'SORT_DESC'
}
}
Service.Hades('public/hades/getTaskCustomerRecordPage', _query).then((res: any) => {
res.result.records.map((item: any) => { res.result.records.map((item: any) => {
item.department =item.departmentNameList.map((_item:any)=>{ item.department = item.departmentNameList.map((_item: any) => {
if (_item == '1000') { if (_item == '1000') {
return '微信' return '微信'
} else { } else {
return <WWOpenDataCom type="departmentName" openid={_item} /> return <WWOpenDataCom type="departmentName" openid={_item} />
} }
}) })
}) })
setList(res.result.records) setList(res.result.records)
setTotal(res.result.total) setTotal(res.result.total)
}) })
} }
const columns = [ const columns = [
{ {
title: '学员', title: '学员',
...@@ -74,13 +85,13 @@ function StudyTable(props: any) { ...@@ -74,13 +85,13 @@ function StudyTable(props: any) {
key: 'departmentNameList', key: 'departmentNameList',
dataIndex: 'departmentNameList', dataIndex: 'departmentNameList',
render: (val: any, record: any) => { render: (val: any, record: any) => {
return <div> return <div>
{ {
record.department.map((item:any,index:number)=>{ record.department.map((item: any, index: number) => {
if((index+1) ==record.department.length){ if ((index + 1) == record.department.length) {
return item return item
}else{ } else {
return [item,';'] return [item, ';']
} }
}) })
...@@ -104,9 +115,17 @@ function StudyTable(props: any) { ...@@ -104,9 +115,17 @@ function StudyTable(props: any) {
}, },
}, },
{ {
title: '学习进度', title: <div>学习进度 <Tooltip
title={'已完成任务数/任务总数'}>
<span
style={{ color: "rgba(191, 191, 191, 1)", fontWeight: 400 }}
className="iconfont"
>&#xe61d;</span>
</Tooltip></div>,
key: 'learnPercentage', key: 'learnPercentage',
sorter: true,
dataIndex: 'learnPercentage', dataIndex: 'learnPercentage',
sortOrder: (orderFiled == 'learnPercentage') ? sort : null,
render: (val: any, record: any) => { render: (val: any, record: any) => {
return `${val}%`; return `${val}%`;
}, },
...@@ -118,8 +137,8 @@ function StudyTable(props: any) { ...@@ -118,8 +137,8 @@ function StudyTable(props: any) {
dataIndex: 'latelyLearnTime', dataIndex: 'latelyLearnTime',
sorter: true, sorter: true,
width: 240, width: 240,
sortOrder: (orderFiled == 'latelyLearnTime') ? sort : null,
render: (val: any, record: any) => { render: (val: any, record: any) => {
return `${formatDate('YYYY-MM-DD H:i', parseInt(record.latelyLearnTime))}`; return `${formatDate('YYYY-MM-DD H:i', parseInt(record.latelyLearnTime))}`;
}, },
}, },
...@@ -129,6 +148,8 @@ function StudyTable(props: any) { ...@@ -129,6 +148,8 @@ function StudyTable(props: any) {
dataIndex: 'startLearnTime', dataIndex: 'startLearnTime',
width: 240, width: 240,
sorter: true, sorter: true,
field: 'yuiooo',
sortOrder: (orderFiled == 'startLearnTime') ? sort : null,
render: (val: any, record: any) => { render: (val: any, record: any) => {
return <div>{formatDate('YYYY-MM-DD H:i', val)}</div>; return <div>{formatDate('YYYY-MM-DD H:i', val)}</div>;
}, },
...@@ -155,6 +176,13 @@ function StudyTable(props: any) { ...@@ -155,6 +176,13 @@ function StudyTable(props: any) {
}, },
]; ];
function onChange(pagination: any, filters: any, sorter: any, extra: any) {
console.log(sorter)
setOrderFiled(sorter.field || null)
setSort(sorter.order)
}
return <div className="study_Table"> return <div className="study_Table">
<div className="filter"> <div className="filter">
...@@ -257,6 +285,7 @@ function StudyTable(props: any) { ...@@ -257,6 +285,7 @@ function StudyTable(props: any) {
storeUserId: User.getStoreUserId(), storeUserId: User.getStoreUserId(),
userId: User.getStoreUserId(), userId: User.getStoreUserId(),
}) })
setSort('')
}}> }}>
&#xe61b;{' '} &#xe61b;{' '}
</span> </span>
...@@ -276,7 +305,7 @@ function StudyTable(props: any) { ...@@ -276,7 +305,7 @@ function StudyTable(props: any) {
columns={columns} columns={columns}
pagination={false} pagination={false}
className='user-learning-table' className='user-learning-table'
onChange={() => { }} onChange={onChange}
showSorterTooltip={false} showSorterTooltip={false}
bordered bordered
/> />
...@@ -294,7 +323,7 @@ function StudyTable(props: any) { ...@@ -294,7 +323,7 @@ function StudyTable(props: any) {
</div> </div>
)} )}
</div> </div>
<Route path={`${props.match.url}/user-learning-data/:storeCustomerId`} render={() => <UserLearningData taskId={props.taskId} />} />
</div> </div>
} }
......
import React, { useState, useRef, useEffect } from "react";
import Service from "@/common/js/service";
import { PageControl } from "@/components";
import { Input, Select, Tooltip, Table, Button } from "antd";
import { ColumnsType } from "antd/es/table";
import User from "@/common/js/user";
import moment from "moment";
import { XMTable } from "@/components";
import college from "@/common/lottie/college.json";
import "./userData.less";
const { Search } = Input;
const { Option } = Select;
declare var window: any;
interface sortType {
type: "ascend" | "descend" | null | undefined;
}
interface User {
key: number;
name: string;
}
function DataAnalysic(props: any) {
const sortStatus: sortType = {
type: undefined,
};
const useDataInit: any = {};
const queryInit: any = { current: 1, size: 10 };
const [useData, setUserData] = useState(useDataInit);
const [list, setList] = useState([]);
const [query, setQuery] = useState(queryInit);
const [total, setTotal] = useState(0);
const [field, setfield] = useState("");
const [allData, setAllData] = useState(0);
const [order, setOrder] = useState(sortStatus.type);
const userTypeEnum = {
WORK_WE_CHAT: "企业微信",
WE_CHAT: "微信",
};
const userExamStateEnum = {
EXAM: "进行中",
LACK_EXAM: "缺考",
FINISH_EXAM: "已考试",
};
const ExamPassColorEnum = {
EXAM_FAIL: "rgba(255, 79, 79, 1)",
EXAM_PASS: "rgba(59, 189, 170, 1)",
};
const ExamPassEnum = {
EXAM_FAIL: "不及格",
EXAM_PASS: "及格",
};
const userExamStateColorEnum = {
EXAM: "rgba(35, 143, 255, 1)",
LACK_EXAM: "rgba(204, 204, 204, 1)",
FINISH_EXAM: "rgba(47, 200, 60, 1)",
};
const orderEnum = {
score: {
ascend: "EXAM_SCORE_ASC",
descend: "EXAM_SCORE_DESC",
},
userDuration: {
ascend: "USER_DURATION_ASC",
descend: "USER_DURATION_DESC",
},
};
const queryRef = useRef({});
useEffect(() => {
queryExamUserData();
}, []);
useEffect(() => {
queryRef.current = query;
queryExamUserDataList();
}, [query]);
function queryExamUserData() {
Service.Hades("public/hades/queryExamUserData", {
examId: props.examId,
tenantId: User.getStoreId(),
userId: User.getStoreUserId(),
source: 0,
}).then((res) => {
setUserData(res.result);
});
}
function queryExamUserDataList() {
Service.Hades("public/hades/queryExamUserDataList", {
...query,
examId: props.examId,
tenantId: User.getStoreId(),
userId: User.getStoreUserId(),
source: 0,
}).then((res) => {
setList(res.result.records);
setTotal(parseInt(res.result.total));
if (!allData) {
setAllData(parseInt(res.result.total));
}
});
}
const columns: ColumnsType<User> = [
{
title: "学员",
dataIndex: "userName",
render: (text: any, record: any) => (
<span>
{text}
<span
style={{
color:
record.userSource === "WORK_WE_CHAT"
? "rgba(255, 157, 20, 1)"
: "rgba(29, 204, 101, 1)",
}}
>
@{(userTypeEnum as any)[record.userSource]}
</span>
</span>
),
},
{
title: "手机号",
dataIndex: "phone",
},
{
title: "考试状态",
dataIndex: "userExamState",
render: (text: any) => (
<span>
{" "}
<span
className="exstatus"
style={{ background: (userExamStateColorEnum as any)[text] }}
></span>{" "}
{(userExamStateEnum as any)[text]}
</span>
),
},
{
title: "考试成绩",
dataIndex: "score",
sorter: true,
sortOrder: field === "score" ? order : sortStatus.type,
render: (text: any, record: any) => (
<span>
{" "}
{text}{" "}
<span
style={{
border: `1px solid ${
(ExamPassColorEnum as any)[record.examPass]
}`,
fontSize: 12,
color: (ExamPassColorEnum as any)[record.examPass],
display: "inline-block",
padding: "0px 2px",
}}
>
{(ExamPassEnum as any)[record.examPass]}
</span>
</span>
),
},
{
title: "进入考试时间",
dataIndex: "examStartTime",
render: (text: any) => (
<span>{moment(text).format("YYYY-MM-DD HH:mm")}</span>
),
},
{
title: "考试用时",
dataIndex: "userDuration",
sorter: true,
sortOrder: field === "userDuration" ? order : sortStatus.type,
render: (text: any, record: any) => (
<span>
{record.userExamState === "FINISH_EXAM"
? window.formatHourTime(text)
: "-"}{" "}
</span>
),
},
//TODO:
{
title: "操作",
key: "",
dataIndex: "edit",
render: (value: any, record: any) => {
return (
<Choose>
<When condition={record.userExamState === "FINISH_EXAM"}>
<div
className="answer-detail"
onClick={() => {
checkAnswerDetail(record);
}}
>
答题详情
</div>
</When>
<Otherwise>-</Otherwise>
</Choose>
);
},
},
];
function onChange(pagination: any, filters: any, sorter: any, extra: any) {
setfield(sorter.field);
setOrder(sorter.order);
console.log(sorter.field, sorter.order, (orderEnum as any)[sorter.field]);
let _query: any = { ...queryRef.current };
_query.order = (orderEnum as any)[sorter.field][sorter.order];
setQuery(_query);
}
function download() {
Service.Hades("public/hades/exportExamData", {
// ...query,
examId: props.examId,
exportDataType: "EXAM_USER_DATA",
tenantId: User.getStoreId(),
userId: User.getStoreUserId(),
source: 0,
}).then((res) => {
const dom = (document as any).getElementById("load-play-back-excel");
dom.setAttribute("href", res.result);
dom.click();
});
}
//查看答题详情
function checkAnswerDetail(record: any) {
const { paperId, userExamState } = props.examDetail?.examPaper;
const { userId } = record;
window.RCHistory.push({
pathname: `/test-detail/${props.examId}?paperId=${paperId}&userExamState=${userExamState}&userId=${userId}`,
});
}
return (
<div className="rr">
<a
target="_blank"
download
id="load-play-back-excel"
style={{ position: "absolute", left: "-10000px" }}
>
111
</a>
<div className="dataPanal">
<div className="item">
<div className="num">{useData.joinCnt || 0}</div>
<div className="percent"></div>
<div className="subTitle">参与人数</div>
</div>
<div className="item">
<div className="num">{useData.finishCnt || 0}</div>
<div className="percent">
占比
{parseInt(
((useData.finishCnt || 0) / (useData.joinCnt || 1)) * 100 + ""
)}
%
</div>
<div className="subTitle">完成考试数 (人)</div>
</div>
<div className="item">
<div className="num">{useData.passCnt || 0}</div>
<div className="percent">
占比
{parseInt(
((useData.passCnt || 0) / (useData.finishCnt || 1)) * 100 + ""
)}
%
</div>
<div className="subTitle">及格数 (人)</div>
</div>
<div className="item">
<div className="num">{useData.averageScore || 0}</div>
<div className="percent">
总分{props.examDetail?.examPaper?.totalScore}
</div>
<div className="subTitle">平均分</div>
</div>
<div className="item">
<div className="num">
{" "}
{window.formatHourTime(useData.averageDuration || 0)}{" "}
</div>
<div className="percent"></div>
<div className="subTitle">平均用时</div>
</div>
</div>
<div className="xm-search-filter" style={{ marginTop: "24px" }}>
<div style={{ display: "flex" }}>
<div className="search-condition">
<div className="search-condition__item">
<span className="search-name">学员:</span>
<Search
value={query.examName}
className="search-input"
placeholder="搜索学员名或手机号"
onChange={(e) => {
const _query = { ...query };
_query.searchKey = e.target.value;
setQuery(_query);
}}
onSearch={() => {}}
enterButton={<span className="icon iconfont">&#xe832;</span>}
/>
</div>
<div className="search-condition__item">
<span className="search-name">学员类型:</span>
<Select
value={query.userSource}
placeholder="请选择学员类型"
onChange={(val) => {
const _query = { ...query };
_query.userSource = val;
setQuery(_query);
}}
className="search-input"
allowClear
>
{Object.keys(userTypeEnum).map((key: any) => {
return (
<Option value={key} key={key}>
{(userTypeEnum as any)[key]}
</Option>
);
})}
</Select>
</div>
<div className="search-condition__item">
<span className="search-name">考试状态:</span>
<Select
value={query.userExamState}
placeholder="请选择考试状态"
onChange={(val) => {
const _query = { ...query };
_query.userExamState = val;
setQuery(_query);
}}
className="search-input"
allowClear
>
{Object.keys(userExamStateEnum).map((key: any) => {
return (
<Option value={key} key={key}>
{(userExamStateEnum as any)[key]}
</Option>
);
})}
</Select>
</div>
</div>
<div className="reset-fold-area">
<Tooltip title="清空筛选">
<span
className="resetBtn iconfont icon"
onClick={() => {
setfield("");
setQuery({ current: 1, size: 10 });
}}
>
&#xe61b;{" "}
</span>
</Tooltip>
</div>
</div>
</div>
{!!allData && (
<Button style={{ marginBottom: 12 }} onClick={download}>
导出
</Button>
)}
<div className="content analysic-content">
<XMTable
renderEmpty={{
image: college,
description: '暂无数据'
}}
bordered
size="small"
rowClassName="analysic-content-row"
columns={columns}
dataSource={list}
onChange={onChange}
pagination={false}
></XMTable>
{total > 0 && (
<PageControl
size="small"
current={query.current - 1}
pageSize={query.size}
total={total}
toPage={(page: any) => {
console.log(page);
let _query: any = { ...queryRef.current };
_query.current = page + 1;
setQuery(_query);
}}
/>
)}
</div>
</div>
);
}
export default DataAnalysic;
...@@ -38,13 +38,20 @@ ...@@ -38,13 +38,20 @@
.taskItemList{ .taskItemList{
margin-left: 64px; margin-left: 64px;
.item{ .item{
padding: 16px 0px 16px 32px; padding: 16px 0px 16px 16px;
border-bottom: 1px dashed #E8E8E8; border-bottom: 1px dashed #E8E8E8;
font-size: 14px; font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC; font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400; font-weight: 400;
color: #333333; color: #333333;
line-height: 20px; line-height: 20px;
.name{
img{
width: 20px;
position: relative;
top: -2px;
}
}
&.noBorder{ &.noBorder{
border:none; border:none;
} }
......
.dataAnalysic {
.titleBox {
position: relative;
font-size: 19px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 26px;
background: #ffffff;
&::before {
width: 4px;
height: 12px;
content: '';
background-image: linear-gradient(#2966ff 83.5%, #0acca4 16.5%);
display: inline-block;
margin-right: 8px;
}
}
.ant-tabs-content-holder {
margin-top: 8px;
}
}
.dataPanal {
border-radius: 4px;
border: 1px solid #e8e8e8;
display: flex;
.item {
text-align: center;
// width: 29.9%;
position: relative;
flex: 1;
.num {
font-size: 26px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 26px;
margin-top: 12px;
}
.percent {
margin-top: 6px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #999999;
line-height: 17px;
height: 20px;
margin-bottom: 18px;
}
.subTitle {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
line-height: 20px;
margin-bottom: 12px;
}
.type {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
line-height: 20px;
span {
color: rgba(153, 153, 153, 1);
}
.icon {
color: rgba(204, 204, 204, 1);
font-size: 16px;
margin-right: 4px;
position: relative;
top: 1px;
}
}
&:after {
content: '';
width: 0px;
height: 40px;
position: absolute;
width: 1px;
background-color: rgba(232, 232, 232, 1);
top: 40px;
right: 0px;
}
&:last-child {
&:after {
display: none;
}
}
}
.exstatus {
width: 4px;
height: 4px;
background: rgb(35, 143, 255);
display: inline-block;
border-radius: 50%;
position: relative;
top: -4px;
}
}
.answer-detail {
color: rgb(35, 143, 255);
}
.analysic-content {
.ant-table-bordered .ant-table-tbody tr {
&.analysic-content-row {
height: 50px;
}
}
}
...@@ -33,8 +33,7 @@ ...@@ -33,8 +33,7 @@
line-height: 25px; line-height: 25px;
} }
.status{ .status{
width: 42px; padding: 0px 8px;
height: 20px;
font-size: 14px; font-size: 14px;
font-family: PingFangSC-Medium, PingFang SC; font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500; font-weight: 500;
...@@ -42,7 +41,9 @@ ...@@ -42,7 +41,9 @@
line-height: 20px; line-height: 20px;
text-align: center; text-align: center;
margin-left: 24px; margin-left: 24px;
position: relative;
top: 2px;
height: 20px;
} }
} }
.info{ .info{
...@@ -79,14 +80,28 @@ ...@@ -79,14 +80,28 @@
width: 85px; width: 85px;
margin-top: 27px; margin-top: 27px;
margin-right: 24px; margin-right: 24px;
position: relative;
.wcl{ .wcl{
font-size: 16px; font-size: 16px;
font-family: PingFangSC-Medium, PingFang SC; font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500; font-weight: 500;
color: #666666; color: #666666;
line-height: 22px; line-height: 22px;
text-align: center; text-align: center;
// left: 0px;
// top: 20px;
// width: 100%;
// height: 100%;
// display: none;
// position: absolute;
// z-index: 1;
} }
// &:hover{
// .wcl{
// display: block;
// }
// }
} }
.num{ .num{
margin-top: 27px; margin-top: 27px;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-07-29 13:57:03 * @Date: 2021-07-29 13:57:03
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-08-14 14:30:11 * @LastEditTime: 2021-08-16 19:47:41
* @Description: 任务中心-培训任务-新建页面 * @Description: 任务中心-培训任务-新建页面
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
...@@ -22,45 +22,40 @@ import TaskCenterService from '@/domains/task-center-domain/TaskCenterService'; ...@@ -22,45 +22,40 @@ import TaskCenterService from '@/domains/task-center-domain/TaskCenterService';
import Bus from '@/core/bus'; import Bus from '@/core/bus';
import $ from 'jquery'; import $ from 'jquery';
const defaultCover = 'https://image.xiaomaiketang.com/xm/rEAetaTEh3.png';
const DEFAULT_BASIC_INFO = {
taskName: '', // 培训任务名称
coverUrl: defaultCover,
coverId: null,
helpStoreUserIds: [], // 指定协同者id
timeType: 'FOREVER', // 培训时间,默认永久有效
startTime: null, // 固定时间段-开始时间
endTime: null, // 固定时间段-结束时间
learnType: 'FREEDOM', // 学习模式,默认自由学习
assignList: [], // 指派列表-assignId assignType
introduce: null, // 培训目的
loadintroduce: false,
};
const DEFAULT_STAGE_LIST = [
{
stageName: '阶段一',
contentList: [],
check: false,
},
];
const DEFAULT_FINISH_STANDARD = {
percentCompleteLive: 80,
percentCompleteVideo: 80, // 线上课完成百分比
percentCompletePicture: 80, // 图文课完成百分比
};
function AddTrainTask() { function AddTrainTask() {
const type = getParameterByName('type'); const type = getParameterByName('type');
const taskId = getParameterByName('taskId'); const taskId = getParameterByName('taskId');
const defaultCover = 'https://image.xiaomaiketang.com/xm/rEAetaTEh3.png';
const DEFAULT_BASIC_INFO = {
taskName: '', // 培训任务名称
coverUrl: defaultCover,
coverId: null,
helpStoreUserIds: [], // 指定协同者id
timeType: 'FOREVER', // 培训时间,默认永久有效
startTime: null, // 固定时间段-开始时间
endTime: null, // 固定时间段-结束时间
learnType: 'FREEDOM', // 学习模式,默认自由学习
assignList: [], // 指派列表-assignId assignType
introduce: null, // 培训目的
loadintroduce: false,
};
const DEFAULT_STAGE_LIST = [
{
stageName: '阶段一',
contentList: [],
check: false,
},
];
const [activeStep, setActiveStep] = useState('BASIC_INFO'); const [activeStep, setActiveStep] = useState('BASIC_INFO');
const [basicInfo, setBasicInfo] = useState(DEFAULT_BASIC_INFO); const [basicInfo, setBasicInfo] = useState(DEFAULT_BASIC_INFO);
const [stageList, setStageList] = useState(DEFAULT_STAGE_LIST); const [stageList, setStageList] = useState(DEFAULT_STAGE_LIST);
const [finishStandard, setFinishStandard] = useState(DEFAULT_FINISH_STANDARD); // 完成百分比 const [percentCompleteLive, setPercentCompleteLive] = useState(80); // 完成百分比
const [expiredCourseList, setExpiredCourseList] = useState([]); // 失效课程 const [percentCompleteVideo, setPercentCompleteVideo] = useState(80); // 完成百分比
const [percentCompletePicture, setPercentCompletePicture] = useState(80); // 完成百分比
const [startCheck, setStartCheck] = useState(false); // 是否启动校验 const [startCheck, setStartCheck] = useState(false); // 是否启动校验
const basicInfoRef = useRef(null); const basicInfoRef = useRef(null);
...@@ -71,92 +66,82 @@ function AddTrainTask() { ...@@ -71,92 +66,82 @@ function AddTrainTask() {
useEffect(() => { useEffect(() => {
if (type === 'edit') { if (type === 'edit') {
initTaskData(); initTaskData();
getTrainingCourseAutoCancel();
}
}, []);
// 编辑回显数据详情
function initTaskData() {
TaskCenterService.getTrainingTaskDetail({
taskId,
}).then((res) => {
const {
result: {
createId,
taskName,
courseMediaVOS,
helpStoreUsers,
timeType,
startTime,
endTime,
learnType,
assignList,
percentCompleteLive,
percentCompletePicture,
percentCompleteVideo,
trainingStageList,
},
} = res;
const _assignList = assignList // 编辑回显数据详情
? assignList.map((item) => { function initTaskData() {
item.checkedId = item.assignId; TaskCenterService.getTrainingTaskDetail({
item.checkedName = item.assignName; taskId,
item.checkedType = item.assignType; }).then((res) => {
const {
result: {
createId,
taskName,
courseMediaVOS,
helpStoreUsers,
timeType,
startTime,
endTime,
learnType,
assignList,
percentCompleteLive,
percentCompletePicture,
percentCompleteVideo,
trainingStageList,
},
} = res;
const _assignList = assignList
? assignList.map((item) => {
item.checkedId = item.assignId;
item.checkedName = item.assignName;
item.checkedType = item.assignType;
return item;
})
: [];
const coverInfo = courseMediaVOS.filter((item) => item.contentType === 'COVER')[0];
const coverUrl = coverInfo ? coverInfo.mediaUrl : defaultCover;
const coverId = coverInfo ? coverInfo.mediaContent : null;
const _helpStoreUserIds = helpStoreUsers.map((item) => {
item.checkedName = item.storeUserName;
item.checkedId = item.storeUserId;
return item; return item;
}) });
: [];
const coverInfo = courseMediaVOS.filter((item) => item.contentType === 'COVER')[0];
const coverUrl = coverInfo ? coverInfo.mediaUrl : defaultCover;
const coverId = coverInfo ? coverInfo.mediaContent : null;
const _helpStoreUserIds = helpStoreUsers.map((item) => {
item.checkedName = item.storeUserName;
item.checkedId = item.storeUserId;
return item;
});
const ITEM_BASIC_INFO = {
createId,
assignList: _assignList,
taskName,
coverUrl,
coverId,
helpStoreUserIds: _helpStoreUserIds,
timeType,
startTime,
endTime,
learnType,
};
const _stageList = trainingStageList.map((item) => {
item.contentList = item.contentVOList;
item.type = 'text';
return item;
});
const introduceInfo = courseMediaVOS.filter((item) => item.contentType === 'INTRO')[0]; const ITEM_BASIC_INFO = {
setBasicInfo({ ...basicInfoRef.current, ...ITEM_BASIC_INFO, loadintroduce: !introduceInfo }); createId,
assignList: _assignList,
taskName,
coverUrl,
coverId,
helpStoreUserIds: _helpStoreUserIds,
timeType,
startTime,
endTime,
learnType,
};
const _stageList = trainingStageList.map((item) => {
item.contentList = item.contentVOList;
item.type = 'text';
return item;
});
setFinishStandard({ const introduceInfo = courseMediaVOS.filter((item) => item.contentType === 'INTRO')[0];
percentCompleteLive, setBasicInfo({ ...basicInfoRef.current, ...ITEM_BASIC_INFO, loadintroduce: !introduceInfo });
percentCompletePicture, setPercentCompleteLive(percentCompleteLive);
percentCompleteVideo, setPercentCompleteVideo(percentCompleteVideo);
}); setPercentCompletePicture(percentCompletePicture);
setStageList(_stageList); setStageList(_stageList);
introduceInfo && getTextDetail('introduce', introduceInfo); introduceInfo && getTextDetail('introduce', introduceInfo);
}); });
} }
}
}, [taskId, type]);
// 获取培训任务失效的课程
function getTrainingCourseAutoCancel() {
TaskCenterService.getTrainingCourseAutoCancel({ taskId }).then((res) => {
setExpiredCourseList(res.result);
});
}
// 获取培训目的内容 // 获取培训目的内容
function getTextDetail(key, info) { function getTextDetail(key, info) {
if (info.mediaType === 'RESOURCE_ID') { if (info.mediaType === 'RESOURCE_ID') {
...@@ -193,7 +178,6 @@ function AddTrainTask() { ...@@ -193,7 +178,6 @@ function AddTrainTask() {
<Button type='primary' onClick={() => setActiveStep('TRAIN_CONTENT')}> <Button type='primary' onClick={() => setActiveStep('TRAIN_CONTENT')}>
下一步 下一步
</Button> </Button>
{/* disabled={submitDisabled} */}
</div> </div>
</When> </When>
<Otherwise> <Otherwise>
...@@ -204,7 +188,6 @@ function AddTrainTask() { ...@@ -204,7 +188,6 @@ function AddTrainTask() {
<Button type='primary' onClick={() => handleSubmit('YES')}> <Button type='primary' onClick={() => handleSubmit('YES')}>
保存并发布 保存并发布
</Button> </Button>
{/* disabled={submitDisabled} */}
</div> </div>
</Otherwise> </Otherwise>
</Choose> </Choose>
...@@ -215,8 +198,6 @@ function AddTrainTask() { ...@@ -215,8 +198,6 @@ function AddTrainTask() {
function submitRemote(introduceId, issue) { function submitRemote(introduceId, issue) {
const { assignList, endTime, helpStoreUserIds, learnType, startTime, taskName, timeType, coverId } = basicInfo; const { assignList, endTime, helpStoreUserIds, learnType, startTime, taskName, timeType, coverId } = basicInfo;
const { percentCompleteLive, percentCompletePicture, percentCompleteVideo } = finishStandard;
let _scheduleMediaRequests = []; let _scheduleMediaRequests = [];
if (coverId) { if (coverId) {
...@@ -293,7 +274,6 @@ function AddTrainTask() { ...@@ -293,7 +274,6 @@ function AddTrainTask() {
function handleSubmit(issue) { function handleSubmit(issue) {
setStartCheck(true); setStartCheck(true);
const { taskName, assignList } = basicInfo; const { taskName, assignList } = basicInfo;
const { percentCompleteLive, percentCompleteVideo, percentCompletePicture } = finishStandard;
if (!taskName) { if (!taskName) {
activeStep === 'TRAIN_CONTENT' && setActiveStep('BASIC_INFO'); activeStep === 'TRAIN_CONTENT' && setActiveStep('BASIC_INFO');
...@@ -381,13 +361,25 @@ function AddTrainTask() { ...@@ -381,13 +361,25 @@ function AddTrainTask() {
if (field === 'stageList') { if (field === 'stageList') {
setStageList(value); setStageList(value);
} else { } else {
setFinishStandard(value); switch (field) {
case 'percentCompleteLive':
setPercentCompleteLive(value);
break;
case 'percentCompleteVideo':
setPercentCompleteVideo(value);
break;
case 'percentCompletePicture':
setPercentCompletePicture(value);
break;
default:
break;
}
} }
} }
return ( return (
<div className='page add-train-task'> <div className='page add-train-task'>
<Breadcrumbs navList={type == 'add' ? '新建培训任务' : '编辑培训任务'} goBack={handleGoBack} /> <Breadcrumbs navList={type === 'add' ? '新建培训任务' : '编辑培训任务'} goBack={handleGoBack} />
<div className='box'> <div className='box'>
<div className='show-tips'> <div className='show-tips'>
<ShowTips message='请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企学院保有依据国家规定及平台规则进行处理的权利' /> <ShowTips message='请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企学院保有依据国家规定及平台规则进行处理的权利' />
...@@ -414,9 +406,10 @@ function AddTrainTask() { ...@@ -414,9 +406,10 @@ function AddTrainTask() {
<TrainContent <TrainContent
stageList={stageList} stageList={stageList}
basicInfo={basicInfo} basicInfo={basicInfo}
expiredCourseList={expiredCourseList}
startCheck={startCheck} startCheck={startCheck}
finishStandard={finishStandard} percentCompleteLive={percentCompleteLive}
percentCompleteVideo={percentCompleteVideo}
percentCompletePicture={percentCompletePicture}
onChange={handleChangeStageInfo} onChange={handleChangeStageInfo}
/> />
)} )}
......
...@@ -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-08-10 15:10:44 * @LastEditTime: 2021-08-14 17:18:39
* @Description: 任务中心-培训任务 * @Description: 任务中心-培训任务
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -23,7 +23,7 @@ function TrainTaskPage(props) { ...@@ -23,7 +23,7 @@ function TrainTaskPage(props) {
issueState: 'ALL', // 发布状态 issueState: 'ALL', // 发布状态
myAssist: false, // 是否由我协同 myAssist: false, // 是否由我协同
size: 10, size: 10,
sortMap: {}, // 排序 sortMap: { UPDATED: 'SORT_DESC' }, // 排序(默认更新时间倒序)
startTime: null, startTime: null,
storeId: User.getStoreId(), storeId: User.getStoreId(),
storeUserId: User.getStoreUserId(), storeUserId: User.getStoreUserId(),
...@@ -48,7 +48,9 @@ function TrainTaskPage(props) { ...@@ -48,7 +48,9 @@ function TrainTaskPage(props) {
useEffect(() => {}, []); useEffect(() => {}, []);
const initPageData = () => { const initPageData = () => {
Bus.bind('getTrainingTaskPage', getTrainingTaskPage); Bus.bind('getTrainingTaskPage', (filterData) => {
getTrainingTaskPage(filterData);
});
Bus.bind('getStoreTaskNum', getStoreTaskNum); Bus.bind('getStoreTaskNum', getStoreTaskNum);
}; };
...@@ -58,8 +60,8 @@ function TrainTaskPage(props) { ...@@ -58,8 +60,8 @@ function TrainTaskPage(props) {
}; };
// 获取计划列表 // 获取计划列表
function getTrainingTaskPage() { function getTrainingTaskPage(filterData) {
let _query = _.clone(query); const _query = { ...query, ...filterData };
if (_query.issueState === 'ALL') { if (_query.issueState === 'ALL') {
delete _query.issueState; delete _query.issueState;
} }
......
...@@ -2,41 +2,88 @@ ...@@ -2,41 +2,88 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-08-03 10:47:59 * @Date: 2021-08-03 10:47:59
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-08-03 18:31:56 * @LastEditTime: 2021-08-16 22:04:31
* @Description: 编辑培训任务-失效课程 * @Description: 编辑培训任务-失效课程
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React from 'react'; import React, { useState, useEffect } from 'react';
import { List } from 'antd'; import { List, message, Modal } from 'antd';
import './ExpiredCourseList.less'; import './ExpiredCourseList.less';
import ENUM from '../../enum'; import ENUM from '../../enum';
import moment from 'moment';
import TaskCenterService from '@/domains/task-center-domain/TaskCenterService';
function ExpiredCourseList(props) { function ExpiredCourseList(props) {
const expiredCourseList = [1, 2, 3, 4]; const [expiredCourseList, setExpiredCourseList] = useState([]); // 失效课程
useEffect(() => {
getTrainingCourseAutoCancel();
}, []);
// 获取培训任务失效的课程
function getTrainingCourseAutoCancel() {
TaskCenterService.getTrainingCourseAutoCancel({ taskId: props.taskId }).then((res) => {
setExpiredCourseList(res.result);
});
}
// 移除未成功开课课程
function deLExpiredCourse(contentId) {
Modal.confirm({
content: '你确定要删除该数据内容吗?',
okText: '确定',
cancelText: '取消',
icon: <span className='icon iconfont default-confirm-icon'>&#xe6f4;</span>,
onOk: () => {
const params = {
taskId,
contentIdList: [contentId],
};
TaskCenterService.delTaskCancelContent(params).then((res) => {
message.success('删除成功');
getTrainingCourseAutoCancel();
});
},
});
}
return ( return (
<div className='expired-list-page'> <div>
<div className='tip'>为了不影响学员学习,「未成功开课」的课程已从任务中移出,具体课程如下所示:</div> {expiredCourseList.length > 0 && (
<List <div className='expired-list-page'>
dataSource={expiredCourseList} <div className='tip'>为了不影响学员学习,「未成功开课」的课程已从任务中移出,具体课程如下所示:</div>
renderItem={(item) => ( <List
<List.Item> dataSource={expiredCourseList}
<div className='item-detail'> renderItem={(item) => (
<span className='icon iconfont'>&#xe80b;</span> <List.Item>
<span className='content-status'>未成功开课</span> <div className='item-detail'>
<span className='stage-name'>阶段一、</span> <span className='icon iconfont'>&#xe80b;</span>
<span className='content-name'> <span className='content-status'>未成功开课</span>
<img src={ENUM.LearningContentIcon['LIVE']} /> <span className='stage-name'>{item.stageName}</span>
<span>2.1 入门培训任务</span> <span className='content-name'>
</span> <img src={ENUM.LearningContentIcon[item.courseType]} />
<span className='teacher-name'>张老师</span> <span>{item.courseName}</span>
<span className='split'>|</span> </span>
<span className='course-time'>2020-12-12 09:00~10:00</span> <span className='teacher-name'>{item.teacherName}</span>
<span className='del-btn'>删除记录</span> <span className='split'>|</span>
</div> <span className='course-time'>
</List.Item> {moment(item.startTime).format('YYYY-MM-DD HH:mm')}~{moment(item.endTime).format('HH:mm')}
)} </span>
/> <span
className='del-btn'
onClick={() => {
deLExpiredCourse(item.courseId);
}}>
删除记录
</span>
</div>
</List.Item>
)}
/>
</div>
)}
</div> </div>
); );
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-08-01 17:28:30 * @Date: 2021-08-01 17:28:30
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-08-11 11:27:09 * @LastEditTime: 2021-08-16 19:53:06
* @Description: 新建培训任务-关联课程抽屉 * @Description: 新建培训任务-关联课程抽屉
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
...@@ -10,14 +10,12 @@ ...@@ -10,14 +10,12 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import _ from 'underscore'; import _ from 'underscore';
import { Radio, Tabs, Drawer, Input, message, Button, Tooltip } from 'antd'; import { Radio, Tabs, Drawer, Input, message, Button, Tooltip } from 'antd';
import { PageControl, XMTable } from '@/components'; import { PageControl, XMTable } from '@/components';
import college from '@/common/lottie/college'; import college from '@/common/lottie/college';
import CourseService from '@/domains/course-domain/CourseService'; import CourseService from '@/domains/course-domain/CourseService';
import User from '@/common/js/user'; import User from '@/common/js/user';
import Service from '@/common/js/service'; import Service from '@/common/js/service';
import ENUM from '../../enum';
import './RelatedCourseDrawer.less'; import './RelatedCourseDrawer.less';
const { Search } = Input; const { Search } = Input;
...@@ -97,7 +95,6 @@ class RelatedCourseDrawer extends Component { ...@@ -97,7 +95,6 @@ class RelatedCourseDrawer extends Component {
handleFetchLiveDataList = () => { handleFetchLiveDataList = () => {
const { liveQuery, liveSize } = this.state; const { liveQuery, liveSize } = this.state;
const _data = [...this.props.data]; const _data = [...this.props.data];
console.log('data=========>', _data);
let currentLiveCourseListData = []; let currentLiveCourseListData = [];
_data.map((item) => { _data.map((item) => {
item.contentList.map((childItem, childIndex) => { item.contentList.map((childItem, childIndex) => {
...@@ -129,11 +126,13 @@ class RelatedCourseDrawer extends Component { ...@@ -129,11 +126,13 @@ class RelatedCourseDrawer extends Component {
handleFetchVideoDataList = () => { handleFetchVideoDataList = () => {
const { videoQuery, videoSize, videoDataSource, videoTotalCount, videoCourseDivision } = this.state; const { videoQuery, videoSize, videoDataSource, videoTotalCount, videoCourseDivision } = this.state;
const _data = [...this.props.data]; const _data = [...this.props.data];
console.log('_data', _data);
let currentVideoCourseListData = []; let currentVideoCourseListData = [];
_data.map((item, index) => { _data.map((item, index) => {
item.contentList.map((childItem, childIndex) => { item.contentList.map((childItem, childIndex) => {
console.log('childItem', childItem);
if (childItem.courseType === 'VOICE') { if (childItem.courseType === 'VOICE') {
currentVideoCourseListData.push(childItem.courseId); currentVideoCourseListData.push(childItem.contentId);
} }
return childItem; return childItem;
}); });
...@@ -171,7 +170,7 @@ class RelatedCourseDrawer extends Component { ...@@ -171,7 +170,7 @@ class RelatedCourseDrawer extends Component {
_data.map((item, index) => { _data.map((item, index) => {
item.contentList.map((childItem, childIndex) => { item.contentList.map((childItem, childIndex) => {
if (childItem.courseType === 'PICTURE') { if (childItem.courseType === 'PICTURE') {
currentPictureCourseListData.push(childItem.courseId); currentPictureCourseListData.push(childItem.contentId);
} }
return childItem; return childItem;
}); });
...@@ -286,7 +285,7 @@ class RelatedCourseDrawer extends Component { ...@@ -286,7 +285,7 @@ class RelatedCourseDrawer extends Component {
), ),
key: 'course', key: 'course',
dataIndex: 'course', dataIndex: 'course',
width: '40%', width: '30%',
render: (val, record) => { render: (val, record) => {
if (type === 'live') { if (type === 'live') {
let hasCover = false; let hasCover = false;
...@@ -303,14 +302,7 @@ class RelatedCourseDrawer extends Component { ...@@ -303,14 +302,7 @@ class RelatedCourseDrawer extends Component {
<img className='course-cover' src={'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'} alt='' /> <img className='course-cover' src={'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'} alt='' />
</If> </If>
<div> <div className='course-name'>{record.courseName}</div>
<div className='course-name'>{record.courseName}</div>
{/* <span
className='course-status'
style={{ color: courseStateShow[record.courseState].color, border: `1px solid ${courseStateShow[record.courseState].color}` }}>
{courseStateShow[record.courseState].title}
</span> */}
</div>
</div> </div>
); );
} else { } else {
...@@ -332,10 +324,26 @@ class RelatedCourseDrawer extends Component { ...@@ -332,10 +324,26 @@ class RelatedCourseDrawer extends Component {
}, },
type === 'live' type === 'live'
? { ? {
title: '课程状态',
key: 'courseState',
dataIndex: 'courseState',
width: '25%',
render: (val, record) => {
return (
<div className='course-state'>
<span className='status-point' style={{ backgroundColor: ENUM.trainStatus[val || 'UN_START'].color }}></span>
<span>{ENUM.trainStatus[val || 'UN_START'].text}</span>
</div>
);
},
}
: {},
type === 'live'
? {
title: '上课时间', title: '上课时间',
key: 'courseTime', key: 'courseTime',
dataIndex: 'courseTime', dataIndex: 'courseTime',
width: '40%', width: '25%',
render: (val, record) => { render: (val, record) => {
return ( return (
<div> <div>
......
...@@ -70,19 +70,19 @@ ...@@ -70,19 +70,19 @@
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
line-clamp: 2; line-clamp: 2;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
width: 180px; width: 140px;
} }
.course-state { }
* { .course-state {
vertical-align: middle; * {
display: inline-block; vertical-align: middle;
} display: inline-block;
.status-point { }
width: 6px; .status-point {
height: 6px; width: 6px;
border-radius: 50%; height: 6px;
margin-right: 4px; border-radius: 50%;
} margin-right: 4px;
} }
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-08-03 17:05:32 * @Date: 2021-08-03 17:05:32
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-08-11 11:49:11 * @LastEditTime: 2021-08-16 16:36:59
* @Description: 新建培训任务-关联考试抽屉 * @Description: 新建培训任务-关联考试抽屉
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
...@@ -65,7 +65,7 @@ function RelatedExamDrawer(props) { ...@@ -65,7 +65,7 @@ function RelatedExamDrawer(props) {
paperId, paperId,
examName, examName,
passRate, passRate,
examDuration, examDuration: (examDuration || 0) * 60 * 1000,
examDesc, examDesc,
needOptionDisorder, needOptionDisorder,
resultShow, resultShow,
......
...@@ -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-14 10:10:44 * @LastEditTime: 2021-08-16 22:10:08
* @Description: 任务中心-培训任务-新建-培训内容 * @Description: 任务中心-培训任务-新建-培训内容
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
...@@ -46,25 +46,24 @@ const courseStateShow = { ...@@ -46,25 +46,24 @@ const courseStateShow = {
const SortConvert = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十']; const SortConvert = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'];
// const id = window.getParameterByName('id');
// const type = window.getParameterByName('type');
class TrainContent extends Component { class TrainContent extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
basicInfo: props.basicInfo, basicInfo: props.basicInfo,
stageList: props.stageList, stageList: props.stageList,
finishStandard: props.finishStandard, percentCompleteLive: props.percentCompleteLive,
percentCompleteVideo: props.percentCompleteVideo,
percentCompletePicture: props.percentCompletePicture,
showCourseDrawer: false, showCourseDrawer: false,
showExamDrawer: false, showExamDrawer: false,
selectedStageIndex: 0, selectedStageIndex: 0,
expiredCourseList: props.expiredCourseList, // 失效课程 type: window.getParameterByName('type'),
showStandardDetail: false, // 是否展开高级设置 showStandardDetail: false, // 是否展开高级设置
}; };
} }
componentDidMount() {} componentDidMount() { }
setTrianTypeOption = (index) => { setTrianTypeOption = (index) => {
return ( return (
...@@ -426,7 +425,6 @@ class TrainContent extends Component { ...@@ -426,7 +425,6 @@ class TrainContent extends Component {
}; };
changePercentComplete = (e, field) => { changePercentComplete = (e, field) => {
const { finishStandard } = this.state;
let _percentComplete = 0; let _percentComplete = 0;
const value = e.target.value.replace(/\D/g, ''); const value = e.target.value.replace(/\D/g, '');
if (value > 100) { if (value > 100) {
...@@ -440,24 +438,31 @@ class TrainContent extends Component { ...@@ -440,24 +438,31 @@ class TrainContent extends Component {
} }
this.setState( this.setState(
{ {
finishStandard: { [field]: _percentComplete,
...finishStandard,
[field]: _percentComplete,
},
}, },
() => { () => {
this.props.onChange('finishStandard', this.state.finishStandard); this.props.onChange(field, _percentComplete);
} }
); );
}; };
render() { render() {
const { stageList, showCourseDrawer, showExamDrawer, expiredCourseList, showStandardDetail, finishStandard, basicInfo, selectedStageIndex } = this.state; const {
console.log('finishStandard==================>', finishStandard); stageList,
const { percentCompleteLive, percentCompleteVideo, percentCompletePicture } = finishStandard; showCourseDrawer,
showExamDrawer,
showStandardDetail,
basicInfo,
selectedStageIndex,
percentCompleteLive,
percentCompleteVideo,
percentCompletePicture,
} = this.state;
const { startCheck } = this.props; const { startCheck } = this.props;
const taskId = window.getParameterByName('taskId');
return ( return (
<div className='train-content-page'> <div className='train-content-page'>
<div className='train-content__warp'> <div className='train-content__warp'>
...@@ -481,12 +486,12 @@ class TrainContent extends Component { ...@@ -481,12 +486,12 @@ class TrainContent extends Component {
)} )}
{showExamDrawer && <RelatedExamDrawer basicInfo={basicInfo} stageList={stageList} onClose={this.onCloseExamDrawer} onSave={this.confirmCreateExam} />} {showExamDrawer && <RelatedExamDrawer basicInfo={basicInfo} stageList={stageList} onClose={this.onCloseExamDrawer} onSave={this.confirmCreateExam} />}
</div> </div>
{window.getParameterByName('type') === 'edit' && expiredCourseList.length > 0 && (
<div className='expired-info__wrap'> {
<div className='module-title'>失效课程</div> this.state.type === 'edit' && <ExpiredCourseList taskId={taskId} />
<ExpiredCourseList expiredCourseList={expiredCourseList} /> }
</div>
)}
<div className='finish-standard__warp'> <div className='finish-standard__warp'>
<div <div
className='module-title' className='module-title'
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
} }
.finish-standard__warp { .finish-standard__warp {
margin-top: 24px; margin-top: 24px;
margin-bottom: 60px;
.module-title { .module-title {
height: 22px; height: 22px;
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
* @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-14 10:48:01 * @LastEditTime: 2021-08-16 22:08:57
* @Description: 描述一下咯 * @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Route, withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { Tooltip, Checkbox, Dropdown, Radio, Button, Space, Modal, message } from 'antd'; import { Tooltip, Checkbox, Dropdown, Radio, Button, Space, Modal, message } from 'antd';
import './TrainList.less'; import './TrainList.less';
import { XMTable, PageControl } from '@/components'; import { XMTable, PageControl } from '@/components';
...@@ -30,23 +30,21 @@ function TrainList(props) { ...@@ -30,23 +30,21 @@ function TrainList(props) {
const [chooseAssignorModal, setChooseAssignorModal] = useState(null); const [chooseAssignorModal, setChooseAssignorModal] = useState(null);
// 发布或取消发布培训任务 // 发布或取消发布培训任务
function updateIssueStateTrain(taskId, issueState) { function updateIssueStateTrain(taskId, state) {
Modal.confirm({ Modal.confirm({
title: '提示', title: '提示',
content: content:
issueState === 'YES' state === 'YES' ? '发布后,被指派学员将任务列表中看到该任务,确定要发布?' : '取消发布后,任务对学员暂不可见,可能会影响正在学习学员,确定要取消?',
? '发布后,被指派学员将任务列表中看到该任务,确定要发布?'
: '取消发布后,任务对学员暂不可见,可能会影响正在学习学员,确定要取消?',
okText: '确定', okText: '确定',
cancelText: '取消', cancelText: '取消',
icon: <span className='icon iconfont default-confirm-icon'>&#xe6f4;</span>, icon: <span className='icon iconfont default-confirm-icon'>&#xe6f4;</span>,
onOk: () => { onOk: () => {
TaskCenterService.updateIssueStateTraining({ TaskCenterService.updateIssueStateTraining({
taskId, taskId,
issueState, issueState: state,
}).then((res) => { }).then((res) => {
message.success(issueState === 'YES' ? '发布成功' : '取消发布成功'); message.success(state === 'YES' ? '发布成功' : '取消发布成功');
Bus.trigger('getTrainingTaskPage'); Bus.trigger('getTrainingTaskPage', { issueState, myAssist });
Bus.trigger('getStoreTaskNum'); Bus.trigger('getStoreTaskNum');
}); });
}, },
...@@ -66,7 +64,7 @@ function TrainList(props) { ...@@ -66,7 +64,7 @@ function TrainList(props) {
taskId, taskId,
}).then((res) => { }).then((res) => {
message.success('删除成功'); message.success('删除成功');
Bus.trigger('getTrainingTaskPage'); Bus.trigger('getTrainingTaskPage', { issueState, myAssist });
Bus.trigger('getStoreTaskNum'); Bus.trigger('getStoreTaskNum');
}); });
}, },
...@@ -140,7 +138,7 @@ function TrainList(props) { ...@@ -140,7 +138,7 @@ function TrainList(props) {
} }
TaskCenterService.updateTrainingTaskAssign(params).then((res) => { TaskCenterService.updateTrainingTaskAssign(params).then((res) => {
message.success('指派成功'); message.success('指派成功');
Bus.trigger('getTrainingTaskPage'); Bus.trigger('getTrainingTaskPage', { issueState, myAssist });
setChooseAssignorModal(null); setChooseAssignorModal(null);
}); });
} }
...@@ -234,10 +232,9 @@ function TrainList(props) { ...@@ -234,10 +232,9 @@ function TrainList(props) {
}, },
{ {
title: '学习人数', title: '学习人数',
width: '10%', width: '12%',
key: 'cultureCustomerNum', key: 'cultureCustomerNum',
dataIndex: 'cultureCustomerNum', dataIndex: 'cultureCustomerNum',
sorter: true,
render: (val, record) => { render: (val, record) => {
return ( return (
<Tooltip <Tooltip
...@@ -248,7 +245,13 @@ function TrainList(props) { ...@@ -248,7 +245,13 @@ function TrainList(props) {
<div>已逾期:{record.overdueCustomerNum}</div> <div>已逾期:{record.overdueCustomerNum}</div>
</div> </div>
}> }>
<span style={{ color: '#2966FF' }}>{val}</span> <span
style={{ color: '#2966FF', cursor: 'pointer' }}
onClick={() => {
props.history.push(`${match.path}/data/${record.taskId}`);
}}>
{val}
</span>
</Tooltip> </Tooltip>
); );
}, },
...@@ -272,17 +275,16 @@ function TrainList(props) { ...@@ -272,17 +275,16 @@ function TrainList(props) {
</Tooltip> </Tooltip>
</span> </span>
), ),
width: '10%', width: '11.5%',
key: 'finishPercent', key: 'finishPercent',
dataIndex: 'finishPercent', dataIndex: 'finishPercent',
sorter: true,
render: (val) => { render: (val) => {
return <span>{val}%</span>; return <span>{val}%</span>;
}, },
}, },
{ {
title: '培训时间', title: '培训时间',
width: '12.5%', width: '17%',
key: 'trainTime', key: 'trainTime',
dataIndex: 'trainTime', dataIndex: 'trainTime',
render: (val, record) => { render: (val, record) => {
...@@ -291,7 +293,7 @@ function TrainList(props) { ...@@ -291,7 +293,7 @@ function TrainList(props) {
} }
return ( return (
<span> <span>
{window.formatDate('YYYY-MM-DD H:i', record.startTime)}~{window.formatDate('YYYY-MM-DD H:i', record.endTime)} {window.formatDate('YYYY-MM-DD H:i', record.startTime)} ~ {window.formatDate('YYYY-MM-DD H:i', record.endTime)}
</span> </span>
); );
}, },
...@@ -307,7 +309,7 @@ function TrainList(props) { ...@@ -307,7 +309,7 @@ function TrainList(props) {
}, },
{ {
title: '创建时间', title: '创建时间',
width: '12%', width: '14%',
key: 'created', key: 'created',
dataIndex: 'created', dataIndex: 'created',
sorter: true, sorter: true,
...@@ -317,7 +319,7 @@ function TrainList(props) { ...@@ -317,7 +319,7 @@ function TrainList(props) {
}, },
{ {
title: '更新时间', title: '更新时间',
width: '12%', width: '14%',
key: 'updated', key: 'updated',
dataIndex: 'updated', dataIndex: 'updated',
sorter: true, sorter: true,
...@@ -331,7 +333,7 @@ function TrainList(props) { ...@@ -331,7 +333,7 @@ function TrainList(props) {
key: 'operate', key: 'operate',
dataIndex: 'operate', dataIndex: 'operate',
fixed: 'right', fixed: 'right',
width: '16%', width: '18%',
render: (val, record) => { render: (val, record) => {
return ( return (
<div className='operate'> <div className='operate'>
...@@ -383,28 +385,6 @@ function TrainList(props) { ...@@ -383,28 +385,6 @@ function TrainList(props) {
let _columnKey; let _columnKey;
let _order; let _order;
if (columnKey == 'cultureCustomerNum' && order === 'ascend') {
// 按学习人数升序排序
_columnKey = 'CUSTOMER_NUM';
_order = 'SORT_ASC';
}
if (columnKey == 'cultureCustomerNum' && order === 'descend') {
// 按学习人数降序排序
_columnKey = 'CUSTOMER_NUM';
_order = 'SORT_DESC';
}
if (columnKey == 'finishPercent' && order === 'ascend') {
// 按完成率升序排序
_columnKey = 'FINISH_PERCENT';
_order = 'SORT_ASC';
}
if (columnKey == 'finishPercent' && order === 'descend') {
// 按完成率降序排序
_columnKey = 'FINISH_PERCENT';
_order = 'SORT_DESC';
}
if (columnKey === 'created' && order === 'ascend') { if (columnKey === 'created' && order === 'ascend') {
// 按创建时间升序排序 // 按创建时间升序排序
_columnKey = 'CREATED'; _columnKey = 'CREATED';
...@@ -429,13 +409,15 @@ function TrainList(props) { ...@@ -429,13 +409,15 @@ function TrainList(props) {
const _query = { const _query = {
...query, ...query,
sortMap: {}, sortMap: {
UPDATED: 'SORT_DESC',
},
}; };
_query.sortMap[_columnKey] = _order; _query.sortMap[_columnKey] = _order;
props.onChange(_query); props.onChange(_query);
} }
function handleCreatePlan() { function handleCreateTask() {
window.RCHistory.push({ window.RCHistory.push({
pathname: '/create-train-task?type=add', pathname: '/create-train-task?type=add',
}); });
...@@ -445,7 +427,7 @@ function TrainList(props) { ...@@ -445,7 +427,7 @@ function TrainList(props) {
<div className='train-list-page'> <div className='train-list-page'>
<div className='header-line'> <div className='header-line'>
{(User.getUserRole() === 'CloudManager' || User.getUserRole() === 'StoreManager') && ( {(User.getUserRole() === 'CloudManager' || User.getUserRole() === 'StoreManager') && (
<Button type='primary' className='mr12' onClick={handleCreatePlan}> <Button type='primary' className='mr12' onClick={handleCreateTask}>
新建培训任务 新建培训任务
</Button> </Button>
)} )}
...@@ -475,7 +457,7 @@ function TrainList(props) { ...@@ -475,7 +457,7 @@ function TrainList(props) {
onChange={handleChangeTable} onChange={handleChangeTable}
bordered bordered
size='middle' size='middle'
scroll={{ x: 1600 }} scroll={{ x: 1400 }}
className='train-list-table' className='train-list-table'
renderEmpty={{ renderEmpty={{
description: <span style={{ display: 'block', paddingBottom: 24 }}>暂无数据</span>, description: <span style={{ display: 'block', paddingBottom: 24 }}>暂无数据</span>,
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
.train-task-name { .train-task-name {
display: flex; display: flex;
align-items: center; align-items: center;
cursor: pointer;
.train-cover { .train-cover {
width: 106px; width: 106px;
height: 60px; height: 60px;
...@@ -62,9 +63,12 @@ ...@@ -62,9 +63,12 @@
margin: 0 8px; margin: 0 8px;
color: #bfbfbf; color: #bfbfbf;
} }
.more-text { .more-operate {
color: #2966ff;
cursor: pointer; cursor: pointer;
.more-text {
color: #2966ff;
cursor: pointer;
}
} }
} }
......
...@@ -2,45 +2,76 @@ ...@@ -2,45 +2,76 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-08-05 17:09:36 * @Date: 2021-08-05 17:09:36
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-08-13 19:18:54 * @LastEditTime: 2021-08-16 20:35:24
* @Description: 新建培训任务-选择指派对象 * @Description: 新建培训任务-选择指派对象
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import { Modal, Tree, Tooltip, AutoComplete, Tabs } from 'antd'; import { Modal, Tree, Tooltip, Tabs, Input, Checkbox } from 'antd';
import User from '@/common/js/user'; import User from '@/common/js/user';
import { DepType } from '@/domains/store-domain/constants'; import { DepType } from '@/domains/store-domain/constants';
import StoreService from '@/domains/store-domain/storeService'; import StoreService from '@/domains/store-domain/storeService';
import WWOpenDataCom from '@/components/WWOpenDataCom'; import WWOpenDataCom from '@/components/WWOpenDataCom';
import _ from 'underscore';
import './ChooseAssignorModal.less'; import './ChooseAssignorModal.less';
import $ from 'jquery';
const { TabPane } = Tabs; const { TabPane } = Tabs;
const { DirectoryTree } = Tree; const { DirectoryTree } = Tree;
const { Search } = Input;
function ChooseAssignorModal(props) { function ChooseAssignorModal(props) {
const [structureData, setStructureData] = useState([]);
const [activeKey, setActiveKey] = useState('departMentTab');
const [checkedAssignorList, setCheckedAssignorList] = useState(props.currentAssignorList || []); // 勾选的指派对象
const [checkedAssignorKeys, setCheckedAssignorKeys] = useState(props.currentAssignorList.map((item) => item.checkedId) || []);
const [completeOptions, setCompleteOption] = useState([]);
const [searchKey, setSearchKey] = useState('');
const [open, setOpen] = useState(false);
const AssignTypeEnum = { const AssignTypeEnum = {
departMentTab: 'SECTION', departMentTab: 'SECTION',
postGrouptab: 'POST', postGrouptab: 'POST',
customGroupTab: 'CUSTOM', customGroupTab: 'CUSTOM',
}; };
const DeptTypeEnum = {
departMentTab: ['部门'],
postGrouptab: ['岗位', '岗位组'],
customGroupTab: ['分组', '分组集合'],
};
const [dropDownVisible, setDropDownVisible] = useState(false);
const [structureData, setStructureData] = useState([]);
const [activeKey, setActiveKey] = useState('departMentTab');
const [checkedAssignorList, setCheckedAssignorList] = useState(props.currentAssignorList || []); // 勾选的指派对象
const [checkedAssignorKeys, setCheckedAssignorKeys] = useState(props.currentAssignorList.map((item) => item.checkedId) || []);
const [queryName, setQueryName] = useState(''); // 搜索框内的值
const [departmentUserVOList, setDepartmentUserVOList] = useState([]);
const [departmentVOList, setDepartmentVOList] = useState([]);
const [subLevelDepartmentVOList, setSubLevelDepartmentVOList] = useState([]);
const queryNameRef = useRef(null);
const timer = useRef(null);
useEffect(() => {
queryNameRef.current = queryName;
clearTimeout(timer.current);
timer.current = setTimeout(() => {
if (!!queryName) return getCompleteOptionData(queryNameRef.current);
}, 500);
}, [queryName]);
useEffect(() => { useEffect(() => {
setQueryName(''); // 切换tab时搜索置空
setDepartmentUserVOList([]);
setDepartmentVOList([]);
setSubLevelDepartmentVOList([]);
setStructureData([]);
getStructureData(); getStructureData();
}, [activeKey]); }, [activeKey]);
useEffect(() => {
documentClick();
}, []);
function getStructureData() { function getStructureData() {
const params = { const params = {
depType: DepType[activeKey], depType: DepType[activeKey],
enterpriseId: User.getEnterpriseId(), enterpriseId: User.getEnterpriseId(),
source: 0, //0代表来自企培 source: 0, // 0代表来自企培
storeId: User.getStoreId(), storeId: User.getStoreId(),
userId: User.getUserId(), userId: User.getUserId(),
whetherCount: false, whetherCount: false,
...@@ -116,52 +147,9 @@ function ChooseAssignorModal(props) { ...@@ -116,52 +147,9 @@ function ChooseAssignorModal(props) {
setCheckedAssignorList([]); setCheckedAssignorList([]);
} }
function renderTitle(title) {
return <span>{title}</span>;
}
function renderItem(record, type) {
return {
value: record.userName || record.name,
label: (
<div
style={{
display: 'flex',
justifyContent: 'space-between',
}}
depId={record.id}
type={type}>
{type === 'user' ? (
<div>
<WWOpenDataCom type='userName' openid={record.userName} />
</div>
) : (
<div>
<WWOpenDataCom type='departmentName' openid={record.name} />
</div>
)}
{type === 'user' &&
record.postDepNamesList.map((item, index) => {
return (
<span>
<WWOpenDataCom type='departmentName' openid={item} />
</span>
);
})}
{type === 'post' && (
<span type='post' openid={record.parentName}>
{record.parentName}
</span>
)}
</div>
),
};
}
function getCompleteOptionData(value) { function getCompleteOptionData(value) {
setCompleteOption([]);
const params = { const params = {
depType: DepType[props.treeType], depType: DepType[activeKey],
queryName: value, queryName: value,
enterpriseId: User.getEnterpriseId(), enterpriseId: User.getEnterpriseId(),
source: 0, //0代表来自企培 source: 0, //0代表来自企培
...@@ -172,75 +160,131 @@ function ChooseAssignorModal(props) { ...@@ -172,75 +160,131 @@ function ChooseAssignorModal(props) {
queryType: 'CUSTOMER', queryType: 'CUSTOMER',
}; };
StoreService.getDepartmentUser(params).then((res) => { StoreService.getDepartmentUser(params).then((res) => {
const _completeOptions = [];
const userObj = {};
const departmentGroupObj = {};
const postobj = {};
const { result = {} } = res; const { result = {} } = res;
const { departmentUserVOList = [], departmentVOList = [], subLevelDepartmentVOList = [] } = result; const { departmentUserVOList = [], departmentVOList = [], subLevelDepartmentVOList = [] } = result;
if (departmentUserVOList.length > 0) { const _departmentUserVOList = departmentUserVOList.map((item) => {
userObj.label = renderTitle('学员'); item.checkedName = item.userName;
userObj.options = departmentUserVOList.map((item, index) => { item.checkedId = item.storeCustomerId;
return renderItem(item, 'user'); item.checked = checkedAssignorKeys.includes(item.checkedId);
item.checkedType = 'CUSTOMER';
return item;
});
const _departmentVOList = departmentVOList.map((item) => {
item.checkedName = item.name;
item.checkedId = item.id;
item.checked = checkedAssignorKeys.includes(item.checkedId);
item.checkedType = AssignTypeEnum[activeKey];
return item;
});
const _subLevelDepartmentVOList = subLevelDepartmentVOList.map((item) => {
item.checkedName = item.name;
item.checkedId = item.id;
item.checked = checkedAssignorKeys.includes(item.checkedId);
item.checkedType = AssignTypeEnum[activeKey];
return item;
});
setDepartmentUserVOList(_departmentUserVOList);
setDepartmentVOList(_departmentVOList);
setSubLevelDepartmentVOList(_subLevelDepartmentVOList);
});
}
// 搜索空状态渲染;
function renderEmptyContent() {
return (
<div className='empty-con'>
<img src='https://image.xiaomaiketang.com/xm/wRDrb2pJFb.png' className='empty-img' />
<div className='empty-text'>暂无数据</div>
</div>
);
}
function handleCheckedSearchAssignor(e, type) {
const { value, checked } = e.target;
let _departmentUserVOList = [...departmentUserVOList];
let _departmentVOList = [...departmentVOList];
let _subLevelDepartmentVOList = [...subLevelDepartmentVOList];
let _checkedAssignorList = [...checkedAssignorList];
if (type === 'CUSTOMER') {
if (checked) {
_departmentUserVOList = departmentUserVOList.map((item) => {
if (item.checkedId === value.checkedId) {
item.checked = true;
}
return item;
}); });
} _checkedAssignorList.push({ ...value, checked: true });
if (departmentVOList.length > 0) { } else {
switch (props.treeType) { _departmentUserVOList = departmentUserVOList.map((item) => {
case 'departMentTab': if (item.checkedId === value.checkedId) {
departmentGroupObj.label = renderTitle('部门'); item.checked = false;
break; }
case 'postGrouptab': return item;
departmentGroupObj.label = renderTitle('岗位组');
break;
case 'customGroupTab':
departmentGroupObj.label = renderTitle('分组集合');
break;
default:
break;
}
departmentGroupObj.options = departmentVOList.map((item, index) => {
return renderItem(item, 'group');
}); });
_checkedAssignorList = _checkedAssignorList.filter((item) => item.checkedId !== value.checkedId);
} }
if (subLevelDepartmentVOList.length > 0) { setDepartmentUserVOList(_departmentUserVOList);
switch (props.treeType) { }
case 'postGrouptab':
postobj.label = renderTitle('岗位'); if (type === 'DEPART') {
break; if (checked) {
case 'customGroupTab': _departmentVOList = departmentVOList.map((item) => {
postobj.label = renderTitle('分组'); if (item.checkedId === value.checkedId) {
break; item.checked = true;
default: }
break; return item;
}
postobj.options = subLevelDepartmentVOList.map((item, index) => {
return renderItem(item, 'post');
}); });
_checkedAssignorList.push({ ...value, checked: true });
} else {
_departmentVOList = departmentVOList.map((item) => {
if (item.checkedId === value.checkedId) {
item.checked = false;
}
return item;
});
_checkedAssignorList = _checkedAssignorList.filter((item) => item.checkedId !== value.checkedId);
} }
if (Object.keys(userObj).length !== 0) { setDepartmentVOList(_departmentVOList);
_completeOptions.push(userObj); }
}
if (Object.keys(departmentGroupObj).length !== 0) { if (type === 'GROUP') {
_completeOptions.push(departmentGroupObj); if (checked) {
} _subLevelDepartmentVOList = subLevelDepartmentVOList.map((item) => {
if (Object.keys(postobj).length !== 0) { if (item.checkedId === value.checkedId) {
_completeOptions.push(postobj); item.checked = true;
}
return item;
});
_checkedAssignorList.push({ ...value, checked: true });
} else {
_subLevelDepartmentVOList = subLevelDepartmentVOList.map((item) => {
if (item.checkedId === value.checkedId) {
item.checked = false;
}
return item;
});
_checkedAssignorList = subLevelDepartmentVOList.filter((item) => item.checkedId !== value.checkedId);
} }
setCompleteOption(_completeOptions); setSubLevelDepartmentVOList(_subLevelDepartmentVOList);
}); }
const _checkedAssignorKeys = _checkedAssignorList.map((item) => item.checkedId);
setCheckedAssignorKeys(_checkedAssignorKeys);
setCheckedAssignorList(_checkedAssignorList);
} }
// 弱提示渲染
function handlePlaceHolder() { function handlePlaceHolder() {
let placeholder = ''; let placeholder = '';
switch (props.treeType) { switch (activeKey) {
case 'departMentTab': case 'departMentTab':
placeholder = '搜索学员姓名、部门'; placeholder = '搜索学员、部门';
break; break;
case 'postGrouptab': case 'postGrouptab':
placeholder = '搜索学员姓名/岗位/岗位组'; placeholder = '搜索学员、岗位、岗位组';
break; break;
case 'customGroupTab': case 'customGroupTab':
placeholder = '搜索学员姓名/自定义分组集合/自定义分组'; placeholder = '搜索学员、分组、分组集合';
break; break;
default: default:
break; break;
...@@ -248,6 +292,94 @@ function ChooseAssignorModal(props) { ...@@ -248,6 +292,94 @@ function ChooseAssignorModal(props) {
return placeholder; return placeholder;
} }
function handleDepName(depArray) {
const depArrayDom = depArray.map((item, index) => {
return (
<span>
<WWOpenDataCom type='departmentName' openid={item} />
</span>
);
});
return depArrayDom;
}
function renderOptions() {
return (
<div className='left-search-dropdown' id='left-search-dropdown'>
{departmentUserVOList.length > 0 && (
<div>
<div>学员</div>
{departmentUserVOList.map((record) => {
return (
<Checkbox checked={record.checked} value={record} key={record.checkedId} onChange={(e) => handleCheckedSearchAssignor(e, 'CUSTOMER')}>
<div className='search-result-item' depId={record.checkedId} type={type}>
<div className='search-result-item__left'>
<WWOpenDataCom type='userName' openid={record.userName} />
</div>
<div className='search-result-item__right'>
<Tooltip title={<div>{handleDepName(record.depNamesList)}</div>} placement='top' arrowPointAtCenter>
{record.depNamesList.map((item, index) => {
return (
<span>
<WWOpenDataCom type='departmentName' openid={item} />
{index < record.depNamesList.length - 1 ? ';' : ''}
</span>
);
})}
</Tooltip>
</div>
</div>
</Checkbox>
);
})}
</div>
)}
{departmentVOList.length > 0 && (
<div>
<div>{DeptTypeEnum[activeKey][0]}</div>
{departmentVOList.map((record) => {
return (
<Checkbox checked={record.checked} value={record} key={record.checkedId} onChange={(e) => handleCheckedSearchAssignor(e, 'DEPART')}>
<div className='search-result-item' depId={record.checkedId} type={type}>
<div className='search-result-item__left'>
{activeKey === 'departMentTab' ? <WWOpenDataCom type='departmentName' openid={record.name} /> : <span>{record.name}</span>}
</div>
<div className='search-result-item__right'>{activeKey === 'postGrouptab' && <span>{record.parentName}</span>}</div>
</div>
</Checkbox>
);
})}
</div>
)}
{subLevelDepartmentVOList.length > 0 && (
<div>
<div>{DeptTypeEnum[activeKey][1]}</div>
{subLevelDepartmentVOList.map((record) => {
return (
<Checkbox checked={record.checked} value={record} key={record.checkedId} onChange={(e) => handleCheckedSearchAssignor(e, 'GROUP')}>
<div className='search-result-item' depId={record.checkedId} type={type}>
<div className='search-result-item__left'>{<WWOpenDataCom type='departmentName' openid={record.name} />}</div>
</div>
</Checkbox>
);
})}
</div>
)}
{departmentUserVOList.length === 0 && departmentVOList.length === 0 && subLevelDepartmentVOList.length === 0 && renderEmptyContent()}
</div>
);
}
function documentClick() {
document.onclick = function (e) {
let _con = $('#left-search-dropdown');
if (!_con.is(e.target) && _con.has(e.target).length === 0) {
setDropDownVisible(false);
}
};
}
return ( return (
<Modal <Modal
className='choose-assignor-modal' className='choose-assignor-modal'
...@@ -261,29 +393,18 @@ function ChooseAssignorModal(props) { ...@@ -261,29 +393,18 @@ function ChooseAssignorModal(props) {
maskClosable={false}> maskClosable={false}>
<div className='assignor-container'> <div className='assignor-container'>
<div className='left-list'> <div className='left-list'>
{/* <AutoComplete <Search
dropdownClassName='certain-category-search-dropdown' style={{ width: 272 }}
dropdownMatchSelectWidth={272} placeholder={handlePlaceHolder()}
allowClear value={queryName}
onChange={(value) => setSearchKey(value)} enterButton={<span className='icon iconfont'>&#xe832;</span>}
onSearch={(value) => { // onFocus={() => setDropDownVisible(true)}
getCompleteOptionData(value); onChange={(e) => {
}} setQueryName(e.target.value);
// notFoundContent={notFoundContentNode()} setDropDownVisible(!!e.target.value);
value={searchKey}
open={open}
onFocus={() => {
setOpen(true);
}}
onBlur={() => {
setOpen(false);
}}
style={{
width: 272,
}} }}
options={completeOptions} />
// onSelect={confirmSearchSelect} {dropDownVisible && renderOptions()}
placeholder={handlePlaceHolder()}></AutoComplete> */}
<div className='data-body'> <div className='data-body'>
<Tabs size={'small'} onChange={(key) => setActiveKey(key)}> <Tabs size={'small'} onChange={(key) => setActiveKey(key)}>
<TabPane key='departMentTab' tab='部门'></TabPane> <TabPane key='departMentTab' tab='部门'></TabPane>
......
...@@ -3,10 +3,73 @@ ...@@ -3,10 +3,73 @@
display: flex; display: flex;
height: 417px; height: 417px;
.left-list { .left-list {
position: relative;
width: 50%; width: 50%;
margin-right: 24px; margin-right: 24px;
padding: 0 0 12px 16px; padding: 12px 0 12px 16px;
border: 1px solid #e8e8e8; border: 1px solid #e8e8e8;
.ant-select-auto-complete .ant-select-clear {
font-size: 14px;
right: 15px;
}
.left-search-dropdown {
position: absolute;
padding: 16px;
background: #fff;
box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.08);
z-index: 999;
border-radius: 2px;
width: 274px;
max-height: 280px;
overflow-y: scroll;
.catalog-title {
font-size: 14px;
color: #666;
margin-bottom: 14px;
}
.search-result-item {
padding: 14px 0;
color: #333;
width: 220px;
display: flex;
justify-content: space-between;
.title-icon {
color: #999;
margin-right: 3px;
}
.search-result-item__left {
font-size: 14px;
}
.search-result-item__right {
font-size: 14px;
width: 84px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #999;
text-align: right;
}
}
.ant-select-dropdown-menu-item-group-title {
color: #666;
font-weight: bold;
}
.ant-select-item-option-grouped {
padding-left: 12px;
}
.empty-con {
text-align: center;
.empty-img {
width: 150px;
height: 150px;
}
.empty-text {
color: #666;
}
}
}
.data-body { .data-body {
.ant-tabs-nav { .ant-tabs-nav {
margin: 0 !important; margin: 0 !important;
...@@ -18,7 +81,7 @@ ...@@ -18,7 +81,7 @@
.tree-con { .tree-con {
overflow-y: scroll; overflow-y: scroll;
overflow-x: hidden; overflow-x: hidden;
max-height: 367px; max-height: 323px;
padding-right: 16px; padding-right: 16px;
.ant-tree .ant-tree-treenode { .ant-tree .ant-tree-treenode {
padding: 12px 0 !important; padding: 12px 0 !important;
......
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