Commit 9c1ae54a by zhangleyuan

feat:解决合并代码后的冲突

parents cb19a47f 0625e798
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -117,7 +117,6 @@ class ShareLiveModal extends React.Component {
>{`【${courseName}】开课啦,快来学习!`}</div>
<img
src={coverImgSrc}
crossOrigin="*"
className="course-cover"
alt="course-cover"
/>
......
......@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Date: 2020-08-31 09:34:31
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-22 15:24:03
* @LastEditTime: 2021-01-09 14:39:46
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
......@@ -27,7 +27,7 @@ interface HeadersType{
storeId?:any,
storeUserId?:any,
userId?:any,
token?:any
xmtoken?:any
}
class Axios {
static post(
......@@ -49,7 +49,7 @@ class Axios {
headerObject.userId = User.getUserId();
}
if(User.getToken()){
headerObject.token = User.getToken();
headerObject.xmtoken = User.getToken();
}
const instance: AxiosInstance = axios.create({
timeout: TIME_OUT,
......
import React from 'react'
import React from 'react';
import { Modal, Button } from "antd";
import "./DownloadLiveModal.less"
......@@ -12,37 +13,12 @@ class DownloadLiveModal extends React.Component {
type: 'pre',
}
}
downloadLiveClient(){
if (type === 'pre') {
const isMac = /macintosh|mac os x/i.test(navigator.userAgent);
if(isMac){
Modal.info({
title: "抱歉,暂不支持Mac版",
content: "Mac版正在开发中,敬请期待",
icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>,
okText: '我知道了'
});
return;
}
url && window.open(url);
this.setState({
image: 'https://image.xiaomaiketang.com/xm/wPwRdaa7MM.png',
tip: '安装完成后,再次打开即可开始直播。',
text: '我知道了',
type: 'finish',
})
} else {
this.props.onCancel();
}
}
render() {
const { url } = this.props;
const { image, tip, text, type } = this.state;
return <Modal
visible={true}
maskClosable={false}
title="下载客户端"
className="download-live-modal"
footer={null}
......@@ -56,8 +32,17 @@ class DownloadLiveModal extends React.Component {
type="primary"
className="download-button"
onClick={() => {
if (type === 'pre') {
url && window.open(url);
this.setState({
image: 'https://image.xiaomaiketang.com/xm/wPwRdaa7MM.png',
tip: '安装完成后,再次打开即可开始直播。',
text: '我知道了',
type: 'finish',
})
} else {
this.props.onCancel();
}
}}
>{text}</Button>
</Modal>
......
......@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import { Modal, Button } from 'antd';
import Service from '@/common/js/service';
import User from '@/common/js/user';
import PhotoClip from 'photoclip'
let cutFlag = false;
class ImgCutModalNew extends React.Component {
......@@ -66,6 +67,7 @@ class ImgCutModalNew extends React.Component {
})
}
};
if (!photoclip) {
const _photoclip = new PhotoClip('#imgCutModalNew', options);
_photoclip.load(imageFile);
......
......@@ -9,7 +9,6 @@ import React from 'react'
import { message } from "antd";
import moment from 'moment';
require("./MultipleDatePicker.less");
class MultipleDatePicker extends React.Component {
constructor(props) {
super(props);
......@@ -245,13 +244,14 @@ class MultipleDatePicker extends React.Component {
</div>
)}
<ul className="week">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul className="calendar" id="multiCalendar">
{this.state.calendar}
......
......@@ -2,7 +2,7 @@
* @Author: wufan
* @Date: 2020-12-01 17:21:21
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-22 15:39:00
* @LastEditTime: 2021-01-09 11:06:42
* @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -38,6 +38,9 @@ export function sendNewPhoneAuthCode(params: object) {
export function editUserPhone(params: object) {
return Service.Hades("public/hades/editUserPhone", params);
}
export function getLastedVersion(params: object) {
return Service.Hades("public/hades/getLastedVersion", params);
}
export const getOssClient = (
data: object,
instId: string,
......
......@@ -2,12 +2,12 @@
* @Author: wufan
* @Date: 2020-12-01 17:20:49
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-11 11:36:19
* @LastEditTime: 2021-01-09 11:08:02
* @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import { getUserStore, getUserPermission ,logout,getStoreUser,sendBizAuthCode,editUserPhone,checkBizAuthCode,sendNewPhoneAuthCode,sendLoginAuthCode,login} from '@/data-source/base/request-apis';
import { getUserStore, getUserPermission ,logout,getStoreUser,sendBizAuthCode,editUserPhone,checkBizAuthCode,sendNewPhoneAuthCode,sendLoginAuthCode,login,getLastedVersion} from '@/data-source/base/request-apis';
export default class StoreService {
// 获取员工列表
......@@ -46,4 +46,7 @@ export default class StoreService {
static login(params: any){
return login(params);
}
static getLastedVersion(params: any){
return getLastedVersion(params);
}
}
\ No newline at end of file
/*
* @Author: 陈剑宇
* @Date: 2020-05-07 14:43:01
* @LastEditTime: 2020-12-26 14:10:34
* @LastEditTime: 2021-01-18 21:05:12
* @LastEditors: zhangleyuan
* @Description:
* @FilePath: /wheat-web-demo/src/domains/basic-domain/constants.ts
......@@ -9,7 +9,7 @@
import { MapInterface } from '@/domains/basic-domain/interface'
// 默认是 dev 环境
const ENV: string = process.env.DEPLOY_ENV || 'dev';
const ENV: string = process.env.DEPLOY_ENV || 'prod';
console.log("process.env.DEPLOY_ENV",process)
const BASIC_HOST_MAP: MapInterface = {
dev: 'https://dev-heimdall.xiaomai5.com/',
......@@ -25,5 +25,6 @@ export const USER_TYPE: string = 'B';
export const PROJECT = 'xmzj-web-b';
export const VERSION = '5.4.8';
export const PREFIX = 'cloud-class';
// host
export const BASIC_HOST: string = BASIC_HOST_MAP[ENV];
/*
* @Author: 吴文洁
* @Date: 2020-08-20 09:21:40
* @LastEditors: wufan
* @LastEditTime: 2021-01-06 21:16:34
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-01-18 21:05:31
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
import { MapInterface } from '@/domains/basic-domain/interface'
const ENV: string = process.env.DEPLOY_ENV || 'dev';
const ENV: string = process.env.DEPLOY_ENV || 'prod';
const appIdMap: MapInterface = {
dev: 'wx3ea60e78ddfa277e',
......@@ -25,7 +25,7 @@ const shareUrlMap: MapInterface = {
'gray': 'https://prod.xiaomai5.com/share/show?appid='
}
const LIVE_SHARE_MAP: MapInterface = {
const LIVE_SHARE_MAP: MapInterface = {
dev: 'https://dev.xiaomai5.com/store-live/index.html#/',
dev1: 'https://dev.xiaomai5.com/store-live/index.html#/',
rc: 'https://rc.xiaomai5.com/store-live/index.html#/',
......@@ -33,6 +33,9 @@ const shareUrlMap: MapInterface = {
prod: 'https://res.xiaomai0.com/store-live/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-08-24 12:20:57
* @LastEditors: wufan
* @LastEditTime: 2021-01-12 13:52:23
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-01-12 15:26:36
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
-->
......
......@@ -13,13 +13,12 @@ class DateRangePicker extends React.Component {
}
render() {
const showTime = { showTime: true }
const showTime = { showTime: false }
return (
<RangePicker
{...this.props}
format={this.props.format || 'YYYY-MM-DD'}
allowClear={this.props.allowClear}
ranges={this.props.ranges || { '本月': [moment().startOf('month'), moment().endOf('month')], '本周': [moment().startOf('week'), moment().endOf('week')], '上月': [moment().subtract(1, 'M').startOf('month'), moment().subtract(1, 'M').endOf('month')], '上周': [moment().subtract(1, 'w').startOf('week'), moment().subtract(1, 'w').endOf('week')] }}
onChange={(date) => {
if (!_.isEmpty(date)) {
date[0] = date[0].startOf('day')
......
......@@ -82,6 +82,8 @@ class AddLive extends React.Component {
teacherId: null,
teacherName: null,
assistant:[],
assistantStoreUserId:[],
assistantNames:[],
liveDate: null,
timeHorizonStart: null,
timeHorizonEnd: null,
......@@ -169,6 +171,8 @@ class AddLive extends React.Component {
const timeHorizonStart = startTime;
const timeHorizonEnd = endTime;
const assistant = _.pluck(admins, "adminId");
const assistantStoreUserId = _.pluck(admins, "adminStoreUserId"); //编辑时的选中的助教的查询用storeUserId查询
const assistantNames = _.pluck(admins, "adminName");
const addLiveClassInfo = {
assistant,
liveDate,
......@@ -179,6 +183,8 @@ class AddLive extends React.Component {
timeHorizonEnd,
startTime,
endTime,
assistantNames,
assistantStoreUserId
}
// liveCourseMediaRequests = liveCourseMediaRequests.length
......@@ -220,16 +226,21 @@ handleChangeBasicInfo = (field, value) => {
}
// 修改上课信息
handleChangeClassInfo = (field, value ,_teacherName) => {
handleChangeClassInfo = (field, value ,type, optionValue) => {
const _value = value ? value.valueOf() : null;
const { teacherName } = this.state.addLiveClassInfo;
const { assistantNames } = this.state.addLiveClassInfo;
const { assistantStoreUserId } = this.state.addLiveClassInfo
this.setState({
addLiveClassInfo: {
...this.state.addLiveClassInfo,
[field]: _value,
teacherName:_teacherName?_teacherName:teacherName
teacherName:type==='teacherType'?optionValue:teacherName,
assistantNames:type==='assistantType'?_.pluck(optionValue, "children"):assistantNames,
assistantStoreUserId:type==='assistantType'?_.pluck(optionValue, "key"):assistantStoreUserId,
}
});
// 批量开始时间改变,结束时间自动同步一致
if (field === 'startTime') {
this.setState({
......@@ -388,7 +399,7 @@ handleChangeBasicInfo = (field, value) => {
message.warning('请选择上课日期');
resolve(false);
return;
} else if(startTime === endTime) {
} else if(startTime === endTime || startTime > endTime) {
message.warning('结束时间必须晚于开始时间');
resolve(false);
return;
......@@ -444,36 +455,11 @@ handleChangeBasicInfo = (field, value) => {
}
}
if(!teacherId){
message.warning('上课老师不能为空');
message.warning('请选择讲师');
resolve(false);
return;
}
resolve(true)
// if(!teacherId) {
// message.warning('上课老师不能为空');
// resolve(false);
// return;
// } else if(!applyMode) {
// message.warning('请选择分享设置');
// resolve(false);
// return;
// } else {
// const textIntro = liveCourseMediaRequests.filter(item => { return item.mediaType === 'TEXT'; });
// for (let i = 0, len = textIntro.length; i < len; i++) {
// if (textIntro[i].mediaContent && textIntro[i].mediaContentLength.length > 1000) {
// message.warning(`第${i+1}个文字简介的字数超过了1000个字`);
// resolve(false);
// return;
// }
// }
// }
// if(window.NewVersion && type === 'add') {
// this.handleValidateLackConsumeModal(consumeHourNum, calendarTime, consumeStudentList).then(res => {
// resolve(res)
// })
// } else {
// resolve(true);
// }
});
}
......@@ -537,7 +523,7 @@ handleChangeBasicInfo = (field, value) => {
/>
<div className="box">
<div className="show-tips">
<ShowTips message="请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦助教保有依据国家规定及平台规则进行处理的权利" />
<ShowTips message="请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企培保有依据国家规定及平台规则进行处理的权利" />
</div>
<div className="add-live-page__form">
<div className="basic-info__wrap">
......
......@@ -151,8 +151,8 @@ class DataList extends React.Component {
},
{
title: "累计在线时长",
dataIndex: "watchDuration",
sorter: (a, b) => a.watchDuration - b.watchDuration,
dataIndex: "totalDuration",
sorter: (a, b) => a.totalDuration - b.totalDuration,
sortDirections: ["descend", "ascend"],
render: (text, record) => {
//如无离开时间,就置空
......
......@@ -95,6 +95,9 @@
&.avatar-name-phone {
justify-content: flex-start;
padding-left: 26px;
.avatar{
border-radius:50%;
}
.name {
height: 22px;
font-size: 16px;
......
......@@ -30,10 +30,12 @@ class AddLiveBasic extends React.Component {
showCutModal: false,
courseCatalogList:[],
showSelectFileModal: false,
cutImageBlob: null
cutImageBlob: null,
hasImgReady: false // 图片是否上传成功
}
}
componentWillUnmount() {
}
componentDidMount(){
......@@ -142,20 +144,22 @@ class AddLiveBasic extends React.Component {
const _dataUrl = this.clip()
self.setState({
dataUrl: _dataUrl,
hasImgReady: true
})
}, 100)
},
};
const imgUrl = `${imageFile.ossUrl}?${new Date().getTime()}`
if (!this.state.photoclip) {
const _photoclip = new PhotoClip("#headPicModal", options);
_photoclip.load(imageFile.ossUrl);
_photoclip.load(imgUrl);
this.setState({
photoclip: _photoclip,
});
} else {
this.state.photoclip.clear();
this.state.photoclip.load(imageFile.ossUrl);
this.state.photoclip.load(imgUrl);
}
}, 200);
......@@ -197,7 +201,8 @@ class AddLiveBasic extends React.Component {
}
render() {
const { showCutModal, imageFile,courseCatalogList,showSelectFileModal,visible,cutImageBlob} = this.state;
const { showCutModal, imageFile,courseCatalogList,showSelectFileModal,visible,cutImageBlob,hasImgReady
} = this.state;
const { data,pageType,isEdit} = this.props;
const { courseName,categoryName,coverUrl} = data;
const fileName = '';
......@@ -254,7 +259,7 @@ class AddLiveBasic extends React.Component {
<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="请选择课程分类" />
<Cascader 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="请选择课程分类" />
......@@ -278,8 +283,9 @@ class AddLiveBasic extends React.Component {
onClose={() => this.setState({ showCutModal: false })}
reUpload={() => { this.state.currentInputFile.click() }}
/>
{showSelectFileModal &&
<SelectPrepareFileModal
key="basic"
operateType="select"
multiple={false}
accept="image/jpeg,image/png,image/jpg"
......@@ -291,6 +297,7 @@ class AddLiveBasic extends React.Component {
}}
onSelect={this.handleSelectCover}
/>
}
<Modal
title="设置图片"
width={1080}
......@@ -311,6 +318,7 @@ class AddLiveBasic extends React.Component {
<Button
key="submit"
type="primary"
disabled={!hasImgReady}
onClick={() => {
if (!cutFlag) {
cutFlag = true;
......
......@@ -48,12 +48,19 @@ class AddLiveClass extends React.Component {
this.getTeacherList();
this.getAssistantList();
}
componentWillReceiveProps(nextProps) {
if(nextProps.data.assistantStoreUserId.sort().toString() !== this.props.data.assistantStoreUserId.sort().toString()) {
console.log('我在改变')
// 获取助教老师列表
this.getAssistantList(1, nextProps.data.assistantStoreUserId);
}
}
getTeacherList(current = 1, selectList){
const { teacherQuery,teacherList} = this.state;
const _query = {
...teacherQuery,
current,
size:10
size:15
};
StoreService.getStoreUserBasicPage( _query).then((res) => {
const { result = {} } = res;
......@@ -67,17 +74,24 @@ class AddLiveClass extends React.Component {
}
// 获取助教老师列表
getAssistantList = (current = 1, selectList) => {
console.log('zhujiao',current);
const { assistantQuery,assistantList} = this.state;
const { assistantStoreUserId } = this.props.data;
const idList = selectList ? selectList : assistantStoreUserId;
const _query = {
...assistantQuery,
current,
size:10
idList,
size: idList.length <= 10 ? 10 : idList.length + 10
};
StoreService.getStoreUserBasicPage( _query).then((res) => {
const { result = {} } = res;
const { records = [], total = 0, hasNext} = result;
const { teacherId } = this.props.data
let list = current > 1 ? assistantList.concat(records) : records;
console.log("hasNext",typeof(hasNext),hasNext)
this.setState({
assistantHasNext:hasNext,
assistantList: list,
......@@ -92,7 +106,11 @@ class AddLiveClass extends React.Component {
const scrollToBottom = container && container.scrollHeight <= container.clientHeight + container.scrollTop;
if (scrollToBottom && hasNext) {
const { teacherQuery } = this.state;
this.getTeacherList(teacherQuery.current + 1);
let _teacherQuery = teacherQuery;
_teacherQuery.current = _teacherQuery.current + 1
this.setState({
assistantQuery:{..._teacherQuery}
},()=>{this.getTeacherList(_teacherQuery.current)})
}
}
......@@ -103,7 +121,11 @@ class AddLiveClass extends React.Component {
const scrollToBottom = container && container.scrollHeight <= container.clientHeight + container.scrollTop;
if (scrollToBottom && assistantHasNext) {
const { assistantQuery } = this.state;
this.getAssistantList(assistantQuery.current + 1);
let _assistantQuery = assistantQuery;
_assistantQuery.current = _assistantQuery.current + 1
this.setState({
assistantQuery:{..._assistantQuery}
},()=>{this.getAssistantList(_assistantQuery.current)})
}
}
......@@ -134,7 +156,9 @@ class AddLiveClass extends React.Component {
liveDate,
timeHorizonStart,
timeHorizonEnd,
assistant
assistant,
assistantNames,
teacherName
} = data;
console.log("teacherId",teacherId);
return (
......@@ -241,19 +265,23 @@ class AddLiveClass extends React.Component {
</div>
}
<div className="teacher">
<div className="teacher" id="teacher">
<span className="label"><span className="require">* </span>讲师:</span>
<Select
placeholder="请选择讲师"
// key={teacherName}
// defaultValue={teacherName}
value={teacherName}
style={{ width: 240, marginTop: 6 }}
disabled={!isEdit ? true: false}
showSearch
value={teacherId}
filterOption={(input, option) => option}
onPopupScroll={this.handleScrollTeacherList}
onChange={(value,option) => {
this.props.onChange('teacherId', value,option.children)
console.log("value",value);
this.props.onChange('teacherId',value,'teacherType',option.children)
}}
onSearch={(value) => {
teacherQuery.nickName = value
this.setState({
......@@ -262,6 +290,9 @@ class AddLiveClass extends React.Component {
this.getTeacherList()
})
}}
getPopupContainer={() =>
document.getElementById("teacher")
}
>
{_.map(teacherList, (item, index) => {
if( !assistant.includes(item.userId) ){
......@@ -271,12 +302,15 @@ class AddLiveClass extends React.Component {
}
})}
</Select>
</div>
<div className="assistant-teacher">
<div className="assistant-teacher" id="assistant-teacher">
<span className="label">助教:</span>
<Select
id="assistant"
placeholder="请选择助教老师"
// key={assistantNames}
// defaultValue={assistantNames}
value={assistant}
disabled={!isEdit ? true: false}
mode={'multiple'}
......@@ -285,8 +319,9 @@ class AddLiveClass extends React.Component {
style={{ width: 240, marginTop: 6 }}
filterOption={(input, option) => option}
onPopupScroll={this.handleScrollAssistantList}
onChange={(value) => {
this.props.onChange('assistant', value)
onChange={(value,option) => {
console.log('option',option);
this.props.onChange('assistant',value,'assistantType',option)
}}
onSearch={(value) => {
assistantQuery.nickName = value
......@@ -296,11 +331,14 @@ class AddLiveClass extends React.Component {
this.getAssistantList()
})
}}
getPopupContainer={() =>
document.getElementById("assistant-teacher")
}
>
{_.map(assistantList, (item, index) => {
if(item.userId !== teacherId){
return (
<Select.Option value={item.userId} key={item.userId}>{item.nickName}</Select.Option>
<Select.Option value={item.userId} key={item.id}>{item.nickName}</Select.Option>
);
}
......
......@@ -52,7 +52,7 @@ class AddLiveIntro extends React.Component {
if(selectType === 'WARMUP'){
const liveCourseWarmMedia = {
contentType: 'WARMUP',
mediaType: folderFormat === 'MP4' ? 'VIDEO' : 'PICTURE',
mediaType: folderFormat === 'MP4' || folderFormat === 'video/mp4' ? 'VIDEO' : 'PICTURE',
mediaContent: resourceId,
mediaUrl: ossUrl,
mediaName: folderName,
......@@ -391,7 +391,9 @@ class AddLiveIntro extends React.Component {
</div>
</div>
{/* 选择暖场图文件弹窗 */}
{ showSelectFileModal &&
<SelectPrepareFileModal
key="instro"
operateType="select"
accept={selectType==="INTRO"?"image/jpeg,image/png,image/jpg":"video/mp4,image/jpeg,image/png,image/jpg"}
selectTypeList={ selectType==="INTRO" ? ['JPG', 'JPEG', 'PNG']: ['MP4', 'JPG', 'JPEG', 'PNG'] }
......@@ -402,6 +404,8 @@ class AddLiveIntro extends React.Component {
}}
onSelect={this.handleSelectVideo}
/>
}
</div>
)
......
......@@ -15,6 +15,7 @@ import TeacherSearchSelect from "@/modules/common/TeacherSearchSelect";
import RangePicker from "@/modules/common/DateRangePicker";
import moment from 'moment';
import StoreService from "@/domains/store-domain/storeService";
import User from '@/common/js/user';
import './LiveCourseFilter.less';
const { Search } = Input;
......@@ -98,8 +99,10 @@ class LiveCourseFilter extends React.Component {
query.endTime = dates[1].valueOf();
}
this.setState({
query,
query:{
...query,
current: 1,
}
}, () => {
this.props.onChange(this.state.query);
})
......@@ -124,7 +127,6 @@ class LiveCourseFilter extends React.Component {
handleReset = () => {
this.setState({
query: {
...this.state.query,
courseName: null,
startTime: null,
endTime: null,
......@@ -132,6 +134,7 @@ class LiveCourseFilter extends React.Component {
teacherName: null,
courseState: undefined,
current: 1,
shelfState:null,
},
}, () => {
this.props.onChange(this.state.query);
......@@ -172,8 +175,10 @@ class LiveCourseFilter extends React.Component {
format={"YYYY-MM-DD"}
onChange={(dates) => { this.handleChangeDates(dates) }}
style={{ width: "calc(100% - 70px)" }}
/>
</div>
{ User.getUserRole()!=="CloudLecturer" &&
<div className="search-condition__item">
<span>讲师:</span>
<Select
......@@ -185,7 +190,7 @@ class LiveCourseFilter extends React.Component {
onPopupScroll={this.handleScrollTeacherList}
value={teacherId}
onChange={(value) => {
this.handleChangeQuery('teacherId', value)
this.handleChangeQuery('teacherId', value);
}}
onSearch={(value) => {
teacherQuery.nickName = value
......@@ -195,6 +200,18 @@ class LiveCourseFilter extends React.Component {
this.getTeacherList()
})
}}
onClear ={(value)=>{
this.setState({
teacherQuery:{
size: 10,
current: 1,
nickName:null
}
}, () => {
this.getTeacherList()
})
}
}
>
{_.map(teacherList, (item, index) => {
return (
......@@ -203,8 +220,8 @@ class LiveCourseFilter extends React.Component {
})}
</Select>
</div>
{ expandFilter &&
}
{ ((expandFilter && User.getUserRole()!=="CloudLecturer") || User.getUserRole()==="CloudLecturer") &&
<div className="search-condition__item">
<span className="select-status">上课状态:</span>
<Select
......
......@@ -17,7 +17,7 @@
color: #333333;
line-height: 20px;
font-weight: bold;
max-width:238px;
max-width:244px;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
......@@ -77,9 +77,11 @@
color: #5289FA;
line-height: 20px;
text-align:right;
cursor:pointer;
}
.quota-icon{
color:#5289FA;
cursor:pointer;
}
.operate {
display: flex;
......@@ -124,8 +126,14 @@
font-size: 12px;
}
}
}
}
.ant-tooltip{
max-width:700px !important;
}
.ant-tooltip-inner{
max-width:700px !important;
}
.live-course-more-menu {
background: white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
......
......@@ -8,7 +8,10 @@
import React from 'react';
import { Button, Modal, message } from 'antd';
import Service from '@/common/js/service';
import './liveCourseOpt.less';
import BaseService from "@/domains/basic-domain/baseService";
import User from '@/common/js/user'
class LiveCourseOpt extends React.Component {
constructor(props) {
super(props);
......@@ -22,30 +25,30 @@ class LiveCourseOpt extends React.Component {
handleDownloadClient = () => {
const isMac = /macintosh|mac os x/i.test(navigator.userAgent);
// 判断用户系统
if(!isMac) {
// axios
// .Apollo("anon/version/getLastedVersion", { model: 1, platform: 1 })
// .then((res) => {
// const a = document.createElement("a");
// document.body.appendChild(a);
// a.href = res.result.releaseUrl;
// a.click();
// document.body.removeChild(a);
// })
}else {
Modal.info({
title: "抱歉,暂不支持Mac版",
content: "Mac版正在开发中,敬请期待",
icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>,
okText: '我知道了'
});
let platform;
if(!isMac){
platform = 1
}else{
platform = 4
}
BaseService
.getLastedVersion({ model: 5, platform})
.then((res) => {
const a = document.createElement("a");
document.body.appendChild(a);
a.href = res.result.releaseUrl;
a.click();
document.body.removeChild(a);
})
}
render() {
const userRole = User.getUserRole();
return (
<div className="live-course-opt">
<div className="opt__left">
{ userRole !== "CloudLecturer" &&
<Button type="primary" onClick={this.handleCreateLiveCouese}>新建直播课</Button>
}
<Button onClick={this.handleDownloadClient}>下载直播客户端</Button>
</div>
</div>
......
......@@ -122,7 +122,7 @@ class ManageCoursewareModal extends React.Component {
// 上传文件
addFile() {
// 判断是否早于开课前45分钟
// 判断是否早于开课前30分钟
const { startTime } = this.props.data;
const currentTime = new Date().getTime();
if (currentTime >= startTime - 30 * 60 * 1000) {
......@@ -313,7 +313,7 @@ class ManageCoursewareModal extends React.Component {
const uploadFail = failObject[item.id];
// 上课前45分钟/上课中/已结束的情况下都不可操作
if (this.props.data.startTime < Date.now() + 2700000 || item.progress || uploadFail) {
if (this.props.data.startTime < Date.now() + 1800000 || item.progress || uploadFail) {
return <span>-</span>
}
return (
......
......@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Date: 2020-07-23 14:54:16
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-01-08 17:49:46
* @LastEditTime: 2021-01-09 16:26:03
* @Description: 大班直播课预览弹窗
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
......@@ -36,7 +36,16 @@ class PreviewCourseModal extends React.Component {
}
}
dealTimeDuration = (time) => {
const diff = Math.floor(time % 3600);
let hours = Math.floor(time / 3600);
let mins = Math.floor(diff / 60);
let seconds = Math.floor(time % 60);
hours = hours < 10 ? ("0" + hours) : hours;
mins = mins < 10 ? ("0" + mins) : mins;
seconds = seconds < 10 ? ("0" + seconds) : seconds;
return hours + ":" + mins + ":" + seconds;
}
dealWithTime = (startTime, endTime) => {
const startDate = new Date(Number(startTime));
const endDate = new Date(Number(endTime));
......@@ -64,8 +73,8 @@ class PreviewCourseModal extends React.Component {
render() {
const { courseBasicInfo, courseClassInfo = {}, courseIntroInfo, type,courseState} = this.props;
const { coverUrl, courseName, scheduleVideoUrl } = courseBasicInfo;
const { courseBasicInfo, courseClassInfo = {}, courseIntroInfo, type,courseState,origin} = this.props;
const { coverUrl, courseName, scheduleVideoUrl,videoDuration} = courseBasicInfo;
const { liveDate, calendarTime,startTime,endTime,timeHorizonStart, timeHorizonEnd, teacherName } = courseClassInfo;
const { liveCourseMediaRequests } = courseIntroInfo;
......@@ -128,13 +137,15 @@ class PreviewCourseModal extends React.Component {
<img src={coverUrl} className="course-cover" />
}
</div>
{
type === 'videoCourse' ?
<div className="container__body">
<div className="title__name">{courseName}</div>
<div className="title__inst-name">{window.currentUserInstInfo.name}</div>
</div> :
{videoDuration &&
<div>视频时长:{this.dealTimeDuration(videoDuration)}</div>
}
</div>
:
<div className="container__body">
<div className="container__body__title">
<div className="title__name">{courseName}</div>
......@@ -144,13 +155,11 @@ class PreviewCourseModal extends React.Component {
<span className="time__label">上课时间:</span>
<span className="time__value">
{
[
<span>{liveDateStr}&nbsp;</span>,
<span>{startTimeStr}~{endTimeStr }</span>
]
}
</span>
</div>
<div className="container__body__teacher">
......@@ -161,7 +170,11 @@ class PreviewCourseModal extends React.Component {
}
<div className="container__introduction">
{ type === 'videoCourse' ?
<div className="container__introduction__title">视频简介</div>
:
<div className="container__introduction__title">直播简介</div>
}
<div className="container__introduction__list editor-box">
{
liveCourseMediaRequests.map((item, index) => {
......
......@@ -93,8 +93,8 @@ class ShareLiveModal extends React.Component {
// 如果是默认图, 显示视频的第一帧, 否则显示上传的视频封面
? ((!coverUrl || isDefaultCover)
? `${scheduleVideoUrl}?x-oss-process=video/snapshot,t_0,m_fast&anystring=anystring`
: `${coverUrl}${!needStr ? '&anystring=anystring': ''}`)
: `${coverUrl}${(!needStr && !isDefaultCover) ? '&anystring=anystring' : ''}`
: `${coverUrl}`)
: `${coverUrl}`
return (
......@@ -113,9 +113,14 @@ class ShareLiveModal extends React.Component {
</div>
<div className="course-name-title">{type === 'videoClass' ? `${courseName}开课啦`: `邀请你观看直播:`}</div>
{
type === "liveClass" &&
<div class="live-couse-name">{courseName}</div>
}
<img
src={coverImgSrc}
crossOrigin="*"
className="course-cover"
/>
......@@ -132,13 +137,26 @@ class ShareLiveModal extends React.Component {
<div className="right">
<div className="share-poster right__item">
<div className="title">① 海报分享</div>
<div className="sub-title">学生可通过微信识别二维码,报名观看直播</div>
{ type === "liveClass" &&
<div className="sub-title">用户可通过微信扫描海报二维码,观看直播</div>
}
{ type === "videoClass" &&
<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>
{ type === "liveClass" &&
<div className="sub-title">用户可通过微信打开以下链接,观看直播</div>
}
{ type === "videoClass" &&
<div className="sub-title">用户可通过打开链接,报名观看视频</div>
}
<div className="content">
<div className="share-url" id="shareUrl">{shareUrl}</div>
<Button type="primary" onClick={this.handleCopy}>复制</Button>
......
......@@ -14,6 +14,11 @@
line-height: 20px;
margin-bottom: 4px;
}
.live-couse-name{
font-size:16px;
color:#333333;
font-weight: 600;
}
.course-name {
color: #333;
font-size: 16px;
......
......@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Date: 2020-08-05 10:07:47
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-01-08 17:56:17
* @LastEditTime: 2021-01-18 18:18:49
* @Description: 视频课新增/编辑页
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
......@@ -22,11 +22,23 @@ 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 _ from "underscore";
import './AddVideoCourse.less';
const EDIT_BOX_KEY = Math.random(16);
const EDIT_BOX_KEY = Math.random();
const fieldNames = { label: 'categoryName', value: 'id', children: 'sonCategoryList' };
//添加课程时课程默认的一些值
const defaultShelfState = 'YES';
const defaultScheduleMedia = [{
contentType:'INTRO',
mediaType: 'TEXT',
mediaContent: '',
key: EDIT_BOX_KEY
}]
const whetherVisitorsJoin = 'NO'
class AddVideoCourse extends React.Component {
constructor(props) {
......@@ -39,7 +51,6 @@ class AddVideoCourse extends React.Component {
id, // 视频课ID,编辑的时候从URL上带过来
pageType, // 页面类型: add->新建 edit->编辑
imageFile: null, // 需要被截取的图片
courseName: null, // 视频课名称
scheduleVideoId: null, // 视频课链接
coverId: null, // 视频封面的recourceId
......@@ -50,7 +61,7 @@ class AddVideoCourse extends React.Component {
contentType:"INTRO",
mediaType: 'TEXT',
mediaContent: '',
key: Math.random()
key: EDIT_BOX_KEY
}],
diskList: [], // 机构可见磁盘目录
selectedFileList: [], // 已经从资料云盘中勾选的文件
......@@ -171,12 +182,23 @@ class AddVideoCourse extends React.Component {
categoryName,
categoryId
});
})
}
handleGoBack = () => {
const {
coverId,
videoName,
videoDuration,
courseName,
scheduleMedia,
scheduleVideoId,
categoryId,
shelfState,
whetherVisitorsJoin
} = this.state;
if(videoName || videoDuration || scheduleVideoId || !_.isEqual(scheduleMedia, defaultScheduleMedia) || categoryId || courseName || coverId || shelfState !== defaultShelfState || whetherVisitorsJoin !== whetherVisitorsJoin ){
Modal.confirm({
title: '确认要返回吗?',
content: '返回后,本次编辑的内容将不被保存。',
......@@ -187,6 +209,9 @@ class AddVideoCourse extends React.Component {
RCHistory.goBack();
}
});
}else{
RCHistory.goBack();
}
}
// 修改表单
......@@ -239,15 +264,17 @@ class AddVideoCourse extends React.Component {
coverUrl,
scheduleVideoUrl,
courseName,
scheduleMedia
scheduleMedia,
videoDuration
} = this.state;
const courseBasinInfo = {
coverUrl,
scheduleVideoUrl,
courseName,
videoDuration
}
const courseIntroInfo = {
liveCourseMediaRequests: scheduleMedia
}
......@@ -409,7 +436,7 @@ class AddVideoCourse extends React.Component {
<div className="box">
<div className="show-tips">
<ShowTips message="请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦助教保有依据国家规定及平台规则进行处理的权利" />
<ShowTips message="请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企培保有依据国家规定及平台规则进行处理的权利" />
</div>
<div className="form">
......@@ -483,8 +510,8 @@ class AddVideoCourse extends React.Component {
</div>
</div>
</div>
<div className="course-catalog">
<span className="label"><span className="require">*</span>课程分类:</span>
<div className="course-catalog required">
<span className="label">课程分类:</span>
{ (pageType === 'add') &&
<Cascader defaultValue={[categoryName]} options={courseCatalogList} displayRender={ label => label.join('-')} fieldNames={fieldNames} onChange={this.catalogChange} style={{ width: 240 }} placeholder="请选择课程分类" />
}
......
......@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Date: 2020-08-05 10:11:57
* @LastEditors: zhangleyuan
* @LastEditTime: 2020-12-31 18:27:26
* @LastEditTime: 2021-01-15 13:52:10
* @Description: 视频课-搜索模块
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
......@@ -97,8 +97,10 @@ class VideoCourseFilter extends React.Component {
query.endTime = dates[1].valueOf();
}
this.setState({
query,
query:{
...query,
current: 1,
}
}, () => {
this.props.onChange(this.state.query);
})
......@@ -164,6 +166,18 @@ class VideoCourseFilter extends React.Component {
this.getTeacherList()
})
}}
onClear ={(value)=>{
this.setState({
teacherQuery:{
size: 10,
current: 1,
nickName:null
}
}, () => {
this.getTeacherList()
})
}
}
>
{_.map(teacherList, (item, index) => {
return (
......
/*
* @Author: 吴文洁
* @Date: 2020-08-05 10:12:45
* @LastEditors: wufan
* @LastEditTime: 2021-01-09 13:59:06
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-01-18 21:03:40
* @Description: 视频课-列表模块
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
......@@ -23,7 +23,7 @@ import User from '@/common/js/user'
import './VideoCourseList.less';
const ENV = process.env.DEPLOY_ENV || 'dev';
const ENV = process.env.DEPLOY_ENV || 'prod';
class VideoCourseList extends React.Component {
......@@ -68,14 +68,20 @@ class VideoCourseList extends React.Component {
title: '视频课',
key: 'scheduleName',
dataIndex: 'scheduleName',
width: '20%',
width:'15%',
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">{record.courseName}</span>
{ record.courseName.length > 25?
<Tooltip title={record.courseName}>
<div className="course-name">{record.courseName}</div>
</Tooltip>
:
<div className="course-name">{record.courseName}</div>
}
</div>
)
}
......@@ -84,6 +90,7 @@ class VideoCourseList extends React.Component {
title: '课程分类',
key: 'categoryName',
dataIndex: 'categoryName',
width: '10%',
render: (val, record) => {
return (
<div className="record__item">
......@@ -95,14 +102,30 @@ class VideoCourseList extends React.Component {
{
title: '创建人',
key: 'createName',
dataIndex: 'createName'
dataIndex: 'createName',
width: '8%',
render: (val) => {
return (
<div>
{ val &&
<Tooltip title={val}>
<div>
{val.length > 4 ? `${val.slice(0,4)}...` : val}
</div>
</Tooltip>
}
</div>
)
}
},
{
title: <span>
<span>店铺展示</span>
<Tooltip title="开启后,用户可在店铺内查看到此课程。若课程“未成功开课”,则系统会自动“关闭”店铺展示。关闭后,店铺内不再展示此课程,但用户仍可通过分享的海报/链接查看此课程。"><i className="icon iconfont" style={{ marginLeft: '5px',cursor:'pointer',color:'#bfbfbf'}}>&#xe61d;</i></Tooltip>
<Tooltip title={<div>开启后,用户可在店铺内查看到此课程。若课程“未成功开课”,则系统会自动“关闭”店铺展示。<br/>关闭后,店铺内不再展示此课程,但用户仍可通过分享的海报/链接查看此课程。</div>}><i className="icon iconfont" style={{ marginLeft: '5px',cursor:'pointer',color:'#bfbfbf'}}>&#xe61d;</i></Tooltip>
</span>,
width: "7%",
width: '12%',
dataIndex: "courseware",
render: (val, item, index) => {
return (
......@@ -123,6 +146,7 @@ class VideoCourseList extends React.Component {
},
{
title: '创建时间',
width: "10%",
key: 'created',
dataIndex: 'created',
sorter: true,
......@@ -132,6 +156,7 @@ class VideoCourseList extends React.Component {
},
{
title: '更新时间',
width: "10%",
key: 'updated',
dataIndex: 'updated',
sorter: true,
......@@ -143,6 +168,7 @@ class VideoCourseList extends React.Component {
title: '操作',
key: 'operate',
dataIndex: 'operate',
width: "20%",
render: (val, record) => {
return (
<div className="operate">
......@@ -215,6 +241,8 @@ class VideoCourseList extends React.Component {
title: '你确定要删除此视频课吗?',
content: '删除后,学员将不能进行观看。',
icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>,
okText: '确定',
cancelText: '取消',
onOk: () => {
const param ={
courseId:scheduleId,
......@@ -269,17 +297,17 @@ class VideoCourseList extends React.Component {
const { query } = this.props;
let { order: _order } =query;
// 按创建时间升序排序
if (columnKey === 'createTime' && order === 'ascend') { _order = 'CREATED_ASC'; }
if (columnKey === 'created' && order === 'ascend') { _order = 'CREATED_ASC'; }
// 按创建时间降序排序
if (columnKey === 'createTime' && order === 'descend') { _order = 'CREATED_DESC'; }
if (columnKey === 'created' && order === 'descend') { _order = 'CREATED_DESC'; }
// 按更新时间升序排序
if (columnKey === 'updateTime' && order === 'ascend') { _order = 'UPDATED_ASC'; }
if (columnKey === 'updated' && order === 'ascend') { _order = 'UPDATED_ASC'; }
// 按更新时间降序排序
if (columnKey === 'updateTime' && order === 'descend') { _order = 'UPDATED_DESC'; }
if (columnKey === 'updated' && order === 'descend') { _order = 'UPDATED_DESC'; }
const _query = {
...query,
order: _order
orderEnum: _order
};
this.props.onChange(_query);
}
......
......@@ -2,7 +2,7 @@
margin-top: 12px;
.operate-text {
color: #FF8534;
color: #5289FA;
cursor: pointer;
}
......@@ -10,7 +10,7 @@
display: flex;
&__item {
color: #FF8534;
color: #5289FA;
cursor: pointer;
&.split {
......@@ -19,7 +19,6 @@
}
}
}
.record__item {
display: flex;
......@@ -34,6 +33,13 @@
.course-name {
color: #666;
width:188px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
height:48px;
}
}
}
......@@ -51,3 +57,9 @@
}
}
}
.ant-tooltip{
max-width:700px !important;
}
.ant-tooltip-inner{
max-width:700px !important;
}
\ No newline at end of file
......@@ -76,7 +76,17 @@ class SelectPrepareFileModal extends React.Component {
showNonCompliantFileModal: false,
}
}
componentDidMount() {
const { diskList = [], currentRootDisk} = this.props;
const _currentRootDisk = diskList[0] || currentRootDisk || defaultRootDisk;
this.setState({
query: defaultQuery,
currentRootDisk: _currentRootDisk,
folderPathList: [_currentRootDisk],
}, () => {
this.handleFetchFolderList();
});
}
componentWillReceiveProps(nextProps) {
const { diskList = [], currentRootDisk} = nextProps;
if (nextProps.isOpen) {
......
......@@ -115,7 +115,7 @@ function Login(props) {
<div className="login-page" >
<div className="login-main">
<div className="left-banner">
<div><img src={require("../../common/images/logo.png")} alt="" style={{ width: 60, height: 61 }} /></div>
<div><img src={require("../../common/images/logo.png")} alt="" style={{ width: 60,height:61}} /></div>
<div className="name">小麦企培</div>
<div className="desc">一键开启直播授课 让知识更有价值</div>
</div>
......
......@@ -2,7 +2,7 @@
* @Author: wufan
* @Date: 2020-11-30 10:47:38
* @LastEditors: wufan
* @LastEditTime: 2021-01-03 22:37:32
* @LastEditTime: 2021-01-18 14:53:17
* @Description: web店铺banner页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -269,15 +269,18 @@ class StoreH5Decoration extends React.Component {
},
};
const imgUrl = `${imageFile.ossUrl}?${new Date().getTime()}`
if (!this.state.photoclip) {
const _photoclip = new PhotoClip("#headPicModal", options);
_photoclip.load(imageFile.ossUrl);
_photoclip.load(imgUrl);
this.setState({
photoclip: _photoclip,
});
} else {
this.state.photoclip.clear();
this.state.photoclip.load(imageFile.ossUrl);
this.state.photoclip.load(imgUrl);
}
}, 200);
......
......@@ -2,7 +2,7 @@
* @Author: wufan
* @Date: 2020-11-30 10:47:38
* @LastEditors: wufan
* @LastEditTime: 2021-01-04 11:11:38
* @LastEditTime: 2021-01-18 14:59:57
* @Description: web店铺banner页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -268,15 +268,17 @@ class StoreWebDecoration extends React.Component {
},
};
const imgUrl = `${imageFile.ossUrl}?${new Date().getTime()}`
if (!this.state.photoclip) {
const _photoclip = new PhotoClip("#headPicModal", options);
_photoclip.load(imageFile.ossUrl);
_photoclip.load(imgUrl);
this.setState({
photoclip: _photoclip,
});
} else {
this.state.photoclip.clear();
this.state.photoclip.load(imageFile.ossUrl);
this.state.photoclip.load(imgUrl);
}
}, 200);
......
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