Commit 9df2307f by zhangleyuan

feat:创建课程条助教选项改为多选

parent 6bb59f47
import React from 'react';
import PropTypes from 'prop-types';
import { Modal, Button } from 'antd';
import UploadOss from '@/core/upload';
import Service from '@/common/js/service';
import User from '@/common/js/user';
let cutFlag = false;
class ImgCutModalNew extends React.Component {
......@@ -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);
window.axios.Apollo("public/apollo/commonOssAuthority", params).then((res) => {
Service.Hades('public/hades/commonOssAuthority', param).then((res) => {
const { resourceId, accessId, policy, callback, signature,key, host } = res.result;
const localUrl = URL.createObjectURL(cutImage);
// 构建上传的表单
......
......@@ -20,7 +20,7 @@ import PreviewCourseModal from './modal/PreviewCourseModal';
import CourseService from "@/domains/course-domain/CourseService";
import moment from 'moment';
import User from '@/common/js/user';
import _ from "underscore";
import './AddLive.less';
const defaultCover = 'https://image.xiaomaiketang.com/xm/YNfi45JwFA.png';
......@@ -28,15 +28,15 @@ const defaultBasicInfo = {
courseName: null, // 课程名称
coverId: null,
coverUrl: defaultCover,
parentCatalogId:'',
parentCatalogName:'',
sonCatalogId:'',
sonCatalogName:''
parentCatalogId:null,
sonCatalogId:null,
categoryId:null,
categoryName:null
};
const defaultClassInfo = {
teacherId: null, //讲师的Id
adminId:null, //助教的Id
assistant:[], //助教
teacherName: null,
liveDate: null,
timeHorizonStart: null,
......@@ -73,15 +73,17 @@ class AddLive extends React.Component {
courseName: null, // 课程名称
coverId: null,
coverUrl: defaultCover,
parentCatalogId:'',
sonCatalogId:''
parentCatalogId:null,
sonCatalogId:null,
categoryId:null,
categoryName:null
},
// 直播课上课信息
addLiveClassInfo: {
teacherId: null,
teacherName: null,
adminId:null,
assistant:[],
liveDate: null,
timeHorizonStart: null,
timeHorizonEnd: null,
......@@ -129,8 +131,11 @@ class AddLive extends React.Component {
needRecord,
whetherVisitorsJoin,
warmMedia,
categoryId,
categoryName,
admins
} = res.result;
courseMediaVOS.map((item) => {
item.key = window.random_string(16);
return item;
......@@ -140,12 +145,17 @@ class AddLive extends React.Component {
courseName,
coverId,
coverUrl: coverUrl || defaultCover,
categoryId,
categoryName
};
const liveDate = startTime;
const timeHorizonStart = startTime;
const timeHorizonEnd = endTime;
const assistant = _.pluck(admins, "adminId");
console.log('assistant',assistant);
const addLiveClassInfo = {
assistant,
liveDate,
nickname,
teacherId,
......@@ -154,6 +164,7 @@ class AddLive extends React.Component {
startTime,
endTime,
}
const liveCourseMediaRequests = courseMediaVOS.length
? [...courseMediaVOS]
: [{ contentType:"INTRO",mediaType: 'TEXT', mediaContent: '', key: window.random_string(16) }, ...courseMediaVOS];
......@@ -164,6 +175,7 @@ class AddLive extends React.Component {
whetherVisitorsJoin,
liveCourseMediaRequests,
}
// 晚于开课前30分钟
if(new Date().getTime() > startTime - 1800000) {
isEdit = false
......@@ -247,11 +259,11 @@ class AddLive extends React.Component {
this.handleValidate(addLiveBasicInfo, addLiveClassInfo, addLiveIntroInfo, isEdit).then((res) => {
if (!res) return;
const { type } = this.state;
const { courseName, coverId, coverUrl,parentCatalogId} = addLiveBasicInfo;
const { courseName, coverId, coverUrl,parentCatalogId,sonCatalogId,categoryId} = addLiveBasicInfo;
const {
liveDate,
teacherId,
adminId,
assistant,
timeHorizonEnd,
timeHorizonStart,
calendarTime,
......@@ -259,6 +271,7 @@ class AddLive extends React.Component {
let { startTime, endTime } = addLiveClassInfo;
const { liveCourseMediaRequests, needRecord,whetherVisitorsJoin,liveCourseWarmMedia} = addLiveIntroInfo;
if(type === 'add') {
startTime = startTime;
endTime = endTime;
......@@ -270,9 +283,9 @@ class AddLive extends React.Component {
endTime = moment(_liveDate + ' ' + _timeHorizonEnd).format('x');
}
const commonParams = {
adminIds:[adminId],
adminIds:assistant,
calendarTime,
categoryId:parentCatalogId,
categoryId,
endTime,
needRecord,
startTime,
......@@ -280,13 +293,13 @@ class AddLive extends React.Component {
storeId:User.getStoreId(),
teacherId:teacherId,
whetherVisitorsJoin,
scheduleMediaRequests:[...liveCourseMediaRequests]
// scheduleMediaRequests:[...liveCourseMediaRequests]
}
if (type === 'add') {
const params = {
...commonParams,
operatorId:User.getUserId(),
}
CourseService.createLiveCloudCourse(params).then((res) => {
......@@ -317,23 +330,25 @@ class AddLive extends React.Component {
handleValidate = (addLiveBasicInfo, addLiveClassInfo, addLiveIntroInfo, isEdit) => {
return new Promise((resolve) => {
const { type } = this.state;
const { courseName,parentCatalogId} = addLiveBasicInfo;
const { courseName,parentCatalogId,categoryId} = addLiveBasicInfo;
const {
liveDate, timeHorizonStart, timeHorizonEnd, teacherId, calendarTime
} = addLiveClassInfo;
const { liveCourseMediaRequests } = addLiveIntroInfo;
const currentTime = +new Date();
if(!courseName) {
message.warning('请输入课程名称');
resolve(false);
return;
}
if(!parentCatalogId){
if(!categoryId){
message.warning('请选择课程分类');
resolve(false);
return;
}
if(type === 'add') {
const { startTime, endTime } = addLiveClassInfo;
if(calendarTime.length && calendarTime.length === 0) {
......@@ -494,6 +509,7 @@ class AddLive extends React.Component {
<div className="title">基本信息</div>
<AddLiveBasic
isEdit={isEdit}
pageType={type}
data={addLiveBasicInfo}
onChange={this.handleChangeBasicInfo}
/>
......
/*
* @Author: 吴文洁
* @Date: 2020-07-15 17:29:12
* @Last Modified by: 吴文洁
* @Last Modified time: 2020-07-15 18:16:05
* @Description: 新建/编辑直播课-基本信息
*/
import React from 'react';
import { Input, Button, message ,Cascader } from 'antd';
import UploadOss from "@/core/upload";
import { ImgCutModalNew } from '@/components';
import StoreService from "@/domains/store-domain/storeService";
import './AddLiveBasic.less';
const defaultCover = 'https://image.xiaomaiketang.com/xm/YNfi45JwFA.png';
const fieldNames = { label: 'categoryName', value: 'id', children: 'sonCategoryList' };
class AddLiveBasic extends React.Component {
constructor(props) {
super(props);
this.state = {
imageFile: null,
showCutModal: false,
courseCatalogList:[]
}
}
componentWillUnmount() {
}
componentDidMount(){
this.getCourseCatalogList();
}
getCourseCatalogList = ()=>{
StoreService.getCourseCatalogList({current:1,size:1000}).then((res) => {
this.setState({
courseCatalogList:res.result.records
})
});
}
// 上传封面图
handleShowImgCutModal = (event) => {
const imageFile = event.target.files[0];
if (!imageFile) return;
this.setState({
imageFile,
showCutModal: true,
});
}
// 使用默认封面图
handleResetCoverUrl = () => {
const { data: { coverUrl } } = this.props;
const isDefaultCover = coverUrl === defaultCover;
// 如果已经是默认图的话,不做任何任何处理
if (isDefaultCover) return;
message.success('已替换为默认图');
this.props.onChange('coverId', null, defaultCover);
}
catalogChange= (value) => {
const changeValueLength = value.length;
switch (changeValueLength){
case 1:
this.props.onChange('parentCatalogId',value[0]);
break;
case 2:
this.props.onChange('parentCatalogId',value[0]);
setTimeout(()=>{
this.props.onChange('sonCatalogId',value[1]);
},1000)
break;
default:
break;
}
}
render() {
const { showCutModal, imageFile,courseCatalogList} = this.state;
const { data} = this.props;
const { courseName, coverUrl} = data;
const fileName = '';
// 当前是否使用的是默认图片
const isDefaultCover = coverUrl === defaultCover;
return (
<div className="add-live__basic-info">
<div className="course-name">
<span className="label"><span className="require">*</span>课程名称:</span>
<Input
value={courseName}
placeholder="请输入直播名称(40字以内)"
maxLength={40}
style={{ width: 240 }}
onChange={(e) => { this.props.onChange('courseName', e.target.value)}}
/>
</div>
<div className="course-cover">
<span className="label">封面图:</span>
<div className="course-cover__wrap">
<div className="img-content">
{
isDefaultCover && <span className="tag">默认图</span>
}
<img src={coverUrl} />
</div>
<div className="opt-btns">
<input
type="file"
value={fileName} // 避免选择同一文件 value不改变 不触发onChange事件
accept="image/png, image/jpeg, image/bmp, image/jpg"
ref="stagePicInputFile"
style={{display: 'none'}}
onChange={(event) => { this.handleShowImgCutModal(event) }}
/>
<Button onClick={() => {
this.setState({
currentInputFile: this.refs.stagePicInputFile
});
this.refs.stagePicInputFile.click();
}}>上传图片</Button>
<span
className={`default-btn ${isDefaultCover ? 'disabled' : ''}`}
onClick={this.handleResetCoverUrl}
>使用默认图</span>
<div className="tips">建议尺寸690*398像素,图片支持jpg、jpeg、png格式。</div>
</div>
</div>
</div>
<div className="course-catalog">
<span className="label"><span className="require">*</span>课程分类:</span>
<Cascader options={courseCatalogList} displayRender={ label => label.join('-')} fieldNames={fieldNames} onChange={this.catalogChange} style={{ width: 240 }} placeholder="请选择课程分类" />
</div>
<ImgCutModalNew
title="裁剪"
width={550}
cutWidth={500}
cutHeight={282}
cutContentWidth={500}
cutContentHeight={300}
visible={showCutModal}
imageFile={imageFile}
bizCode='LIVE_COURSE_MEDIA'
onOk={(urlStr, resourceId) => {
this.setState({ showCutModal: false });
this.props.onChange('coverId', resourceId, urlStr);
this.state.currentInputFile.value = '';
}}
onClose={() => this.setState({ showCutModal: false })}
reUpload={() => { this.state.currentInputFile.click() }}
/>
</div>
)
}
}
export default AddLiveBasic;
\ No newline at end of file
/*
* @Author: 吴文洁
* @Date: 2020-07-15 17:44:24
* @Last Modified by: mikey.zhaopeng
* @Last Modified time: 2020-11-23 22:06:33
* @Description: 添加直播课-上课信息
*/
import React from 'react';
import {TimePicker, Select, Spin, Tooltip,DatePicker} from 'antd';
import {InfoCircleFilled} from '@ant-design/icons';
import StoreService from "@/domains/store-domain/storeService";
// import TeacherSelectV5 from "@/modules/classManage_V5/classDetail/TeacherSelectV5";
import ChargeExplainModal from '../modal/ChargeExplainModal';
import SelectStudent from '../modal/select-student/index';
import MultipleDatePicker from '@/components/MultipleDatePicker';
import moment from 'moment';
import './AddLiveClass.less';
const defaultTeacherQuery = {
size: 10,
current: 1,
nickName:null
}
const defaultAssistantQuery = {
size: 10,
current: 1,
nickName:null
}
class AddLiveClass extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: false,
hasNext: false,
assistantHasNext:false,
teacherQuery: defaultTeacherQuery,
teacherList:[],
assistantQuery:defaultAssistantQuery,
assistantList: [], // 助教老师列表
addLiveType: props.addLiveType
}
}
componentDidMount() {
this.getTeacherList();
this.getAssistantList();
}
getTeacherList(current = 1, selectList){
const { teacherQuery,teacherList} = this.state;
const _query = {
...teacherQuery,
current,
size:10
};
StoreService.getEmployeeList( _query).then((res) => {
const { result = {} } = res;
const { records = [], total = 0, hasNext } = result;
const list = current > 1 ? teacherList.concat(records) : records;
this.setState({
hasNext,
teacherList: list,
})
});
}
// 获取助教老师列表
getAssistantList = (current = 1, selectList) => {
const { assistantQuery,assistantList} = this.state;
const _query = {
...assistantQuery,
current,
size:10
};
StoreService.getEmployeeList( _query).then((res) => {
const { result = {} } = res;
const { records = [], total = 0, hasNext} = result;
const list = current > 1 ? assistantList.concat(records) : records;
this.setState({
assistantHasNext:hasNext,
assistantList: list,
})
});
}
// 滑动加载更多讲师列表
handleScrollTeacherList = (e) => {
const { hasNext } = this.state;
const container = e.target;
const scrollToBottom = container && container.scrollHeight <= container.clientHeight + container.scrollTop;
if (scrollToBottom && hasNext) {
const { teacherQuery } = this.state;
this.getTeacherList(teacherQuery.current + 1);
}
}
// 滑动加载更多助教列表
handleScrollAssistantList = (e) => {
const { assistantHasNext } = this.state;
const container = e.target;
const scrollToBottom = container && container.scrollHeight <= container.clientHeight + container.scrollTop;
if (scrollToBottom && assistantHasNext) {
const { assistantQuery } = this.state;
this.getAssistantList(assistantQuery.current + 1);
}
}
disabledDate = (current) => {
return current.valueOf() < moment().subtract(1, "days")
};
selectMultiDate = (calendarTime) => {
this.setState({
calendarTime
})
}
render() {
const {
loading,
teacherList,
assistantList,
teacherQuery,
assistantQuery
} = this.state;
const { pageType,data,isEdit} = this.props;
const {
endTime,
startTime,
calendarTime,
teacherId,
liveDate,
timeHorizonStart,
timeHorizonEnd
} = data;
console.log("teacherId",teacherId);
return (
<Spin spinning={loading}>
<div className="add-live__class-info">
{/* <div className="course">
<div className="day">
<span className="label">
<span className="require">*</span>
上课日期
<Tooltip
overlayStyle={{maxWidth: 300, zIndex: '9999'}}
title={<div style={{width: '266px'}}>支持按上课日期批量创建直播课,创建后按“课程名称_日期”命名,例如:<br/>张三的语文课_9月18日<br/>张三的语文课_9月19日......</div>}>
<InfoCircleFilled className="tip-icon"/>
</Tooltip>:
</span>
<div>
<div className='select-day'>
已选
<span className="mark-day">
{isLongArr(calendarTime)
? calendarTime.length : 0
}
</span> 天
</div>
<MultipleDatePicker
selectDateList={calendarTime}
onSelect={this.selectMultiDate}
canSelectTodayBefore={false}
/>
</div>
</div>
<div className="hour" id="hour">
<span className="label"><span className="require">*</span>上课时间:</span>
<TimePicker
format="HH:mm"
value={startTime ? moment(startTime) : null}
placeholder="开始时间"
style={{ width: 100, minWidth: 100}}
onChange={(time) => {
this.props.onChange('startTime', time);
}}
/>&nbsp;&nbsp;~&nbsp;&nbsp;
<TimePicker
format="HH:mm"
value={endTime ? moment(endTime) : null}
placeholder="结束时间"
style={{ width: 100, minWidth: 100 }}
onChange={(time) => {
this.props.onChange('endTime', time)
}}
/>
</div>
</div> */}
{pageType === 'add' &&
<div className="course">
<div className="day">
<span className="label">
<span className="require">*</span>
上课日期
<Tooltip
overlayStyle={{maxWidth: 300, zIndex: '9999'}}
title={<div style={{width: '266px'}}>支持按上课日期批量创建直播课,创建后按“课程名称_日期”命名,例如:<br/>张三的语文课_9月18日<br/>张三的语文课_9月19日......</div>}>
<span className="iconfont">&#xe6f2;</span>
</Tooltip>
</span>
<div>
<div className='select-day'>
已选
<span className="mark-day">
{isLongArr(calendarTime)
? calendarTime.length : 0
}
</span>
</div>
<MultipleDatePicker
selectDateList={calendarTime}
onSelect={this.selectMultiDate}
canSelectTodayBefore={false}
/>
</div>
</div>
<div className="hour" id="hour">
<span className="label"><span className="require">*</span>上课时间:</span>
<TimePicker
format="HH:mm"
value={startTime ? moment(startTime) : null}
placeholder="开始时间"
style={{ width: 100, minWidth: 100}}
onChange={(time) => {
this.props.onChange('startTime', time);
}}
/>&nbsp;&nbsp;~&nbsp;&nbsp;
<TimePicker
format="HH:mm"
value={endTime ? moment(endTime) : null}
placeholder="结束时间"
style={{ width: 100, minWidth: 100 }}
onChange={(time) => {
this.props.onChange('endTime', time)
}}
/>
</div>
</div>
}
{pageType === 'edit' &&
<div className="time" id="time">
<div className="content">
<span className="label"><span className="require">*</span>上课时间:</span>
<DatePicker
disabled={!isEdit}
format="YYYY-MM-DD"
value={liveDate ? moment(Number(liveDate)) : null}
style={{ width: 160, minWidth: 130, marginRight: 10 }}
placeholder="上课日期"
getCalendarContainer={() =>
document.getElementById("time")
}
disabledDate={this.disabledDate}
onChange={(date) => { this.props.onChange('liveDate', date) }}
/>
<TimePicker
disabled={!isEdit}
format="HH:mm"
value={timeHorizonStart ? moment(Number(timeHorizonStart)) : null}
defaultOpenValue={moment(new Date().setHours(0,0,0,0))}
placeholder="开始时间"
style={{ width: 100, minWidth: 100, marginRight: 10 }}
getPopupContainer={() =>
document.getElementById("time")
}
onChange={(time) => { this.props.onChange('timeHorizonStart', time) }}
/>
<TimePicker
disabled={!isEdit}
format="HH:mm"
value={timeHorizonEnd ? moment(Number(timeHorizonEnd)) : null}
defaultOpenValue={moment(new Date().setHours(0,0,0,0))}
placeholder="结束时间"
style={{ width: 100, minWidth: 100 }}
getPopupContainer={() =>
document.getElementById("time")
}
onChange={(time) => { this.props.onChange('timeHorizonEnd', time) }}
/>
</div>
</div>
}
<div className="teacher">
<span className="label"><span className="require">* </span>讲师:</span>
<Select
placeholder="请选择讲师"
style={{ width: 240, marginTop: 6 }}
showSearch
allowClear
value={teacherId}
filterOption={(input, option) => option}
onPopupScroll={this.handleScrollTeacherList}
onChange={(value) => {
this.props.onChange('teacherId', value)
}}
onSearch={(value) => {
teacherQuery.nickName = value
this.setState({
teacherQuery
}, () => {
this.getTeacherList()
})
}}
>
{_.map(teacherList, (item, index) => {
return (
<Select.Option value={item.userId} key={item.userId}>{item.nickName}</Select.Option>
);
})}
</Select>
</div>
<div className="assistant-teacher">
<span className="label">助教:</span>
<Select
id="assistant"
placeholder="请选择助教老师"
showSearch
allowClear
style={{ width: 240, marginTop: 6 }}
filterOption={(input, option) => option}
onPopupScroll={this.handleScrollAssistantList}
onChange={(value) => {
this.props.onChange('adminId', value)
}}
onSearch={(value) => {
assistantQuery.nickName = value
this.setState({
assistantQuery
}, () => {
this.getAssistantList()
})
}}
>
{_.map(assistantList, (item, index) => {
return (
<Select.Option value={item.userId} key={item.userId}>{item.nickName}</Select.Option>
);
})}
</Select>
</div>
</div>
</Spin>
)
}
}
export default AddLiveClass;
\ No newline at end of file
/*
* @Author: 吴文洁
* @Date: 2020-07-16 11:05:17
* @Last Modified by: mikey.zhaopeng
* @Last Modified time: 2020-11-24 14:29:52
* @Description: 添加直播-简介
*/
import React from 'react';
import { Input, message, Upload, Radio, Row, Col, Button, Popover, Switch } from 'antd';
import Service from '@/common/js/service';
import EditorBox from '../components/EditorBox';
import User from '@/common/js/user';
import UploadOss from '@/core/upload';
import './AddLiveIntro.less';
// import SelectPrepareFileModal from '../modal/SelectPrepareFileModal';
import { DISK_MAP } from '@/common/constants/academic/lessonEnum';
import { ImgCutModalNew } from '@/components';
const { TextArea } = Input;
const defaultCover = 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1599635741526.png';
class AddLiveIntro extends React.Component {
constructor(props) {
super(props);
this.state = {
warmUrl: defaultCover,
showSelectFileModal: false,
diskList: [],
}
}
// 上传封面图
handleShowImgCutModal = (event) => {
const imageFile = event.target.files[0];
if (!imageFile) return;
this.setState({
imageFile,
showCutModal: true,
});
}
// 选择暖场资源
handleSelectVideo = (file) => {
this.setState({
showSelectFileModal: false
})
const { ossUrl, resourceId, folderName, folderFormat, folderSize } = file;
const liveCourseWarmMedia = {
contentType: 'WARMUP',
mediaType: folderFormat === 'MP4' ? 'VIDEO' : 'PICTURE',
mediaContent: resourceId,
mediaUrl: ossUrl,
mediaName: folderName,
size: folderSize
}
this.props.onChange('liveCourseWarmMedia', liveCourseWarmMedia);
}
// 获取机构可见的磁盘
handleFetchDiskList = () => {
// axios.Apollo('public/apollo/getUserDisk', {}).then((res) => {
// const { result = [] } = res;
// const diskList = result.map((item) => {
// return {
// ...item,
// folderName: DISK_MAP[item.disk]
// }
// });
// this.setState({ diskList });
// });
}
// 删除简介
handleDeleteIntro = (index) => {
const { liveCourseMediaRequests } = this.props.data;
liveCourseMediaRequests.splice(index, 1);
this.props.onChange('liveCourseMediaRequests', liveCourseMediaRequests);
}
// 上移简介
handleMoveUpIntro = (index) => {
const { liveCourseMediaRequests } = this.props.data;
const prevItem = liveCourseMediaRequests[index];
const nextItem = liveCourseMediaRequests[index + 1];
liveCourseMediaRequests.splice(index, 2, nextItem, prevItem);
this.props.onChange('liveCourseMediaRequests', liveCourseMediaRequests);
}
// 下移简介
handleMoveDownIntro = (index) => {
const { liveCourseMediaRequests } = this.props.data;
const prevItem = liveCourseMediaRequests[index - 1];
const nextItem = liveCourseMediaRequests[index];
liveCourseMediaRequests.splice(index - 1, 2, nextItem, prevItem);
this.props.onChange('liveCourseMediaRequests', liveCourseMediaRequests);
}
renderLittleIcon = (index) => {
const { liveCourseMediaRequests } = this.props.data;
return (
<div className="little-icon">
<span
className="icon iconfont close"
onClick={() => { this.handleDeleteIntro(index); }}
></span>
{
index > 0 &&
<span
className="icon iconfont"
onClick={() => { this.handleMoveDownIntro(index); }}
>&#xe6d1;</span>
}
{
index !== liveCourseMediaRequests.length - 1 &&
<span
className="icon iconfont"
onClick={() => { this.handleMoveUpIntro(index); }}
>&#xe6cf;</span>
}
</div>
)
}
handleChangeIntro = (index, value, length) => {
const { liveCourseMediaRequests } = this.props.data;
liveCourseMediaRequests[index].mediaContent = value;
liveCourseMediaRequests[index].mediaContentLength = length
this.props.onChange('liveCourseMediaRequests', liveCourseMediaRequests);
}
handleAddIntroText = () => {
const { liveCourseMediaRequests } = this.props.data;
liveCourseMediaRequests.push({
contentType:"INTRO",
mediaType: 'TEXT',
mediaContent: '',
key: window.random_string(16)
});
this.props.onChange('liveCourseMediaRequests', liveCourseMediaRequests);
}
handleUpload = (Blob) => {
// 最多添加九图片
const { liveCourseMediaRequests } = this.props.data;
const list = _.filter(liveCourseMediaRequests, (item) => {
return item.mediaType == "PICTURE";
});
if (list.length > 8) {
message.warning("最多添加9张图片");
return;
}
const { instId } = window.currentUserInstInfo;
const { name, size } = Blob;
const resourceName = window.random_string(16) + name.slice(name.lastIndexOf('.'));
// UploadOss.uploadBlobToOSS(Blob, 'avatar' + (new Date()).valueOf(),'', 'id').then((imgAddress) => {
// liveCourseMediaRequests.push({
// contentType:"INTRO",
// size,
// mediaName: name,
// mediaContent: imgAddress.resourceId,
// mediaType: 'PICTURE',
// });
// this.props.onChange('liveCourseMediaRequests', liveCourseMediaRequests);
// });
const params = {
resourceName,
accessTypeEnum: 'PUBLIC',
bizCode: 'LIVE_COURSE_MEDIA',
instId:User.getStoreId(),
}
Service.Hades("public/hades/commonOssAuthority", params).then((res) => {
const { resourceId } = res.result;
const signInfo = res.result;
// 构建上传的表单
const xhr = new XMLHttpRequest();
const formData = new FormData();
formData.append("OSSAccessKeyId", signInfo.accessId);
formData.append("policy", signInfo.policy);
formData.append("callback", signInfo.callback);
formData.append("Signature", signInfo.signature);
formData.append("key", signInfo.key);
formData.append("file", Blob);
formData.append("success_action_status", 200);
xhr.open("POST", signInfo.host);
xhr.onload = () => {
liveCourseMediaRequests.push({
size,
mediaName: name,
mediaContent: resourceId,
mediaType: 'PICTURE',
mediaUrl: window.URL.createObjectURL(Blob),
});
this.props.onChange('liveCourseMediaRequests', liveCourseMediaRequests);
};
xhr.onerror = () => {
xhr.abort();
};
xhr.send(formData);
this.setState({ xhr })
});
}
whetherVisitorsJoinChange = ()=>{
if(this.props.data.whetherVisitorsJoin==="NO"){
this.props.onChange('whetherVisitorsJoin','YES')
}else{
this.props.onChange('whetherVisitorsJoin','NO')
}
}
componentWillMount() {
this.handleFetchDiskList();
}
// componentWillUnmount() {
// const { xhr } = this.state;
// xhr && xhr.abort();
// }
render() {
const {liveType, isXiaomai, isEdit, data: { introduction, needRecord,whetherVisitorsJoin,liveCourseMediaRequests = [], liveCourseWarmMedia = {} } } = this.props;
console.log("whetherVisitorsJoin",whetherVisitorsJoin);
const { showCutModal, warmUrl, showSelectFileModal, diskList, imageFile } = this.state
return (
<div className="add-live__intro-info">
<div className="playback">
<span className="label"><span className="require">*</span>直播回放:</span>
<div className="content">
<Radio.Group value={needRecord} onChange={(e) => { this.props.onChange('needRecord', e.target.value) }}>
<Row style={{ marginBottom: '5px' }}>
<Col span={8}>
<Radio value="YES">
自动录制
</Radio>
</Col>
<Col span={16}>
<span className="playback__text">系统自助进行全程直播录制</span>
</Col>
</Row>
<Row>
<Col span={8}>
<Radio value="NO">
手动录制
</Radio>
</Col>
<Col span={16}>
<span className="playback__text">讲师手动选择何时开始录制</span>
</Col>
</Row>
</Radio.Group>
</div>
</div>
<div className="allow-tourist-join">
<span className="label">允许游客加入:</span>
<div className="content">
<Row>
<Col span={3}>
<Switch checked={whetherVisitorsJoin==="YES"? true:false} onChange={this.whetherVisitorsJoinChange}/>
</Col>
<Col span={21}>
<div>开启:用户可直接进入直播间观看直播</div>
<div>关闭:用户需先填写手机号并短信验证,通过后才可进入直播间观看直播</div>
</Col>
</Row>
</div>
</div>
<div className="warmup">
<span className="label">直播暖场图:</span>
<div className="course-cover__wrap">
<div className="img-content" style={ liveCourseWarmMedia.mediaUrl ? {background: '#000'} : {} }>
<img src={liveCourseWarmMedia.mediaType === 'VIDEO' ? `${liveCourseWarmMedia.mediaUrl}?x-oss-process=video/snapshot,t_0,m_fast` : (liveCourseWarmMedia.mediaUrl ? liveCourseWarmMedia.mediaUrl : defaultCover )} />
{
liveCourseWarmMedia.mediaUrl &&
<div className="img-delete-wrap">
<img src="https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1600073872956.png" onClick={() => {
this.props.onChange('liveCourseWarmMedia', {});
}}/>
</div>
}
</div>
<div className="opt-btns">
<Button
disabled={!isEdit}
onClick={() => {
this.setState({
showSelectFileModal: true
})
}}>上传图片/视频</Button>
<div className="tips">建议尺寸1280*720px或16:9。图片最大5M,支持jpg、jpeg和png;视频最大500M,支持mp4。</div>
<Popover content={
<div className="example-wrap">
<p className="title">直播间暖场图示例</p>
<p className="text">直播开始前,展示在直播间视频区域</p>
<img src='https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1599644482652.png'></img>
</div>
}>
<div className="checkExample">查看示例</div>
</Popover>
</div>
</div>
</div>
<div className="introduce">
<span className="label">直播简介:</span>
<div className="content">
<div className="intro-list">
{
liveCourseMediaRequests.map((item, index) => {
if (item.mediaType === 'TEXT') {
return (
<div className="intro-list__item" key={item.key}>
<EditorBox
detail={{
content: item.mediaContent
}}
onChange={(val, length) => { this.handleChangeIntro(index, val, length) }}
/>
{this.renderLittleIcon(index)}
</div>
)
}
if (item.mediaType === 'PICTURE') {
return (
<div className="intro-list__item picture" key={index}>
<div className="img__wrap">
<img src={item.mediaUrl} />
</div>
{this.renderLittleIcon(index)}
</div>
)
}
})
}
</div>
<div className="operate">
<div className="operate__item" onClick={this.handleAddIntroText}>
<span className="icon iconfont">&#xe639;</span>
<span className="text">文字</span>
</div>
<Upload
fileList={[]}
accept="image/jpeg, image/png, image/jpg, image/gif"
beforeUpload={(Blob) => {
this.handleUpload(Blob);
return false;
}}
>
<div className="operate__item">
<span className="icon iconfont">&#xe63b;</span>
<span className="text">图片</span>
</div>
</Upload>
</div>
<div className="tips">
• 图片支持jpeg、jpg、png、gif格式
</div>
</div>
</div>
{/* 选择暖场图文件弹窗 */}
{/* <SelectPrepareFileModal
operateType="select"
accept="video/mp4,image/jpeg,image/png,image/jpg"
selectTypeList={['MP4', 'JPG', 'JPEG', 'PNG']}
tooltip='支持文件类型:jpg、jpeg、png、mp4'
isOpen={showSelectFileModal}
diskList={diskList}
onClose={() => {
this.setState({ showSelectFileModal: false })
}}
onSelect={this.handleSelectVideo}
/> */}
</div>
)
}
}
export default AddLiveIntro;
......@@ -172,17 +172,16 @@ class LiveCourseList extends React.Component {
<div className="course-name">{record.courseName}</div>
<div>
<span className="course-time">{formatDate("YYYY-MM-DD H:i",parseInt(record.startTime))}~{formatDate("H:i", parseInt(record.endTime))}</span>
<span>{courseStateShow[record.courseState].title}</span>
<span className="course-status" style={{color:courseStateShow[record.courseState].color,border:`1px solid ${courseStateShow[record.courseState].color}`}}>{courseStateShow[record.courseState].title}</span>
</div>
<div>
<span>讲师:{record.teacherName}</span>
<span> | </span>
<span className="teacher">讲师:{record.teacherName}</span>
<span className="split"> | </span>
<span>助教:
<span className="assistant">助教:
{ record.admins.map((item,index)=>{
return <span>{item.adminName}</span>
return <span>{item.adminName} { (index < record.admins.length-1)&&(<span></span>)} </span>
})
}
</span>
......@@ -199,7 +198,7 @@ class LiveCourseList extends React.Component {
dataIndex: "couseCatalog",
render: (val, item) => {
return (
<div>{item.categoryName}</div>
<div className="categoryName">{item.categoryName}</div>
)
},
},
......@@ -210,7 +209,7 @@ class LiveCourseList extends React.Component {
dataIndex: "courseware",
render: (val, item) => {
return (
<span>{item.courseDocumentCount}</span>
<span className="courseware">{item.courseDocumentCount}</span>
);
},
},
......@@ -221,7 +220,7 @@ class LiveCourseList extends React.Component {
dataIndex: "quota",
render: (val, item) => {
return (
<span className="iconfont icon data-icon" onClick={() => {
<span className="iconfont icon quota-icon" onClick={() => {
this.handleLinkToClassData(item)
}}>&#xe7d6;</span>
);
......
.live-course-list {
margin-top: 16px;
.record__item {
display: flex;
align-items: center;
}
.operate {
display: flex;
align-items: center;
flex-wrap: wrap;
.operate__item {
color: #ff7519;
cursor: pointer;
&.split {
margin: 0 8px;
color: #BFBFBF;
}
}
}
.operate-text {
color: #ff7519;
cursor: pointer;
}
.course-cover {
min-width: 90px;
max-width: 90px;
height: 50px;
border-radius: 2px;
margin-right: 8px;
}
.course-status {
display: flex;
.badge {
transform: none !important;
display: flex;
align-items: center;
.ant-badge-status-dot {
top: 0;
}
.ant-badge-status-text {
white-space: nowrap;
}
}
}
.course-start-end {
margin-left: 16px;
width: 78px;
height: 20px;
border-radius: 2px;
border: 1px solid rgba(204, 204, 204, 1);
display: flex;
align-items: center;
cursor: pointer;
white-space: nowrap;
.start-icon {
color: #3296fa;
font-size: 12px;
transform: scale(0.8);
margin: 0 5px;
}
.end-icon {
color: #00d700;
font-size: 12px;
transform: scale(0.8);
margin: 0 5px;
}
.start-end-text {
font-size: 12px;
}
}
}
.live-course-more-menu {
background: white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
border-radius: 4px;
div {
line-height: 30px;
padding: 0 15px;
cursor: pointer;
&:hover {
background: #f3f6fa;
}
}
}
.tipTitle {
.type {
font-weight: 700;
}
}
\ No newline at end of file
......@@ -27,7 +27,7 @@ import ScanFileModal from '../modal/ScanFileModal';
import CreateFolderModal from '../modal/CreateFolderModal';
const DEL_FOLDER_URL_MAP = {
'MYSELF': 'public/apollo/delFolder',
'MYSELF': 'public/hadesStore/delFolder',
'COMMON': 'public/apollo/delCommonFolder'
}
......@@ -163,7 +163,7 @@ class FolderList extends React.Component {
disk: currentRootDisk.disk,
}
Service.Hades('public/apollo/folderPath', params).then((res) => {
Service.Hades('public/hadesStore/folderPath', params).then((res) => {
const { result = [] } = res;
this.props.onChangeFolderPath(result, false);
})
......@@ -347,7 +347,7 @@ class FolderList extends React.Component {
return;
}
Service.Hades('public/apollo/renameFolder', {
Service.Hades('public/hadesStore/renameFolder', {
id: renameModalData.id,
name: folderName
}).then(() => {
......@@ -371,7 +371,7 @@ class FolderList extends React.Component {
folderType: 'FOLDER',
}
const res = await Service.Hades('public/apollo/sameNameFile', params);
const res = await Service.Hades('public/hadesStore/sameNameFile', params);
const { result } = res;
return result;
}
......
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