Commit 850e1a4a authored by baixian's avatar baixian

优化

parent 90406730
...@@ -18,5 +18,5 @@ ...@@ -18,5 +18,5 @@
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
<script type="text/javascript" src="/dist/main.6867e5.js"></script></body> <script type="text/javascript" src="/dist/main.80d239.js"></script></body>
</html> </html>
\ No newline at end of file
...@@ -222,7 +222,7 @@ export default { ...@@ -222,7 +222,7 @@ export default {
activeurl: `${__IMGCDN__}menu/crmactive.png`, activeurl: `${__IMGCDN__}menu/crmactive.png`,
notactiveurl: `${__IMGCDN__}menu/crm.png`, notactiveurl: `${__IMGCDN__}menu/crm.png`,
path: '/sjd/liveClass', path: '/sjd/liveClass',
relativePath: ['/sjd/liveClass', '/sjd/addLive'], relativePath: ['/sjd/liveClass', '/sjd/addLive', '/sjd/editLive/:id'],
}, },
], ],
}; };
...@@ -145,8 +145,8 @@ export default { ...@@ -145,8 +145,8 @@ export default {
yield put({ yield put({
type: 'updateState', type: 'updateState',
payload: { payload: {
liveUrlData: data.data,
downloadVisible: true, downloadVisible: true,
liveUrlData: data.data,
}, },
}); });
} else { } else {
...@@ -204,6 +204,28 @@ export default { ...@@ -204,6 +204,28 @@ export default {
}); });
} }
}, },
* handleLiveEnd({ payload }, { call, put, select }) {
const { id, type } = payload;
const data = yield call(liveAjax.closeLive, {
id,
});
if (data.code == 200) {
yield put({
type: 'changeStatus',
payload: {
id,
type,
},
});
} else {
yield put({
type: 'webapp/errorrequestresolve',
payload: {
data,
},
});
}
},
* queryimagesignature({ payload }, { call, put, select }) { * queryimagesignature({ payload }, { call, put, select }) {
const { userInfo, sid } = yield select(state => state.webapp); const { userInfo, sid } = yield select(state => state.webapp);
const { files, uploadtype, contentSort } = payload; const { files, uploadtype, contentSort } = payload;
...@@ -273,6 +295,10 @@ export default { ...@@ -273,6 +295,10 @@ export default {
addLiveObj, addLiveObj,
liveLoading, liveLoading,
} = yield select(state => state.liveclass); } = yield select(state => state.liveclass);
if (addLiveObj.cover == '') {
message.error('请先上传封面图', 0.5);
return;
}
if (liveLoading) { if (liveLoading) {
return; return;
} }
...@@ -316,6 +342,7 @@ export default { ...@@ -316,6 +342,7 @@ export default {
}); });
setTimeout(loadmessage); setTimeout(loadmessage);
if (data.code === 200) { if (data.code === 200) {
message.success('保存成功', 0.5);
if (callBack && (typeof callBack == 'function')) { if (callBack && (typeof callBack == 'function')) {
callBack(); callBack();
} }
...@@ -337,9 +364,8 @@ export default { ...@@ -337,9 +364,8 @@ export default {
}, },
}, },
}); });
message.success('保存成功', 0.5);
yield delay(300);
yield put(routerRedux.goBack()); yield put(routerRedux.goBack());
yield delay(300);
if (Number(data.data.status) == 2) { if (Number(data.data.status) == 2) {
yield put({ yield put({
type: 'queryLiveUrl', type: 'queryLiveUrl',
......
...@@ -141,7 +141,7 @@ class AddCrmForm extends React.Component { ...@@ -141,7 +141,7 @@ class AddCrmForm extends React.Component {
<div className={pageStyle.topTip}>查看教程</div> <div className={pageStyle.topTip}>查看教程</div>
<div className={pageStyle.headerWrap}> <div className={pageStyle.headerWrap}>
<div className={pageStyle.commonTitle}><span className={pageStyle.line} />基本信息</div> <div className={pageStyle.commonTitle}><span className={pageStyle.line} />基本信息</div>
<Form hideRequiredMark labelAlign="left" onSubmit={this.save}> <Form labelAlign="left" onSubmit={this.save}>
<FormItem {...formItemLayout} label="直播名称"> <FormItem {...formItemLayout} label="直播名称">
{getFieldDecorator('title', { {getFieldDecorator('title', {
initialValue: addLiveObj.title, initialValue: addLiveObj.title,
...@@ -150,17 +150,21 @@ class AddCrmForm extends React.Component { ...@@ -150,17 +150,21 @@ class AddCrmForm extends React.Component {
{ max: 40, message: '直播名称字数不能超过40位!' }, { max: 40, message: '直播名称字数不能超过40位!' },
], ],
})( })(
<Input style={{ width: 490 }} placeholder="请输入直播名称" />, <Input maxLength={45} style={{ width: 490 }} placeholder="请输入直播名称" />,
)} )}
</FormItem> </FormItem>
<FormItem {...formItemLayout} label="直播简介"> <FormItem {...formItemLayout} label="直播简介">
{getFieldDecorator('remark', { {getFieldDecorator('remark', {
initialValue: addLiveObj.remark, initialValue: addLiveObj.remark,
rules: [
{ max: 250, message: '直播简介字数不能超过250个字符!' },
],
})( })(
<TextArea <TextArea
style={{ width: 490 }} style={{ width: 490 }}
placeholder="请填写直播简介" placeholder="请填写直播简介"
rows={4} rows={4}
maxLength={260}
/>, />,
)} )}
</FormItem> </FormItem>
...@@ -197,7 +201,14 @@ class AddCrmForm extends React.Component { ...@@ -197,7 +201,14 @@ class AddCrmForm extends React.Component {
/> />
<span>选择文件</span> <span>选择文件</span>
</Button> </Button>
<div className={pageStyle.imgTip}>建议尺寸750*560px43JPGPNG 格式, 图片小于5M <span>查看示例</span></div> <div className={pageStyle.imgTip}><span>建议尺寸750*560px43JPGPNG 格式, 图片小于5M</span>
<div className={pageStyle.imgCase} onClick={this.lookCase}>
<span>查看示例</span>
<div className={pageStyle.caseWrap}>
<img src="https://static-resource.xiaoeknow.com/b_static/course_manage/courseListResource/images/video_push.jpg?428ddd1727e2ef7dcad0112b98b0e453&app_id=appnsHaHvXv8409" alt="" />
</div>
</div>
</div>
</div> </div>
</div> </div>
</FormItem> </FormItem>
...@@ -246,6 +257,9 @@ class AddCrmForm extends React.Component { ...@@ -246,6 +257,9 @@ class AddCrmForm extends React.Component {
<FormItem {...formItemLayout} label="" className={pageStyle.radioWrap}> <FormItem {...formItemLayout} label="" className={pageStyle.radioWrap}>
{getFieldDecorator('need_replay', { {getFieldDecorator('need_replay', {
initialValue: Number(addLiveObj.need_replay), initialValue: Number(addLiveObj.need_replay),
rules: [
{ required: true, message: '直播回放设置不能为空' },
],
})( })(
<Radio.Group disabled={addLiveObj.live_status != undefined && addLiveObj.live_status != 1}> <Radio.Group disabled={addLiveObj.live_status != undefined && addLiveObj.live_status != 1}>
<Radio style={radioStyle} value={1}><span className={pageStyle.radioName}>开启回放</span><span className={pageStyle.radioTip}>开启回放,直播结束后直播间将播放回放视频</span></Radio> <Radio style={radioStyle} value={1}><span className={pageStyle.radioName}>开启回放</span><span className={pageStyle.radioTip}>开启回放,直播结束后直播间将播放回放视频</span></Radio>
...@@ -257,6 +271,9 @@ class AddCrmForm extends React.Component { ...@@ -257,6 +271,9 @@ class AddCrmForm extends React.Component {
<FormItem {...formItemLayout} label="" className={pageStyle.radioWrap}> <FormItem {...formItemLayout} label="" className={pageStyle.radioWrap}>
{getFieldDecorator('status', { {getFieldDecorator('status', {
initialValue: Number(addLiveObj.status), initialValue: Number(addLiveObj.status),
rules: [
{ required: true, message: '上架设置不能为空!' },
],
})( })(
<Radio.Group> <Radio.Group>
<Radio style={radioStyle} value={2}><span className={pageStyle.radioName}>立即上架</span></Radio> <Radio style={radioStyle} value={2}><span className={pageStyle.radioName}>立即上架</span></Radio>
......
...@@ -98,12 +98,39 @@ ...@@ -98,12 +98,39 @@
font-weight:400; font-weight:400;
color:rgba(143,143,143,1); color:rgba(143,143,143,1);
width: 270px; width: 270px;
&>span { line-height: 1.8;
font-size:14px; margin-top: 40px;
font-family:PingFang SC; .imgCase {
font-weight:400; position: relative;
color:rgba(24,144,255,1); display: inline-block;
cursor: pointer; &>span {
font-size:14px;
font-family:PingFang SC;
font-weight:400;
color:rgba(24,144,255,1);
cursor: pointer;
}
&:hover .caseWrap{
opacity: 1;
z-index: 111;
}
.caseWrap {
position: absolute;
top: -300px;
right: -80px;
opacity: 1;
width: 200px;
height: 297px;
box-shadow: 0px 6px 12px 0px rgba(0, 0, 0, 0.05), 0px 2px 4px 0px rgba(0, 0, 0, 0.05);
border-radius: 2px;
z-index: -1;
padding: 14px 10px;
background-color: #fff;
&>img {
width: 100%;
height: 100%;
}
}
} }
} }
} }
......
...@@ -16,17 +16,20 @@ class DownloadModal extends React.Component { ...@@ -16,17 +16,20 @@ class DownloadModal extends React.Component {
} }
componentDidMount() { // 挂载 componentDidMount() { // 挂载
pageIn('直播课堂'); pageIn('直播课堂');
message.config({
maxCount: 1,
});
this.clipboard1 = new ClipboardJS('#btnCopyLink1'); // 点击按钮复制到粘贴板 this.clipboard1 = new ClipboardJS('#btnCopyLink1'); // 点击按钮复制到粘贴板
this.clipboard2 = new ClipboardJS('#btnCopyLink2'); this.clipboard2 = new ClipboardJS('#btnCopyLink2');
this.clipboard3 = new ClipboardJS('#btnCopyLink3'); this.clipboard3 = new ClipboardJS('#btnCopyLink3');
this.clipboard1.on('success', (e) => { this.clipboard1.on('success', () => {
message.success('复制成功', 0.5); message.success('复制成功', 0.3);
}); });
this.clipboard2.on('success', (e) => { this.clipboard2.on('success', () => {
message.success('复制成功', 0.5); message.success('复制成功', 0.3);
}); });
this.clipboard3.on('success', (e) => { this.clipboard3.on('success', () => {
message.success('复制成功', 0.5); message.success('复制成功', 0.3);
}); });
} }
componentWillUnmount() { // 卸载 componentWillUnmount() { // 卸载
...@@ -35,6 +38,13 @@ class DownloadModal extends React.Component { ...@@ -35,6 +38,13 @@ class DownloadModal extends React.Component {
const { form, close } = this.props; const { form, close } = this.props;
close(); close();
} }
downLoadApp = (type) => {
const a = document.createElement('a'); // 生成一个a元素
const event = new MouseEvent('click'); // 创建一个单击事件
const url = (type == 'windows' ? 'https://xiaoetong-1252524126.file.myqcloud.com/obs-download/OBS-Studio-23.0.1-Full-Installer-x86.exe' : 'https://xiaoetong-1252524126.file.myqcloud.com/obs-download/OBS-Studio-23.0.1-Full-Installer-x86.exe');
a.href = url; // 将生成的URL设置为a.href属性
a.dispatchEvent(event); // 触发a的单击事件
}
render() { render() {
const { const {
visible, visible,
...@@ -69,14 +79,14 @@ class DownloadModal extends React.Component { ...@@ -69,14 +79,14 @@ class DownloadModal extends React.Component {
<img className={pageStyle.macImg} src={`${__IMGCDN__}liveclass/mac.png`} alt="" /> <img className={pageStyle.macImg} src={`${__IMGCDN__}liveclass/mac.png`} alt="" />
<div className={pageStyle.downloadItemRight}> <div className={pageStyle.downloadItemRight}>
<span>Mac</span> <span>Mac</span>
<span className={pageStyle.dowloadSize}>下载</span> <span className={pageStyle.dowloadSize} onClick={() => this.downLoadApp('mac')}>下载</span>
</div> </div>
</div> </div>
<div className={pageStyle.downloadItem}> <div className={pageStyle.downloadItem}>
<img className={pageStyle.windowsImg} src={`${__IMGCDN__}liveclass/windows.png`} alt="" /> <img className={pageStyle.windowsImg} src={`${__IMGCDN__}liveclass/windows.png`} alt="" />
<div className={pageStyle.downloadItemRight}> <div className={pageStyle.downloadItemRight}>
<span>Mac</span> <span>Windows</span>
<span className={pageStyle.dowloadSize}>下载</span> <span className={pageStyle.dowloadSize} onClick={() => this.downLoadApp('windows')}>下载</span>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -100,6 +100,7 @@ ...@@ -100,6 +100,7 @@
border: 1px solid #BFBFBF; border: 1px solid #BFBFBF;
text-align: center; text-align: center;
line-height: 23px; line-height: 23px;
cursor: pointer;
} }
} }
} }
......
...@@ -20,7 +20,6 @@ class QrcodeShow extends React.Component { ...@@ -20,7 +20,6 @@ class QrcodeShow extends React.Component {
const Qr = document.getElementById('qrid'); const Qr = document.getElementById('qrid');
const image = new Image(); const image = new Image();
image.src = Qr.toDataURL('image/png'); image.src = Qr.toDataURL('image/png');
console.log(image, 'image');
image.onload = () => { image.onload = () => {
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
canvas.width = image.width; canvas.width = image.width;
......
import React from 'react';
import { Icon } from 'antd';
import { Player } from 'video-react';
import componentStyle from './VideoPlay.less';
import { ossVideofy } from '../../../utils/index';
class VideoPlay extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
componentDidMount() {
}
componentWillUpdate() {
}
render() {
const { src, closeVideoPlay } = this.props;
return (
<div className={`${componentStyle.VideoPlayBox} VideoPlayBox`}>
<Icon type="close-circle" className={componentStyle.closeIcon} onClick={closeVideoPlay} />
<Player
ref={(player) => {
this.player = player;
}}
className={componentStyle.videoitem}
>
<source src={src} />
</Player>
</div>
);
}
}
export default VideoPlay;
This diff is collapsed.
...@@ -17,14 +17,16 @@ import { ...@@ -17,14 +17,16 @@ import {
Pagination, Pagination,
Tooltip, DatePicker, Tooltip, DatePicker,
Divider, Divider,
Avatar,
} from 'antd'; } from 'antd';
import moment from 'moment'; import moment from 'moment';
import { routerRedux } from 'dva/router'; import { routerRedux } from 'dva/router';
import pageStyle from './index.less'; import pageStyle from './index.less';
import DownloadModal from './DownloadModal'; import DownloadModal from './DownloadModal';
import { pageIn, hasBtnPower, btnPermission, translateType } from '../../utils/index'; import { pageIn, hasBtnPower, btnPermission, translateType, imagify } from '../../utils/index';
import BtnPermission from '../../components/BtnPermission'; import BtnPermission from '../../components/BtnPermission';
import QrcodeShow from './components/QrcodeShow'; import QrcodeShow from './components/QrcodeShow';
import VideoPlay from './components/VideoPlay';
const { Option } = Select; const { Option } = Select;
const { TextArea } = Input; const { TextArea } = Input;
const { Search } = Input; const { Search } = Input;
...@@ -162,6 +164,21 @@ class LiveClass extends React.Component { ...@@ -162,6 +164,21 @@ class LiveClass extends React.Component {
id: record.id, id: record.id,
}, },
}); });
} else if (Number(record.live_status) == 2 || Number(record.live_status) == 3) {
Modal.confirm({
title: '提示',
content: '下架操作若直播间正在直播立即结束直播,直播间为下架状态',
icon: <Icon type="info-circle" theme="filled" style={{ color: '#1890ff', fontSize: 30 }} />,
onOk() {
dispatch({
type: 'liveclass/handleLiveEnd',
payload: {
type,
id: record.id,
},
});
},
});
} else { } else {
Modal.confirm({ Modal.confirm({
title: '提示', title: '提示',
...@@ -225,10 +242,12 @@ class LiveClass extends React.Component { ...@@ -225,10 +242,12 @@ class LiveClass extends React.Component {
} }
goLook = (record) => { goLook = (record) => {
const { dispatch } = this.props; const { dispatch } = this.props;
console.log(record, 'record');
dispatch({ dispatch({
type: 'liveclass/queryDetail', type: 'liveclass/updateState',
payload: { payload: {
id: record.id, lookVideoShow: true,
lookVideoUrl: record.replay_url[0],
}, },
}); });
} }
...@@ -242,12 +261,23 @@ class LiveClass extends React.Component { ...@@ -242,12 +261,23 @@ class LiveClass extends React.Component {
liveUrlData, liveUrlData,
previewQrcodeShow, previewQrcodeShow,
previewQrcode, previewQrcode,
lookVideoShow,
lookVideoUrl,
} = this.props; } = this.props;
const columns = [ const columns = [
{ {
title: '课程名称', title: '直播名称',
dataIndex: 'title', dataIndex: 'title',
key: 'title', key: 'title',
width: 330,
render: (text, record) => {
return (
<div className={pageStyle.tableImg}>
<img src={imagify(record.cover)} alt="" />
<div className={pageStyle.tableText}>{text}</div>
</div>
);
},
}, },
{ {
title: '创建时间', title: '创建时间',
...@@ -309,7 +339,7 @@ class LiveClass extends React.Component { ...@@ -309,7 +339,7 @@ class LiveClass extends React.Component {
<Divider type="vertical" /> <Divider type="vertical" />
<span className="hreflink" onClick={() => this.goShare(record)}>分享直播间</span> <span className="hreflink" onClick={() => this.goShare(record)}>分享直播间</span>
{ {
record.status == 2 && <span className="hreflink" onClick={() => this.goStartLive(record)}><Divider type="vertical" />去直播</span> (record.status != 3 && record.live_status != 4) && <span className="hreflink" onClick={() => this.goStartLive(record)}><Divider type="vertical" />去直播</span>
} }
{ {
(record.live_status == 4 && record.need_replay == 1) && <span className="hreflink" onClick={() => this.goLook(record)}><Divider type="vertical" />直播回放</span> (record.live_status == 4 && record.need_replay == 1) && <span className="hreflink" onClick={() => this.goLook(record)}><Divider type="vertical" />直播回放</span>
...@@ -342,9 +372,9 @@ class LiveClass extends React.Component { ...@@ -342,9 +372,9 @@ class LiveClass extends React.Component {
className={pageStyle.formList} className={pageStyle.formList}
> >
<Col className={pageStyle.formitem} xs={{ span: 12 }} sm={{ span: 12 }} md={{ span: 12 }} lg={{ span: 8 }} xl={{ span: 8 }}> <Col className={pageStyle.formitem} xs={{ span: 12 }} sm={{ span: 12 }} md={{ span: 12 }} lg={{ span: 8 }} xl={{ span: 8 }}>
<div className={pageStyle.formitemlabel}>课程名称:</div> <div className={pageStyle.formitemlabel}>直播名称:</div>
{/* eslint-disable-next-line react/no-string-refs */} {/* eslint-disable-next-line react/no-string-refs */}
<Search allowClear style={{ width: '100%' }} ref="searchBar" placeholder="请输入课程标题" onSearch={e => this.searchParamsChange(e, 'Input', 'title')} /> <Search allowClear style={{ width: '100%' }} ref="searchBar" placeholder="请输入直播标题" onSearch={e => this.searchParamsChange(e, 'Input', 'title')} />
</Col> </Col>
<Col className={pageStyle.formitem} xs={{ span: 12 }} sm={{ span: 12 }} md={{ span: 12 }} lg={{ span: 8 }} xl={{ span: 8 }}> <Col className={pageStyle.formitem} xs={{ span: 12 }} sm={{ span: 12 }} md={{ span: 12 }} lg={{ span: 8 }} xl={{ span: 8 }}>
<div className={pageStyle.formitemlabel} >全部状态:</div> <div className={pageStyle.formitemlabel} >全部状态:</div>
...@@ -399,6 +429,13 @@ class LiveClass extends React.Component { ...@@ -399,6 +429,13 @@ class LiveClass extends React.Component {
previewQrcode={previewQrcode} previewQrcode={previewQrcode}
title="请使用微信扫一扫,扫码查看直播" title="请使用微信扫一扫,扫码查看直播"
/> />
{
lookVideoShow &&
<VideoPlay
src={lookVideoUrl}
closeVideoPlay={this.closeVideoPlay}
/>
}
</div> </div>
); );
} }
...@@ -417,6 +454,8 @@ function mapStateToProps(state) { ...@@ -417,6 +454,8 @@ function mapStateToProps(state) {
liveUrlData, liveUrlData,
previewQrcodeShow, previewQrcodeShow,
previewQrcode, previewQrcode,
lookVideoShow,
lookVideoUrl,
} = state.liveclass; } = state.liveclass;
const { const {
guideStep, guideStep,
...@@ -438,6 +477,8 @@ function mapStateToProps(state) { ...@@ -438,6 +477,8 @@ function mapStateToProps(state) {
liveUrlData, liveUrlData,
previewQrcodeShow, previewQrcodeShow,
previewQrcode, previewQrcode,
lookVideoShow,
lookVideoUrl,
}; };
} }
export default connect(mapStateToProps)(LiveClassForm); export default connect(mapStateToProps)(LiveClassForm);
......
...@@ -182,3 +182,21 @@ ...@@ -182,3 +182,21 @@
} }
} }
.tableImg {
display: flex;
&>img {
width: 80px;
height: 60px;
border-radius: 2px;
margin-right: 12px;
}
.tableText {
width: 200px;
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
word-break: break-all;
text-overflow: ellipsis;
}
}
...@@ -157,7 +157,6 @@ function isOnline(expiredate) { ...@@ -157,7 +157,6 @@ function isOnline(expiredate) {
return false; return false;
} }
function formatDate(date) { function formatDate(date) {
console.log(date, 'date');
const time = Number(date); const time = Number(date);
if (time === undefined || time === '' || time <= 0) { if (time === undefined || time === '' || time <= 0) {
......
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