Commit 465e113b authored by baixian's avatar baixian

111222

parent 5ec6da9f
import React from 'react';
import { Button, Form, Input, Icon, Modal, Select, Upload, message, Radio, Pagination, List, Card } from 'antd';
import pageStyle from './MaterialModal.less';
import { imagify } from '../utils';
const FormItem = Form.Item;
const { Option } = Select;
const { TextArea } = Input;
class MaterialModalForm extends React.Component {
constructor(props) {
super(props);
this.state = {
checkValue: '',
};
}
close = () => {
const {
close,
} = this.props;
close();
this.setState({
checkValue: '',
});
}
onChange = (e) => {
console.log('radio checked', e.target.value);
this.setState({
checkValue: e.target.value,
});
};
changePagination = (page, perPage) => {
const { changePagination } = this.props;
changePagination({
page,
perPage,
});
}
save = () => {
const { save } = this.props;
const { checkValue } = this.state;
if (!checkValue) {
message.error('请先选择图片', 1);
}
save({
checkValue,
});
}
render() {
const {
visible,
list,
queryParams,
total,
} = this.props;
const { checkValue } = this.state;
return (
<div>
<Modal
visible={visible}
maskClosable={false}
closable={false}
title="添加素材"
cancelText="取消"
okText="保存"
onCancel={this.close}
bodyStyle={{ padding: '20px 30px' }}
className={pageStyle.modalWrap}
width={730}
onOk={this.save}
>
<div className={pageStyle.list}>
<Radio.Group onChange={this.onChange} value={checkValue}>
<List
size="large"
grid={{
gutter: 10,
xs: 4,
sm: 4,
}}
footer={
<div className={pageStyle.tablefooterbox}>
<Pagination
total={Number(total)}
onChange={this.changePagination}
pageSize={queryParams.perPage}
/>
</div>
}
dataSource={list}
renderItem={item => (
<List.Item>
<div className={pageStyle.item}>
<Radio value={item.src}>
<img className={pageStyle.img} src={imagify(item.src)} alt="" />
</Radio>
</div>
</List.Item>
)}
/>
</Radio.Group>
</div>
</Modal>
</div>
);
}
}
const MaterialModal = Form.create()(MaterialModalForm);
export default MaterialModal;
.modalWrap {
:global {
.ant-modal-header {
border-bottom: none;
}
}
.item {
width: 150px;
height: 150px;
border-radius: 8px;
position: relative;
:global {
.ant-radio-wrapper {
margin-right: 0;
}
.ant-radio {
position: absolute;
top: 5px;
left: 20px;
}
.ant-radio-inner {
background-color: transparent;
}
}
.img {
width: 150px;
height: 150px;
border-radius: 8px;
}
}
}
......@@ -185,6 +185,7 @@ export default {
} = payload;
addCourseObj.content = JSON.stringify(addCourseObj.content);
const newCourseObj = { ...addCourseObj };
console.log(addCourseObj, 'addCourseObj1111111111111111111');
const loadmessage = message.loading('保存中...', 0);
const newParams = Object.assign(newCourseObj, {
title,
......@@ -392,7 +393,7 @@ export default {
};
const uploadImg = yield call(uploader.uploadVideo, params);
const videoUrl = filename;
if (uploadtype == 'uploadVideoJob') {
if (uploadtype == 'uploadVideo') {
addCourseObj.content.push({
type: 'video',
value: videoUrl,
......@@ -480,7 +481,7 @@ export default {
},
});
},
* deleteJobImg({ payload }, { call, put, select }) {
* deleteCourseImg({ payload }, { call, put, select }) {
const { index } = payload;
const { addCourseObj } = yield select(state => state.onlineclasses);
const newContent = addCourseObj.content;
......@@ -512,6 +513,18 @@ export default {
},
});
},
* updateCover({ payload }, { call, put, select }) {
const { values } = payload;
const { addCourseObj } = yield select(state => state.onlineclasses);
addCourseObj.cover = values.checkValue;
yield put({
type: 'updateState',
payload: {
addCourseObj: { ...addCourseObj },
materialVisible: false,
},
});
},
* courseMoveContent({ payload }, { call, put, select }) {
const { index, direction } = payload;
const { addCourseObj } = yield select(state => state.onlineclasses);
......
import { connect } from 'dva';
import React from 'react';
import { Icon, Divider, Tabs, Select, Form, Upload, Row, Col, Input, Radio, Modal, message } from 'antd';
import pageStyle from './ThemeEditor.less';
import { pageIn, hasBtnPower, imagify, ossVideofy } from '../../utils/index';
const upImg = `${__IMGCDN__}subjectUp.png`;
const { TabPane } = Tabs;
const { TextArea } = Input;
class ThemeEditor extends React.Component {
constructor(props) {
super(props);
this.state = {
previewVisible: false,
previewImage: '',
};
}
componentDidMount() { // 挂载
pageIn('轻校-线上课堂');
}
componentDidUpdate() {
}
componentWillUnmount() { // 卸载
}
priviewImg = (img) => {
this.setState({
previewVisible: true,
previewImage: img,
});
}
handleCancel = () => {
this.setState({
previewVisible: false,
});
}
render() {
const { previewVisible, previewImage } = this.state;
const {
editorUploadImg,
commentParams,
editorUploadAudio,
editorChange,
deleteThemeImg,
editorAddText,
moveContent,
editorUploadVideo,
} = this.props;
return (
<div className={pageStyle.container}>
<div className={pageStyle.editorwrap}>
{/* eslint-disable-next-line array-callback-return,consistent-return */}
{commentParams.content.map((item, index) => {
// eslint-disable-next-line default-case
switch (item.type) {
case 'text':
return (
<div key={index} className={pageStyle.textWrap}>
<TextArea autoSize={{ minRows: 4, maxRows: 10 }} value={item.value} onChange={e => editorChange(e, index)} placeholder="请输入内容" style={{ width: 560 }} maxLength={500} />
<div className={pageStyle.sizeNumber}>{item.value.length}/500</div>
<div className={pageStyle.toolList}>
{ index === 0 && <div aria-disabled="true" className={pageStyle.noup}><img src={upImg} alt="" /> </div> }
{ index > 0 && <div className={pageStyle.up} onClick={() => moveContent(index, 'up')}><img src={upImg} alt="" /> </div> }
{ index === (commentParams.content.length - 1) && <div className={pageStyle.nodown}><img src={upImg} alt="" /> </div> }
{ index < (commentParams.content.length - 1) && <div className={pageStyle.down} onClick={() => moveContent(index, 'down')}><img src={upImg} alt="" /> </div> }
<div className={pageStyle.delete} onClick={() => deleteThemeImg(index)}><Icon type="delete" theme="filled" /></div>
</div>
</div>
);
case 'img':
return (
<div key={index} className={pageStyle.uploadimgbox}>
<div className={pageStyle.imgwrap}>
<div className={pageStyle.uploadimgwrap}> <img alt={item.type} className={pageStyle.teacheruploadimg} src={imagify(item.value)} /></div>
<div className={pageStyle.imghide}>
<span title="预览文件" onClick={() => this.priviewImg(item.value)} ><Icon style={{ color: '#fff' }} type="eye" /> 预览</span>
</div>
<div className={pageStyle.toolList}>
{ index === 0 && <div aria-disabled="true" className={pageStyle.noup}><img src={upImg} alt="" /> </div> }
{ index > 0 && <div className={pageStyle.up} onClick={() => moveContent(index, 'up')}><img src={upImg} alt="" /> </div> }
{ index === (commentParams.content.length - 1) && <div className={pageStyle.nodown}><img src={upImg} alt="" /> </div> }
{ index < (commentParams.content.length - 1) && <div className={pageStyle.down} onClick={() => moveContent(index, 'down')}><img src={upImg} alt="" /> </div> }
<div className={pageStyle.delete} onClick={() => deleteThemeImg(index)}><Icon type="delete" theme="filled" /></div>
</div>
</div>
</div>
);
case 'video':
return (
<div key={index} className={pageStyle.videowrap}>
<video controls="controls" className={pageStyle.videoPoster} src={ossVideofy(item.value)} />
<div className={pageStyle.toolList}>
{ index === 0 && <div aria-disabled="true" className={pageStyle.noup}><img src={upImg} alt="" /> </div> }
{ index > 0 && <div className={pageStyle.up} onClick={() => moveContent(index, 'up')}><img src={upImg} alt="" /> </div> }
{ index === (commentParams.content.length - 1) && <div className={pageStyle.nodown}><img src={upImg} alt="" /> </div> }
{ index < (commentParams.content.length - 1) && <div className={pageStyle.down} onClick={() => moveContent(index, 'down')}><img src={upImg} alt="" /> </div> }
<div className={pageStyle.delete} onClick={() => deleteThemeImg(index)}><Icon type="delete" theme="filled" /></div>
</div>
</div>
);
case 'audio':
return (
<div key={index} className={pageStyle.videowrap}>
<audio controls="controls" className={pageStyle.videoPoster} src={imagify(item.value)} />
<div className={pageStyle.toolList}>
{ index === 0 && <div aria-disabled="true" className={pageStyle.noup}><img src={upImg} alt="" /> </div> }
{ index > 0 && <div className={pageStyle.up} onClick={() => moveContent(index, 'up')}><img src={upImg} alt="" /> </div> }
{ index === (commentParams.content.length - 1) && <div className={pageStyle.nodown}><img src={upImg} alt="" /> </div> }
{ index < (commentParams.content.length - 1) && <div className={pageStyle.down} onClick={() => moveContent(index, 'down')}><img src={upImg} alt="" /> </div> }
<div className={pageStyle.delete} onClick={() => deleteThemeImg(index)}><Icon type="delete" theme="filled" /></div>
</div>
</div>
);
}
},
)}
</div>
<div className={pageStyle.uploadflex}>
<div className={pageStyle.uploadimg} onClick={editorAddText}><Icon style={{ marginRight: 10 }} type="font-size" />添加文字</div>
<div className={pageStyle.uploadimg}><input type="file" id="uploadImg" className={pageStyle.fileuploadinput} onChange={editorUploadImg} accept="image/*" /><Icon style={{ marginRight: 10 }} type="picture" />添加图片</div>
<div className={pageStyle.uploadimg}><input type="file" id="uploadVideo" className={pageStyle.fileuploadinput} onChange={editorUploadVideo} accept="video/*" /><Icon style={{ marginRight: 10 }} type="video-camera" />添加视频</div>
<div className={pageStyle.uploadimg}><input type="file" id="uploadAudio" className={pageStyle.fileuploadinput} onChange={editorUploadAudio} accept="audio/*" /><Icon style={{ marginRight: 10 }} type="audio" />添加音频</div>
</div>
<Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
<img alt="图片" style={{ width: '100%' }} src={imagify(previewImage)} />
</Modal>
</div>
);
}
}
ThemeEditor.propTypes = {
};
export default connect()(ThemeEditor);
.textWrap {
width: 560px;
height: auto;
position: relative;
margin-bottom:10px;
:global {
.ant-input {
padding: 6px 15px 20px;
}
}
.sizeNumber {
position: absolute;
bottom: 8px;
right: 10px;
}
}
.editorwrap {
width: 563px;
margin-top: 15px;
.videowrap {
width: 100%;
height: 120px;
position: relative;
margin-bottom: 10px;
.videoPoster {
width: 100%;
height: 100%;
}
}
.videowrap:hover {
cursor: pointer;
.videohide {
opacity: 1;
background-color: rgba(0,0,0,0.5);
transition: all .3s;
z-index: 1;
color: #fff;
}
}
.videohide {
position: absolute;
width: 100%;
height: 100%;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
opacity: 0;
color: #fff;
z-index: -1;
a {
color: #fff;
}
}
.uploadimgbox {
display: flex;
align-items: flex-end;
margin-bottom: 18px;
flex-wrap: wrap;
.imgwrap {
width: 100%;
height: 120px;
border-radius: 4px;
margin-right: 6px;
position: relative;
.uploadimgwrap {
width: 100%;
height: 120px;
overflow: hidden;
}
}
.imgwrap:hover {
cursor: pointer;
.imghide {
opacity: 1;
background-color: rgba(0,0,0,0.5);
transition: all .3s;
z-index: 1;
color: #fff;
}
}
.imghide {
position: absolute;
width: 100%;
height: 100%;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
opacity: 0;
color: #fff;
z-index: -1;
a {
color: #fff;
}
}
.teacheruploadimg {
object-fit: contain;
border-radius: 4px;
}
.teacheruploadimg:nth-child(4n){
margin-right: 0;
}
}
}
.uploadflex {
display: flex;
align-items: center;
.uploadimg {
cursor: pointer;
width: 106px;
height: 32px;
line-height: 32px;
text-align: center;
border: 1px solid #D9D9D9;
border-radius: 4px;
color: rgba(0,0,0,0.65);
position: relative;
margin-right: 30px;
.fileuploadinput {
cursor: pointer;
position: absolute;
width: 100%;
height: 100%;
z-index: 1;
opacity: 0;
left: 0;
top: 0;
}
}
}
.toolList {
position: absolute;
right: -30px;
top: 0;
width: 30px;
height: 90px;
display: flex;
flex-direction: column;
background-color: #D3D3D3;
opacity: 0;
border-radius: 2px;
z-index: -1;
div {
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 14px;
cursor: pointer;
}
div>img {
width: 14px;
height: 14px;
}
.up:hover {
background-color: #1890FF;
}
.down,.nodown {
transform: rotate(180deg);
}
.nodown,.noup {
cursor: not-allowed;
}
.down:hover {
background-color: #1890FF;
}
.delete:hover {
background-color: #FF6060;
}
}
.textWrap:hover,.imgwrap:hover,.videowrap:hover {
.toolList {
opacity: 1;
z-index: 1;
}
}
......@@ -17,8 +17,9 @@ import {
InputNumber, Checkbox, Radio, message,
} from 'antd';
import moment from 'moment';
import ThemeEditor from '../../newtheme/ThemeEditor';
import ThemeEditor from '../ThemeEditor';
import pageStyle from './CourseDetail.less';
import MaterialModal from '../../../components/MaterialModal';
import { pageIn, hasBtnPower, imagify } from '../../../utils';
const { TabPane } = Tabs;
const FormItem = Form.Item;
......@@ -56,13 +57,13 @@ class CourseDetailForm extends React.Component {
},
});
}
courseUploadAudio = (e) => {
courseUploadVideo = (e) => {
const { dispatch } = this.props;
dispatch({
type: 'onlineclasses/queryvideosignature',
payload: {
files: e.target,
uploadtype: 'uploadVideoJob',
uploadtype: 'uploadaudio',
},
});
}
......@@ -108,6 +109,16 @@ class CourseDetailForm extends React.Component {
},
});
}
courseUploadAudio = (e) => {
const { dispatch } = this.props;
dispatch({
type: 'onlineclasses/queryvoiceignature',
payload: {
files: e.target,
uploadtype: 'uploadImg',
},
});
}
save = (e) => {
const { dispatch, form } = this.props;
e.preventDefault();
......@@ -119,7 +130,6 @@ class CourseDetailForm extends React.Component {
start_time,
study_count,
} = values;
console.log(values, '1111111111');
dispatch({
type: 'onlineclasses/editCourse',
payload: {
......@@ -174,11 +184,86 @@ class CourseDetailForm extends React.Component {
},
});
}
chooseMaterial = () => {
const { dispatch } = this.props;
dispatch({
type: 'onlineclasses/updateState',
payload: {
materialVisible: true,
},
});
dispatch({
type: 'coursemateria/querymaterialist',
payload: {
params: {
type: 1,
page: 1,
perPage: 12,
},
},
});
}
materialClose = () => {
const { dispatch } = this.props;
dispatch({
type: 'onlineclasses/updateState',
payload: {
materialVisible: false,
},
});
dispatch({
type: 'coursemateria/querymaterialist',
payload: {
params: {
type: '',
page: 1,
perPage: 20,
},
},
});
}
changeListPagination = (values) => {
const { dispatch } = this.props;
dispatch({
type: 'coursemateria/querymaterialist',
payload: {
params: {
type: 1,
page: values.page,
perPage: values.perPage,
},
},
});
}
materialSave = (values) => {
console.log(values, '1111111111111');
const { dispatch } = this.props;
dispatch({
type: 'onlineclasses/updateCover',
payload: {
values,
},
});
dispatch({
type: 'coursemateria/querymaterialist',
payload: {
params: {
type: '',
page: 1,
perPage: 20,
},
},
});
}
render() {
const {
form: { getFieldDecorator, getFieldValue },
addCourseObj,
editLoading,
materialVisible,
materiaList,
queryParams,
materiaListTotal,
} = this.props;
console.log(addCourseObj, 'addCourseObj');
const formItemModalLineLayout = {
......@@ -209,7 +294,7 @@ class CourseDetailForm extends React.Component {
</div>
</div> :
<div className={pageStyle.photoWrap}>
<div className={pageStyle.material}>
<div className={pageStyle.material} onClick={this.chooseMaterial}>
<img src={`${__IMGCDN__}/course/check.png`} alt="从素材库选择" />
<div className={pageStyle.tip}>从素材库选择</div>
</div>
......@@ -300,11 +385,12 @@ class CourseDetailForm extends React.Component {
<ThemeEditor
commentParams={addCourseObj}
editorUploadImg={this.courseUploadImg}
editorUploadAudio={this.courseUploadAudio}
editorUploadVideo={this.courseUploadVideo}
editorChange={this.courseChangeSize}
deleteThemeImg={this.deleteCourseImg}
moveContent={this.courseMoveContent}
editorAddText={this.courseAddText}
editorUploadAudio={this.courseUploadAudio}
/>
</FormItem>
<FormItem {...formItemModalLineLayout}>
......@@ -313,6 +399,15 @@ class CourseDetailForm extends React.Component {
<Button>上传课件</Button>
</FormItem>
</Form>
<MaterialModal
visible={materialVisible}
close={this.materialClose}
list={materiaList}
queryParams={queryParams}
total={materiaListTotal}
changePagination={this.changeListPagination}
save={this.materialSave}
/>
</div>
);
}
......@@ -326,10 +421,20 @@ function mapStateToProps(state) {
const {
addCourseObj,
editLoading,
materialVisible,
} = state.onlineclasses;
const {
materiaList,
queryParams,
materiaListTotal,
} = state.coursemateria;
return {
addCourseObj,
editLoading,
materialVisible,
materiaList,
queryParams,
materiaListTotal,
};
}
export default connect(mapStateToProps)(CourseDetail);
......
......@@ -156,7 +156,7 @@ class ClassMgtForm extends React.Component {
dataSource={courseList}
renderItem={item => (
<List.Item>
<Card bodyStyle={{ padding: 20 }}>
<Card bodyStyle={{ padding: 20, minHeight: 172 }}>
<Card.Meta
style={{ padding: 0 }}
avatar={<img className={pageStyle.itemImg} alt="图片" src={imagify(item.cover)} />}
......
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