Commit c4c91386 by yuananting

feat:培训任务初始化

parent 4f646be7
/*
* @Author: yuananting
* @Date: 2021-07-28 11:25:58
* @LastEditors: yuananting
* @LastEditTime: 2021-07-28 15:41:00
* @Description: 任务中心-培训任务
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { useEffect, useState } from 'react'
import TrainFilter from './components/TrainFilter'
import TrainOpt from './components/TrainOpt'
import TrainList from './components/TrainList'
// import PlanList from './components/PlanList'
import PlanService from '@/domains/plan-domain/planService'
import User from '@/common/js/user'
function TrainTaskPage() {
const [trainListData, setTrainListData] = useState([]) // 培训任务列表
const [query, setQuery] = useState({
current: 1,
size: 10
})
const [totalCount, setTotalCount] = useState(0) // 总数
useEffect(() => {
handleFetchTrainList()
}, [query])
function handleFetchTrainList(_query) {
const params = {
...query,
..._query,
storeUserId: User.getStoreUserId()
}
//动态获取计划列表
PlanService.getTrainingPlanPage(params).then((res) => {
const {
result: { records = [], total }
} = res
setTrainListData(records)
setTotalCount(total)
})
}
function queryChange(_query) {
const params = {
...query,
..._query
}
setQuery(params)
}
return (
<div className='page'>
<div className='content-header'>培训任务</div>
<div className='box'>
<TrainFilter />
<TrainOpt />
<TrainList trainListData={trainListData}/>
{/* <PlanList planListData={planListData} query={query} totalCount={totalCount} onChange={queryChange} /> */}
</div>
</div>
)
}
export default TrainTaskPage
\ No newline at end of file
/*
* @Author: 吴文洁
* @Date: 2020-07-14 15:41:30
* @Last Modified by: 吴文洁
* @Last Modified time: 2020-07-23 13:45:16
* @Description: 大班直播、互动班课列表的筛选组件
*/
import React, { useState, useEffect } from 'react';
import { withRouter } from 'react-router-dom';
import { Row, Input, Select ,Tooltip} from 'antd';
import RangePicker from "@/modules/common/DateRangePicker";
import moment from 'moment';
import StoreService from "@/domains/store-domain/storeService";
import './TrainFilter.less';
const { Search } = Input;
const { Option } = Select;
const DEFAULT_QUERY = { // 头部筛选默认值
planName: null,
startTime: null,
endTime: null,
enableState: null,
createId: null
}
const DEFAULT_CREATOR_QUERY = { // 创建人列表筛选默认值
size: 10,
current: 1,
nickName: null
}
function TrainFilter(props) {
const [expandFilter, setExpandFilter] = useState(false);
const [query, setQuery] = useState(DEFAULT_QUERY);
const [hasNext, setHasNext] = useState(false);
const [creatorQuery, setCreatorQuery] = useState(DEFAULT_CREATOR_QUERY);
const [creatorList, setCreatorList] = useState([]);
useEffect(() => {
getCreatorList();
}, []);
// 获取创建人列表
function getCreatorList(current = 1, selectList){
const _query = {
...creatorQuery,
current,
};
StoreService.getStoreUserBasicPage( _query).then((res) => {
const { result = {} } = res;
const { records = [], hasNext } = result;
const list = current > 1 ? creatorList.concat(records) : records;
setHasNext(hasNext);
setCreatorList(list);
});
}
// 滑动加载更多讲师列表
function handleScrollCreatorList(e){
const container = e.target;
const scrollToBottom = container && container.scrollHeight <= container.clientHeight + container.scrollTop;
if (scrollToBottom && hasNext) {
const _creatorQuery = {...creatorQuery};
_creatorQuery.current = creatorQuery.current + 1;
setCreatorQuery(_creatorQuery);
getCreatorList(creatorQuery.current + 1);
}
}
// 改变搜索条件
function handleChangeQuery(field, value){
const _query ={
...query,
[field]: value,
current: 1,
}
setQuery(_query);
if (field === 'planName') return;
// props.onChange( _query);
}
function handleChangeDates (dates){
const _query = _.clone(query);
if (_.isEmpty(dates)) {
delete _query.startTime;
delete _query.endTime;
} else {
_query.startTime = dates[0].valueOf();
_query.endTime = dates[1].valueOf();
}
const param ={
..._query,
current: 1,
}
setQuery(param);
props.onChange(param);
}
// 重置搜索条件
function handleReset(){
setQuery(DEFAULT_QUERY);
// props.onChange(DEFAULT_QUERY);
}
return (
<div className="train-filter-page">
<Row>
<div className="search-condition">
<div className="search-condition__item">
<span>培训任务:</span>
<Search
value={query.planName}
placeholder="搜索培训任务名称"
onChange={(e) => { handleChangeQuery('planName', e.target.value.trim())}}
// onSearch={ () => { props.onChange(query) } }
style={{ width: "calc(100% - 70px)" }}
enterButton={<span className="icon iconfont">&#xe832;</span>}
/>
</div>
<div className="search-condition__item">
<span>创建人:</span>
<Select
placeholder="请选择创建人"
style={{width:"calc(100% - 70px)"}}
showSearch
allowClear
filterOption={(input, option) => option}
suffixIcon={<span className="icon iconfont" style={{fontSize:'12px',color:'#BFBFBF'}}>&#xe835;</span>}
onPopupScroll={handleScrollCreatorList}
value={query.createId}
// onChange={(value) => {
// handleChangeQuery('createId', value)
// }}
// onSearch={(value) => {
// creatorQuery.nickName = value
// setCreatorQuery(creatorQuery)
// getCreatorList()
// }
// }
// onClear ={(value)=>{
// setCreatorQuery({
// size: 10,
// current: 1,
// nickName:null
// })
// getCreatorList()
// }
// }
>
{_.map(creatorList, (item, index) => {
return (
<Select.Option value={item.id} key={item.id}>{item.nickName}</Select.Option>
);
})}
</Select>
</div>
<div className="search-condition__item">
<span className="search-date">创建日期:</span>
<RangePicker
id="course_date_picker"
allowClear={false}
value={ query.startTime ? [moment(query.startTime), moment(query.endTime)] : null }
format={"YYYY-MM-DD"}
onChange={(dates) => { handleChangeDates(dates) }}
style={{ width: "calc(100% - 70px)" }}
/>
</div>
{ expandFilter &&
<div className="search-condition__item">
<span className="shelf-status">当前状态:</span>
<Select
style={{ width: "calc(100% - 70px)" }}
placeholder="请选择当前状态"
allowClear={true}
value={query.enableState}
onChange={(value) => { handleChangeQuery('enableState', value) }}
suffixIcon={<span className="icon iconfont" style={{fontSize:'12px',color:'#BFBFBF'}}>&#xe835;</span>}
>
<Option value="YES">开启</Option>
<Option value="NO">关闭</Option>
</Select>
</div>
}
</div>
<div className="reset-fold-area">
<Tooltip title="清空筛选"><span className="resetBtn iconfont icon" onClick={handleReset}>&#xe61b; </span></Tooltip>
<span style={{ cursor: 'pointer' }} className="fold-btn" onClick={() => {
setExpandFilter(!expandFilter)
}}>{expandFilter ? <span><span>收起</span><span className="iconfont icon fold-icon" >&#xe82d; </span> </span> : <span>展开<span className="iconfont icon fold-icon" >&#xe835; </span></span>}</span>
</div>
</Row>
</div>
)
}
export default withRouter(TrainFilter);
\ No newline at end of file
.train-filter-page {
position: relative;
margin-bottom: 4px;
.ant-input-search-button{
border-left:none;
}
.search-condition {
width: calc(100% - 80px);
display: flex;
align-items: center;
flex-wrap: wrap;
&__item {
width: 30%;
margin-right: 3%;
margin-bottom: 12px;
line-height: 32px;
}
}
.reset-fold-area {
position: absolute;
right: 12px;
}
.resetBtn {
color: #999999;
font-size: 18px;
margin-right: 8px;
}
.fold-btn {
font-size: 14px;
color: #666666;
line-height: 20px;
.fold-icon {
font-size: 12px;
margin-left:4px;
}
}
}
\ No newline at end of file
/*
* @Author: yuananting
* @Date: 2021-07-28 14:56:52
* @LastEditors: yuananting
* @LastEditTime: 2021-07-29 09:42:01
* @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React, { useState, useEffect } from "react";
import { Tabs, Tooltip, Switch, Dropdown } from "antd";
import "./TrainList.less";
import { XMTable, PageControl } from "@/components";
import User from "@/common/js/user";
const { TabPane } = Tabs;
function renderMoreOperate(item) {
return (
<div className="live-course-more-menu">
<div className="operate__item">编辑</div>
<div className="operate__item">分享</div>
<div className="operate__item">审批作业</div>
<div className="operate__item">删除 </div>
</div>
);
}
function parseColumns() {
const columns = [
{
title: "培训任务",
key: "planName",
dataIndex: "planName",
width: "18%",
fixed: "left",
render: (val, record) => {
return (
<div className="plan_name_item">
<img
className="plan-cover"
src={
record.coverUrl ||
"https://image.xiaomaiketang.com/xm/rEAetaTEh3.png"
}
alt=""
/>
<Choose>
<When condition={record.planName.length > 25}>
<Tooltip title={record.planName}>
<div className="plan-name">{val}</div>
</Tooltip>
</When>
<Otherwise>
<div className="plan-name">{val}</div>
</Otherwise>
</Choose>
</div>
);
},
},
{
title: "任务状态",
width: "10%",
key: "status",
dataIndex: "status",
render: (val, record) => {
return <div className="course-number">{"未开始"}</div>;
},
},
{
title: "任务数",
width: "10%",
key: "courseNum",
dataIndex: "courseNum",
render: (val, record) => {
return <div className="course-number">{val}</div>;
},
},
{
title: "学习人数",
width: "10%",
align: "right",
key: "cultureCustomerNum",
dataIndex: "cultureCustomerNum",
sorter: true,
render: (val) => {
return <div className="join-number">{val}</div>;
},
},
{
title: (
<span>
完成率
<Tooltip title="完成培训任务的人数/学习总人数">
<i
className="icon iconfont"
style={{
marginLeft: "5px",
cursor: "pointer",
color: "#bfbfbf",
fontSize: "14px",
fontWeight: "normal",
}}
>
&#xe61d;
</i>
</Tooltip>
</span>
),
width: "10%",
key: "rate",
dataIndex: "rate",
sorter: true,
render: (val) => {
return <span>100%</span>
},
},
{
title: "培训时间",
width: "12.5%",
key: "created",
dataIndex: "created",
sorter: true,
render: (val) => {
return (
<span style={{ whiteSpace: "nowrap" }}>
{window.formatDate("YYYY-MM-DD H:i", val)}
</span>
);
},
},
{
title: "创建人",
key: "createName",
dataIndex: "createName",
width: "11%",
render: (val) => {
return <div className="create-name">{val}</div>;
},
},
{
title: "创建时间",
width: "12.5%",
key: "created",
dataIndex: "created",
sorter: true,
render: (val) => {
return (
<span style={{ whiteSpace: "nowrap" }}>
{window.formatDate("YYYY-MM-DD H:i", val)}
</span>
);
},
},
{
title: "更新时间",
width: "10%",
key: "updated",
dataIndex: "updated",
sorter: true,
render: (val) => {
return (
<span style={{ whiteSpace: "nowrap" }}>
{window.formatDate("YYYY-MM-DD H:i", val)}
</span>
);
},
},
{
title: "操作",
key: "operate",
dataIndex: "operate",
fixed: "right",
width: "18%",
render: (val, record) => {
return (
<div className="operate">
<div
className="operate__item"
onClick={() => toLearningDataPage(record)}
>
数据
</div>
{record.enableState === "YES" && (
<>
<span className="operate__item split"> | </span>
<div
className="operate__item"
onClick={() => {
handleShowShareModal(record);
}}
>
指派
</div>
</>
)}
{record.enableState === "YES" && (
<>
<span className="operate__item split"> | </span>
<div
className="operate__item"
onClick={() => {
handleShowShareModal(record);
}}
>
发布
</div>
</>
)}
{(User.getUserRole() === "CloudManager" ||
User.getUserRole() === "StoreManager") && (
<>
<span className="operate__item split"> | </span>
<Dropdown overlay={renderMoreOperate(record)}>
<span className="more-operate">
<span className="operate-text">更多</span>
<span
className="iconfont icon"
style={{ color: "#2966FF" }}
>
&#xe824;
</span>
</span>
</Dropdown>
</>
)}
</div>
);
},
},
];
return columns;
}
function TrainList(props) {
console.log(props.trainListData);
return (
<div className="train-list-page">
<div className="search-box">
<Tabs type="card">
<TabPane tab="全部" key="all" />
<TabPane tab="已发布" key="published" />
<TabPane tab="未发布" key="unpublished" />
</Tabs>
</div>
<div className="list-content">
<XMTable
rowKey={(record) => record.id}
showSorterTooltip={false}
dataSource={props.trainListData}
columns={parseColumns()}
pagination={false}
// onChange={handleChangeTable}
bordered
size="middle"
scroll={{ x: 1400 }}
// className='plan-list-table'
renderEmpty={{
description: (
<span style={{ display: "block", paddingBottom: 24 }}>
暂无数据
</span>
),
}}
/>
{/* <div className='box-footer'>
<PageControl
current={props.query.current - 1}
pageSize={props.query.size}
total={props.totalCount}
toPage={(page) => {
// const _query = { ...props.query, current: page + 1 };
// props.onChange(_query);
}}
// onShowSizeChange={onShowSizeChange}
/> */}
{/* </div> */}
</div>
</div>
);
}
export default TrainList;
.train-list-page {
margin-top: 12px;
.ant-tabs-nav {
margin: 0 !important;
}
.course-number {
margin-right: 45px;
}
.plan-list-table {
thead.ant-table-thead {
tr {
th {
padding: 10px 12px;
}
}
}
tbody {
tr {
td.ant-table-cell {
padding: 16px 12px;
color: #333;
}
&:nth-child(even) {
background: transparent;
td {
background: #fff;
}
}
&:nth-child(odd) {
background: #fafafa;
td {
background: #fafafa;
}
}
&:hover {
td {
background: #f3f6fa;
}
}
}
}
}
.plan_name_item {
display: flex;
align-items: center;
.plan-cover {
width: 106px;
height: 60px;
border-radius: 2px;
margin-right: 8px;
}
.plan-name {
width: 188px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
height: 40px;
}
}
.operate-text {
color: #2966ff;
cursor: pointer;
}
.operate {
display: flex;
&__item {
color: #2966ff;
cursor: pointer;
&.split {
margin: 0 8px;
color: #bfbfbf;
}
}
}
.join-number {
text-align: right;
margin-right: 12px;
}
.more-operate {
line-height: 20px;
}
}
/*
* @Author: zhangleyuan
* @Date: 2021-02-20 16:45:51
* @LastEditors: yuananting
* @LastEditTime: 2021-07-28 14:46:51
* @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React from 'react';
import { Button } from 'antd';
import { withRouter } from 'react-router-dom';
import User from '@/common/js/user';
// import './PlanOpt.less';
function PlanOpt() {
function handleCreatePlan(){
window.RCHistory.push({
pathname: '/create-plan?type=add',
})
}
return (
<div className="plan-opt-page">
{ (User.getUserRole() === "CloudManager" || User.getUserRole() === "StoreManager") &&
<Button
type="primary"
className="mr12"
onClick={handleCreatePlan}
>新建培训任务</Button>
}
</div>
);
}
export default withRouter(PlanOpt)
\ No newline at end of file
/* /*
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-04-29 10:26:32 * @Date: 2020-04-29 10:26:32
* @LastEditors: wufan * @LastEditors: yuananting
* @LastEditTime: 2021-05-13 16:39:51 * @LastEditTime: 2021-07-28 11:33:13
* @Description: 内容线路由配置 * @Description: 内容线路由配置
*/ */
import Home from '@/modules/home/Home'; import Home from '@/modules/home/Home';
...@@ -36,6 +36,7 @@ import ExaminationManagerIndex from '@/modules/teach-tool/examination-manager/In ...@@ -36,6 +36,7 @@ import ExaminationManagerIndex from '@/modules/teach-tool/examination-manager/In
import ExaminationManagerTestDetail from '@/modules/teach-tool/examination-manager/TestDetailPage'; import ExaminationManagerTestDetail from '@/modules/teach-tool/examination-manager/TestDetailPage';
import KnowledgeBase from '@/modules/knowledge-base/index'; import KnowledgeBase from '@/modules/knowledge-base/index';
import CollegeInfoPage from '@/modules/college-manage/CollegeInfoPage'; import CollegeInfoPage from '@/modules/college-manage/CollegeInfoPage';
import TrainTaskPage from '@/modules/task-center/TrainTaskPage';
const mainRoutes = [ const mainRoutes = [
{ {
...@@ -161,6 +162,11 @@ const mainRoutes = [ ...@@ -161,6 +162,11 @@ const mainRoutes = [
name: '培训计划', name: '培训计划',
}, },
{ {
path: '/train-task',
component: TrainTaskPage,
name: '培训任务',
},
{
path: '/create-plan', path: '/create-plan',
component: AddPlanPage, component: AddPlanPage,
name: '创建线上课', name: '创建线上课',
......
/* /*
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-21 15:53:31 * @Date: 2021-02-21 15:53:31
* @LastEditors: wufan * @LastEditors: yuananting
* @LastEditTime: 2021-07-05 10:29:23 * @LastEditTime: 2021-07-28 11:29:17
* @Description: 描述一下咯 * @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -59,6 +59,20 @@ export const menuList: any = [ ...@@ -59,6 +59,20 @@ export const menuList: any = [
], ],
}, },
{ {
groupName: '任务中心',
groupCode: 'TrainManage',
icon: '&#xe8a6;',
img: 'https://image.xiaomaiketang.com/xm/Yy6pZ6G6kS.png',
selectImg: 'https://image.xiaomaiketang.com/xm/Z8G6NMQhaH.png',
children: [
{
groupName: '培训任务',
groupCode: 'TrainPlan',
link: '/train-task',
},
],
},
{
groupName: '助学工具', groupName: '助学工具',
groupCode: 'AidTool', groupCode: 'AidTool',
icon: '&#xe8a9;', icon: '&#xe8a9;',
......
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