视频二级目录和外链

dev_aliyun2
caicai8 5 years ago committed by harry
parent 72eafee2f8
commit c12fdfab44

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -5,6 +5,62 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "13353315",
"name": "移动",
"font_class": "yidong",
"unicode": "e734",
"unicode_decimal": 59188
},
{
"icon_id": "13247262",
"name": "下移2",
"font_class": "xiayi1",
"unicode": "e732",
"unicode_decimal": 59186
},
{
"icon_id": "13247261",
"name": "上移2",
"font_class": "shangyi1",
"unicode": "e731",
"unicode_decimal": 59185
},
{
"icon_id": "13247178",
"name": "下移",
"font_class": "xiayi",
"unicode": "e730",
"unicode_decimal": 59184
},
{
"icon_id": "13247175",
"name": "上移",
"font_class": "shangyi",
"unicode": "e72f",
"unicode_decimal": 59183
},
{
"icon_id": "13247173",
"name": "编辑",
"font_class": "bianji5",
"unicode": "e72e",
"unicode_decimal": 59182
},
{
"icon_id": "13247168",
"name": "删除",
"font_class": "shanchu3",
"unicode": "e72d",
"unicode_decimal": 59181
},
{
"icon_id": "13183780",
"name": "选择",
"font_class": "xuanze",
"unicode": "e72c",
"unicode_decimal": 59180
},
{
"icon_id": "2077714",
"name": "编辑",

@ -20,6 +20,30 @@ Created by iconfont
/>
<missing-glyph />
<glyph glyph-name="yidong" unicode="&#59188;" d="M855.341176-121.976471H174.682353c-90.352941 0-156.611765 72.282353-156.611765 156.611765V721.317647C18.070588 811.670588 90.352941 877.929412 174.682353 877.929412h680.658823c90.352941 0 156.611765-72.282353 156.611765-156.611765v-78.305882h-90.352941V721.317647c0 36.141176-30.117647 66.258824-66.258824 66.258824H174.682353c-36.141176 0-66.258824-30.117647-66.258824-66.258824v-680.658823c0-36.141176 30.117647-66.258824 66.258824-66.258824h680.658823c36.141176 0 66.258824 30.117647 66.258824 66.258824v78.305882h90.352941v-78.305882c6.023529-90.352941-66.258824-162.635294-156.611765-162.635295zM951.717647 299.670588H271.058824c-24.094118 0-48.188235 18.070588-48.188236 48.188236s18.070588 48.188235 48.188236 48.188235h680.658823c24.094118 0 48.188235-18.070588 48.188235-48.188235s-24.094118-48.188235-48.188235-48.188236zM1084.235294 347.858824L921.6 173.176471V534.588235L1084.235294 359.905882v-12.047058z" horiz-adv-x="1084" />
<glyph glyph-name="xiayi1" unicode="&#59186;" d="M512 384m-481.882353 0a481.882353 481.882353 0 1 1 963.764706 0 481.882353 481.882353 0 1 1-963.764706 0ZM512-128C228.894118-128 0 100.894118 0 384S228.894118 896 512 896 1024 667.105882 1024 384 795.105882-128 512-128z m0 963.764706C265.035294 835.764706 60.235294 630.964706 60.235294 384S265.035294-67.764706 512-67.764706 963.764706 137.035294 963.764706 384 758.964706 835.764706 512 835.764706zM502.964706 143.058824c-18.070588 0-30.117647 12.047059-30.117647 30.117647V588.8c0 18.070588 12.047059 30.117647 30.117647 30.117647s30.117647-12.047059 30.117647-30.117647V173.176471c0-18.070588-12.047059-30.117647-30.117647-30.117647zM502.964706 88.847059c-6.023529 0-12.047059 0-18.070588 6.023529l-144.564706 132.517647c-12.047059 12.047059-12.047059 30.117647 0 42.164706 12.047059 12.047059 30.117647 12.047059 42.164706 0l126.494117-108.423529 132.517647 108.423529c12.047059 12.047059 30.117647 12.047059 42.164706-6.023529 6.023529-6.023529 6.023529-30.117647-12.047059-36.141177l-150.588235-132.517647c-6.023529 0-12.047059-6.023529-18.070588-6.023529z" horiz-adv-x="1024" />
<glyph glyph-name="shangyi1" unicode="&#59185;" d="M512 384m-481.882353 0a481.882353 481.882353 0 1 1 963.764706 0 481.882353 481.882353 0 1 1-963.764706 0ZM512-128C228.894118-128 0 100.894118 0 384S228.894118 896 512 896 1024 667.105882 1024 384 795.105882-128 512-128z m0 963.764706C265.035294 835.764706 60.235294 630.964706 60.235294 384S265.035294-67.764706 512-67.764706 963.764706 137.035294 963.764706 384 758.964706 835.764706 512 835.764706zM502.964706 106.917647c-18.070588 0-30.117647 12.047059-30.117647 30.117647V552.658824c0 18.070588 12.047059 30.117647 30.117647 30.117647s30.117647-12.047059 30.117647-30.117647v-415.62353c0-18.070588-12.047059-30.117647-30.117647-30.117647zM653.552941 444.235294c-6.023529 0-12.047059 0-18.070588 6.02353l-132.517647 114.447058-126.494118-108.423529c-12.047059-12.047059-30.117647-12.047059-42.164706 0-12.047059 12.047059-12.047059 30.117647 0 42.164706l144.564706 126.494117c12.047059 12.047059 30.117647 12.047059 42.164706 0l150.588235-126.494117c12.047059-12.047059 12.047059-30.117647 6.02353-42.164706-6.023529-6.023529-12.047059-12.047059-24.094118-12.047059z" horiz-adv-x="1024" />
<glyph glyph-name="xiayi" unicode="&#59184;" d="M512 384m-481.882353 0a481.882353 481.882353 0 1 1 963.764706 0 481.882353 481.882353 0 1 1-963.764706 0ZM512-128C228.894118-128 0 100.894118 0 384S228.894118 896 512 896 1024 667.105882 1024 384 795.105882-128 512-128z m0 963.764706C265.035294 835.764706 60.235294 630.964706 60.235294 384S265.035294-67.764706 512-67.764706 963.764706 137.035294 963.764706 384 758.964706 835.764706 512 835.764706zM502.964706 143.058824c-18.070588 0-30.117647 12.047059-30.117647 30.117647V588.8c0 18.070588 12.047059 30.117647 30.117647 30.117647s30.117647-12.047059 30.117647-30.117647V173.176471c0-18.070588-12.047059-30.117647-30.117647-30.117647zM502.964706 88.847059c-6.023529 0-12.047059 0-18.070588 6.023529l-144.564706 132.517647c-12.047059 12.047059-12.047059 30.117647 0 42.164706 12.047059 12.047059 30.117647 12.047059 42.164706 0l126.494117-108.423529 132.517647 108.423529c12.047059 12.047059 30.117647 12.047059 42.164706-6.023529 6.023529-6.023529 6.023529-30.117647-12.047059-36.141177l-150.588235-132.517647c-6.023529 0-12.047059-6.023529-18.070588-6.023529z" horiz-adv-x="1024" />
<glyph glyph-name="shangyi" unicode="&#59183;" d="M512 384m-481.882353 0a481.882353 481.882353 0 1 1 963.764706 0 481.882353 481.882353 0 1 1-963.764706 0ZM512-128C228.894118-128 0 100.894118 0 384S228.894118 896 512 896 1024 667.105882 1024 384 795.105882-128 512-128z m0 963.764706C265.035294 835.764706 60.235294 630.964706 60.235294 384S265.035294-67.764706 512-67.764706 963.764706 137.035294 963.764706 384 758.964706 835.764706 512 835.764706zM502.964706 106.917647c-18.070588 0-30.117647 12.047059-30.117647 30.117647V552.658824c0 18.070588 12.047059 30.117647 30.117647 30.117647s30.117647-12.047059 30.117647-30.117647v-415.62353c0-18.070588-12.047059-30.117647-30.117647-30.117647zM653.552941 444.235294c-6.023529 0-12.047059 0-18.070588 6.02353l-132.517647 114.447058-126.494118-108.423529c-12.047059-12.047059-30.117647-12.047059-42.164706 0-12.047059 12.047059-12.047059 30.117647 0 42.164706l144.564706 126.494117c12.047059 12.047059 30.117647 12.047059 42.164706 0l150.588235-126.494117c12.047059-12.047059 12.047059-30.117647 6.02353-42.164706-6.023529-6.023529-12.047059-12.047059-24.094118-12.047059z" horiz-adv-x="1024" />
<glyph glyph-name="bianji5" unicode="&#59182;" d="M704.752941-97.882353H198.776471c-78.305882 0-138.541176 60.235294-138.541177 132.517647V667.105882c0 72.282353 66.258824 132.517647 138.541177 132.517647h319.247058c18.070588 0 30.117647-12.047059 30.117647-30.117647s-12.047059-24.094118-30.117647-24.094117H198.776471c-42.164706 0-78.305882-36.141176-78.305883-72.282353v-632.470588c0-42.164706 36.141176-72.282353 78.305883-72.282353h499.952941c42.164706 0 78.305882 36.141176 78.305882 72.282353V293.647059c0 18.070588 12.047059 30.117647 30.117647 30.117647s30.117647-12.047059 30.117647-30.117647v-259.011765c6.023529-72.282353-60.235294-132.517647-132.517647-132.517647zM313.223529 161.129412c-24.094118 0-54.211765 18.070588-60.235294 48.188235v30.117647l36.141177 126.494118 445.741176 445.741176c48.188235 48.188235 120.470588 48.188235 168.658824 0 48.188235-48.188235 48.188235-120.470588 0-168.658823l-445.741177-445.741177-126.494117-30.117647c-6.023529-6.023529-12.047059-6.023529-18.070589-6.023529z m36.141177 174.682353l-36.141177-114.447059 120.470589 30.117647 433.694117 433.694118c12.047059 12.047059 18.070588 24.094118 18.070589 42.164705 0 18.070588-6.023529 30.117647-18.070589 42.164706-24.094118 24.094118-60.235294 24.094118-84.329411 0L349.364706 335.811765z" horiz-adv-x="1024" />
<glyph glyph-name="shanchu3" unicode="&#59181;" d="M654.222222-99.555556H375.466667c-68.266667 0-125.155556 56.888889-136.533334 142.222223L142.222222 571.733333c0 17.066667 5.688889 28.444444 22.755556 34.133334 17.066667 0 28.444444-5.688889 34.133333-22.755556l91.022222-534.755555c11.377778-51.2 45.511111-91.022222 85.333334-91.022223h278.755555c39.822222 0 73.955556 39.822222 85.333334 91.022223l91.022222 534.755555c0 17.066667 17.066667 28.444444 34.133333 22.755556 17.066667 0 28.444444-17.066667 22.755556-34.133334L796.444444 42.666667c-17.066667-85.333333-73.955556-142.222222-142.222222-142.222223zM597.333333 708.266667v5.688889c0 51.2-39.822222 96.711111-85.333333 96.711111s-85.333333-45.511111-85.333333-102.4h-56.888889C369.777778 793.6 432.355556 867.555556 512 867.555556c73.955556 0 136.533333-68.266667 142.222222-147.911112v-5.688888l-56.888889-5.688889zM398.222222 36.977778c-11.377778 0-28.444444 11.377778-28.444444 22.755555L284.444444 577.422222c0 17.066667 11.377778 34.133333 22.755556 34.133334 17.066667 5.688889 34.133333-5.688889 34.133333-22.755556l85.333334-517.688889c0-17.066667-5.688889-34.133333-28.444445-34.133333 5.688889 0 0 0 0 0zM625.777778 36.977778s-5.688889 0 0 0c-22.755556 5.688889-28.444444 17.066667-28.444445 34.133333L682.666667 588.8c0 17.066667 17.066667 28.444444 34.133333 22.755556 11.377778 0 22.755556-17.066667 22.755556-34.133334l-85.333334-517.688889c0-11.377778-17.066667-22.755556-28.444444-22.755555zM512 36.977778c-17.066667 0-28.444444 11.377778-28.444444 28.444444V583.111111c0 17.066667 11.377778 28.444444 28.444444 28.444445s28.444444-11.377778 28.444444-28.444445v-517.688889c0-17.066667-11.377778-28.444444-28.444444-28.444444zM938.666667 645.688889H85.333333c-17.066667 0-28.444444 17.066667-28.444444 28.444444s11.377778 28.444444 28.444444 28.444445h853.333334c17.066667 0 28.444444-11.377778 28.444444-28.444445s-11.377778-28.444444-28.444444-28.444444z" horiz-adv-x="1024" />
<glyph glyph-name="xuanze" unicode="&#59180;" d="M870.4 896H153.6C66.56 896 0 829.44 0 742.4v-716.8c0-87.04 66.56-153.6 153.6-153.6h716.8c87.04 0 153.6 66.56 153.6 153.6V742.4c0 87.04-66.56 153.6-153.6 153.6z m-40.96-394.24l-337.92-358.4c-10.24-10.24-25.6-15.36-40.96-15.36-10.24 0-20.48 5.12-30.72 10.24L174.08 332.8c-20.48 15.36-25.6 51.2-10.24 71.68 15.36 20.48 51.2 25.6 71.68 10.24l209.92-163.84 307.2 327.68c20.48 20.48 51.2 20.48 71.68 0 20.48-20.48 25.6-56.32 5.12-76.8z" horiz-adv-x="1024" />
<glyph glyph-name="bianji4" unicode="&#59178;" d="M934.724189 617.173271L834.414864 516.863946 653.380212 697.898598l100.394659 100.351991A42.257063 42.257063 0 0 0 783.769535 810.666588c6.527999 0 19.157332-1.621333 29.951997-12.415999l121.002657-121.002656a42.538663 42.538663 0 0 0 0-60.074662zM299.374908-18.176009l-200.661316-19.626665 19.669331 200.661316L593.049551 637.52527 774.084202 456.533285l-474.709294-474.709294z m695.679942 755.79727L874.09486 858.581251A127.317323 127.317323 0 0 1 783.769535 895.999915c-32.725331 0-65.407995-12.458666-90.367993-37.418664l-646.229279-646.229279c-7.082666-7.082666-11.434666-16.469332-12.287999-26.495998l-26.197331-267.818645c-2.133333-25.002665 17.706665-46.037329 42.239996-46.037329 1.194667 0 2.432 0.042667 3.626666 0.128l267.818645 26.239998a42.12053 42.12053 0 0 1 26.495998 12.287999l646.186612 646.186613c49.919996 49.919996 49.919996 130.858656 0 180.778651z" horiz-adv-x="1032" />

Before

Width:  |  Height:  |  Size: 396 KiB

After

Width:  |  Height:  |  Size: 405 KiB

@ -538,7 +538,7 @@ class CoursesIndex extends Component {
}
></Route>
{/*视频列表*/}
<Route path="/courses/:coursesId/course_videos/:videoId"
<Route path="/courses/:coursesId/course_video/:videoId"
render={
(props) => (<ListPageIndex {...this.props} {...props} {...this.state} />)
}

@ -188,33 +188,99 @@ class ListPageIndex extends Component {
// console.log(this.props.location.search);
return (
<div>
<div className="newMain clearfix">
{/*头部banner*/}
<CoursesBanner ref={"CoursesBanner"} {...this.props} ispostexcellenttype={(excellent) => this.ispostexcellenttype(excellent)}></CoursesBanner>
{/*下面是指引哦*/}
{/*{yslGuideone!==undefined?*/}
{/*(*/}
{/* yslGuideone===true?*/}
{/* <Guide*/}
{/* setwindowlocal={(b)=>this.setwindowlocal(b)}*/}
{/* >*/}
{/* </Guide>*/}
{/* :""*/}
{/* )*/}
{/* :""*/}
{/*}*/}
<div className="educontent clearfix" style={{ flex: "1 0 auto" }}>
<div className="stud-class-set">
<div className="news">
<div className="edu-class-inner container clearfix">
<div className="member for-content-0 for-content">
<div className="people clearfix mb60">
{/*left_nav*/}
<div className={"with22 fl setleft"} style={{ width: '264px', minHeight: '500px' }}>
<Coursesleftnav {...this.props} {...this.state} comyslElearning={(i) => this.comyslElearning(i)} />
</div>
<div className="newMain clearfix">
{/*头部banner*/}
<CoursesBanner ref={"CoursesBanner"} {...this.props} ispostexcellenttype={(excellent)=>this.ispostexcellenttype(excellent)}></CoursesBanner>
{/*下面是指引哦*/}
{/*{yslGuideone!==undefined?*/}
{/*(*/}
{/* yslGuideone===true?*/}
{/* <Guide*/}
{/* setwindowlocal={(b)=>this.setwindowlocal(b)}*/}
{/* >*/}
{/* </Guide>*/}
{/* :""*/}
{/* )*/}
{/* :""*/}
{/*}*/}
<div className="educontent clearfix" style={{flex: "1 0 auto"}}>
<div className="stud-class-set">
<div className="news">
<div className="edu-class-inner container clearfix">
<div className="member for-content-0 for-content">
<div className="people clearfix mb60">
{/*left_nav*/}
<div className={"with22 fl setleft"} style={{width:'264px',minHeight:'500px'}}>
<Coursesleftnav {...this.props} {...this.state} comyslElearning={(i)=>this.comyslElearning(i)}/>
</div>
{/*right_concent*/}
<div className="with78 fl">
<div className={"ml20 clearfix"}>
<Switch {...this.props}>
{/* --------------------------------------------------------------------- */}
{/* 作业设置 */}
{/* http://localhost:3007/courses/1309/homework/9300/setting */}
{/* 普通作业 */}
<Route path="/courses/:coursesId/common_homeworks/:category_id"
render={
(props) => (<CommonWork {...this.props} {...props} {...this.state} />)
}
></Route>
{/* 作品列表 */}
<Route path="/courses/:coursesId/group_homeworks/:category_id"
render={
(props) => (<CommonWork {...this.props} {...props} {...this.state} />)
}
></Route>
<Route exact path="/courses/:coursesId/boards/:boardId"
render={
(props) => (<Boards {...this.props} {...props} {...this.state} />)
}
></Route>
{/*视频列表*/}
<Route path="/courses/:coursesId/course_video/:videoId"
render={
(props) => (<CourseVideo {...this.props} {...props} {...this.state} />)
}
></Route>
<Route path="/courses/:coursesId/course_videos"
render={
(props) => (<CourseVideo {...this.props} {...props} {...this.state} />)
}
></Route>
<Route path="/courses/:coursesId/teachers"
render={
(props) => (<TeacherList updatabanners={()=>this.updatabanners()} {...this.props} {...props} {...this.state} />)
}
></Route>
{/* 学生列表*/}
<Route path="/courses/:coursesId/students"
render={
(props) => (<StudentsList {...this.props} {...props} {...this.state} />)
}
></Route>
<Route path="/courses/:coursesId/course_groups/:course_group_id"
render={
(props) => (<StudentsList {...this.props} {...props} {...this.state} />)
}
></Route>
<Route path="/courses/:coursesId/course_groups"
render={
(props) => (<CourseGroupList {...this.props} {...props} {...this.state} />)
}
></Route>
<Route path="/courses/:coursesId/exercises/:Id"
render={
(props) => (<Exercise {...this.props} {...props} {...this.state} />)
}
></Route>
{/*right_concent*/}
<div className="with78 fl">

@ -0,0 +1,128 @@
import React,{ Component } from "react";
import { Radio , Modal } from 'antd';
import './video.css';
import axios from 'axios';
class MoveBox extends Component{
constructor(props){
super(props);
this.state={
data:undefined,
selectSubId:undefined
}
}
componentDidUpdate=(prevProps)=>{
if(this.props.id && this.props.visible && this.props.id !== prevProps.id){
this.getSubList(this.props.mainId);
}
}
getSubList=(id)=>{
const url = `/course_modules/${id}.json`;
axios.get(url).then(result=>{
if(result){
let list = result.data.course_module && result.data.course_module.course_second_categories;
let defaultId = list.length>0 ? list[0].id : undefined;
this.setState({
data:result.data.course_module,
selectSubId:defaultId
})
}
}).catch(error=>{
console.log(error);
})
}
cancelMove=()=>{
const { setMoveVisible } = this.props;
setMoveVisible && setMoveVisible(false);
}
// 选择子目录
selectSub=(e)=>{
this.setState({
selectSubId:e.target.value
})
}
handleSubmit=()=>{
const CourseId = this.props.match.params.coursesId;
const { id } = this.props;
const { selectSubId } = this.state;
const url = `/courses/${CourseId}/move_to_category.json`;
axios.post(url,{
video_ids:[id],
new_category_id:selectSubId
}).then(result=>{
if(result){
const { setMoveVisible , successFunc , updataleftNavfun} = this.props;
updataleftNavfun && updataleftNavfun();
setMoveVisible && setMoveVisible(false);
successFunc && successFunc();
}
}).catch(error=>{
console.log(error);
})
}
render(){
const { visible , id } = this.props;
const { data , selectSubId } = this.state;
let list = data && data.course_second_categories && data.course_second_categories.length>0?data.course_second_categories:undefined;
return(
<Modal
visible={visible}
width="560px"
title={'移动到'}
footer={null}
closable={false}
>
<div>
<style>
{
`
.ant-radio-group.ant-radio-group-outline{
display: flex;
flex-direction: column;
}
.ant-radio-wrapper{
margin-bottom:5px;
display:flex;
}
.ant-radio{
margin-top:2px;
}
.ant-radio-group.ant-radio-group-outline span:last-child{
max-height: 450px;
display: block;
flex: 1;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
`
}
</style>
<Radio.Group onChange={this.selectSub} value={selectSubId}>
{
list && list.map((item,key)=>{
return(
<Radio value={item.id} key={item.id}>
{item.name}
</Radio>
)
})
}
</Radio.Group>
<div className="clearfix mt30 edu-txt-center">
<a onClick={this.cancelMove} className="task-btn mr30">取消</a>
<a type="submit" onClick={this.handleSubmit} className="task-btn task-btn-orange">确定</a>
</div>
</div>
</Modal>
)
}
}
export default MoveBox;

@ -5,7 +5,8 @@ import { NoneData, ActionBtn } from 'educoder';
import VideoUploadList from '../../user/usersInfo/video/VideoUploadList';
import VideoInReviewItem from '../../user/usersInfo/video/VideoInReviewItem';
import HeadlessModal from '../../user/usersInfo/common/HeadlessModal';
import EditVideoModal from '../../user/usersInfo/video/EditVideoModal'
import EditVideoModal from '../../user/usersInfo/video/EditVideoModal';
import MoveBox from './MoveBox';
import ClipboardJS from 'clipboard'
import VideoPanel from './video-play'
@ -28,7 +29,10 @@ class Video extends Component {
videoId: undefined,
videoVisible: false,
visible: false
visible: false,
moveVisible:false,
moveVideoId:undefined
}
}
@ -69,7 +73,7 @@ class Video extends Component {
// 编辑成功后回调的方法
editSuccess = () => {
this.props.showNotification("视频名称修改成功!");
this.props.showNotification("视频信息修改成功!");
const { listFunc, page } = this.props;
listFunc && listFunc(page);
}
@ -77,7 +81,8 @@ class Video extends Component {
onEditVideo = (item) => {
let videoId = {
videoId: item.id,
title: item.title
title: item.title,
link:item.link
}
this.setState({
videoId,
@ -142,7 +147,8 @@ class Video extends Component {
const url = `/courses/${CourseId}/delete_course_video.json`;
axios.delete(url, {
params: {
video_id: item.id
video_id: item.id,
is_link:item.link ? true : undefined
}
}).then(result => {
if (result) {
@ -161,8 +167,22 @@ class Video extends Component {
});
}
// 移动到
moveVideo=(id)=>{
this.setState({
moveVisible:true,
moveVideoId:id
})
}
setMoveVisible=(flag)=>{
this.setState({
moveVisible:flag,
moveVideoId:undefined
})
}
render() {
const { visible, videoVisible, videoId } = this.state;
const { visible, videoVisible, videoId , moveVisible , moveVideoId } = this.state;
const CourseId = this.props.match.params.coursesId;
const login = this.props.user && this.props.user.login;
const _inputValue = videoId && this.getCopyText(videoId.file_url, videoId.cover_url);
@ -178,6 +198,14 @@ class Video extends Component {
editSuccess={this.editSuccess}
{...videoId} CourseUser={login}
></EditVideoModal>
<MoveBox
{...this.props}
visible={moveVisible}
mainId={videoData && videoData.course_module_id}
setMoveVisible={(flag)=>this.setMoveVisible(flag)}
successFunc={()=>uploadVideo()}
id={moveVideoId}
></MoveBox>
<HeadlessModal
visible={videoVisible}
setVisible={this.setVideoVisible}
@ -217,6 +245,7 @@ class Video extends Component {
getCopyText={this.getCopyText}
operation={operation}
deleteVideo={(admin || item.user_id === user_id) ? this.deleteVideo : undefined}
moveVideo={videoData && videoData.has_category && operation ?()=>this.moveVideo(item.id):undefined}
>
</VideoInReviewItem>
)

@ -1,13 +1,13 @@
import React,{ Component } from "react";
import { WordsBtn,on, trigger ,publicSearchs} from 'educoder';
import { Menu, Spin } from 'antd';
import { WordsBtn } from 'educoder';
import axios from 'axios';
import Videos from './Video';
import Lives from './Live';
import LivesNew from './LiveNew';
import VideoLink from './VideoLink';
import './video.css';
import '../css/Courses.css';
@ -28,6 +28,7 @@ class VideoIndex extends Component{
upload:false,
videos:undefined,
videoData:undefined,
otherLinkVisible:false,
type:"video",
isSpining:false,
@ -37,6 +38,7 @@ class VideoIndex extends Component{
liveId:undefined,
liveVisible:false
}
}
@ -69,6 +71,12 @@ class VideoIndex extends Component{
this.checkType("video",page);
}
}
componentDidUpdate = (prevProps) => {
if(this.props.match.params.videoId !== prevProps.match.params.videoId ){
const { page } = this.state;
this.checkType("video",page);
}
}
// 获取直播列表
getLiveList=(page)=>{
const CourseId=this.props.match.params.coursesId;
@ -142,6 +150,7 @@ class VideoIndex extends Component{
this.setVisible(true);
}
uploadVideo=(upload)=>{
this.setState({
upload,
isSpining:true
@ -202,20 +211,45 @@ class VideoIndex extends Component{
this.setliveVisibel(true);
}
// 新增目录
addDir=()=>{
let {videoData}=this.state;
trigger('videoAdd', parseInt(videoData.course_module_id));
}
editDir=()=>{
// 目录重命名
editDir=(name,id)=>{
let data={id,name,update:this.getList}
trigger('editVideo',data);
}
// 增加外链
setLinkeVisible=(flag,refresh)=>{
this.setState({
otherLinkVisible:flag
})
if(refresh){
const { page } = this.state;
this.getList(page);
}
}
render(){
const { videos , upload , videoData , type , liveData , lives , page , liveVisible , isSpining , liveId } = this.state;
const { videos , upload , videoData , type , liveData , lives , page , liveVisible , isSpining , liveId , otherLinkVisible } = this.state;
const { admin , is_teacher , business } = this.props.user;
const { coursesId , videoId }=this.props.match.params;
const {course_identity} = this.props.coursedata;
const flag = parseInt(course_identity) < 4;
console.log(flag);
const newOperation = flag;
const new_upload = flag || admin || is_teacher;
// console.log("p",this.props);
return(
<React.Fragment>
<VideoLink
coursesId={coursesId}
visible={otherLinkVisible}
notification={this.props.showNotification}
setVisible={this.setLinkeVisible}
></VideoLink>
<LivesNew
visible={liveVisible}
liveId={liveId}
@ -245,41 +279,51 @@ class VideoIndex extends Component{
<div className="edu-back-white" style={{marginBottom:"1px"}}>
<div className="clearfix pl30 pr30 menuDiv">
<div className="task_menu_ul fl">
<Menu mode="horizontal" selectedKeys={[type]} onClick={this.changeType}>
<Menu.Item key="video">视频</Menu.Item>
<Menu.Item key="live">直播</Menu.Item>
</Menu>
</div>
{
(admin || is_teacher || business) &&
<li className="fr mt18">
{
type === "video" ?
<React.Fragment>
videoData && videoData.category_name && type === "video" ?
<span className="font-18 fl color-dark-21 mt20 mb20">{videoData.category_name}</span>
:
<div className="task_menu_ul fl mt2">
<Menu mode="horizontal" selectedKeys={[type]} onClick={this.changeType}>
<Menu.Item key="video">视频</Menu.Item>
<Menu.Item key="live">直播</Menu.Item>
</Menu>
</div>
}
<li className="fr mt20 mb20">
{
type === "video" ?
<React.Fragment>
{
newOperation ?
<span>
{
this.props.isAdmin() &&
<span>
videoId ?
<WordsBtn style="blue" onClick={()=>this.editDir(videoData && videoData.category_name,videoId)} className={"mr30 font-16"}>目录重命名</WordsBtn>
:
<React.Fragment>
<WordsBtn style="blue" className="mr30 font-16" onClick={this.addDir}>新建目录</WordsBtn>
<WordsBtn style="blue" className="mr30 font-16" onClick={()=>this.setLinkeVisible(true)}>增加外链</WordsBtn>:""
</React.Fragment>
}
</span>:""
}
{
new_upload ?
<span>
{
videoId ?
<WordsBtn style="blue" onClick={()=>this.editDir()} className={"mr30 font-16"}>目录重命名</WordsBtn>
upload ?
<WordsBtn style="grey" className="font-16" onClick={()=>this.uploadVideo(false)}>取消</WordsBtn>
:
<WordsBtn style="blue" className="mr30 font-16" onClick={this.addDir()} onClick={this.toUpload}>新建目录</WordsBtn>
<WordsBtn style="blue" className="font-16" onClick={this.toUpload}>上传视频</WordsBtn>
}
</span>
}
{
upload ?
<WordsBtn style="grey" className="font-16" onClick={()=>this.uploadVideo(false)}>取消</WordsBtn>
:
<WordsBtn style="blue" className="font-16" onClick={this.toUpload}>上传视频</WordsBtn>
}
</React.Fragment>
:
<WordsBtn style="blue" className="font-16 ml30" onClick={this.liveSetting}>添加直播</WordsBtn>
}
</li>
}
</span>:""
}
</React.Fragment>
:
<WordsBtn style="blue" className="font-16 ml30" onClick={()=>this.setLinkeVisible(true)}>添加直播</WordsBtn>
}
</li>
</div>
</div>
<Spin spinning={isSpining}>

@ -0,0 +1,86 @@
import React,{ Component } from "react";
import { Modal , Form , Input , Spin , Select , AutoComplete , DatePicker , InputNumber } from 'antd';
import axios from 'axios';
class VideoLink extends Component{
cancelNew=()=>{
const { setVisible } = this.props;
setVisible && setVisible(false);
}
validateDesc= (rule, value, callback) => {
if(!value){
callback();
}
if (value.length > 60) {
callback("视频名称不能超过60个字");
}else{
callback();
}
}
// 提交
handleSubmit=()=>{
this.props.form.validateFields((err, values) => {
if(!err){
const { coursesId } = this.props;
const url = `/courses/${coursesId}/course_videos.json`;
axios.post(url,{
...values
}).then(result=>{
if(result){
const { notification , setVisible } = this.props;
notification && notification('视频外链新增成功!');
setVisible && setVisible(false,true);
}
}).catch(error=>{
console.log(error);
})
}
})
}
render(){
const {getFieldDecorator} = this.props.form;
const { visible } = this.props;
const layout = {
labelCol: { span: 5 },
wrapperCol: { span: 19 },
}
return(
<Modal
visible={visible}
width="560px"
title={'添加外链'}
footer={null}
closable={false}
>
<div className="task-popup-content">
<Form onSubmit={this.handleSubmit} {...layout}>
<Form.Item label={`视频名称:`}>
{getFieldDecorator('name', {
rules: [{required: true, message: "请输入名称"},{
validator: this.validateDesc,
}],
})(
<Input placeholder="请输入名称最大限制60个字符" />
)}
</Form.Item>
<Form.Item label={`链接地址:`}>
{getFieldDecorator('link', {
rules: [{required: true, message: "请输入链接地址"}],
})(
<Input placeholder="请输入链接地址" />
)}
</Form.Item>
<div className="clearfix mt30 edu-txt-center">
<a onClick={this.cancelNew} className="task-btn mr30">取消</a>
<a type="submit" onClick={this.handleSubmit} className="task-btn task-btn-orange">确定</a>
</div>
</Form>
</div>
</Modal>
)
}
}
const WrappedVideoLink = Form.create({name: 'VideoLink'})(VideoLink);
export default WrappedVideoLink;

@ -61,6 +61,8 @@ class Coursesleftnav extends Component{
sandiantypes:undefined,
antIcon:false,
chapterupdate:false,
successFunc:undefined
}
}
@ -138,61 +140,68 @@ class Coursesleftnav extends Component{
off('shixun_homeworkadd',this.addshixunchild)
off('editshixunname',this.editshixunchild)
off('editshixunmainname',this.editshixunmainname)
off('videoAdd',this.addVideo)
off('editVideo',this.editVideo)
}
addshixunchild=(e, data)=>{
this.Navmodalnames(e,1,"shixun_homework",data)
this.Navmodalnames(e,1,"shixun_homework",data);
}
editshixunchild=(e, data)=>{
this.Navmodalnames(e,4,"editSecondname",data.id,data.name)
this.Navmodalnames(e,4,"editSecondname",data.id,data.name);
}
editshixunmainname=(e, data)=>{
this.Navmodalnames(e,3,"editname",data.id,data.name)
this.Navmodalnames(e,3,"editname",data.id,data.name);
}
boardAddListener = (e, data) => {
this.Navmodalnames(e,6,"board", data)
this.Navmodalnames(e,6,"board", data);
}
addVideo=(e,id)=>{
this.Navmodalnames(e,1,"video",id);
}
editVideo=(e,data)=>{
this.setState({
successFunc:data.update
})
this.Navmodalnames(e,4,"editSecondname",data.id,data.name);
}
boardRenameListener = (e, data) => {
this.Navmodalnames(e,7,"editSecondname", data.category_id, data.category_name)
this.Navmodalnames(e,7,"editSecondname", data.category_id, data.category_name);
}
groupAddListener = (e, data) => {
this.Navmodalnames(e,2,"course_group", data)
this.Navmodalnames(e,2,"course_group", data);
}
groupRenameListener = (e, data) => {
this.Navmodalnames(e,5,"editSecondname", data.id, data.name)
this.Navmodalnames(e,5,"editSecondname", data.id, data.name);
}
attachmentAddlog=(e,data)=>{
this.Navmodalnames(e,1,"attachment",data)
this.Navmodalnames(e,1,"attachment",data);
}
flieseditDir=(e, data)=>{
this.Navmodalnames(e,4,"editSecondname",data.id,data.name)
this.Navmodalnames(e,4,"editSecondname",data.id,data.name);
}
componentDidMount() {
this.setState({
url:this.props.match.url
})
on('boardAdd', this.boardAddListener)
on('boardRename', this.boardRenameListener)
on('groupAdd', this.groupAddListener)
on('groupRename', this.groupRenameListener)
on('attachmentAddlog', this.attachmentAddlog)
on('flieseditDir', this.flieseditDir)
on('shixun_homeworkadd',this.addshixunchild)
on('editshixunname',this.editshixunchild)
on('editshixunmainname',this.editshixunmainname)
on('boardAdd', this.boardAddListener);
on('boardRename', this.boardRenameListener);
on('groupAdd', this.groupAddListener);
on('groupRename', this.groupRenameListener);
on('attachmentAddlog', this.attachmentAddlog);
on('flieseditDir', this.flieseditDir);
on('shixun_homeworkadd',this.addshixunchild);
on('editshixunname',this.editshixunchild);
on('editshixunmainname',this.editshixunmainname);
on('videoAdd',this.addVideo);
on('editVideo',this.editVideo)
// this.props.updataleftNavfun();
// this.props.getleftNavid && this.props.getleftNavid("shixun_homework");
// const position =parseInt(this.props.match.params.position);
let courstype=this.props.match.url;
courstype = courstype.split('/');
courstype = courstype.split('/');
courstype=courstype[3];
// console.log(courstype)
courstype=courstype[3];
const query =this.props.location.search;
@ -520,7 +529,9 @@ class Coursesleftnav extends Component{
// loadtype:true,
// NavmodalValue:""
// })
navidtype=true
navidtype=true;
const { successFunc } = this.state;
successFunc && successFunc(1);
}
saveNavmodapost=(url,value,positiontype,coursesId)=>{

@ -8,10 +8,12 @@ function EditVideoModal (props) {
const modalEl = useRef(null);
const theme = useContext(ThemeContext);
const { history, videoId, cover_url, title, created_at, isReview, onEditVideo, visible, setVisible,
form, editSuccess } = props;
form, editSuccess , link } = props;
const getFieldDecorator = form.getFieldDecorator
let username = props.match.params.username
const _title = form.getFieldsValue().title;
const _link = form.getFieldsValue().link;
if(props.CourseUser){
username = props.CourseUser;
@ -27,9 +29,14 @@ function EditVideoModal (props) {
form.validateFieldsAndScroll((err, values) => {
if (!err) {
const url = `/users/${username}/videos/${videoId}.json`
axios.put(url, {
title: _title
const url = link?`/course_videos/${videoId}.json`:`/users/${username}/videos/${videoId}.json`;
axios.put(url, link ? {
name:_title,
link:_link
}:{
title: _title,
link:_link
}).then((response) => {
if (response.data) {
onCancel()
@ -54,7 +61,7 @@ function EditVideoModal (props) {
}, [visible])
useEffect(() => {
visible && form.setFieldsValue({
title,
title,link
})
}, [visible])
return (
@ -71,10 +78,9 @@ function EditVideoModal (props) {
{
`
.exercicenewinputysl .ant-input{
border-right: none !important;
height: 40px !important;
}
border-right: none !important;
height: 40px !important;
}
`
}
</style>
@ -93,7 +99,24 @@ function EditVideoModal (props) {
<Input placeholder="" className="titleInput exercicenewinputysl" maxLength={MAX_LENGTH}
addonAfter={String(_title ? `${String(_title.length)}/${MAX_LENGTH}` : 0)} />
)}
</Form.Item>
</Form.Item>
{
link ?
<Form.Item
label="视频链接"
className="title formItemInline"
>
{getFieldDecorator('link', {
rules: [{
required: true, message: '请输入视频链接',
}],
})(
<Input placeholder="请输入视频链接" className="titleInput exercicenewinputysl" />
)}
</Form.Item>
:""
}
</ModalWrapper>
)
}

@ -142,4 +142,26 @@
.videoItem:hover{
box-shadow:0px 4px 10px 0px rgba(3,7,45,0.1);
border-radius:12px;
}
.otherLink{
position: absolute;
height:30px;
line-height: 30px;
padding:0px 18px;
background:rgba(249,117,26,1);
border-radius:0px 100px 100px 0px;
display: block;
left: 0;
top:32px;
color: #fff;
z-index:2;
}
.otherLinkPanel{
display: block;
position: absolute;
width: 100%;
top:0px;
left:0px;
height: 220px;
z-index: 1;
}

@ -5,7 +5,8 @@ import axios from 'axios'
import moment from 'moment'
import playIcon from './images/play.png'
import ClipboardJS from 'clipboard'
import defaultImg from './images/default.png';
import './InfosVideo.css';
/**
cover_url: "http://video.educoder.net/f6ba49c3944b43ee98736898e31b7d88/snapshots/12da3f7df07c499b8f0fc6dc410094e9-00005.jpg"
created_at: "2019-08-12 13:48:26"
@ -20,7 +21,7 @@ const clipboardMap = {}
function VideoInReviewItem (props) {
const theme = useContext(ThemeContext);
const { history, file_url, cover_url, title, created_at, published_at, isReview, id
, onEditVideo, onMaskClick, getCopyText, showNotification,vv,play_duration,operation , deleteVideo} = props;
, onEditVideo, onMaskClick, getCopyText, showNotification,vv,play_duration,operation , deleteVideo , moveVideo ,link} = props;
useEffect(()=> {
if (!isReview) {
_clipboard = new ClipboardJS(`.copybtn_item_${id}`);
@ -46,12 +47,16 @@ function VideoInReviewItem (props) {
return (
<div className={`${isReview ? 'videoInReviewItem' : 'nItem'} videoItem`}>
<img className="cover" src={cover_url || "http://video.educoder.net/e7d18970482a46d2a6f0e951b504256c/snapshots/491e113950d74f1dab276097dae287dd-00005.jpg"}
></img>
{!isReview && <div className="mask" onClick={() => onMaskClick(props)}>
<img className="cover" src={cover_url || defaultImg} alt=""></img>
{ link ?
<a href={link} target='_blank' className="otherLinkPanel">
<span className="otherLink">外链</span>
</a>
: ""
}
</div>}
{!isReview &&
{!isReview && <div className="mask" onClick={() => onMaskClick(props)}></div>}
{!isReview && !link &&
<div className="playWrap" onClick={() => onMaskClick(props)}>
<img className="play mp23" src={playIcon}></img>
{play_duration===0?"":<div className={"play_duration"}>累计学习时长{play_duration} h</div>}
@ -68,11 +73,19 @@ function VideoInReviewItem (props) {
<div className="df buttonRow">
{/* 2019-09-01 10:00:22 */}
<span className={"dianjilianicon"}>
{vv===0?"":<Tooltip title="播放次数" placement="bottom">
{!vv || (vv && vv)===0 ? "" : <Tooltip title="播放次数" placement="bottom">
<i className={`icon-dianjiliang iconfont dianjilianicon`}></i>
</Tooltip> } {vv===0?"":vv}
</Tooltip> } {!vv || (vv && vv)===0?"":vv}
</span>
{ isReview != true && <div>
{
moveVideo &&
<Tooltip title="移动到" placement="bottom">
<i className="icon-yidong iconfont font-15" onClick={() => moveVideo(props)}
style={{ marginTop: '1px', display: 'inline-block'}}
></i>
</Tooltip>
}
{
deleteVideo &&
<Tooltip title="删除" placement="bottom">

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Loading…
Cancel
Save