Commit 90406730 authored by baixian's avatar baixian

优化

parent 378b0dc2
......@@ -13,10 +13,10 @@
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=XSZBZ-5LHCV-5I2P7-UQHPW-6456F-JBB3B"></script>
<script src="/js/ueeditor/ueditor.config.js?20200107" charset="utf-8"></script><script src="/js/ueeditor/ueditor.all.js?20200107" charset="utf-8"></script>
<script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/js/console-polyfill.js?20200107" charset="utf-8"></script><script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/js/es6-shim.min.js?20200107" charset="utf-8"></script><script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/js/es5-shim.js?20200107" charset="utf-8"></script><script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/js/es5-sham.min.js?20200107" charset="utf-8"></script><script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/js/json3.min.js?20200107" charset="utf-8"></script><script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/js/html5shiv.min.js?20200107" charset="utf-8"></script><script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/js/polyfill.js?20200107" charset="utf-8"></script><script src="https://cdn.img.shangjiadao.cn/qingxiao/biz/lib/vendor.dll.js?20200107" charset="utf-8"></script>
<script src="js/console-polyfill.js?20200107" charset="utf-8"></script><script src="js/es6-shim.min.js?20200107" charset="utf-8"></script><script src="js/es5-shim.js?20200107" charset="utf-8"></script><script src="js/es5-sham.min.js?20200107" charset="utf-8"></script><script src="js/json3.min.js?20200107" charset="utf-8"></script><script src="js/html5shiv.min.js?20200107" charset="utf-8"></script><script src="js/polyfill.js?20200107" charset="utf-8"></script><script src="lib/vendor.dll.js?20200107" charset="utf-8"></script>
</head>
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="https://cdn.img.shangjiadao.cn/qingxiao/biz/dist/main.81f828.js"></script></body>
<script type="text/javascript" src="/dist/main.6867e5.js"></script></body>
</html>
\ No newline at end of file
......@@ -247,5 +247,6 @@ export default {
lives: `${dakaapi}member/lives`,
livesStatus: `${dakaapi}member/live/status`,
livesUrl: `${dakaapi}member/live/url`,
livesEnd: `${dakaapi}member/live/end`,
},
};
......@@ -12,7 +12,6 @@ import {
import errorcode from '../common/errorcode';
import * as uploader from '../services/uploader';
import * as liveAjax from '../services/liveclass';
import * as themeAjax from '../services/createtheme';
export default {
namespace: 'liveclass',
state: {
......@@ -32,7 +31,7 @@ export default {
live_start_time: '',
need_replay: 1,
pay_switch: 1,
status: 1,
status: 2,
content: [
{ type: 'editor', value: '' },
],
......@@ -124,6 +123,7 @@ export default {
status: data.data.status,
content: JSON.parse(data.data.content),
id: data.data.id,
live_status: data.data.live_status,
},
},
});
......@@ -181,6 +181,29 @@ export default {
});
}
},
* closeLive({ payload }, { call, put, select }) {
const { record } = payload;
const data = yield call(liveAjax.closeLive, {
id: record.id,
});
if (data.code == 200) {
message.success('保存成功', 0.5);
yield put({
type: 'queryList',
payload: {
params: {
},
},
});
} else {
yield put({
type: 'webapp/errorrequestresolve',
payload: {
data,
},
});
}
},
* queryimagesignature({ payload }, { call, put, select }) {
const { userInfo, sid } = yield select(state => state.webapp);
const { files, uploadtype, contentSort } = payload;
......@@ -307,7 +330,7 @@ export default {
live_start_time: '',
need_replay: 1,
pay_switch: 1,
status: 1,
status: 2,
content: [
{ type: 'editor', value: '' },
],
......@@ -317,12 +340,14 @@ export default {
message.success('保存成功', 0.5);
yield delay(300);
yield put(routerRedux.goBack());
yield put({
type: 'queryLiveUrl',
payload: {
id: data.data.id,
},
});
if (Number(data.data.status) == 2) {
yield put({
type: 'queryLiveUrl',
payload: {
id: data.data.id,
},
});
}
} else {
yield put({
type: 'webapp/errorrequestresolve',
......@@ -365,7 +390,7 @@ export default {
payload: {
params: {
title: '',
state: '',
status: '',
page: 1,
perPage: 10,
},
......@@ -412,7 +437,7 @@ export default {
live_start_time: '',
need_replay: 1,
pay_switch: 1,
status: 1,
status: 2,
content: [
{ type: 'editor', value: '' },
],
......
......@@ -1313,6 +1313,9 @@ export default {
});
}
if (pathname === '/sjd/addLive') {
dispatch({
type: 'liveclass/pageInit',
});
dispatch({
type: 'updateState',
payload: {
......@@ -1559,15 +1562,15 @@ export default {
yield put({
type: 'onlineclasses/pageInit',
});
} if (locationPathname == '/sjd/coursegather') {
} else if (locationPathname == '/sjd/coursegather') {
yield put({
type: 'coursegatherindex/pageInit',
});
} if (pathToRegexp('/sjd/gatherdetail/:id').exec(locationPathname)) {
} else if (pathToRegexp('/sjd/gatherdetail/:id').exec(locationPathname)) {
yield put({
type: 'coursegatherdetail/pageInit',
});
} if (locationPathname == '/sjd/coursemateria') {
} else if (locationPathname == '/sjd/coursemateria') {
yield put({
type: 'coursemateria/pageInit',
});
......@@ -1627,6 +1630,18 @@ export default {
yield put({
type: 'createtheme/pageInit',
});
} else if (pathToRegexp('/sjd/liveClass').exec(locationPathname)) {
yield put({
type: 'liveclass/pageInit',
});
} else if (pathToRegexp('/sjd/addLive').exec(locationPathname)) {
yield put({
type: 'liveclass/pageInit',
});
} else if (pathToRegexp('/sjd/editLive/:id').exec(locationPathname)) {
yield put({
type: 'liveclass/pageInit',
});
}
// yield put({
// type: 'joinschooladd/pageInit',
......
......@@ -172,7 +172,7 @@ class AddCrmForm extends React.Component {
{ required: true, message: '请选择直播开始时间!' },
],
})(
<DatePicker disabled={addLiveObj.id != undefined && addLiveObj.id} showTime placeholder="请选择直播开始时间" />,
<DatePicker disabled={addLiveObj.live_status != undefined && addLiveObj.live_status != 1} showTime placeholder="请选择直播开始时间" />,
)}
</FormItem>
<FormItem {...formItemLayout} label="封面图">
......@@ -227,7 +227,7 @@ class AddCrmForm extends React.Component {
{ required: true, message: '密码不能为空' },
{
message: '请输入正整数',
pattern: new RegExp(/^[1-9]\d*$/, 'g'),
pattern: new RegExp(/^[0-9]\d*$/, 'g'),
},
],
})(<Input maxLength={6} style={{ width: 144 }} placeholder="设置密码" />,
......@@ -247,7 +247,7 @@ class AddCrmForm extends React.Component {
{getFieldDecorator('need_replay', {
initialValue: Number(addLiveObj.need_replay),
})(
<Radio.Group>
<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={2}><span className={pageStyle.radioName}>关闭回放</span><span className={pageStyle.radioTip}>关闭回放,直播结束后直播间不播放回放视频</span></Radio>
</Radio.Group>,
......@@ -259,10 +259,10 @@ class AddCrmForm extends React.Component {
initialValue: Number(addLiveObj.status),
})(
<Radio.Group>
<Radio style={radioStyle} value={2}><span className={pageStyle.radioName}>立即上架</span></Radio>
<Radio style={radioStyle} value={1}>
<span className={pageStyle.radioName}>暂不上架</span>
</Radio>
<Radio style={radioStyle} value={2}><span className={pageStyle.radioName}>立即上架</span></Radio>
</Radio.Group>,
)}
</FormItem>
......
......@@ -16,10 +16,16 @@ class DownloadModal extends React.Component {
}
componentDidMount() { // 挂载
pageIn('直播课堂');
this.clipboard = new ClipboardJS('#btnCopyLink1'); // 点击按钮复制到粘贴板
this.clipboard = new ClipboardJS('#btnCopyLink2');
this.clipboard = new ClipboardJS('#btnCopyLink3');
this.clipboard.on('success', () => {
this.clipboard1 = new ClipboardJS('#btnCopyLink1'); // 点击按钮复制到粘贴板
this.clipboard2 = new ClipboardJS('#btnCopyLink2');
this.clipboard3 = new ClipboardJS('#btnCopyLink3');
this.clipboard1.on('success', (e) => {
message.success('复制成功', 0.5);
});
this.clipboard2.on('success', (e) => {
message.success('复制成功', 0.5);
});
this.clipboard3.on('success', (e) => {
message.success('复制成功', 0.5);
});
}
......
import React from 'react';
import { Modal, Icon } from 'antd';
import QRCode from 'qrcode.react';
import { imagify } from '../../../utils/index';
import pageStyle from './QrcodeShow.less';
class QrcodeShow extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
componentDidMount() { // 挂载
}
componentWillUnmount() { // 卸载
}
download = () => {
const { previewQrcode, downloadTitle } = this.props;
const Qr = document.getElementById('qrid');
const image = new Image();
image.src = Qr.toDataURL('image/png');
console.log(image, 'image');
image.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
const context = canvas.getContext('2d');
context.drawImage(image, 0, 0, image.width, image.height);
const url = canvas.toDataURL('image/png'); // 得到图片的base64编码数据
const a = document.createElement('a'); // 生成一个a元素
const event = new MouseEvent('click'); // 创建一个单击事件
a.download = '二维码'; // 设置图片名称
a.href = url; // 将生成的URL设置为a.href属性
a.dispatchEvent(event); // 触发a的单击事件
};
}
render() {
const {
previewQrcodeShow,
previewQrcode,
closeQrcodeShow,
title,
} = this.props;
return (
<div className={pageStyle.container} style={{ display: previewQrcodeShow ? 'flex' : 'none' }}>
<div className={pageStyle.mask}></div>
<div className={pageStyle.qrcodeBox}>
<Icon type="close-circle" className={pageStyle.closeIcon} onClick={closeQrcodeShow} />
<div className={pageStyle.boxHeader}>
<div className={pageStyle.headerTitle}>{title}</div>
</div>
<div className={pageStyle.qrCode}>
{
previewQrcode && <QRCode className={pageStyle.qrCodeImage} id="qrid" value={previewQrcode} />
}
<div className={pageStyle.download} onClick={this.download}>保存图片至桌面</div>
</div>
</div>
</div>
);
}
}
QrcodeShow.propTypes = {
};
export default QrcodeShow;
@import '../../../less/variables.less';
@keyframes qrCodefadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.container {
position: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
z-index: 200;
display: flex;
align-items: center;
justify-content: center;
}
.mask {
position: absolute;
z-index: 1;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
}
.qrcodeBox {
min-height: 320px;
border-radius: 10px;
background-color: #fff;
position: relative;
z-index: 2;
animation: qrCodefadeIn 0.1s linear 1 forwards;
// overflow: hidden;
max-width: 520px;
width: calc(100% - 10px);
}
.boxHeader {
height: 150px;
background-image: url('@{imagesroot}qrboxheader.png');
background-size: 100% 100%;
}
.headerTitle {
color: #fff;
text-align: center;
font-size: 18px;
line-height: 1;
padding-top: 34px;
}
.closeIcon {
position: absolute;
font-size: 30px;
color: rgba(255, 255, 255 ,0.7);
// right: 0;
// top: 0;
right: -15px;
z-index: 2;
top: -15px;
cursor: pointer;
&:hover {
transition: 0.2s;
color: rgba(255, 255, 255 ,1);
}
}
.qrCode {
text-align: center;
}
.qrCodeImage {
width: 160px;
height: 160px;
display: block;
margin: -10px auto 0;
}
.download {
font-size: 16px;
color: #1890FF;
text-align: center;
padding: 20px 0;
cursor: pointer;
}
......@@ -12,7 +12,7 @@ import {
Modal,
Form,
Alert,
Radio,
Badge,
message,
Pagination,
Tooltip, DatePicker,
......@@ -24,6 +24,7 @@ import pageStyle from './index.less';
import DownloadModal from './DownloadModal';
import { pageIn, hasBtnPower, btnPermission, translateType } from '../../utils/index';
import BtnPermission from '../../components/BtnPermission';
import QrcodeShow from './components/QrcodeShow';
const { Option } = Select;
const { TextArea } = Input;
const { Search } = Input;
......@@ -152,11 +153,81 @@ class LiveClass extends React.Component {
});
}
changeStatus = (type, record) => {
const { dispatch } = this.props;
if (Number(type) == 2) {
dispatch({
type: 'liveclass/changeStatus',
payload: {
type,
id: record.id,
},
});
} else {
Modal.confirm({
title: '提示',
content: '下架操作若直播间正在直播立即结束直播,直播间为下架状态',
icon: <Icon type="info-circle" theme="filled" style={{ color: '#1890ff', fontSize: 30 }} />,
onOk() {
dispatch({
type: 'liveclass/changeStatus',
payload: {
type,
id: record.id,
},
});
},
});
}
}
closeLive = (record) => {
const { dispatch } = this.props;
Modal.confirm({
title: '提示',
content: '结束直播操作后将会立即结束直播,学员将无法看到老师操作内容,学员直播间提示:直播已结束',
icon: <Icon type="close-circle" style={{ color: 'red' }} />,
onOk() {
dispatch({
type: 'liveclass/closeLive',
payload: {
record,
},
});
},
okButtonProps: {
type: 'danger',
style: {
color: '#fff',
backgroundColor: '#ff4d4f',
borderColor: '#ff4d4f',
},
},
});
}
goShare = (record) => {
const { dispatch } = this.props;
dispatch({
type: 'liveclass/changeStatus',
type: 'liveclass/updateState',
payload: {
previewQrcodeShow: true,
previewQrcode: `${record.id}`,
},
});
}
closeQrcodeShow = (record) => {
const { dispatch } = this.props;
dispatch({
type: 'liveclass/updateState',
payload: {
previewQrcodeShow: false,
previewQrcode: '',
},
});
}
goLook = (record) => {
const { dispatch } = this.props;
dispatch({
type: 'liveclass/queryDetail',
payload: {
type,
id: record.id,
},
});
......@@ -169,6 +240,8 @@ class LiveClass extends React.Component {
liveListParams,
downloadVisible,
liveUrlData,
previewQrcodeShow,
previewQrcode,
} = this.props;
const columns = [
{
......@@ -181,11 +254,6 @@ class LiveClass extends React.Component {
dataIndex: 'created_at',
key: 'created_at',
},
{
title: '直播时间',
dataIndex: 'live_start_time',
key: 'live_start_time',
},
{
title: '直播状态',
dataIndex: 'live_status',
......@@ -195,12 +263,17 @@ class LiveClass extends React.Component {
<div className={pageStyle.typeColor}>
{text == 1 && <div className={pageStyle.typeColor1}><span className={pageStyle.point}></span>待直播</div> }
{text == 2 && <div className={pageStyle.typeColor2}><span className={pageStyle.point}></span>直播中</div>}
{text == 3 && <div className={pageStyle.typeColor3}><span className={pageStyle.point}></span>直播</div>}
{text == 4 && <div className={pageStyle.typeColor4}><span className={pageStyle.point}></span>已下架</div>}
{text == 3 && <div className={pageStyle.typeColor3}><span className={pageStyle.point}></span>直播暂停</div>}
{text == 4 && <div className={pageStyle.typeColor4}><span className={pageStyle.point}></span>直播结束</div>}
</div>
);
},
},
{
title: '直播时间',
dataIndex: 'live_start_time',
key: 'live_start_time',
},
{
title: '状态',
dataIndex: 'status',
......@@ -208,9 +281,9 @@ class LiveClass extends React.Component {
render: (text, record) => {
return (
<div className={pageStyle.typeColor}>
{text == 1 && <div className={pageStyle.typeColor1}><span className={pageStyle.point}></span>待上架</div> }
{text == 2 && <div className={pageStyle.typeColor2}><span className={pageStyle.point}></span>已上架</div>}
{text == 3 && <div className={pageStyle.typeColor3}><span className={pageStyle.point}></span>已下架</div>}
{text == 1 && <div><Badge color="orange" />待上架</div> }
{text == 2 && <div><Badge color="#2fce63" />已上架</div>}
{text == 3 && <div><Badge color="#b2b2b2" />已下架</div>}
</div>
);
},
......@@ -234,13 +307,14 @@ class LiveClass extends React.Component {
record.status == 3 && <span className="hreflink" onClick={() => this.changeStatus(2, record)}>上架</span>
}
<Divider type="vertical" />
<span className="hreflink">分享直播间</span>
<span className="hreflink" onClick={() => this.goShare(record)}>分享直播间</span>
{
record.status == 2 && <span className="hreflink" onClick={() => this.goStartLive(record)}><Divider type="vertical" />去直播</span>
}
{
record.replay_url != '' && <span className="hreflink">直播回放<Divider type="vertical" /></span>
(record.live_status == 4 && record.need_replay == 1) && <span className="hreflink" onClick={() => this.goLook(record)}><Divider type="vertical" />直播回放</span>
}
{ record.status == 2 && (record.live_status == 2 || record.live_status == 3) && <span className="hreflink" onClick={() => this.closeLive(record)}><Divider type="vertical" />结束直播</span> }
<span className="hreflink" onClick={() => this.deleteLive(record)}><Divider type="vertical" />删除</span>
</div>
);
......@@ -274,8 +348,7 @@ class LiveClass extends React.Component {
</Col>
<Col className={pageStyle.formitem} xs={{ span: 12 }} sm={{ span: 12 }} md={{ span: 12 }} lg={{ span: 8 }} xl={{ span: 8 }}>
<div className={pageStyle.formitemlabel} >全部状态:</div>
<Select allowClear style={{ width: '100%', overflow: 'hidden' }} className={pageStyle.selectitem} onChange={e => this.searchParamsChange(e, 'Select', 'status')} placeholder="全部">
<Option value="">全部</Option>
<Select allowClear style={{ width: '100%', overflow: 'hidden' }} value={liveListParams.status ? liveListParams.status : undefined} className={pageStyle.selectitem} onChange={e => this.searchParamsChange(e, 'Select', 'status')} placeholder="全部">
<Option value={1}>待上架</Option>
<Option value={2}>已上架</Option>
<Option value={3}>已下架</Option>
......@@ -320,6 +393,12 @@ class LiveClass extends React.Component {
close={this.closeDownload}
liveUrlData={liveUrlData}
/>
<QrcodeShow
previewQrcodeShow={previewQrcodeShow}
closeQrcodeShow={this.closeQrcodeShow}
previewQrcode={previewQrcode}
title="请使用微信扫一扫,扫码查看直播"
/>
</div>
);
}
......@@ -336,6 +415,8 @@ function mapStateToProps(state) {
liveListParams,
downloadVisible,
liveUrlData,
previewQrcodeShow,
previewQrcode,
} = state.liveclass;
const {
guideStep,
......@@ -355,6 +436,8 @@ function mapStateToProps(state) {
liveListParams,
downloadVisible,
liveUrlData,
previewQrcodeShow,
previewQrcode,
};
}
export default connect(mapStateToProps)(LiveClassForm);
......
......@@ -149,35 +149,35 @@
margin-right: 5px;
}
.typeColor1 {
color: #3ADD60;
color: #FEC02A;
display: flex;
align-items: center;
.point {
background-color: #3ADD60;
background-color: #FEC02A;
}
}
.typeColor2 {
display: flex;
align-items: center;
color: #FFB97A;
color: #3ADD60;
.point {
background-color: #FFB97A;
background-color: #3ADD60;
}
}
.typeColor3 {
color: #65B8F4;
display: flex;
align-items: center;
color: #F96500;
.point {
background-color: #65B8F4;
background-color: #F96500;
}
}
.typeColor4 {
color: #FF6B6B;
color: #818181;
display: flex;
align-items: center;
.point {
background-color: #FF6B6B;
background-color: #818181;
}
}
......
......@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import {
message, Row, Col, Input, Select, Modal, Form, InputNumber, Checkbox, Radio, Tabs,
Icon, Pagination,
Empty,
} from 'antd';
import { imagify, pageIn } from '../../../utils/index';
import pageStyle from './AddThemeClassModal.less';
......@@ -194,7 +195,7 @@ class AddThemeClassModal extends React.Component {
<div>课程类型</div>
</div>
{
themeList.length > 0 && themeList.map((item, index) =>
themeList.length > 0 ? themeList.map((item, index) =>
(
<div className={pageStyle.radioItem} onClick={() => this.handleCheck(item)}>
<div className={pageStyle.radioLeft}>
......@@ -209,7 +210,7 @@ class AddThemeClassModal extends React.Component {
<div>{this.getSubjectType(item.subject_type)}</div>
</div>
),
)
) : <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
}
</div>
<Pagination
......
......@@ -55,3 +55,11 @@ export function liveUrl(params) {
method: 'GET',
});
}
export function closeLive(params) {
const data = qs.stringify(params);
return request({
url: `${api.liveClass.livesEnd}`,
method: 'POST',
data,
});
}
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