Commit da09f281 by zhangleyuan

feat:处理培训计划

parent b033a851
......@@ -2,7 +2,7 @@
* @Author: zhangleyuan
* @Date: 2021-02-20 16:13:39
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-02-22 16:45:21
* @LastEditTime: 2021-02-25 17:49:09
* @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -14,7 +14,29 @@ import BasicInfo from './components/BasicInfo';
import TrainingTask from './components/TrainingTask'
import './AddPlan.less'
const DEFAULT_BASIC_DATA = {
planName:"",
enableState:"YES",
selectOperatorList:[],
instro:'',
operateType:'All_Operate',
percentCompleteLive:80,
percentCompleteVideo:80
}
function AddPlan() {
const [basicData,setBasicData] = useState(DEFAULT_BASIC_DATA);
function handleChangeBasicInfo(field, value){
console.log('field',value);
setBasicData( {
...basicData,
[field]: value,
}
)
}
return (
<div className="page add-plan-page">
<Breadcrumbs
......@@ -27,7 +49,10 @@ function AddPlan() {
<div className="add-plan-page__form">
<div className="basic-info__wrap">
<div className="title">基本信息</div>
<BasicInfo/>
<BasicInfo
data={basicData}
onChange={handleChangeBasicInfo}
/>
</div>
<div className="basic-info__wrap">
<div className="title">培训任务</div>
......
......@@ -2,25 +2,51 @@
* @Author: zhangleyuan
* @Date: 2021-02-20 16:45:51
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-02-22 18:21:13
* @LastEditTime: 2021-02-25 17:48:12
* @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React from 'react';
import React, { useState, useRef, useEffect } from 'react';
import { Button,Input,Switch,Radio,Row,Col} from 'antd';
import { withRouter } from 'react-router-dom';
import SelectOperatorModal from '../modal/SelectOperatorModal'
import './BasicInfo.less';
const { TextArea } = Input;
function BasicInfo() {
function BasicInfo(props) {
const [operatorModalVisible,setOperatorModalVisible] = useState(false);
function handleShowSelectOperatorModal(){
setOperatorModalVisible(true);
}
function handleCloseSelectOperatorMOdal(){
setOperatorModalVisible(false);
}
function handleConfirmSelectOperator(selectOperatorList){
console.log("selectOperatorList",selectOperatorList);
props.onChange('selectOperatorList',selectOperatorList);
setOperatorModalVisible(false);
}
function enableStateChange(){
if(props.data.enableState==="NO"){
props.onChange('enableState','YES')
}else{
props.onChange('enableState','NO')
}
}
return (
<div className="plan-basic-info">
<div className="plan-name">
<span className="label"><span className="require">*</span>课程名称:</span>
<Input
value={props.data.planName}
placeholder="请输入培训计划名称,最多20字"
maxLength={20}
style={{ width: 240 }}
onChange={(e)=>props.onChange('planName', e.target.value)}
/>
</div>
<div className="cover">
......@@ -46,13 +72,15 @@ function BasicInfo() {
maxLength={200}
style={{ width: 480 }}
className="instro-textarea"
value={props.data.instro}
onChange={(e)=>props.onChange('instro', e.target.value)}
/>
</div>
<div className="wether-use">
<span className="label">是否启用:</span>
<div className="content">
<div>
<Switch checked={true} />
<Switch checked={props.data.enableState==="YES"? true:false} onChange={enableStateChange}/>
</div>
<div>
<div className="instro-text">
......@@ -65,10 +93,10 @@ function BasicInfo() {
<div className="view-range" >
<span className="label"><span className="require">*</span>可见范围:</span>
<div className="content">
<Radio.Group >
<Radio.Group value={props.data.operateType} onChange={(e) => { props.onChange('operateType', e.target.value) }}>
<Row style={{ marginBottom: '5px' }}>
<Col span={24}>
<Radio value="YES">
<Radio value="All_Operate">
所有运营师
<span className="playback__text">后续新增的运营师都有权限可见</span>
</Radio>
......@@ -76,7 +104,7 @@ function BasicInfo() {
</Row>
<Row>
<Col span={8}>
<Radio value="NO">
<Radio value="Assign_Operate ">
指定运营师
<span className="playback__text">仅被选择的运营师有权限可见</span>
</Radio>
......@@ -84,8 +112,8 @@ function BasicInfo() {
</Row>
</Radio.Group>
<div className="choose-business">
<Button>选择运营师</Button>
<span>已选择<span>0</span>名运营师</span>
<Button onClick={handleShowSelectOperatorModal}>选择运营师</Button>
<span>已选择<span>{props.data.selectOperatorList.length}</span>名运营师</span>
</div>
</div>
</div>
......@@ -94,14 +122,22 @@ function BasicInfo() {
<div>
<div>
<span className="icon iconfont">&#xe865;</span>
<span>直播课单个课程,用户学习进度达到<Input width="40"/>% 即视为“已完成”学习</span>
<span>直播课单个课程,用户学习进度达到<Input width="40" value={props.data.percentCompleteLive} onChange={(e) => { props.onChange('percentCompleteLive', e.target.value) }}/>% 即视为“已完成”学习</span>
</div>
<div>
<span className="icon iconfont">&#xe864;</span>
<span>视频课单个课程,用户学习进度达到<Input width="40"/>%即视为“已完成”学习</span>
<span>视频课单个课程,用户学习进度达到<Input width="40" value={props.data.percentCompleteVideo} onChange={(e) => { props.onChange('percentCompleteVideo', e.target.value) }} />%即视为“已完成”学习</span>
</div>
</div>
</div>
{ operatorModalVisible &&
<SelectOperatorModal
visible={operatorModalVisible}
onClose={handleCloseSelectOperatorMOdal}
selectOperatorList={props.data.selectOperatorList}
onSelect={handleConfirmSelectOperator}
/>
}
</div>
);
}
......
......@@ -2,7 +2,7 @@
* @Author: zhangleyuan
* @Date: 2021-02-20 16:45:51
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-02-24 19:53:39
* @LastEditTime: 2021-02-25 13:42:07
* @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -22,57 +22,63 @@ const DragHandle = sortableHandle(() => (
));
const data = [
{
taskName: '培训计划名称A',
index:0,
type:'text',
courserList:[
{
courseName:'培训计划课程A-1',
type:'text',
index:0
},
{
courseName:'培训计划课程A-2',
type:'text',
index:1
},
{
courseName:'培训计划课程A-3',
type:'text',
index:2
}
]
},
{
taskName: '培训计划名称B',
index:1,
type:'text',
courserList:[
{
courseName:'培训计划课程B-1',
index:0,
type:'text',
},
{
courseName:'培训计划课程B-2',
index:1,
type:'text',
}
]
},
{
taskName: '培训计划名称C',
index:2,
type:'text',
courserList:[
{
courseName:'培训计划课程c-1',
index:0,
type:'text'
}
]
},
// {
// taskName: '培训计划名称A',
// index:0,
// type:'text',
// courserList:[
// {
// courseName:'培训计划课程A-1',
// type:'text',
// index:0,
// id:'00'
// },
// {
// courseName:'培训计划课程A-2',
// type:'text',
// index:1,
// id:'01'
// },
// {
// courseName:'培训计划课程A-3',
// type:'text',
// index:2,
// id:'02'
// }
// ]
// },
// {
// taskName: '培训计划名称B',
// index:1,
// type:'text',
// courserList:[
// {
// courseName:'培训计划课程B-1',
// index:0,
// type:'text',
// id:'10'
// },
// {
// courseName:'培训计划课程B-2',
// index:1,
// type:'text',
// id:'11'
// }
// ]
// },
// {
// taskName: '培训计划名称C',
// index:2,
// type:'text',
// courserList:[
// {
// courseName:'培训计划课程c-1',
// index:0,
// type:'text',
// id:'20'
// }
// ]
// },
];
const SortableItem = sortableElement(props => <tr {...props} />);
......@@ -92,7 +98,7 @@ class TrainingTask extends React.Component {
title: 'taskName',
dataIndex: 'taskName',
className: 'drag-visible',
render: (val, record) => {
render: (val, record,index) => {
return (
<div>
{record.type==='text'?
......@@ -118,7 +124,7 @@ class TrainingTask extends React.Component {
key: 'operate',
dataIndex: 'operate',
width: '25%',
render: (val, record) => {
render: (val, record,index) => {
return (
<div className="operate">
<DragHandle />
......@@ -126,7 +132,7 @@ class TrainingTask extends React.Component {
<span className="icon iconfont">&#xe6f5;</span>
<span onClick={(e)=>{const {dataSource}= this.state; record.type="input";this.setState(dataSource)}}>重命名</span>
</span>
<span className="operate__item">
<span className="operate__item" onClick={()=>{this.handleDeleteTask(index)}} >
<span className="icon iconfont">&#xe6f6;</span>
<span>删除</span>
</span>
......@@ -137,7 +143,7 @@ class TrainingTask extends React.Component {
];
return columns;
}
parseCoursecolumns = ()=>{
parseCoursecolumns = (parentIndex)=>{
const coursecolumns = [
{
title: 'courseName',
......@@ -170,7 +176,7 @@ class TrainingTask extends React.Component {
key: 'operate',
dataIndex: 'operate',
width: '25%',
render: (val, record) => {
render: (val, record,index) => {
return (
<div className="operate">
<DragHandle />
......@@ -178,7 +184,7 @@ class TrainingTask extends React.Component {
<span className="icon iconfont">&#xe6f5;</span>
<span onClick={(e)=>{const {dataSource}= this.state; record.type="input";this.setState(dataSource)}}>重命名</span>
</span>
<span className="operate__item">
<span className="operate__item" onClick={()=>{this.handleDeleteCourse(parentIndex,index)}}>
<span className="icon iconfont">&#xe6f6;</span>
<span>删除</span>
</span>
......@@ -231,7 +237,6 @@ class TrainingTask extends React.Component {
handleRenameTaskName = (e,record) => {
const { value } = e.target;
const { index } = record;
const { dataSource } = this.state;
record.taskName = value;
}
......@@ -246,7 +251,6 @@ class TrainingTask extends React.Component {
handleRenameCourseName = (e,record) => {
const { value } = e.target;
const { index } = record;
const { dataSource } = this.state;
record.courseName = value;
}
......@@ -258,10 +262,22 @@ class TrainingTask extends React.Component {
record.type="text";
this.setState(dataSource);
}
}
handleDeleteTask = (index)=>{
const {dataSource}= this.state;
const newData=[...dataSource];
newData.splice(index,1);
this.setState({dataSource:newData});
}
handleDeleteCourse = (parentIndex,index)=>{
const {dataSource}= this.state;
const newData=[...dataSource];
const selectData = [...newData[parentIndex].courserList]
selectData.splice(index,1)
newData[parentIndex].courserList= selectData;
this.setState({dataSource:newData});
}
render() {
const { dataSource } = this.state;
return (
......@@ -271,20 +287,20 @@ class TrainingTask extends React.Component {
dataSource={dataSource}
columns={this.parseTaskColumns()}
rowKey="index"
expandedRowRender={(record) => {
expandedRowRender={(record,index) => {
if (record.courserList.length !== 0){
return <div>
<Table
pagination={false}
dataSource={record.courserList}
columns={this.parseCoursecolumns()}
columns={this.parseCoursecolumns(index)}
rowKey="index"
components={{
body: {
wrapper: this.DraggableContainer,
row: this.DraggableBodyRow,
},
}}
// components={{
// body: {
// wrapper: this.DraggableContainer,
// row: this.DraggableBodyRow,
// },
// }}
/>
<div><Button><span>+</span><span>关联课程</span></Button></div>
</div>
......
import React from 'react';
import {Table, Modal,Input} from 'antd';
import { PageControl } from "@/components";
import StoreService from "@/domains/store-domain/storeService";
import User from '@/common/js/user'
import './SelectOperatorModal.less';
import _ from "underscore";
const { Search } = Input;
class SelectOperatorModal extends React.Component {
constructor(props) {
super(props);
this.state = {
dataSource:[],
size:10,
query: {
current: 1,
},
totalCount:0,
selectOperatorList:props.selectOperatorList
};
}
componentDidMount() {
this.handleFetchDataList();
}
// 获取运营师列表
handleFetchDataList = () => {
const {query,size,totalCount} = this.state
const params ={
...query,
size
}
StoreService.getStoreUserBasicPage(params).then((res) => {
const { result = {} } = res ;
const { records = [], total = 0 } = result;
this.setState({
dataSource: records,
totalCount: Number(total)
});
});
}
handleChangNickname = (value)=>{
const isPhone = (value || '').match(/^\d+$/);
const { query } = this.state;
if(isPhone){
query.phone = value;
query.nickName = null;
}else{
query.nickName = value;
query.phone = null;
}
query.current = 1;
this.setState({
query
})
}
onShowSizeChange = (current, size) => {
if (current == size) {
return
}
this.setState({
size
},()=>{this.handleFetchDataList()})
}
// 请求表头
parseColumns = () => {
const columns = [
{
title: '姓名',
key: 'nickName',
dataIndex: 'nickName'
},
{
title: '手机号',
key: 'phone',
dataIndex: 'phone'
}
];
return columns;
}
selectOperator = (record,selected) =>{
const {selectOperatorList} = this.state;
let _list = [];
if (selected || !_.find(selectOperatorList, (item) => item.id == record.id)) {
_list = _.uniq(selectOperatorList.concat([record]), false, (item) => item.id);
} else {
_list = _.reject(selectOperatorList, (item) => item.id === record.id);
}
this.setState({selectOperatorList:_list});
}
render() {
const { size,dataSource,totalCount,query,selectOperatorList} = this.state;
const { visible } = this.props;
return (
<Modal
title="选择运营师"
onCancel={this.props.onClose}
maskClosable={false}
visible={visible}
className="select-operator-modal"
closable={true}
width={800}
onOk={() => this.props.onSelect(selectOperatorList) }
>
<div className="search-container">
<Search placeholder="搜索运营师/手机号" style={{ width: 200 }} onChange={(e) => { this.handleChangNickname(e.target.value)}} onSearch={ () => { this.handleFetchDataList()}} />
</div>
<div>
<Table
rowKey={record => record.id}
dataSource={dataSource}
columns={this.parseColumns()}
pagination={false}
rowSelection={{
type: 'checkbox',
selectedRowKeys: _.pluck(selectOperatorList, 'id'),
onSelect: (record, selected) => {
this.selectOperator(record, selected)
},
onSelectAll: (selected, _selectedRows, changeRows) => {
let _list = [];
if (selected) {
_list = _.uniq(selectOperatorList.concat(changeRows), false, (item) => item.id);
} else {
_list = _.reject(selectOperatorList, (item) => _.find(changeRows, (data) => data.id === item.id));
}
this.setState({selectOperatorList:_list});
},
}}
/>
{dataSource.length >0 &&
<div className="box-footer">
<PageControl
current={query.current - 1}
pageSize={size}
total={totalCount}
toPage={(page) => {
const _query = {...query, current: page + 1};
this.setState({
query:_query
},()=>{ this.handleFetchDataList()})
}}
onShowSizeChange={this.onShowSizeChange}
/>
</div>
}
</div>
</Modal>
)
}
}
export default SelectOperatorModal;
\ No newline at end of file
.select-operator-modal{
.search-container{
margin-bottom:16px;
}
}
\ No newline at end of file
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