Commit 55a028ed by wufan

feat:完成直播课分享弹框

parent 76ea84eb
/*
* @Author: wufan
* @Date: 2020-12-12 11:57:10
* @LastEditors: wufan
* @LastEditTime: 2020-12-12 14:32:44
* @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import Service from "@/common/js/service";
/*
* @Author: 吴文洁
* @Date: 2020-08-20 09:21:40
* @LastEditors: wufan
* @LastEditTime: 2020-12-12 11:18:53
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
import { MapInterface } from '@/domains/basic-domain/interface'
const ENV: string = process.env.DEPLOY_ENV || 'dev';
const appIdMap: MapInterface = {
dev: 'wx3ea60e78ddfa277e',
dev1: 'wx3ea60e78ddfa277e',
rc: 'wx5c5a1fb71ecab7bc',
gray: "wxdd6b458500d4c224", // 小麦校讯通
prod: 'wxdd6b458500d4c224'
}
const shareUrlMap: MapInterface = {
'dev': 'https://dev.xiaomai5.com/share/show?appid=',
'dev1': 'https://dev.xiaomai5.com/share/show?appid=',
'rc': 'https://rc.xiaomai5.com/share/show?appid=',
'prod': 'https://prod.xiaomai5.com/share/show?appid=',
'gray': 'https://prod.xiaomai5.com/share/show?appid='
}
const LIVE_SHARE_MAP: MapInterface = {
dev: 'https://dev.xiaomai5.com/xiaomai-live-share/index.html#/',
dev1: 'https://dev.xiaomai5.com/xiaomai-live-share/index.html#/',
rc: 'https://rc.xiaomai5.com/xiaomai-live-share/index.html#/',
gray: 'https://res.xiaomai5.com/xiaomai-live-share/gray/index.html#/',
prod: 'https://res.xiaomai5.com/xiaomai-live-share/index.html#/',
}
export const appId: string = appIdMap[ENV];
export const shareUrl: string = shareUrlMap[ENV];
export const LIVE_SHARE: string = LIVE_SHARE_MAP[ENV];
/*
* @Author: 吴文洁
* @Date: 2020-09-29 10:01:08
* @LastEditors: wufan
* @LastEditTime: 2020-12-10 10:50:19
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
import { SUFFIX_MAP } from '@/domains/resource-disk/constants';
const getFileTypeByName = (name: string) => {
const nameArray: string[] = name.split(".");
const suffix: string = nameArray[nameArray.length - 1];
return SUFFIX_MAP[suffix];
}
export {
getFileTypeByName
};
\ No newline at end of file
......@@ -13,7 +13,6 @@ import { Table, Modal, Tooltip, Badge, message, Dropdown, Button,Switch} from 'a
// import User from "@/core/user";
// import User_t from "@/teacher/core/user";
import { PageControl } from "@/components";
// import { LIVE_SHARE_MAP } from '@/common/constants/academic/cloudClass';
// import DownloadLiveModal from '@/components/DownloadLiveModal';
// import LiveStudentListModal from '../modal/LiveStudentListModal';
......@@ -22,12 +21,13 @@ import { PageControl } from "@/components";
// import ClassRecordModal from '../modal/ClassRecordModal';
// import PlayBackRecordModal from '../modal/PlayBackRecordModal';
// import ManageCoursewareModal from '../modal/ManageCoursewareModal';
// import ShareLiveModal from '../modal/ShareLiveModal';
import ShareLiveModal from '../modal/ShareLiveModal';
// import AccountChargeModal from '../modal/AccountChargeModal';
// import SelectStudent from '../modal/select-student';
import './LiveCourseList.less';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { appId, shareUrl, LIVE_SHARE } from '@/domains/course-domain/constants';
const { confirm } = Modal;
const courseStateShow = {
UN_START: {
......@@ -77,6 +77,34 @@ class LiveCourseList extends React.Component {
}
// 显示分享弹窗
handleShowShareModal = (item, needStr = false) => {
const _appId = appId;
const _shareUrl = shareUrl;
const { liveCourseId } = item;
const { saaSVersionEnum } = window.currentUserInstInfo;
const htmlUrl = `${LIVE_SHARE}liveShare?id=${liveCourseId}&saasVersion=${saaSVersionEnum}`;
const link = `${_appId}&redirect_uri=${encodeURIComponent(htmlUrl)}%26appid%3D${_appId}&response_type=code&scope=snsapi_base&state=state#wechat_redirect`;
const longUrl = `${_shareUrl}${link}`;
const shareData = { ...item, longUrl };
const shareLiveModal = (
<ShareLiveModal
needStr={needStr}
data={shareData}
close={() => {
this.setState({
shareLiveModal: null
});
localStorage.setItem('largeLiveCourseItem', '');
}}
/>
)
this.setState({ shareLiveModal })
}
// 前往上课数据页面
handleLinkToClassData = (item) => {
// TODOLIST 确定后端是否是根据liveCourseId 返回数据
......@@ -191,6 +219,7 @@ class LiveCourseList extends React.Component {
<div
key="share"
className="operate__item"
onClick={() => { this.handleShowShareModal(item); }}
>
分享
</div>
......@@ -279,6 +308,7 @@ class LiveCourseList extends React.Component {
}}
/>
</div>
{ this.state.shareLiveModal }
</div>
)
}
......
import React, { useEffect, useState } from 'react';
import { Modal, Button } from 'antd';
import qrcode from "@/libs/qrcode/qrcode.js";
import './StudentClassReportModal.less';
const StudentClassReportModal = (props) => {
const url = window.CONFIG.parentHref[window.CONFIG.env];
const previewUrl = `${url}#/live/pc-cloud-class-report?courseId=${props.courseId}&studentId=${props.studentId}`
const mobileUrl = `${url}#/live/cloud-class-report?courseId=${props.courseId}&studentId=${props.studentId}`
useEffect(() => {
window.axios.Sales('public/businessShow/convertShortUrls', {
urls: [mobileUrl]
}).then((res) => {
const { result = [] } = res;
const qrcodeNode = new qrcode({
text: result[0].shortUrl,
size: 106
});
document.querySelector('#qrcode').appendChild(qrcodeNode)
})
}, [])
return (
<Modal
visible={true}
title={props.studentId? "TA的课堂报告":"老师的课堂报告"}
width={560}
onCancel={props.onCancel}
className="student-class-report-modal"
footer={ <div onMouseEnter={(e) => {
e.preventDefault();
}}
>
<Button
key="cancel"
onMouseEnter={(e) => {
e.preventDefault();
let qrcode = document.getElementsByClassName("qrcode")[0];
qrcode.style.display = "block";
}}
onMouseLeave={(e) => {
e.preventDefault();
let qrcode = document.getElementsByClassName("qrcode")[0];
qrcode.style.display = "none";
}}
>
分享TA的课堂报告
</Button>
</div>}
>
<div className="modal-content">
<iframe
src={previewUrl}
style={{ width: '100%', height: '70vh', border: 'none' }}
/>
</div>
<div className="qrcode">
<div className="qrcode-text">微信扫码查看/分享</div>
<div id="qrcode"></div>
<div className="triangle"></div>
</div>
</Modal>
)
}
export default StudentClassReportModal;
\ No newline at end of file
.student-class-report-modal {
.modal-content {
height: 70vh;
margin-left: -3px;
margin-right: -3px;
position: relative;
}
.share-entry {
width: 560px;
height: 48px;
background: #ffffff;
border-radius: 0px 0px 6px 6px;
position: fixed;
left: 0;
bottom: -48px;
.share-btn {
width: 148px;
height: 28px;
background: #ffffff;
border: 1px solid #e8e8e8;
position: absolute;
right: 23px;
top: 10px;
width: 116px;
font-size: 14px;
font-weight: 400;
color: #666666;
line-height: 28px;
}
}
.qrcode {
display: none;
position: absolute;
bottom:70px;
right:0;
width: 200px;
height: 191px;
background: #FFFFFF;
padding: 14px 40px 18px 40px;
text-align: center;
border-radius:8px;
box-shadow: 0 0 6px 0 rgba(0,0,0,.2);
.qrcode-text {
width: 126px;
height: 21px;
font-size: 15px;
color: #333333;
line-height: 21px;
margin-bottom: 22px;
}
#qrcode {
width: 106px;
height: 106px;
margin: 0 auto;
}
.triangle {
position: absolute;
width: 10px;
height: 10px;
transform: rotate(45deg);
bottom: -5px;
left: 95px;
background-color: #fff;
box-shadow: 0 0 6px 0 rgba(0,0,0,.2);
}
}
}
.class-report-modal {
.modal-content {
height: 70vh;
margin-left: -3px;
margin-right: -3px;
}
}
import React, { useEffect, useState } from 'react';
import { Modal } from 'antd';
import './TeacherClassReportModal.less';
import TeacherClassReportPage from './TeacherClassReportPage';
interface TeacherClassReportModal {
onCancel: Function,
courseId: string,
}
const TeacherClassReportModal = (props: TeacherClassReportModal) => {
return (
<Modal
visible={true}
// title={props.studentId? "TA的课堂报告":"老师的课堂报告"}
width={560}
footer={null}
// onCancel={props.onCancel}
className="class-report-modal"
>
<div className="modal-content">
<TeacherClassReportPage courseId={props.courseId}/>
</div>
</Modal>
)
}
export default TeacherClassReportModal;
\ No newline at end of file
.teacher-class-report-page {
.class-loading-page {
position: absolute;
z-index: 1;
left: 20px;
top: 60px;
right: 20px;
bottom: 0;
background: #fff;
#lottie-box {
width: 88px;
height: 106px;
margin: 0 auto;
}
.loading-box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
.app-logo {
display: block;
margin: 0 auto;
width: 240px;
height: 240px;
}
.h5-logo {
display: block;
width: 220px;
height: 220px;
}
.box-tip {
margin-top: 16px;
display: block;
color: #666;
font-size: 26px;
.tip-button {
font-size: 26px;
color: #ffb100;
margin: 0 8px;
}
}
}
}
width: 512px;
text-align: center;
background-color: #fff;
.iconfont {
color: rgba(191, 191, 191, 1);
}
.teacher-title {
width: 512px;
background: #fff0e7;
border-radius: 4px;
font-size: 14px;
font-weight: 400;
color: #666666;
line-height: 44px;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
display: flex;
justify-content: center;
.teacher-name {
font-size: 16px;
font-weight: 400;
color: #ff7519;
line-height: 44px;
max-width: 192px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
.class-detail {
margin-top: 20px;
margin-bottom: 21px;
.class-title {
width: 480px;
margin: 0 auto;
font-size: 16px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #242b33;
line-height: 22px;
text-align: center;
}
.class-duration {
text-align: center;
height: 22px;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #8c8e93;
line-height: 22px;
margin-top: 8px;
}
}
.sign-in-detail {
.title {
height: 24px;
font-size: 17px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 24px;
text-align: center;
position: relative;
margin-bottom: 29px;
&::before {
content: '';
width: 24px;
height: 4px;
background: #fc9c6b;
border-radius: 8px;
position: absolute;
bottom: -6px;
left: 50%;
transform: translateX(-50%);
}
}
.content {
.line-height {
color: rgba(255, 117, 25, 1);
}
.rate-block {
display: flex;
justify-content: space-between;
flex-flow: wrap;
.item {
width: 50%;
margin-bottom: 20px;
.rate {
height: 33px;
font-size: 24px;
font-weight: 500;
color: #333333;
line-height: 33px;
.tiny {
font-size: 18px;
}
}
.explaination {
text-align: center;
height: 20px;
font-size: 14px;
font-weight: 400;
color: #999999;
line-height: 20px;
}
}
}
.progress-block {
.item {
.tip {
display: flex;
justify-content: space-between;
.text {
height: 22px;
font-size: 14px;
color: rgba(140, 142, 147, 1);
line-height: 22px;
.tip-title {
color: rgba(51, 51, 51, 1);
font-weight: 500;
}
}
.num {
color: #333333;
line-height: 22px;
.left-num {
color: rgba(51, 51, 51, 1);
font-weight: 500;
font-size: 24px;
}
}
}
.progress {
position: relative;
width: 512px;
.up-progress {
position: absolute;
z-index: 10;
width: 80%;
height: 10px;
border-radius: 5px;
background-color: rgba(252, 156, 107, 1);
}
.down-progress {
width: 512px;
height: 10px;
background: #f6f7f8;
border-radius: 5px;
}
}
}
.total-class {
width: 512px;
height: 44px;
background: #f6f7f8;
border-radius: 2px;
display: flex;
justify-content: space-between;
margin-top: 10px;
margin-bottom: 20px;
line-height: 44px;
padding-left: 10px;
padding-right: 10px;
.text {
}
.num {
.left-num {
color: rgba(51, 51, 51, 1);
font-weight: 500;
font-size: 16px;
}
}
}
}
}
}
.class-data-detail {
margin-top: 30px;
.title {
height: 24px;
font-size: 17px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 24px;
text-align: center;
position: relative;
margin-bottom: 11px;
&::before {
content: '';
width: 24px;
height: 4px;
background: #fc9c6b;
border-radius: 8px;
position: absolute;
bottom: -6px;
left: 50%;
transform: translateX(-50%);
}
}
.content {
.data-block {
.item {
width: 512px;
padding: 26px 20px;
display: flex;
justify-content: flex-start;
text-align: left;
border-bottom: 1px dashed rgba(232, 232, 232, 1);
&:last-child {
border-bottom: none;
}
&.column-center {
align-items: center;
}
img {
display: inline-block;
width: 40px;
height: 42px;
margin-right: 16px;
}
.large-line-height {
color: rgba(255, 117, 25, 1);
font-size: 24px;
line-height: 22px;
}
.line-height {
color: rgba(255, 117, 25, 1);
font-size: 14px;
line-height: 22px;
}
}
}
}
}
}
.class-high-light {
color:rgba(255, 117, 25, 1);
margin-left: 4px;
margin-right: 4px;
}
......@@ -11,13 +11,11 @@ import { Modal, Input, Button, message } from 'antd';
import domtoimage from 'dom-to-image';
import html2canvas from 'html2canvas';
import qrcode from "@/libs/qrcode/qrcode.js";
import User from '@/common/js/user';
import './ShareLiveModal.less';
const BASE_IMG = require('@/images/xiaomai-IMG.png');
const { name, banner = BASE_IMG } = currentUserInstInfo;
const storeName = User.getStoreName();
const DEFAULT_COVER = 'https://image.xiaomaiketang.com/xm/YNfi45JwFA.png';
class ShareLiveModal extends React.Component {
......@@ -37,22 +35,22 @@ class ShareLiveModal extends React.Component {
handleConvertShortUrl = () => {
const { longUrl } = this.props.data;
// 发请求
axios.Sales('public/businessShow/convertShortUrls', {
urls: [longUrl]
}).then((res) => {
const { result = [] } = res;
this.setState({
shareUrl: result[0].shortUrl
}, () => {
const qrcodeWrapDom = document.querySelector('#qrcodeWrap');
const qrcodeNode = new qrcode({
text: this.state.shareUrl,
size: 98,
})
qrcodeWrapDom.appendChild(qrcodeNode);
});
})
// // 发请求
// axios.Sales('public/businessShow/convertShortUrls', {
// urls: [longUrl]
// }).then((res) => {
// const { result = [] } = res;
// this.setState({
// shareUrl: result[0].shortUrl
// }, () => {
// const qrcodeWrapDom = document.querySelector('#qrcodeWrap');
// const qrcodeNode = new qrcode({
// text: this.state.shareUrl,
// size: 98,
// })
// qrcodeWrapDom.appendChild(qrcodeNode);
// });
// })
}
componentWillUnmount() {
......@@ -107,8 +105,11 @@ class ShareLiveModal extends React.Component {
onCancel={this.props.close}
>
<div className="left" id="poster">
<div className="course-name">{`【${courseName}】开课啦,快来学习!`}</div>
<div className="store-name">
<span className="text">{storeName}</span>
</div>
<div className="course-name">{type === 'videoClass' ? `${courseName}开课啦`: `邀请你观看直播:《${courseName}》`}</div>
<img
src={coverImgSrc}
crossOrigin="*"
......@@ -124,12 +125,14 @@ class ShareLiveModal extends React.Component {
</div>
</div>
<div className="inst-name">
<span className="icon iconfont">&#xe7b1;</span>
<span className="text">{name}</span>
</div>
</div>
<div className="right">
<div className="share-poster right__item">
<div className="title">② 海报分享</div>
<div className="sub-title">学生可通过微信识别二维码,报名观看直播</div>
<div className="content" onClick={this.handleDownloadPoster}>下载海报</div>
</div>
<div className="share-url right__item">
<div className="title">① 链接分享</div>
<div className="sub-title">学生可通过微信打开链接,报名观看直播</div>
......@@ -139,11 +142,6 @@ class ShareLiveModal extends React.Component {
</div>
</div>
<div className="share-poster right__item">
<div className="title">② 海报分享</div>
<div className="sub-title">学生可通过微信识别二维码,报名观看直播</div>
<div className="content" onClick={this.handleDownloadPoster}>下载海报</div>
</div>
</div>
</Modal>
)
......
......@@ -52,22 +52,20 @@
}
}
.inst-name {
background-color: #FAFAFA;
min-height: 36px;
border-radius: 9px;
padding: 8px 16px;
.store-name {
// padding: 8px 16px;
display: flex;
align-items: center;
.iconfont {
color: #999;
margin-right: 4px;
}
margin-bottom: 8px;
.text {
font-size: 12px;
color: #999;
font-size: 14px;
line-height: 20px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 100%;
}
}
}
......@@ -106,10 +104,10 @@
}
.share-poster {
margin-top: 40px;
margin-bottom: 40px;
.content {
color: #FF7519;
color:rgba(82, 137, 250, 1);
cursor: pointer;
}
}
......
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