Commit 542a3ab6 by zhangleyuan

feat:联调视屏课相关模块

parent 3695560d
......@@ -30,10 +30,10 @@ class ImgCutModalNew extends React.Component {
const fileName = window.random_string(16) + name.slice(name.lastIndexOf('.'));
const params = {
bizCode: bizCode,
accessTypeEnum: 'PUBLIC',
instId: LS.get('instId'),
resourceName: fileName
accessTypeEnum:"PUBLIC",
bizCode:'CLOUD_CLASS_COMMON',
instId:User.getStoreId(),
resourceName:name
}
// 压缩
if (compress) {
......@@ -41,7 +41,7 @@ class ImgCutModalNew extends React.Component {
dataUrl = this.getBase64Size(dataUrl) > compressSizeByte ? await this.handleCompressImg(dataUrl, compressSizeByte, cutWidth) : dataUrl;
}
const cutImage = this.convertBase64UrlToBlob(dataUrl);
Service.Hades('public/hades/commonOssAuthority', param).then((res) => {
Service.Hades('public/hades/commonOssAuthority', params).then((res) => {
const { resourceId, accessId, policy, callback, signature,key, host } = res.result;
const localUrl = URL.createObjectURL(cutImage);
// 构建上传的表单
......
......@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Date: 2020-08-05 10:07:47
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-28 10:12:44
* @LastEditTime: 2020-12-30 17:20:19
* @Description: 视频课新增/编辑页
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
......@@ -20,6 +20,7 @@ import SelectStudent from '../modal/select-student';
import SelectPrepareFileModal from '../../prepare-lesson/modal/SelectPrepareFileModal';
import PreviewCourseModal from '../modal/PreviewCourseModal';
import StoreService from "@/domains/store-domain/storeService";
import CourseService from "@/domains/course-domain/CourseService";
import User from '@/common/js/user';
import './AddVideoCourse.less';
......@@ -43,13 +44,13 @@ class AddVideoCourse extends React.Component {
scheduleVideoId: null, // 视频课链接
coverId: null, // 视频封面的recourceId
coverUrl: null, // 视频课封面
joinType: null, // 观看模式, 默认为指定某些学员可以观看
studentList: [], // 上课学员列表
shelfState:'YES', //是否开启店铺展示
scheduleMedia: [{ // 视频课媒体资源
contentType:"INTRO",
mediaType: 'TEXT',
mediaContent: '',
key: EDIT_BOX_KEY
key: Math.random()
}],
diskList: [], // 机构可见磁盘目录
selectedFileList: [], // 已经从资料云盘中勾选的文件
......@@ -69,12 +70,12 @@ class AddVideoCourse extends React.Component {
this.getCourseCatalogList();
if (pageType === 'edit') {
this.handleFetchScheudleDetail(id);
this.handleFetchStudentList(id);
// this.handleFetchStudentList(id);
}
}
//获取分类列表
getCourseCatalogList = ()=>{
StoreService.getCourseCatalogList({current:1,size:10}).then((res) => {
StoreService.getCourseCatalogList({current:1,size:1000}).then((res) => {
this.setState({
courseCatalogList:res.result.records
})
......@@ -96,9 +97,9 @@ class AddVideoCourse extends React.Component {
}
}
// 获取视频课详情
handleFetchScheudleDetail = (scheduleId) => {
window.axios.Apollo('public/apollo/getLessonScheduleDetail', {
scheduleId
handleFetchScheudleDetail = (courseId) => {
CourseService.videoScheduleDetail({
courseId
}).then((res) => {
const { result = {} } = res || {};
const {
......@@ -107,11 +108,9 @@ class AddVideoCourse extends React.Component {
videoType,
videoDuration,
videoName,
studentIds,
scheduleMedia,
courseName,
scheduleVideoId,
joinType,
scheduleVideoUrl,
} = result;
this.setState({
......@@ -120,11 +119,9 @@ class AddVideoCourse extends React.Component {
videoType,
videoName,
videoDuration,
studentIds,
scheduleMedia,
courseName,
scheduleVideoId,
joinType,
scheduleVideoUrl,
});
......@@ -132,19 +129,19 @@ class AddVideoCourse extends React.Component {
}
// 获取视频课学员
handleFetchStudentList = (scheduleId) => {
window.axios.Apollo('public/apollo/getLessonStuIdListByScheduleId', {
scheduleId
}).then((res) => {
const studentIds = res.result || [];
const studentList = [];
_.each(studentIds, (item) => {
studentList.push({ studentId: item });
});
// handleFetchStudentList = (scheduleId) => {
// window.axios.Apollo('public/apollo/getLessonStuIdListByScheduleId', {
// scheduleId
// }).then((res) => {
// const studentIds = res.result || [];
// const studentList = [];
// _.each(studentIds, (item) => {
// studentList.push({ studentId: item });
// });
this.setState({ studentList })
});
}
// this.setState({ studentList })
// });
// }
// 获取机构可见的磁盘
// handleFetchDiskList = () => {
......@@ -317,29 +314,22 @@ class AddVideoCourse extends React.Component {
storeId:User.getStoreId(),
shelfState,
whetherVisitorsJoin
};
// 校验必填字段:课程名称, 课程视频
this.handleValidate(courseName, scheduleVideoId, joinType, scheduleMedia).then((res) => {
this.handleValidate(courseName, scheduleVideoId,categoryId, scheduleMedia).then((res) => {
if (!res) return;
if (pageType === 'add') {
window.axios.Apollo('public/apollo/createLessonSchedule', commonParams).then((res) => {
CourseService.createVideoSchedule(commonParams).then((res) => {
if (!res) return;
message.success("新建成功");
// localStorage.setItem('videoCourseItem', JSON.stringify({
// ...commonParams,
// coverUrl,
// scheduleVideoUrl,
// id: res.result
// }));
window.RCHistory.goBack();
})
} else {
const editParams = {
id,
courseId:id,
...commonParams,
}
window.axios.Apollo('public/apollo/editLessonSchedule', editParams).then((res) => {
CourseService.editVideoSchedule(editParams).then((res) => {
if (!res) return;
message.success("保存成功");
window.RCHistory.goBack();
......@@ -348,24 +338,29 @@ class AddVideoCourse extends React.Component {
});
}
handleValidate = (courseName, scheduleVideoId, joinType, scheduleMedia) => {
handleValidate = (courseName, scheduleVideoId,categoryId,scheduleMedia) => {
return new Promise((resolve) => {
if (!courseName) {
message.warning('请输入课程名称');
resolve(false);
} else if (!scheduleVideoId) {
return false
}
if (!scheduleVideoId) {
message.warning('请上传视频');
resolve(false);
} else if (!joinType) {
message.warning('请选择观看设置');
return false
}
if(!categoryId){
message.warning('请选择课程分类');
resolve(false);
} else {
return false
}
const textMedia = scheduleMedia.filter((item) => item.mediaType === 'TEXT');
for (let i = 0, len = textMedia.length; i < len; i++) {
if (textMedia[i].mediaContentLength && textMedia[i].mediaContentLength.length > 1000) {
message.warning(`第${i+1}个文字简介的字数超过了1000个字`);
resolve(false);
}
return false
}
}
resolve(true);
......@@ -471,12 +466,12 @@ class AddVideoCourse extends React.Component {
</div>
<div className="course-catalog">
<span className="label"><span className="require">*</span>课程分类:</span>
{ pageType === 'add' &&
<Cascader defaultValue={[categoryName]} options={courseCatalogList} displayRender={ label => label.join('-')} fieldNames={fieldNames} onChange={this.catalogChange} style={{ width: 240 }} placeholder="请选择课程分类" />
}
{ (pageType === 'edit' && categoryName) &&
<Cascader disabled={!isEdit ? true: false} defaultValue={[categoryName]} options={courseCatalogList} displayRender={ label => label.join('-')} fieldNames={fieldNames} onChange={this.catalogChange} style={{ width: 240 }} placeholder="请选择课程分类" />
}
{/* { (pageType === 'edit') &&
<Cascader defaultValue={[categoryName]} options={courseCatalogList} displayRender={ label => label.join('-')} fieldNames={fieldNames} onChange={this.catalogChange} style={{ width: 240 }} placeholder="请选择课程分类" />
} */}
</div>
<div className="intro-info mt16">
<AddVideoIntro
......
......@@ -2,18 +2,20 @@
* @Author: 吴文洁
* @Date: 2020-08-05 10:12:45
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-26 14:10:44
* @LastEditTime: 2020-12-30 17:44:18
* @Description: 视频课-列表模块
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
import React from 'react';
import { Table, Modal, message } from 'antd';
import { Table, Modal, message , Tooltip,Switch,Dropdown} from 'antd';
import { PageControl } from "@/components";
import { LIVE_SHARE_MAP } from '@/common/constants/academic/cloudClass';
import StudentListModal from '../modal/StudentListModal';
import ShareLiveModal from '@/modules/course-manage/modal/ShareLiveModal';
import CourseService from "@/domains/course-domain/CourseService";
import User from '@/common/js/user'
import './VideoCourseList.less';
......@@ -44,43 +46,63 @@ class VideoCourseList extends React.Component {
title: '视频课',
key: 'scheduleName',
dataIndex: 'scheduleName',
width: '25%',
width: '20%',
render: (val, record) => {
const { coverUrl, scheduleVideoUrl } = record;
return (
<div className="record__item">
{/* 上传了封面的话就用上传的封面, 没有的话就取视频的第一帧 */}
<img className="course-cover" src={coverUrl || `${scheduleVideoUrl}?x-oss-process=video/snapshot,t_0,m_fast`} />
<span className="course-name">{val}</span>
<span className="course-name">{record.courseName}</span>
</div>
)
}
},
{
title: '学员人数',
key: "stuNum",
dataIndex: "stuNum",
title: '课程分类',
key: 'categoryName',
dataIndex: 'categoryName',
render: (val, record) => {
return (
<span
className="operate-text"
onClick={() => this.handleShowStudentListModal(record)}
>
{val}
</span>
);
},
<div className="record__item">
{record.categoryName}
</div>
)
}
},
{
title: '创建人',
key: 'teacherName',
dataIndex: 'teacherName'
key: 'createName',
dataIndex: 'createName'
},
{
title: <span>
<span>店铺展示</span>
<Tooltip title="开启后,用户可在店铺内查看到此课程。若课程“未成功开课”,则系统会自动“关闭”店铺展示。关闭后,店铺内不再展示此课程,但用户仍可通过分享的海报/链接查看此课程。"><i className="icon iconfont" style={{ marginLeft: '5px',cursor:'pointer',color:'#bfbfbf'}}>&#xe61d;</i></Tooltip>
</span>,
width: "7%",
dataIndex: "courseware",
render: (val, item, index) => {
return (
<Switch defaultChecked={item.shelfState==="YES"?true:false} onChange={()=>this.changeShelfState(item)}/>
)
},
},
{
title: "观看用户数",
width: "10%",
key: "watchUserCount",
dataIndex: "watchUserCount",
render: (val, item) => {
return (
<div className="watchUserCount">{val}</div>
)
},
},
{
title: '创建时间',
key: 'createTime',
dataIndex: 'createTime',
key: 'created',
dataIndex: 'created',
sorter: true,
render: (val) => {
return formatDate('YYYY-MM-DD H:i', val)
......@@ -88,8 +110,8 @@ class VideoCourseList extends React.Component {
},
{
title: '更新时间',
key: 'updateTime',
dataIndex: 'updateTime',
key: 'updated',
dataIndex: 'updated',
sorter: true,
render: (val) => {
return formatDate('YYYY-MM-DD H:i', val)
......@@ -102,27 +124,69 @@ class VideoCourseList extends React.Component {
render: (val, record) => {
return (
<div className="operate">
<div className="operate__item">观看数据</div>
<span className="operate__item split"> | </span>
<div className="operate__item" onClick={() => this.handleShowShareModal(record)}>分享</div>
<span className="operate__item split"> | </span>
<Dropdown overlay={this.renderMoreOperate(record)}>
<span className="more-operate">
<span className="operate-text">更多</span>
<span
className="iconfont icon"
style={{ color: "#5289FA" }}
>
&#xe824;
</span>
</span>
</Dropdown>
</div>
)
}
}
];
return columns;
}
renderMoreOperate = (item) => {
return (
<div className="live-course-more-menu">
<div
className="operate__item"
onClick={() => {
RCHistory.push(`/cloudclass/video_course/create?type=edit&id=${record.id}`);
RCHistory.push(`/create-video-course?type=edit&id=${item.id}`);
}}
>编辑</div>
<span className="operate__item split"> | </span>
<div
className="operate__item"
onClick={() => this.handleDeleteVideoCourse(record.id)}
onClick={() => this.handleDeleteVideoCourse(item.id)}
>删除</div>
</div>
)
}
//改变上架状态
changeShelfState = (item) =>{
let _shelfState = item.shelfState
if(_shelfState==='NO'){
_shelfState = "YES";
item.shelfState = "YES"
}else{
_shelfState = "NO"
item.shelfState = "NO"
}
];
return columns;
const params={
courseId: item.id,
shelfState:_shelfState
}
CourseService.changeVideoShelfState(params).then((res)=>{
if(res.success){
if(_shelfState === "YES"){
message.success("已开启展示");
}else{
message.success("已取消展示");
}
}
})
}
// 删除视频课
handleDeleteVideoCourse = (scheduleId) => {
Modal.confirm({
......@@ -130,9 +194,13 @@ class VideoCourseList extends React.Component {
content: '删除后,学员将不能进行观看。',
icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>,
onOk: () => {
window.axios.Apollo('public/apollo/removeLessonSchedule', {
scheduleId
}).then(() => {
const param ={
courseId:scheduleId,
storeId:User.getStoreId()
}
CourseService.delVideoSchedule(
param
).then(() => {
message.success('删除成功');
this.props.onChange();
})
......@@ -170,13 +238,13 @@ class VideoCourseList extends React.Component {
// 显示分享弹窗
handleShowShareModal = (record, needStr = false) => {
const appId = CONFIG.appId[ENV];
const shareUrl = CONFIG.shareUrl[ENV];
// const appId = CONFIG.appId[ENV];
const shareUrl = "";
const { id, scheduleVideoUrl } = record;
const htmlUrl = `${LIVE_SHARE_MAP[ENV]}videoShare?id=${id}`;
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 link = htmlUrl;
const longUrl = "";
const { coverUrl, scheduleName } = record;
const shareData = {
......
......@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Date: 2020-04-29 10:26:32
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-25 15:20:14
* @LastEditTime: 2020-12-30 16:01:54
* @Description: 内容线路由配置
*/
import EmployeesManagePage from '@/modules/store-manage/EmployeesManagePage';
......
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