Commit 3934ecf3 by guomingpang

style:修改学院装修裁剪banner尺寸

parent 4fd7b88d
import React, { useEffect, useState } from 'react'
import { TreeSelect } from 'antd'
function CourseCatalogSelect(props) {
let {
courseCatalogList = [],
showSearch = false,
value = '',
treeNodeFilterProp = 'title',
style = { width: 240 },
dropdownStyle = { maxHeight: 300, overflow: 'auto' },
placeholder = '请选择课程类型',
allowClear = true,
onChange = () => {},
} = props
let [treeData, setTreeData] = useState([])
let [defaultValue, setDefaultValue] = useState(null)
console.log('aaaaaaa', courseCatalogList, value)
useEffect(() => {
console.log('useEffect', courseCatalogList, value)
function renderTreeNodes(list) {
let newTreeData = list.map((item) => {
item.title = item.categoryName
item.value = item.id
item.key = item.id
console.log(value, item.value, value === item.value, 'item.categoryName')
if (value === item.value) {
setDefaultValue(item.title)
}
if (item.sonCategoryList) {
item.children = renderTreeNodes(item.sonCategoryList)
}
return item
})
return newTreeData
}
let categoryList = renderTreeNodes(courseCatalogList)
setTreeData(categoryList)
}, [props.value])
return (
<TreeSelect
defaultValue={[defaultValue]}
treeNodeLabelProp='categoryName'
showSearch={showSearch}
treeNodeFilterProp={treeNodeFilterProp}
style={style}
dropdownStyle={dropdownStyle}
treeData={treeData}
placeholder={placeholder}
allowClear={allowClear}
// value={value}
treeDefaultExpandAll
onChange={(value, label) => {
onChange(value, label)
}}
/>
)
}
export default CourseCatalogSelect
export { default as RangePicker } from './DateRangePicker'
export { default as CourseCatalogSelect } from './CourseCatalogSelect'
......@@ -7,41 +7,40 @@
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
import React from 'react';
import { Button, Input, Radio, message, Modal, TreeSelect, Select, Switch, TimePicker, InputNumber, Tooltip } from 'antd';
import $ from 'jquery';
import React from 'react'
import { Button, Input, Radio, message, Modal, Select, Switch, TimePicker, InputNumber, Tooltip } from 'antd'
import $ from 'jquery'
import { CourseCatalogSelect, RangePicker } from '@/modules/common/'
import ShowTips from '@/components/ShowTips'
import Breadcrumbs from '@/components/Breadcrumbs'
import SelectPrepareFileModal from '../../prepare-lesson/modal/SelectPrepareFileModal'
import PreviewOfflineModal from './modal/PreviewOfflineModal'
import StoreService from '@/domains/store-domain/storeService'
import Service from '@/common/js/service'
import { randomString } from '@/domains/basic-domain/utils'
import User from '@/common/js/user'
import _ from 'underscore'
import moment from 'moment'
import Upload from '@/core/upload'
import GraphicsEditor from '../components/GraphicsEditor'
import MultipleDatePicker from '@/components/MultipleDatePicker'
import ImgClipModal from '@/components/ImgClipModal'
import './AddOfflineCourse.less'
import Bus from '@/core/bus'
import RangePicker from '@/modules/common/DateRangePicker';
import ShowTips from '@/components/ShowTips';
import Breadcrumbs from '@/components/Breadcrumbs';
import SelectPrepareFileModal from '../../prepare-lesson/modal/SelectPrepareFileModal';
import PreviewOfflineModal from './modal/PreviewOfflineModal';
import StoreService from '@/domains/store-domain/storeService';
import Service from '@/common/js/service';
import { randomString } from '@/domains/basic-domain/utils';
import User from '@/common/js/user';
import _ from 'underscore';
import moment from 'moment';
import Upload from '@/core/upload';
import GraphicsEditor from '../components/GraphicsEditor';
import MultipleDatePicker from '@/components/MultipleDatePicker';
import ImgClipModal from '@/components/ImgClipModal';
import './AddOfflineCourse.less';
import Bus from '@/core/bus';
const { Option } = Select;
const defaultCoverUrl = 'https://image.xiaomaiketang.com/xm/pxbWKsYA87.png';
const { Option } = Select
const defaultCoverUrl = 'https://image.xiaomaiketang.com/xm/pxbWKsYA87.png'
const unitList = [
{ key: 'HOUR', value: '小时' },
{ key: 'MINUTE', value: '分钟' },
];
]
class AddOfflineCourse extends React.Component {
constructor(props) {
super(props);
super(props)
const courseId = window.getParameterByName('id');
const pageType = window.getParameterByName('type');
const courseId = window.getParameterByName('id')
const pageType = window.getParameterByName('type')
this.state = {
courseId, // 线下课ID,编辑的时候从URL上带过来
......@@ -87,74 +86,74 @@ class AddOfflineCourse extends React.Component {
isEditDisablie: false,
startTime: new Date().getTime() + 300000, // 批量开始时分
endTime: new Date().getTime() + 300000, // 批量结束时分
};
}
}
componentWillMount() {
const { courseId, pageType } = this.state;
this.getCourseCatalogList();
this.getTeacherList();
const { courseId, pageType } = this.state
this.getCourseCatalogList()
this.getTeacherList()
if (pageType === 'edit') {
this.handleFetchScheudleDetail(courseId);
this.handleFetchScheudleDetail(courseId)
}
Bus.bind('editorLimit', (editorTextLength) => {
this.setState({
editorTextLength,
});
});
})
})
}
initBus = () => {
Bus.bind('offlineEditorImage', this.uploadImage);
};
Bus.bind('offlineEditorImage', this.uploadImage)
}
removeBus = () => {
Bus.unbind('offlineEditorImage', this.uploadImage);
};
Bus.unbind('offlineEditorImage', this.uploadImage)
}
uploadImage = () => {
this.setState({ showSelectImageModal: true });
};
this.setState({ showSelectImageModal: true })
}
//获取分类列表
getCourseCatalogList = () => {
Service.Hades('public/hades/queryCategoryTree', { source: 0, tenantId: User.getStoreId(), count: false, userId: User.getUserId() }).then((res) => {
const { categoryList = [] } = res.result;
const { categoryList = [] } = res.result
this.setState({
categoryList,
courseCatalogList: this.renderTreeNodes(categoryList),
});
});
};
})
})
}
renderTreeNodes = (data) => {
let newTreeData = data.map((item) => {
item.title = item.categoryName;
item.value = item.id;
item.key = item.id;
item.title = item.categoryName
item.value = item.id
item.key = item.id
if (item.sonCategoryList) {
item.children = this.renderTreeNodes(item.sonCategoryList);
item.children = this.renderTreeNodes(item.sonCategoryList)
}
return item;
});
return newTreeData;
};
return item
})
return newTreeData
}
checkDetail = (courseId) => {
return Service.Hades('public/hades/getOfflineCourseDetail', {
courseId,
}).then((res) => {
const { courseState } = res.result;
return courseState === 'UN_START';
});
};
const { courseState } = res.result
return courseState === 'UN_START'
})
}
// 获取线下课详情
handleFetchScheudleDetail = (courseId) => {
return Service.Hades('public/hades/getOfflineCourseDetail', {
courseId,
}).then((res) => {
const { result = {} } = res || {};
const { result = {} } = res || {}
const {
courseName,
categoryId,
......@@ -183,29 +182,29 @@ class AddOfflineCourse extends React.Component {
signInType,
signOutType,
whetherHaveApply,
} = result;
let coverId;
let coverUrl = this.state.coverUrl;
let hasIntro = false;
} = result
let coverId
let coverUrl = this.state.coverUrl
let hasIntro = false
courseMediaVOS.map((item) => {
switch (item.contentType) {
case 'COVER':
coverId = item.mediaContent;
coverUrl = item.mediaUrl;
break;
coverId = item.mediaContent
coverUrl = item.mediaUrl
break
case 'SCHEDULE':
this.getTextDetail('courseMedia', item.mediaUrl);
break;
this.getTextDetail('courseMedia', item.mediaUrl)
break
case 'INTRO':
hasIntro = true;
this.getTextDetail('introduce', item.mediaUrl);
break;
hasIntro = true
this.getTextDetail('introduce', item.mediaUrl)
break
default:
break;
break
}
return item;
});
return item
})
this.setState({
loadintroduce: !hasIntro,
coverId,
......@@ -237,9 +236,9 @@ class AddOfflineCourse extends React.Component {
signInType,
signOutType,
isEditDisablie: whetherHaveApply === 'YES',
});
});
};
})
})
}
getTextDetail = (key, url) => {
$.ajax({
......@@ -248,13 +247,13 @@ class AddOfflineCourse extends React.Component {
url,
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
success: (res) => {
this.setState({ [key]: res, [`load${key}`]: true });
this.setState({ [key]: res, [`load${key}`]: true })
},
});
};
})
}
handleGoBack = () => {
const { coverId, videoName, videoDuration, courseName, categoryId, whetherVisitorsJoin } = this.state;
const { coverId, videoName, videoDuration, courseName, categoryId, whetherVisitorsJoin } = this.state
if (videoName || videoDuration || categoryId || courseName || coverId || whetherVisitorsJoin !== whetherVisitorsJoin) {
Modal.confirm({
title: '确认要返回吗?',
......@@ -265,15 +264,15 @@ class AddOfflineCourse extends React.Component {
onOk: () => {
window.RCHistory.push({
pathname: `/offline-course`,
});
})
},
});
})
} else {
window.RCHistory.push({
pathname: `/offline-course`,
});
})
}
};
}
// 显示预览弹窗
handleShowPreviewModal = () => {
......@@ -299,7 +298,7 @@ class AddOfflineCourse extends React.Component {
signOutStartTimeUnit,
signOutEndTimeNum,
signOutEndTimeUnit,
} = this.state;
} = this.state
const data = {
coverUrl,
......@@ -323,27 +322,27 @@ class AddOfflineCourse extends React.Component {
signOutStartTimeUnit,
signOutEndTimeNum,
signOutEndTimeUnit,
};
}
const previewOfflineModal = (
<PreviewOfflineModal
data={data}
close={() => {
this.setState({
previewOfflineModal: null,
});
})
}}
/>
);
)
this.setState({ previewOfflineModal });
};
this.setState({ previewOfflineModal })
}
handleSelectCover = (file) => {
this.setState({
visible: true,
imageFile: file
});
};
imageFile: file,
})
}
//获取resourceId
getSignature = (blob, fileName) => {
......@@ -355,18 +354,18 @@ class AddOfflineCourse extends React.Component {
visible: false,
},
() => this.updateCover()
);
});
};
)
})
}
updateCover = () => {
const { coverClicpPath, coverId } = this.state;
const { coverClicpPath, coverId } = this.state
this.setState({
showSelectCoverModal: false,
coverUrl: coverClicpPath,
coverId: coverId,
});
};
})
}
preSubmit = () => {
//过期判断
......@@ -375,16 +374,16 @@ class AddOfflineCourse extends React.Component {
title: '服务已到期',
content: '当前企业购买的小麦企学院服务已到期,如需继续使用学院功能,请尽快续费购买',
okText: '我知道了',
});
return;
})
return
}
const { courseId } = this.state;
const { courseId } = this.state
if (courseId) {
this.checkDetail(courseId).then((bool) => (bool ? this.handleSubmit() : message.warning('课程已开始,无法继续编辑')));
this.checkDetail(courseId).then((bool) => (bool ? this.handleSubmit() : message.warning('课程已开始,无法继续编辑')))
} else {
this.handleSubmit();
this.handleSubmit()
}
};
}
// 保存
handleSubmit = () => {
......@@ -419,22 +418,22 @@ class AddOfflineCourse extends React.Component {
signOutEndTimeUnit,
// isMore,
editorTextLength,
} = this.state;
} = this.state
let coverObj = {
contentType: 'COVER',
mediaContent: coverId,
mediaType: 'PICTURE',
mediaUrl: coverUrl,
};
let scheduleMediaRequests = [];
}
let scheduleMediaRequests = []
if (coverId) {
scheduleMediaRequests = [coverObj];
scheduleMediaRequests = [coverObj]
}
// 编辑且使用默认图时不传
if (pageType === 'edit' && coverUrl === defaultCoverUrl) {
scheduleMediaRequests = [];
scheduleMediaRequests = []
}
const commonParams = {
categoryId,
......@@ -453,33 +452,33 @@ class AddOfflineCourse extends React.Component {
calendarTime,
editorTextLength,
// isMore,
};
}
if (whetherSetApply === 'YES') {
commonParams.startTimeApply = startTimeApply;
commonParams.endTimeApply = endTimeApply;
commonParams.quota = quota;
commonParams.startTimeApply = startTimeApply
commonParams.endTimeApply = endTimeApply
commonParams.quota = quota
}
if (whetherSetSignIn === 'YES') {
commonParams.signInType = signInType;
commonParams.signInTimeNum = signInTimeNum;
commonParams.signInTimeUnit = signInTimeUnit;
commonParams.signInType = signInType
commonParams.signInTimeNum = signInTimeNum
commonParams.signInTimeUnit = signInTimeUnit
}
if (whetherSetSignOut === 'YES') {
commonParams.signOutType = signOutType;
commonParams.signOutType = signOutType
if (commonParams.signOutType === 'START_LATER') {
commonParams.signOutStartTimeNum = signOutStartTimeNum;
commonParams.signOutStartTimeUnit = signOutStartTimeUnit;
commonParams.signOutStartTimeNum = signOutStartTimeNum
commonParams.signOutStartTimeUnit = signOutStartTimeUnit
}
commonParams.signOutEndTimeNum = signOutEndTimeNum;
commonParams.signOutEndTimeUnit = signOutEndTimeUnit;
commonParams.signOutEndTimeNum = signOutEndTimeNum
commonParams.signOutEndTimeUnit = signOutEndTimeUnit
}
// 校验必填字段:课程名称, 课程线下
this.handleValidate(commonParams).then((res) => {
if (!res) return;
if (!res) return
Upload.uploadTextToOSS(
introduce,
`${randomString()}.txt`,
......@@ -489,182 +488,182 @@ class AddOfflineCourse extends React.Component {
pageType,
commonParams,
introduceId,
});
})
},
() => message.warning('上传课程简介失败')
);
});
};
)
})
}
submitRemote = (data) => {
const { courseId, pageType, commonParams, introduceId } = data;
commonParams.introduceId = introduceId;
const { courseId, pageType, commonParams, introduceId } = data
commonParams.introduceId = introduceId
if (pageType === 'add') {
Service.Hades('public/hades/createOfflineCourse', commonParams).then((res) => {
if (!res) return;
message.success('新建成功');
if (!res) return
message.success('新建成功')
window.RCHistory.push({
pathname: `/offline-course`,
});
});
})
})
} else {
const editParams = {
courseId: courseId,
...commonParams,
};
}
Service.Hades('public/hades/updateOfflineCourse', editParams).then((res) => {
if (!res) return;
message.success('保存成功');
if (!res) return
message.success('保存成功')
window.RCHistory.push({
pathname: `/offline-course`,
});
});
})
})
}
};
}
handleValidate = (data) => {
return new Promise((resolve) => {
if (!data.courseName) {
message.warning('请输入课程名称');
resolve(false);
message.warning('请输入课程名称')
resolve(false)
} else if (!data.categoryId) {
message.warning('请选择课程分类');
resolve(false);
message.warning('请选择课程分类')
resolve(false)
} else if (!data.offlinePlace) {
message.warning('请输入上课地点');
resolve(false);
message.warning('请输入上课地点')
resolve(false)
} else if (!data.teacherId) {
message.warning('请选择讲师');
resolve(false);
message.warning('请选择讲师')
resolve(false)
} else if (_.isEmpty(data.calendarTime)) {
message.warning('请选择上课日期');
resolve(false);
message.warning('请选择上课日期')
resolve(false)
} else if (!data.startTime || !data.endTime) {
message.warning('请选择上课时间');
resolve(false);
message.warning('请选择上课时间')
resolve(false)
} else if (moment(moment(data.calendarTime[0]).format('YYYY-MM-DD') + moment(data.startTime).format(' HH:mm')).valueOf() < Date.now()) {
message.warning('上课时间不能早于现在');
resolve(false);
message.warning('上课时间不能早于现在')
resolve(false)
} else if (data.startTime >= data.endTime) {
message.warning('上课结束时间不能早于上课开始时间');
resolve(false);
message.warning('上课结束时间不能早于上课开始时间')
resolve(false)
} else if (data.whetherSetApply === 'YES' && !data.startTimeApply) {
message.warning('请选择报名时间');
resolve(false);
message.warning('请选择报名时间')
resolve(false)
} else if (data.whetherSetApply === 'YES' && data.startTimeApply >= data.endTimeApply) {
message.warning('报名结束时间需大于报名开始时间');
resolve(false);
message.warning('报名结束时间需大于报名开始时间')
resolve(false)
} else if (
data.whetherSetApply === 'YES' &&
data.endTimeApply > moment(moment(data.calendarTime[0]).format('YYYY-MM-DD') + moment(data.endTime).format(' HH:mm:ss')).valueOf()
) {
message.warning('报名结束时间需小于上课开始时间');
resolve(false);
message.warning('报名结束时间需小于上课开始时间')
resolve(false)
} else if (data.whetherSetSignIn === 'YES' && !data.signInTimeNum) {
message.warning('请输入签到时间');
resolve(false);
message.warning('请输入签到时间')
resolve(false)
} else if (data.whetherSetSignOut === 'YES' && ((data.signOutType === 'START_LATER' && !data.signOutStartTimeNum) || !data.signOutEndTimeNum)) {
message.warning('请输入签退时间');
resolve(false);
message.warning('请输入签退时间')
resolve(false)
} else if (data.editorTextLength > 1000) {
message.warning('课程简介超过字数限定');
resolve(false);
message.warning('课程简介超过字数限定')
resolve(false)
} else {
resolve(true);
resolve(true)
}
});
};
})
}
// 使用默认封面图
handleResetCoverUrl = () => {
const { coverUrl } = this.state;
const isDefaultCover = coverUrl === defaultCoverUrl;
const { coverUrl } = this.state
const isDefaultCover = coverUrl === defaultCoverUrl
// 如果已经是默认图的话,不做任何任何处理
if (isDefaultCover) return;
message.success('已替换为默认图');
this.setState({ coverUrl: defaultCoverUrl });
};
if (isDefaultCover) return
message.success('已替换为默认图')
this.setState({ coverUrl: defaultCoverUrl })
}
// 滑动加载更多讲师列表
handleScrollTeacherList = (e) => {
const { hasNext } = this.state;
const container = e.target;
const { hasNext } = this.state
const container = e.target
//判定元素是否滚动到底部
const scrollToBottom = container && container.scrollHeight <= container.clientHeight + container.scrollTop;
const scrollToBottom = container && container.scrollHeight <= container.clientHeight + container.scrollTop
if (scrollToBottom && hasNext) {
const { teacherQuery } = this.state;
let _teacherQuery = teacherQuery;
_teacherQuery.current = _teacherQuery.current + 1;
const { teacherQuery } = this.state
let _teacherQuery = teacherQuery
_teacherQuery.current = _teacherQuery.current + 1
this.setState(
{
teacherQuery: { ..._teacherQuery },
},
() => {
this.getTeacherList(_teacherQuery.current);
this.getTeacherList(_teacherQuery.current)
}
);
)
}
};
}
getTeacherList(current = 1, selectList) {
const { teacherQuery, teacherList } = this.state;
const { teacherQuery, teacherList } = this.state
const _query = {
...teacherQuery,
current,
size: 15,
};
}
StoreService.getStoreUserBasicPage(_query).then((res) => {
const { result = {} } = res;
const { records = [], hasNext } = result;
const list = current > 1 ? teacherList.concat(records) : records;
const { result = {} } = res
const { records = [], hasNext } = result
const list = current > 1 ? teacherList.concat(records) : records
this.setState({
hasNext,
teacherList: list,
teacherQuery: { ..._query },
});
});
})
})
}
changeIntro = (value) => {
this.setState({ introduce: value });
};
this.setState({ introduce: value })
}
selectMultiDate = (calendarTime) => {
const dateList = _.sortBy(calendarTime);
const dateList = _.sortBy(calendarTime)
this.setState({
calendarTime: dateList,
});
};
})
}
handleChangeDates = (dates) => {
const data = {};
const data = {}
if (_.isEmpty(dates)) {
data.startTimeApply = undefined;
data.endTimeApply = undefined;
data.startTimeApply = undefined
data.endTimeApply = undefined
} else {
data.startTimeApply = dates[0].valueOf();
data.endTimeApply = dates[1].startOf('minute').valueOf() + 59000;
data.startTimeApply = dates[0].valueOf()
data.endTimeApply = dates[1].startOf('minute').valueOf() + 59000
}
this.setState(data);
};
this.setState(data)
}
whetherVisitorsJoinChange = () => {
const {whetherSetApply,whetherVisitorsJoin} =this.state;
if(whetherSetApply =='NO'){
const { whetherSetApply, whetherVisitorsJoin } = this.state
if (whetherSetApply == 'NO') {
message.warning('关闭报名无法获取手机号!')
return
}
if (this.state.whetherVisitorsJoin === 'NO') {
this.setState({ whetherVisitorsJoin: 'YES' });
this.setState({ whetherVisitorsJoin: 'YES' })
} else {
this.setState({ whetherVisitorsJoin: 'NO' });
this.setState({ whetherVisitorsJoin: 'NO' })
}
};
}
handleChangeCatalogList = (value, label) => {
this.setState({ categoryId: value, categoryName: label[0] });
};
this.setState({ categoryId: value, categoryName: label[0] })
}
render() {
const {
......@@ -703,8 +702,8 @@ class AddOfflineCourse extends React.Component {
offlinePlace,
isEditDisablie,
imageFile,
} = this.state;
const isDefaultCover = coverUrl === defaultCoverUrl;
} = this.state
const isDefaultCover = coverUrl === defaultCoverUrl
return (
<div className='page add-offline-course-page'>
<Breadcrumbs navList={pageType === 'add' ? '新建线下课' : '编辑线下课'} goBack={this.handleGoBack} />
......@@ -727,7 +726,7 @@ class AddOfflineCourse extends React.Component {
maxLength={40}
style={{ width: 240 }}
onChange={(e) => {
this.setState({ courseName: e.target.value });
this.setState({ courseName: e.target.value })
}}
/>
</div>
......@@ -740,7 +739,7 @@ class AddOfflineCourse extends React.Component {
onClick={() => {
this.setState({
showSelectCoverModal: true,
});
})
}}>
上传图片
</Button>
......@@ -759,7 +758,12 @@ class AddOfflineCourse extends React.Component {
<span className='label special'>
<span className='require'>*</span>课程分类:
</span>
<TreeSelect
<CourseCatalogSelect
courseCatalogList={courseCatalogList}
value={categoryId}
onChange={(value, label) => this.handleChangeCatalogList(value, label)}
/>
{/* <TreeSelect
showSearch
treeNodeFilterProp='title'
style={{ width: 240 }}
......@@ -772,7 +776,7 @@ class AddOfflineCourse extends React.Component {
onChange={(value, label) => {
this.handleChangeCatalogList(value, label);
}}
/>
/> */}
</div>
<div className='course-catalog'>
<span className='label special'>
......@@ -784,7 +788,7 @@ class AddOfflineCourse extends React.Component {
style={{ width: 240 }}
placeholder='请输入上课地点(40字以内)'
onChange={(e) => {
this.setState({ offlinePlace: e.target.value });
this.setState({ offlinePlace: e.target.value })
}}
/>
</div>
......@@ -808,22 +812,22 @@ class AddOfflineCourse extends React.Component {
}
onChange={(value, option) => {
if (option) {
this.setState({ teacherId: value, teacherName: option.children });
this.setState({ teacherId: value, teacherName: option.children })
} else {
this.setState({ teacherId: value, teacherName: '' });
this.setState({ teacherId: value, teacherName: '' })
}
}}
onSearch={(value) => {
let _teacherQuery = { ...this.state.teacherQuery };
_teacherQuery.nickName = value;
let _teacherQuery = { ...this.state.teacherQuery }
_teacherQuery.nickName = value
this.setState(
{
teacherQuery: _teacherQuery,
},
() => {
this.getTeacherList();
this.getTeacherList()
}
);
)
}}
onClear={(value) => {
this.setState(
......@@ -835,9 +839,9 @@ class AddOfflineCourse extends React.Component {
},
},
() => {
this.getTeacherList();
this.getTeacherList()
}
);
)
}}
getPopupContainer={() => document.getElementById('teacher')}>
{_.map(teacherList, (item) => {
......@@ -845,7 +849,7 @@ class AddOfflineCourse extends React.Component {
<Option value={item.id} key={item.id}>
{item.nickName}
</Option>
);
)
})}
</Select>
</div>
......@@ -863,7 +867,7 @@ class AddOfflineCourse extends React.Component {
content: introduce,
}}
onChange={(val) => {
this.changeIntro(val);
this.changeIntro(val)
}}
/>
)}
......@@ -900,7 +904,7 @@ class AddOfflineCourse extends React.Component {
showNow={false}
style={{ width: 100, minWidth: 100 }}
onSelect={(time) => {
this.setState({ startTime: time });
this.setState({ startTime: time })
}}
getPopupContainer={() => document.getElementById('hour')}
/>
......@@ -914,7 +918,7 @@ class AddOfflineCourse extends React.Component {
showNow={false}
style={{ width: 100, minWidth: 100 }}
onSelect={(time) => {
this.setState({ endTime: time });
this.setState({ endTime: time })
}}
getPopupContainer={() => document.getElementById('hour')}
/>
......@@ -927,7 +931,7 @@ class AddOfflineCourse extends React.Component {
style={{ display: 'inline-block' }}
value={offlineCourseType}
onChange={(e) => {
this.setState({ offlineCourseType: e.target.value });
this.setState({ offlineCourseType: e.target.value })
}}
className='mt5'
disabled={isEditDisablie}>
......@@ -952,8 +956,8 @@ class AddOfflineCourse extends React.Component {
startTimeApply: undefined,
endTimeApply: undefined,
quota: null,
whetherVisitorsJoin: whetherSetApply !== 'YES' ? whetherVisitorsJoin : false
});
whetherVisitorsJoin: whetherSetApply !== 'YES' ? whetherVisitorsJoin : false,
})
}}
/>
<span className='switch-tip'>开启后可设置课程报名时间,获取报名数据</span>
......@@ -968,7 +972,7 @@ class AddOfflineCourse extends React.Component {
value={startTimeApply ? [moment(startTimeApply), moment(endTimeApply)] : null}
format={'YYYY-MM-DD HH:mm'}
onChange={(dates) => {
this.handleChangeDates(dates);
this.handleChangeDates(dates)
}}
renderExtraFooter={() => (
<If condition={calendarTime[0]}>
......@@ -1055,7 +1059,7 @@ class AddOfflineCourse extends React.Component {
style={{ margin: '0 4px', width: 90 }}
disabled={oldQuta < 0}
onChange={(value) => {
this.setState({ quota: value });
this.setState({ quota: value })
}}
/>
<span className='switch-label'></span>
......@@ -1068,7 +1072,9 @@ class AddOfflineCourse extends React.Component {
<span className='label'>观看设置:</span>
<div className='content'>
<Switch checked={whetherVisitorsJoin === 'NO' ? true : false} onChange={this.whetherVisitorsJoinChange} />
<div className='desc'>{whetherVisitorsJoin === 'NO' ? '已开启,仅限绑定了手机号的学员报名线下课' : '已关闭,允许未绑定手机号的学员报名线下课'}</div>
<div className='desc'>
{whetherVisitorsJoin === 'NO' ? '已开启,仅限绑定了手机号的学员报名线下课' : '已关闭,允许未绑定手机号的学员报名线下课'}
</div>
</div>
</div>
<div className='course-catalog'>
......@@ -1083,7 +1089,7 @@ class AddOfflineCourse extends React.Component {
signInType: 'START_AGO',
signInTimeNum: null,
signInTimeUnit: 'MINUTE',
});
})
}}
/>
<span className='switch-tip'>开启后可设置获取签到考勤数据</span>
......@@ -1095,7 +1101,7 @@ class AddOfflineCourse extends React.Component {
style={{ display: 'inline-block' }}
value={signInType}
onChange={(e) => {
this.setState({ signInType: e.target.value });
this.setState({ signInType: e.target.value })
}}
className='mt5'>
<Radio value='START_AGO' className='mr-16'>
......@@ -1117,18 +1123,18 @@ class AddOfflineCourse extends React.Component {
precision={0}
style={{ margin: '0 4px', width: 90 }}
onChange={(value) => {
this.setState({ signInTimeNum: value });
this.setState({ signInTimeNum: value })
}}
/>
<Select
style={{ width: 72, marginRight: 4 }}
value={signInTimeUnit}
onChange={(value) => {
const data = { signInTimeUnit: value };
const data = { signInTimeUnit: value }
if (value === 'HOUR' && signInTimeNum > 24) {
data.signInTimeNum = 24;
data.signInTimeNum = 24
}
this.setState(data);
this.setState(data)
}}>
{unitList.map((item) => (
<Option value={item.key} key={item.key}>
......@@ -1155,7 +1161,7 @@ class AddOfflineCourse extends React.Component {
signOutStartTimeUnit: 'MINUTE',
signOutEndTimeNum: null,
signOutEndTimeUnit: 'MINUTE',
});
})
}}
/>
<span className='switch-tip'>开启后可设置获取签退考勤数据</span>
......@@ -1167,7 +1173,7 @@ class AddOfflineCourse extends React.Component {
style={{ display: 'inline-block' }}
value={signOutType}
onChange={(e) => {
this.setState({ signOutType: e.target.value });
this.setState({ signOutType: e.target.value })
}}
className='mt5'>
<Radio value='START_LATER' className='mr-16'>
......@@ -1190,7 +1196,7 @@ class AddOfflineCourse extends React.Component {
precision={0}
style={{ margin: '0 4px', width: 90 }}
onChange={(value) => {
this.setState({ signOutStartTimeNum: value });
this.setState({ signOutStartTimeNum: value })
}}
/>
)}
......@@ -1199,11 +1205,11 @@ class AddOfflineCourse extends React.Component {
style={{ width: 72, marginRight: 4 }}
value={signOutStartTimeUnit}
onChange={(value) => {
const data = { signOutStartTimeUnit: value };
const data = { signOutStartTimeUnit: value }
if (value === 'HOUR' && signOutStartTimeNum > 24) {
data.signOutStartTimeNum = 24;
data.signOutStartTimeNum = 24
}
this.setState(data);
this.setState(data)
}}>
{unitList.map((item) => (
<Option value={item.key} key={item.key}>
......@@ -1220,18 +1226,18 @@ class AddOfflineCourse extends React.Component {
precision={0}
style={{ margin: '0 4px', width: 90 }}
onChange={(value) => {
this.setState({ signOutEndTimeNum: value });
this.setState({ signOutEndTimeNum: value })
}}
/>
<Select
style={{ width: 72, marginRight: 4 }}
value={signOutEndTimeUnit}
onChange={(value) => {
const data = { signOutEndTimeUnit: value };
const data = { signOutEndTimeUnit: value }
if (value === 'HOUR' && signOutEndTimeNum > 24) {
data.signOutEndTimeNum = 24;
data.signOutEndTimeNum = 24
}
this.setState(data);
this.setState(data)
}}>
{unitList.map((item) => (
<Option value={item.key} key={item.key}>
......@@ -1266,7 +1272,7 @@ class AddOfflineCourse extends React.Component {
tooltip='支持文件类型:jpg、jpeg、png'
isOpen={showSelectCoverModal}
onClose={() => {
this.setState({ showSelectCoverModal: false });
this.setState({ showSelectCoverModal: false })
}}
onSelect={this.handleSelectCover}
/>
......@@ -1277,14 +1283,14 @@ class AddOfflineCourse extends React.Component {
imgUrl={imageFile.ossUrl}
onConfirm={this.getSignature}
onClose={() => {
this.setState({ visible: false });
this.setState({ visible: false })
}}
/>
)}
{this.state.previewOfflineModal}
</div>
);
)
}
}
export default AddOfflineCourse;
export default AddOfflineCourse
......@@ -8,8 +8,9 @@
*/
import React from 'react'
import { Button, Input, message, Modal, Cascader, Tooltip, Form, Popconfirm,Menu,Dropdown} from 'antd'
import { FileTypeIcon, FileVerifyMap } from '@/common/constants/academic/lessonEnum'
import { Button, Input, message, Modal, Tooltip, Form, Popconfirm, Menu, Dropdown } from 'antd'
import { FileTypeIcon } from '@/common/constants/academic/lessonEnum'
import { CourseCatalogSelect } from '@/modules/common/'
import ShowTips from '@/components/ShowTips'
import Breadcrumbs from '@/components/Breadcrumbs'
import moment from 'moment'
......@@ -29,7 +30,7 @@ import $ from 'jquery'
import './AddVideoCourse.less'
import Bus from '@/core/bus'
const { TextArea } = Input;
const { TextArea } = Input
const EDIT_BOX_KEY = Math.random()
const fieldNames = { label: 'categoryName', value: 'id', children: 'sonCategoryList' }
......@@ -40,19 +41,19 @@ const defaultScheduleMedia = [
contentType: 'INTRO',
mediaType: 'TEXT',
mediaContent: '',
key: EDIT_BOX_KEY
}
key: EDIT_BOX_KEY,
},
]
const whetherVisitorsJoin = 'NO'
let cutFlag = false;
let cutFlag = false
const SUPPORT_WORD_PDF = [
"application/msword",
"application/wps-writer",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/pdf",
"application/wps-office.pdf"
];
'application/msword',
'application/wps-writer',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/pdf',
'application/wps-office.pdf',
]
class AddVideoCourse extends React.Component {
constructor(props) {
super(props)
......@@ -75,8 +76,8 @@ class AddVideoCourse extends React.Component {
contentType: 'INTRO',
mediaType: 'TEXT',
mediaContent: '',
key: EDIT_BOX_KEY
}
key: EDIT_BOX_KEY,
},
],
diskList: [], // 机构可见磁盘目录
selectedFileList: [], // 已经从资料云盘中勾选的文件
......@@ -90,12 +91,11 @@ class AddVideoCourse extends React.Component {
showSelectCoverModal: false,
cutImageBlob: null,
introduce: '',
courseChapterList:[
], // 课节列表
courseChapterList: [], // 课节列表
// videoType: "MP4",
mediaNameAlias: '', // 任一视频重命名的名称(气泡框)
selectTypeList:['MP4'],
accept:'video/mp4'
selectTypeList: ['MP4'],
accept: 'video/mp4',
}
}
......@@ -108,41 +108,30 @@ class AddVideoCourse extends React.Component {
Bus.bind('editorLimit', (editorTextLength) => {
this.setState({
editorTextLength,
});
});
})
})
}
//获取分类列表
getCourseCatalogList = () => {
StoreService.getCourseCatalogList({ current: 1, size: 1000 }).then((res) => {
this.setState({
courseCatalogList: res.result.records
courseCatalogList: res.result.records,
})
})
}
catalogChange = (value, _categoryName) => {
const categoryName =_.pluck(_categoryName,'categoryName').join('-')
const changeValueLength = value.length
switch (changeValueLength) {
case 1:
this.setState({ categoryId: value[0], categoryName })
break
case 2:
this.setState({ categoryId: value[1], categoryName })
break
default:
this.setState({ categoryId: null })
break
}
console.log(value, _categoryName)
this.setState({ categoryId: value, categoryName: _categoryName[0] })
}
// 获取线上课详情
handleFetchScheudleDetail = (courseId) => {
CourseService.videoScheduleDetail({
courseId
courseId,
}).then((res) => {
const { result = {} } = res || {}
const { courseName, shelfState, whetherVisitorsJoin, courseMediaVOS, categoryOneName, categoryTwoName, categoryId, courseChapterVOList =[] } = result
const { courseName, shelfState, whetherVisitorsJoin, courseMediaVOS, categoryOneName, categoryTwoName, categoryId, courseChapterVOList = [] } = result
let coverId
let coverUrl
// let videoDuration
......@@ -174,9 +163,9 @@ class AddVideoCourse extends React.Component {
categoryName = `${categoryOneName}`
}
const _courseChapterVOList = courseChapterVOList.map(item => {
item.mediaName = item.name;
item.resourceId = item.id;
const _courseChapterVOList = courseChapterVOList.map((item) => {
item.mediaName = item.name
item.resourceId = item.id
return item
})
......@@ -193,7 +182,7 @@ class AddVideoCourse extends React.Component {
whetherVisitorsJoin,
categoryName,
categoryId,
courseChapterList: _courseChapterVOList
courseChapterList: _courseChapterVOList,
})
})
}
......@@ -206,12 +195,12 @@ class AddVideoCourse extends React.Component {
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
success: (res) => {
this.setState({ [key]: res, [`load${key}`]: true })
}
},
})
}
handleGoBack = () => {
const { coverId,courseName, scheduleMedia, courseChapterList, categoryId, shelfState, whetherVisitorsJoin } = this.state
const { coverId, courseName, scheduleMedia, courseChapterList, categoryId, shelfState, whetherVisitorsJoin } = this.state
if (
!courseChapterList.length ||
!_.isEqual(scheduleMedia, defaultScheduleMedia) ||
......@@ -229,13 +218,13 @@ class AddVideoCourse extends React.Component {
icon: <span className='icon iconfont default-confirm-icon'>&#xe6f4;</span>,
onOk: () => {
window.RCHistory.push({
pathname: `/video-course`
pathname: `/video-course`,
})
}
},
})
} else {
window.RCHistory.push({
pathname: `/video-course`
pathname: `/video-course`,
})
}
}
......@@ -244,7 +233,7 @@ class AddVideoCourse extends React.Component {
handleChangeForm = (field, value, coverUrl) => {
this.setState({
[field]: value,
coverUrl: coverUrl ? coverUrl : this.state.coverUrl
coverUrl: coverUrl ? coverUrl : this.state.coverUrl,
})
}
......@@ -262,7 +251,7 @@ class AddVideoCourse extends React.Component {
studentList={studentList}
close={() => {
this.setState({
studentModal: null
studentModal: null,
})
}}
/>
......@@ -281,7 +270,7 @@ class AddVideoCourse extends React.Component {
// 显示预览弹窗
handleShowPreviewModal = () => {
const { coverUrl, scheduleVideoUrl, courseName, scheduleMedia,introduce, courseChapterList, categoryName } = this.state
const { coverUrl, scheduleVideoUrl, courseName, scheduleMedia, introduce, courseChapterList, categoryName } = this.state
const courseBasinInfo = {
coverUrl,
scheduleVideoUrl,
......@@ -290,7 +279,7 @@ class AddVideoCourse extends React.Component {
const courseIntroInfo = {
liveCourseMediaRequests: scheduleMedia,
introduce,
categoryName
categoryName,
}
const previewCourseModal = (
......@@ -300,7 +289,7 @@ class AddVideoCourse extends React.Component {
courseIntroInfo={courseIntroInfo}
close={() => {
this.setState({
previewCourseModal: null
previewCourseModal: null,
})
}}
courseChapterList={courseChapterList}
......@@ -311,43 +300,42 @@ class AddVideoCourse extends React.Component {
}
// 选择视频
handleSelectVideo = (addFolderIds,selectedFileList) => {
handleSelectVideo = (addFolderIds, selectedFileList) => {
this.setState({
showSelectFileModal: false
showSelectFileModal: false,
})
let { courseChapterList } = this.state;
let _courseChapterList = [...courseChapterList];
let { courseChapterList } = this.state
let _courseChapterList = [...courseChapterList]
if(selectedFileList.length + courseChapterList.length > 20){
message.warning(`最多只能上传20个文件`);
return;
if (selectedFileList.length + courseChapterList.length > 20) {
message.warning(`最多只能上传20个文件`)
return
}
selectedFileList.map((file,index) => {
const { ossUrl, resourceId, folderName, folderFormat, folderSize } = file;
const _mediaName =folderName.replace(`.${_.last(folderName.split('.')).toLowerCase()}`,'')
console.log('folderFormat',folderFormat);
if(folderFormat === 'MP4' || folderFormat === 'video/mp4'){
selectedFileList.map((file, index) => {
const { ossUrl, resourceId, folderName, folderFormat, folderSize } = file
const _mediaName = folderName.replace(`.${_.last(folderName.split('.')).toLowerCase()}`, '')
console.log('folderFormat', folderFormat)
if (folderFormat === 'MP4' || folderFormat === 'video/mp4') {
const videoDom = document.createElement('video')
videoDom.src = ossUrl
videoDom.onloadedmetadata = () => {
_courseChapterList.push({
mediaContent: resourceId,
contentType: 'SCHEDULE',
mediaType: "VIDEO",
mediaType: 'VIDEO',
mediaName: _mediaName,
videoDuration: videoDom.duration,
resourceId,
mediaUrl: ossUrl,
sort: _courseChapterList.length
sort: _courseChapterList.length,
})
this.setState({
courseChapterList: _courseChapterList
courseChapterList: _courseChapterList,
})
}
}else if( folderFormat==="WORD" || folderFormat==="PDF" || SUPPORT_WORD_PDF.indexOf(folderFormat)>-1){
const suffix = _.last(folderName.split('.')).toUpperCase();
} else if (folderFormat === 'WORD' || folderFormat === 'PDF' || SUPPORT_WORD_PDF.indexOf(folderFormat) > -1) {
const suffix = _.last(folderName.split('.')).toUpperCase()
_courseChapterList.push({
mediaContent: resourceId,
contentType: 'SCHEDULE',
......@@ -355,61 +343,60 @@ class AddVideoCourse extends React.Component {
mediaName: _mediaName,
resourceId,
mediaUrl: ossUrl,
sort: _courseChapterList.length
sort: _courseChapterList.length,
})
this.setState({
courseChapterList: _courseChapterList
courseChapterList: _courseChapterList,
})
}
})
}
// 校验课节名称
handleValidateChapterName = (chapterName)=> {
let hasError = false;
return new Promise((resolve) => {
if(!chapterName) {
this.setState({
chapterNameValidateStatus: "error",
chapterNameHelpMsg: '请输入课节名称'
})
hasError = true;
resolve(false)
return false
}
if(chapterName.length > 40) {
this.setState({
chapterNameValidateStatus: "error",
chapterNameHelpMsg: '不要超过40字'
})
hasError = true;
resolve(false)
return false
}
if(!hasError){
resolve(true)
this.setState({
chapterNameValidateStatus: "",
chapterNameHelpMsg: ""
})
}
})
}
// 校验课节名称
handleValidateChapterName = (chapterName) => {
let hasError = false
return new Promise((resolve) => {
if (!chapterName) {
this.setState({
chapterNameValidateStatus: 'error',
chapterNameHelpMsg: '请输入课节名称',
})
hasError = true
resolve(false)
return false
}
if (chapterName.length > 40) {
this.setState({
chapterNameValidateStatus: 'error',
chapterNameHelpMsg: '不要超过40字',
})
hasError = true
resolve(false)
return false
}
if (!hasError) {
resolve(true)
this.setState({
chapterNameValidateStatus: '',
chapterNameHelpMsg: '',
})
}
})
}
// 保存
handleSubmit = () => {
//过期判断
if (User.getExpirationTime() && moment().valueOf() > Number(User.getExpirationTime())) {
Modal.warning({
title:"服务已到期",
content: "当前企业购买的小麦企学院服务已到期,如需继续使用学院功能,请尽快续费购买",
okText: "我知道了"
})
return
}
//过期判断
if (User.getExpirationTime() && moment().valueOf() > Number(User.getExpirationTime())) {
Modal.warning({
title: '服务已到期',
content: '当前企业购买的小麦企学院服务已到期,如需继续使用学院功能,请尽快续费购买',
okText: '我知道了',
})
return
}
const {
id,
......@@ -429,7 +416,7 @@ class AddVideoCourse extends React.Component {
const commonParams = {
// videoName,
videoDuration:0, //后端的必要参数,不能传空
videoDuration: 0, //后端的必要参数,不能传空
scheduleMedia: scheduleMedia.filter((item) => !!item.mediaContent),
categoryId,
courseName,
......@@ -439,7 +426,7 @@ class AddVideoCourse extends React.Component {
shelfState,
whetherVisitorsJoin,
courseType: 'VOICE',
courseChapterList
courseChapterList,
}
// 校验必填字段:课程名称, 课程视频
this.handleValidate(courseName, courseChapterList, categoryId, scheduleMedia, editorTextLength).then((res) => {
......@@ -456,19 +443,19 @@ class AddVideoCourse extends React.Component {
if (!res) return
message.success('新建成功')
window.RCHistory.push({
pathname: `/video-course`
pathname: `/video-course`,
})
})
} else {
const editParams = {
courseId: id,
...commonParams
...commonParams,
}
Service.Hades('public/hades/editVideoSchedule', editParams).then((res) => {
if (!res) return
message.success('保存成功')
window.RCHistory.push({
pathname: `/video-course`
pathname: `/video-course`,
})
})
}
......@@ -492,22 +479,22 @@ class AddVideoCourse extends React.Component {
return false
}
if (editorTextLength > 1000) {
message.warning('课程简介超过字数限定');
resolve(false);
return;
message.warning('课程简介超过字数限定')
resolve(false)
return
}
resolve(true)
})
}
handleSelectCover = (file) => {
if(!file){
message.info("请选择文件!");
return;
if (!file) {
message.info('请选择文件!')
return
}
this.setState({
visible: true,
imageFile:file
});
imageFile: file,
})
}
//获取resourceId
getSignature = (blob, fileName) => {
......@@ -516,7 +503,7 @@ class AddVideoCourse extends React.Component {
{
coverClicpPath: signInfo.fileUrl,
coverId: signInfo.resourceId,
visible: false
visible: false,
},
() => this.updateCover()
)
......@@ -527,43 +514,42 @@ class AddVideoCourse extends React.Component {
this.setState({
showSelectCoverModal: false,
coverUrl: coverClicpPath,
coverId: coverId
coverId: coverId,
})
}
handleRenameCourseChapter = (chapterId, chapterIndex) => {
const { mediaNameAlias } = this.state;
const { mediaNameAlias } = this.state
this.handleValidateChapterName(mediaNameAlias).then(res => {
this.handleValidateChapterName(mediaNameAlias).then((res) => {
// 校验不通过不能点确定保存修改课节名称
if (!res) {
return message.warning('重命名失败');
return message.warning('重命名失败')
}
let { courseChapterList } = this.state;
let _courseChapterList = [];
_courseChapterList = courseChapterList.map((item,index)=>{
if(item.resourceId === chapterId && chapterIndex === index){
item.mediaName = mediaNameAlias;
item.visible = false;
let { courseChapterList } = this.state
let _courseChapterList = []
_courseChapterList = courseChapterList.map((item, index) => {
if (item.resourceId === chapterId && chapterIndex === index) {
item.mediaName = mediaNameAlias
item.visible = false
}
return item
})
this.setState({
courseChapterList: _courseChapterList,
chapterNameValidateStatus: '',
        chapterNameHelpMsg: '',
chapterNameValidateStatus: '',
chapterNameHelpMsg: '',
mediaNameAlias: '',
})
});
})
}
handleChangePopConfirmVisible = (chapterId, chapterNameIndex, visible)=> {
let { courseChapterList } = this.state;
let _courseChapterList = [];
_courseChapterList = courseChapterList.map((item,index)=>{
if(item.resourceId === chapterId && chapterNameIndex === index){
handleChangePopConfirmVisible = (chapterId, chapterNameIndex, visible) => {
let { courseChapterList } = this.state
let _courseChapterList = []
_courseChapterList = courseChapterList.map((item, index) => {
if (item.resourceId === chapterId && chapterNameIndex === index) {
item.visible = visible
} else {
item.visible = false
......@@ -576,119 +562,132 @@ class AddVideoCourse extends React.Component {
}
handleDeleteCourseChapter = (chapterId, chapterIndex) => {
console.log('chapterId---',chapterId, chapterIndex);
let { courseChapterList } = this.state;
let _courseChapterList = courseChapterList.filter((item,index) => {
return item.resourceId !== chapterId || item.resourceId === chapterId && chapterIndex !== index
console.log('chapterId---', chapterId, chapterIndex)
let { courseChapterList } = this.state
let _courseChapterList = courseChapterList.filter((item, index) => {
return item.resourceId !== chapterId || (item.resourceId === chapterId && chapterIndex !== index)
})
_courseChapterList.map((item, index) => {
item.sort = index
})
this.setState({
courseChapterList :_courseChapterList
courseChapterList: _courseChapterList,
})
}
renderChapterTitle = (item) => {
const { chapterNameValidateStatus, chapterNameHelpMsg} = this.state;
const { chapterNameValidateStatus, chapterNameHelpMsg } = this.state
return <div className="course-chapter-title-popover">
<div className="tag-title">课节名称</div>
return (
<div className='course-chapter-title-popover'>
<div className='tag-title'>课节名称</div>
<Form>
<Form.Item
validateStatus={chapterNameValidateStatus}
help={chapterNameHelpMsg}
>
<TextArea
defaultValue={item.mediaName}
placeholder="请输入课节名称"
maxLength={40}
autoSize
style={{ width: '318px'}}
onChange={(e) => {
this.setState({
mediaNameAlias: e.target.value.trim()
}, () => {
this.handleValidateChapterName(this.state.mediaNameAlias)
})
}}
/>
<Form.Item validateStatus={chapterNameValidateStatus} help={chapterNameHelpMsg}>
<TextArea
defaultValue={item.mediaName}
placeholder='请输入课节名称'
maxLength={40}
autoSize
style={{ width: '318px' }}
onChange={(e) => {
this.setState(
{
mediaNameAlias: e.target.value.trim(),
},
() => {
this.handleValidateChapterName(this.state.mediaNameAlias)
}
)
}}
/>
</Form.Item>
</Form>
</Form>
</div>
)
}
// 上下移动
handleChangeIndex = (isUp, sortIndex) => {
const { courseChapterList} = this.state;
// 第一个上移和最后一个下移不能使用
if((isUp && sortIndex === 0) || (!isUp && sortIndex === (courseChapterList.length -1))){
return;
}
let _courseChapterList = [...courseChapterList];
const temp = courseChapterList[sortIndex];
// 若上移
if(isUp){
_courseChapterList[sortIndex -1] = temp;
_courseChapterList[sortIndex -1].sort = sortIndex -1;
_courseChapterList[sortIndex] = courseChapterList[sortIndex - 1];
_courseChapterList[sortIndex].sort = sortIndex;
} else { // 若下移
_courseChapterList[sortIndex + 1] = temp;
_courseChapterList[sortIndex + 1].sort = sortIndex + 1;
_courseChapterList[sortIndex] = courseChapterList[sortIndex + 1];
_courseChapterList[sortIndex].sort = sortIndex;
}
this.setState({
courseChapterList: _courseChapterList
})
// 上下移动
handleChangeIndex = (isUp, sortIndex) => {
const { courseChapterList } = this.state
// 第一个上移和最后一个下移不能使用
if ((isUp && sortIndex === 0) || (!isUp && sortIndex === courseChapterList.length - 1)) {
return
}
renderTypemenu =()=>{
return <Menu>
<Menu.Item>
<span onClick={()=>{this.selectFileType("VIDEO")}}>
视频文件
</span>
</Menu.Item>
<Menu.Item>
<span onClick={()=>{this.selectFileType("WORD_PDF")}}>
资料文件
</span>
</Menu.Item>
</Menu>
let _courseChapterList = [...courseChapterList]
const temp = courseChapterList[sortIndex]
// 若上移
if (isUp) {
_courseChapterList[sortIndex - 1] = temp
_courseChapterList[sortIndex - 1].sort = sortIndex - 1
_courseChapterList[sortIndex] = courseChapterList[sortIndex - 1]
_courseChapterList[sortIndex].sort = sortIndex
} else {
// 若下移
_courseChapterList[sortIndex + 1] = temp
_courseChapterList[sortIndex + 1].sort = sortIndex + 1
_courseChapterList[sortIndex] = courseChapterList[sortIndex + 1]
_courseChapterList[sortIndex].sort = sortIndex
}
selectFileType = (type) =>{
const { courseChapterList } = this.state;
if(courseChapterList.length >= 20) {
message.warning(`最多只能上传20个文件`);
return;
}
if(type==="VIDEO"){
this.setState({
showSelectFileModal: true,
selectTypeList:['MP4'],
accept:'video/mp4'
})
}else{
this.setState({
showSelectFileModal: true,
selectTypeList:['DOC','DOCX','PDF'],
accept:'.doc,.docx,.pdf'
})
}
this.setState({
courseChapterList: _courseChapterList,
})
}
renderTypemenu = () => {
return (
<Menu>
<Menu.Item>
<span
onClick={() => {
this.selectFileType('VIDEO')
}}>
视频文件
</span>
</Menu.Item>
<Menu.Item>
<span
onClick={() => {
this.selectFileType('WORD_PDF')
}}>
资料文件
</span>
</Menu.Item>
</Menu>
)
}
selectFileType = (type) => {
const { courseChapterList } = this.state
if (courseChapterList.length >= 20) {
message.warning(`最多只能上传20个文件`)
return
}
if (type === 'VIDEO') {
this.setState({
showSelectFileModal: true,
selectTypeList: ['MP4'],
accept: 'video/mp4',
})
} else {
this.setState({
showSelectFileModal: true,
selectTypeList: ['DOC', 'DOCX', 'PDF'],
accept: '.doc,.docx,.pdf',
})
}
}
renderToolTipTitle = ()=> {
return (<div>
renderToolTipTitle = () => {
return (
<div>
<p>视频支持mp4格式,大小不超过2G;</p>
<p>文件支持PDF、docx、doc格式,大小不超过100M</p>
</div>)
}
</div>
)
}
render() {
const {
pageType,
......@@ -712,10 +711,11 @@ class AddVideoCourse extends React.Component {
courseChapterList,
imageFile,
selectTypeList,
accept
accept,
categoryId,
} = this.state
const defaultCover = 'https://image.xiaomaiketang.com/xm/TwtGPQGE4K.png';
const isDefaultCover = coverUrl === defaultCover || coverUrl == null;
const defaultCover = 'https://image.xiaomaiketang.com/xm/TwtGPQGE4K.png'
const isDefaultCover = coverUrl === defaultCover || coverUrl == null
return (
<div className='page add-video-course-page'>
......@@ -745,7 +745,7 @@ class AddVideoCourse extends React.Component {
<span className='label required upload-chapter'>上传课节:</span>
</div>
<div className='sub-content'>
<div className="btn-wrap">
<div className='btn-wrap'>
{/* <Button
onClick={() => {
if(courseChapterList.length >= 20) {
......@@ -764,68 +764,87 @@ class AddVideoCourse extends React.Component {
<div className='course-ware--empty'>从资料云盘中选择视频</div>
</div>
<div className='tips'>
课节数量限制20个,文件规格说明
<Tooltip title={this.renderToolTipTitle()} overlayClassName="my-chapter-tooltip">
<i className='icon iconfont' style={{ cursor: 'pointer', color: '#bfbfbf', fontSize: '14px'}}> &#xe61d;</i>
</Tooltip>
课节数量限制20个,文件规格说明
<Tooltip title={this.renderToolTipTitle()} overlayClassName='my-chapter-tooltip'>
<i className='icon iconfont' style={{ cursor: 'pointer', color: '#bfbfbf', fontSize: '14px' }}>
{' '}
&#xe61d;
</i>
</Tooltip>
</div>
</div>
</div>
<If condition={courseChapterList.length > 0}>
<div className="course-chapter-list-wrap">
<div className="course-chapter-total">{`共${courseChapterList.length}个课节`}</div>
<div className='course-chapter-list' id="course-chapter-list">
{
_.map(courseChapterList,(item,index) => {
return <div className='course-ware' key={index}>
<div className="course-ware__index">{index < 9 ? `0${index + 1 } ` : `${index + 1 } `}</div>
<img className='course-ware__img' src={FileTypeIcon[item.mediaType]} alt='' />
<div className='course-ware__name'>{item.mediaName && item.mediaName.length > 24 ? <Tooltip title={item.mediaName}>{item.mediaName}</Tooltip>:item.mediaName}</div>
<div className="course-chapter__opt" id={item.resourceId}>
<div className={`up ${Number(index) === 0 ? 'disabled':''}`} onClick={()=> this.handleChangeIndex(true,item.sort,item.resourceId)}>上移</div>
<div className="line">|</div>
<div className={`down ${Number(index) === (courseChapterList.length - 1) ? 'disabled':''}`} onClick={()=> this.handleChangeIndex(false,item.sort,item.resourceId)}>下移</div>
<div className="line">|</div>
<Popconfirm
placement="topLeft"
className="course-chapter-tooltip"
title={this.renderChapterTitle(item)}
color='#fff' trigger="click"
overlayClassName="chapter-popover"
getPopupContainer={() =>
document.getElementById('course-chapter-list')
}
destroyTooltipOnHide={true}
visible={item.visible}
onConfirm={() => this.handleRenameCourseChapter(item.resourceId, index)}
icon={null}
onVisibleChange={(visible)=>{
!visible && this.setState({
chapterNameValidateStatus: '',
        chapterNameHelpMsg: '',
mediaNameAlias: '',
})
}}
onCancel={()=> this.handleChangePopConfirmVisible(item.resourceId, index, false)}
>
<div className="rename" onClick={() => {this.setState({mediaNameAlias: item.mediaName}, ()=>{
this.handleChangePopConfirmVisible(item.resourceId, index, true)})
}}>重命名</div>
</Popconfirm>
<div className="line">|</div>
<div className="delete" onClick={()=>this.handleDeleteCourseChapter(item.resourceId, index)}>移除</div>
</div>
<div className='course-chapter-list-wrap'>
<div className='course-chapter-total'>{`共${courseChapterList.length}个课节`}</div>
<div className='course-chapter-list' id='course-chapter-list'>
{_.map(courseChapterList, (item, index) => {
return (
<div className='course-ware' key={index}>
<div className='course-ware__index'>{index < 9 ? `0${index + 1} ` : `${index + 1} `}</div>
<img className='course-ware__img' src={FileTypeIcon[item.mediaType]} alt='' />
<div className='course-ware__name'>
{item.mediaName && item.mediaName.length > 24 ? <Tooltip title={item.mediaName}>{item.mediaName}</Tooltip> : item.mediaName}
</div>
})
}
</div>
</div>
</If>
<div className='course-chapter__opt' id={item.resourceId}>
<div
className={`up ${Number(index) === 0 ? 'disabled' : ''}`}
onClick={() => this.handleChangeIndex(true, item.sort, item.resourceId)}>
上移
</div>
<div className='line'>|</div>
<div
className={`down ${Number(index) === courseChapterList.length - 1 ? 'disabled' : ''}`}
onClick={() => this.handleChangeIndex(false, item.sort, item.resourceId)}>
下移
</div>
<div className='line'>|</div>
<Popconfirm
placement='topLeft'
className='course-chapter-tooltip'
title={this.renderChapterTitle(item)}
color='#fff'
trigger='click'
overlayClassName='chapter-popover'
getPopupContainer={() => document.getElementById('course-chapter-list')}
destroyTooltipOnHide={true}
visible={item.visible}
onConfirm={() => this.handleRenameCourseChapter(item.resourceId, index)}
icon={null}
onVisibleChange={(visible) => {
!visible &&
this.setState({
chapterNameValidateStatus: '',
chapterNameHelpMsg: '',
mediaNameAlias: '',
})
}}
onCancel={() => this.handleChangePopConfirmVisible(item.resourceId, index, false)}>
<div
className='rename'
onClick={() => {
this.setState({ mediaNameAlias: item.mediaName }, () => {
this.handleChangePopConfirmVisible(item.resourceId, index, true)
})
}}>
重命名
</div>
</Popconfirm>
<div className='line'>|</div>
<div className='delete' onClick={() => this.handleDeleteCourseChapter(item.resourceId, index)}>
移除
</div>
</div>
</div>
)
})}
</div>
</div>
</If>
<div className='cover-url flex mt16'>
<div className='label cover'>封面图:</div>
<div className='label cover'>封面图:</div>
<div className='cover-url__wrap'>
<div className='opt-btns'>
<div>
......@@ -838,7 +857,7 @@ class AddVideoCourse extends React.Component {
onClick={() => {
this.setState({
coverUrl: '',
coverId: ''
coverId: '',
})
}}>
使用默认图
......@@ -848,9 +867,7 @@ class AddVideoCourse extends React.Component {
</div>
<div className='img-content'>
{
isDefaultCover && <span className="tag">默认图</span>
}
{isDefaultCover && <span className='tag'>默认图</span>}
{/* 如果视频和封面都没有上传的话, 那么就显示缺省, 如果上传了视频, 那么封面图就默认显示视频的第一帧, 如果上传了封面图, 那么就显示上传的封面图 */}
<img src={coverUrl || `https://image.xiaomaiketang.com/xm/TwtGPQGE4K.png`} alt='' />
</div>
......@@ -858,7 +875,7 @@ class AddVideoCourse extends React.Component {
</div>
<div className='course-catalog required'>
<span className='label'>课程分类:</span>
{pageType === 'add' && (
{/* {pageType === 'add' && (
<Cascader
defaultValue={[]}
options={courseCatalogList}
......@@ -889,7 +906,8 @@ class AddVideoCourse extends React.Component {
</span>
}
/>
)}
)} */}
<CourseCatalogSelect courseCatalogList={courseCatalogList} value={categoryId} onChange={this.catalogChange} />
</div>
<div className='intro-info mt16'>
<AddVideoIntro
......@@ -899,7 +917,7 @@ class AddVideoCourse extends React.Component {
shelfState,
whetherVisitorsJoin,
introduce,
loadintroduce
loadintroduce,
}}
onChange={this.handleChangeForm}
/>
......@@ -907,7 +925,7 @@ class AddVideoCourse extends React.Component {
</div>
</div>
<div className="footer shrink-footer">
<div className='footer shrink-footer'>
<Button onClick={this.handleGoBack}>取消</Button>
<Button onClick={this.handleShowPreviewModal}>预览</Button>
<Button type='primary' onClick={_.debounce(() => this.handleSubmit(), 3000, true)}>
......@@ -925,7 +943,7 @@ class AddVideoCourse extends React.Component {
queryTypeEnum={'ONLINE'}
confirm={{
title: '文件过大,无法上传',
content: '上传的视频大小不能超过2G,文件大小不能超过100M'
content: '上传的视频大小不能超过2G,文件大小不能超过100M',
}}
tooltip={''}
isOpen={showSelectFileModal}
......@@ -952,9 +970,16 @@ class AddVideoCourse extends React.Component {
onSelect={this.handleSelectCover}
/>
)}
{ visible &&
<ImgClipModal visible={visible} imgUrl={imageFile.ossUrl} onConfirm={this.getSignature} onClose={()=>{this.setState({ visible: false });}}/>
}
{visible && (
<ImgClipModal
visible={visible}
imgUrl={imageFile.ossUrl}
onConfirm={this.getSignature}
onClose={() => {
this.setState({ visible: false })
}}
/>
)}
{this.state.previewCourseModal}
</div>
)
......
.store-decoration-page {
.box {
padding-top:11px!important;
padding-top: 11px !important;
}
thead {
display: none;
......@@ -27,11 +27,11 @@
}
.banner-thumbnail {
width: 230px;
height: 79px;
height: 96px;
}
.web-banner-thumbnail {
width: 389px;
height: 67px;
height: 162px;
}
.index-num {
......@@ -51,18 +51,17 @@
.operation {
.edit {
color: #2966FF;
color: #2966ff;
cursor: pointer;
}
.divider-line {
color:#BFBFBF
color: #bfbfbf;
}
.delete {
color: #2966FF;
color: #2966ff;
cursor: pointer;
}
}
}
.clip-box {
display: flex;
......@@ -86,7 +85,7 @@
.preview-url {
width: 500px;
height: 73px;
background: #E6E6E6;
background: #e6e6e6;
}
#preview-url-box {
......@@ -112,11 +111,11 @@
}
.banner-thumbnail {
width: 230px;
height: 79px;
height: 96px;
}
.web-banner-thumbnail {
width: 389px;
height: 67px;
height: 162px;
}
.index-num {
height: 33px;
......
......@@ -7,185 +7,164 @@
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React from "react";
import { withRouter } from "react-router-dom";
import _ from "underscore";
import { Modal, message, Button } from "antd";
import StoreService from "@/domains/store-domain/storeService";
import {
sortableContainer,
sortableElement,
sortableHandle,
} from "react-sortable-hoc";
import { MenuOutlined } from "@ant-design/icons";
import arrayMove from "array-move";
import User from "@/common/js/user";
import SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal";
import "./StoreDecorationPage.less";
import Upload from "@/core/upload";
import { XMTable } from '@/components';
import college from '@/common/lottie/college';
import React from 'react'
import { withRouter } from 'react-router-dom'
import _ from 'underscore'
import { Modal, message, Button } from 'antd'
import StoreService from '@/domains/store-domain/storeService'
import { sortableContainer, sortableElement, sortableHandle } from 'react-sortable-hoc'
import { MenuOutlined } from '@ant-design/icons'
import arrayMove from 'array-move'
import User from '@/common/js/user'
import SelectPrepareFileModal from '@/modules/prepare-lesson/modal/SelectPrepareFileModal'
import './StoreDecorationPage.less'
import Upload from '@/core/upload'
import { XMTable } from '@/components'
import college from '@/common/lottie/college'
import ImgClipModal from '@/components/ImgClipModal'
const { confirm } = Modal;
const DragHandle = sortableHandle(() => (
<MenuOutlined
style={{ cursor: "pointer", color: "#999" }}
className="drag-icon"
/>
));
const SortableItem = sortableElement((props) => <tr {...props} />);
const SortableContainer = sortableContainer((props) => <tbody {...props} />);
let cutFlag = false;
const { confirm } = Modal
const DragHandle = sortableHandle(() => <MenuOutlined style={{ cursor: 'pointer', color: '#999' }} className='drag-icon' />)
const SortableItem = sortableElement((props) => <tr {...props} />)
const SortableContainer = sortableContainer((props) => <tbody {...props} />)
let cutFlag = false
class StoreH5Decoration extends React.Component {
constructor(props) {
super(props);
super(props)
this.state = {
storeDecorationlist: [],
query: {
storeId: User.getStoreId(),
termType: "H5_ADMIN",
termType: 'H5_ADMIN',
},
showSelectFileModal: false,
diskList: [],
photoclip: null,
preview: "",
preview: '',
cutImageBlob: null,
hasImgReady: false, // 图片是否上传成功
imageFile: null // 需要被截取的图片
};
imageFile: null, // 需要被截取的图片
}
}
timer = null
componentDidMount() {
this.getStoreDecorationList();
this.getStoreDecorationList()
}
getStoreDecorationList = () => {
StoreService.getStoreDecorationList(this.state.query).then((res) => {
const data = _.map(res.result, (item, index) => {
item.index = index;
item.key = index;
return item;
});
item.index = index
item.key = index
return item
})
this.setState({
storeDecorationlist: data,
});
});
};
})
})
}
parseColumn = () => {
return [
{
title: "Sort",
dataIndex: "sort",
title: 'Sort',
dataIndex: 'sort',
width: 30,
className: "drag-visible",
className: 'drag-visible',
render: () => <DragHandle />,
},
{
title: "sequence",
dataIndex: "sequence",
key: "sequence",
className: "drag-visible",
title: 'sequence',
dataIndex: 'sequence',
key: 'sequence',
className: 'drag-visible',
width: 20,
render: (val, record, index) => {
return <div className="index-num">{index + 1}</div>;
return <div className='index-num'>{index + 1}</div>
},
},
{
title: "banner",
dataIndex: "bannerPath",
key: "bannerPath",
className: "drag-visible",
title: 'banner',
dataIndex: 'bannerPath',
key: 'bannerPath',
className: 'drag-visible',
render: (val) => {
return <img src={val} alt="banner" className="banner-thumbnail" />;
return <img src={val} alt='banner' className='banner-thumbnail' />
},
},
{
title: "操作",
dataIndex: "operation",
width: "20%",
title: '操作',
dataIndex: 'operation',
width: '20%',
render: (val, record, index) => {
return (
<div className="operation">
<span
className="edit"
onClick={() => this.handleReplaceDecoration(record,index)}
>
<div className='operation'>
<span className='edit' onClick={() => this.handleReplaceDecoration(record, index)}>
替换
</span>
<span className="divider-line">{" | "}</span>
<span
className="delete"
onClick={() => this.handleDeleteDecorationConfirm(record)}
>
<span className='divider-line'>{' | '}</span>
<span className='delete' onClick={() => this.handleDeleteDecorationConfirm(record)}>
删除
</span>
</div>
);
)
},
},
];
};
]
}
handleToAddStoreDecoration = () => {
const { choosedBannerId } = this.state;
const { choosedBannerId } = this.state
if (this.state.storeDecorationlist.length >= 5 && !choosedBannerId) {
message.info("最多可添加5条");
return;
message.info('最多可添加5条')
return
}
this.setState({
showSelectFileModal: true,
choosedBannerId: ""
});
};
choosedBannerId: '',
})
}
handleReplaceDecoration = (record, index) => {
this.setState({
showSelectFileModal: true,
choosedBannerId: record.id,
choosedBannerItem:record
});
};
choosedBannerItem: record,
})
}
handleDeleteDecoration = (record) => {
StoreService.deleteStoreDecorationList({
storeBannerId: record.id,
termType: "H5_ADMIN",
termType: 'H5_ADMIN',
}).then((res) => {
message.success("已删除");
this.getStoreDecorationList();
});
};
message.success('已删除')
this.getStoreDecorationList()
})
}
handleDeleteDecorationConfirm = (record) => {
return confirm({
title: "你确定要删除这个banner吗?",
icon: (
<span className="icon iconfont default-confirm-icon">&#xe839; </span>
),
okText: "删除",
title: '你确定要删除这个banner吗?',
icon: <span className='icon iconfont default-confirm-icon'>&#xe839; </span>,
okText: '删除',
okType: 'danger',
cancelText: "取消",
cancelText: '取消',
onOk: () => {
this.handleDeleteDecoration(record);
this.handleDeleteDecoration(record)
},
});
};
})
}
onSortEnd = ({ oldIndex, newIndex }) => {
const { storeDecorationlist } = this.state;
const { storeDecorationlist } = this.state
if (oldIndex !== newIndex) {
const newData = arrayMove(
[].concat(storeDecorationlist),
oldIndex,
newIndex
).filter((el) => !!el);
const newData = arrayMove([].concat(storeDecorationlist), oldIndex, newIndex).filter((el) => !!el)
this.setState(
{
storeDecorationlist: newData,
......@@ -193,132 +172,108 @@ class StoreH5Decoration extends React.Component {
storeBannerId: storeDecorationlist[oldIndex].id,
},
() => {
this.moveBannerSequence();
this.moveBannerSequence()
}
);
)
}
};
}
DraggableBodyRow = ({ className, style, ...restProps }) => {
const { storeDecorationlist } = this.state;
const { storeDecorationlist } = this.state
// function findIndex base on Table rowKey props and should always be a right array index
const index = storeDecorationlist.findIndex(
(x) => x.index === restProps["data-row-key"]
);
return <SortableItem index={index} {...restProps} />;
};
const index = storeDecorationlist.findIndex((x) => x.index === restProps['data-row-key'])
return <SortableItem index={index} {...restProps} />
}
// 选择云盘资源
handleSelectImg = (file) => {
if(file){
if (file) {
this.setState({
visible: true,
imageFile:file
});
imageFile: file,
})
}
};
}
//获取resourceId
getSignature = (blob) => {
Upload.uploadBlobToOSS(blob, "avatar" + new Date().valueOf()).then(
(addBannerPath) => {
this.setState({
Upload.uploadBlobToOSS(blob, 'avatar' + new Date().valueOf()).then((addBannerPath) => {
this.setState(
{
addBannerPath,
visible: false
}, () => {
this.state.choosedBannerId
? this.editStoreBanner()
: this.addStoreBanner();
});
}
);
};
visible: false,
},
() => {
this.state.choosedBannerId ? this.editStoreBanner() : this.addStoreBanner()
}
)
})
}
editStoreBanner = () => {
const { addBannerPath, choosedBannerId } = this.state;
const { addBannerPath, choosedBannerId } = this.state
const params = {
bannerPath: addBannerPath,
storeBannerId: choosedBannerId,
termType: "H5_ADMIN",
};
termType: 'H5_ADMIN',
}
StoreService.editStoreBanner(params).then((res) => {
message.success("设置成功");
this.getStoreDecorationList();
});
};
message.success('设置成功')
this.getStoreDecorationList()
})
}
moveBannerSequence = () => {
const { newSequence, storeBannerId } = this.state;
const { newSequence, storeBannerId } = this.state
const params = {
sequence: newSequence,
storeBannerId: storeBannerId,
termType: "H5_ADMIN",
};
termType: 'H5_ADMIN',
}
StoreService.moveBannerSequence(params).then((res) => {
this.getStoreDecorationList();
});
};
this.getStoreDecorationList()
})
}
addStoreBanner = () => {
const { addBannerPath } = this.state;
const { addBannerPath } = this.state
const params = {
bannerPath: addBannerPath,
storeId: User.getStoreId(),
termType: "H5_ADMIN",
};
termType: 'H5_ADMIN',
}
StoreService.addStoreBanner(params).then((res) => {
message.success("设置成功");
this.getStoreDecorationList();
});
};
message.success('设置成功')
this.getStoreDecorationList()
})
}
render() {
const {
storeDecorationlist,
showSelectFileModal,
diskList,
visible,
cutImageBlob,
hasImgReady,
imageFile,
} = this.state;
const DraggableContainer = (props) => (
<SortableContainer
useDragHandle
helperClass="row-dragging"
onSortEnd={this.onSortEnd}
{...props}
/>
);
const { storeDecorationlist, showSelectFileModal, diskList, visible, cutImageBlob, hasImgReady, imageFile } = this.state
const DraggableContainer = (props) => <SortableContainer useDragHandle helperClass='row-dragging' onSortEnd={this.onSortEnd} {...props} />
return (
<div className="store-decoration-h5-page">
<div className="box-header">
<div className="banner-setting">
<div className="title">banner设置</div>
<div className="tip">
图片支持bmp、jpeg、jpg、png、gif格式,最大5M,最多可添加5张,拖动可排序。建议尺寸750*252px。
</div>
<div className='store-decoration-h5-page'>
<div className='box-header'>
<div className='banner-setting'>
<div className='title'>banner设置</div>
<div className='tip'>图片支持bmp、jpeg、jpg、png、gif格式,最大5M,最多可添加5张,拖动可排序。建议尺寸750*252px。</div>
</div>
<Button
onClick={() => {
this.handleToAddStoreDecoration();
this.handleToAddStoreDecoration()
}}
type="primary"
className="add-show-btn"
>
type='primary'
className='add-show-btn'>
添加Banner
</Button>
</div>
<div className="box-body">
<XMTable
<div className='box-body'>
<XMTable
renderEmpty={{
image: college,
description: '暂无数据'
description: '暂无数据',
}}
size={"middle"}
size={'middle'}
pagination={false}
dataSource={storeDecorationlist}
columns={this.parseColumn()}
......@@ -333,23 +288,32 @@ class StoreH5Decoration extends React.Component {
/>
</div>
<SelectPrepareFileModal
operateType="select"
accept="image/jpeg,image/png,image/jpg"
selectTypeList={["JPG", "JPEG", "PNG"]}
tooltip="支持文件类型:jpg、jpeg、png"
operateType='select'
accept='image/jpeg,image/png,image/jpg'
selectTypeList={['JPG', 'JPEG', 'PNG']}
tooltip='支持文件类型:jpg、jpeg、png'
isOpen={showSelectFileModal}
diskList={diskList}
onClose={() => {
this.setState({ showSelectFileModal: false });
this.setState({ showSelectFileModal: false })
}}
onSelect={this.handleSelectImg}
/>
{ visible &&
<ImgClipModal visible={visible} imgUrl={imageFile.ossUrl} aspectRatio='500/172' cropBoxHeight='172' onConfirm={this.getSignature} onClose={()=>{this.setState({ visible: false });}}/>
}
{visible && (
<ImgClipModal
visible={visible}
imgUrl={imageFile.ossUrl}
aspectRatio='500/169'
cropBoxHeight='169'
onConfirm={this.getSignature}
onClose={() => {
this.setState({ visible: false })
}}
/>
)}
</div>
);
)
}
}
export default withRouter(StoreH5Decoration);
export default withRouter(StoreH5Decoration)
......@@ -7,184 +7,163 @@
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import React from "react";
import { withRouter } from "react-router-dom";
import _ from "underscore";
import { Modal, message, Button } from "antd";
import StoreService from "@/domains/store-domain/storeService";
import {
sortableContainer,
sortableElement,
sortableHandle,
} from "react-sortable-hoc";
import { MenuOutlined } from "@ant-design/icons";
import arrayMove from "array-move";
import User from "@/common/js/user";
import SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal";
import "./StoreDecorationPage.less";
import Upload from "@/core/upload";
import { XMTable } from '@/components';
import college from '@/common/lottie/college';
import React from 'react'
import { withRouter } from 'react-router-dom'
import _ from 'underscore'
import { Modal, message, Button } from 'antd'
import StoreService from '@/domains/store-domain/storeService'
import { sortableContainer, sortableElement, sortableHandle } from 'react-sortable-hoc'
import { MenuOutlined } from '@ant-design/icons'
import arrayMove from 'array-move'
import User from '@/common/js/user'
import SelectPrepareFileModal from '@/modules/prepare-lesson/modal/SelectPrepareFileModal'
import './StoreDecorationPage.less'
import Upload from '@/core/upload'
import { XMTable } from '@/components'
import college from '@/common/lottie/college'
import ImgClipModal from '@/components/ImgClipModal'
const { confirm } = Modal;
const DragHandle = sortableHandle(() => (
<MenuOutlined
style={{ cursor: "pointer", color: "#999" }}
className="drag-icon"
/>
));
const SortableItem = sortableElement((props) => <tr {...props} />);
const SortableContainer = sortableContainer((props) => <tbody {...props} />);
let cutFlag = false;
const { confirm } = Modal
const DragHandle = sortableHandle(() => <MenuOutlined style={{ cursor: 'pointer', color: '#999' }} className='drag-icon' />)
const SortableItem = sortableElement((props) => <tr {...props} />)
const SortableContainer = sortableContainer((props) => <tbody {...props} />)
let cutFlag = false
class StoreWebDecoration extends React.Component {
constructor(props) {
super(props);
super(props)
this.state = {
storeDecorationlist: [],
query: {
storeId: User.getStoreId(),
termType: "WEB_ADMIN",
termType: 'WEB_ADMIN',
},
showSelectFileModal: false,
diskList: [],
photoclip: null,
preview: "",
preview: '',
cutImageBlob: null,
hasImgReady: false,// 图片是否上传成功
imageFile: null // 需要被截取的图片
};
hasImgReady: false, // 图片是否上传成功
imageFile: null, // 需要被截取的图片
}
}
timer = null
componentDidMount() {
this.getStoreDecorationList();
this.getStoreDecorationList()
}
getStoreDecorationList = () => {
StoreService.getStoreDecorationList(this.state.query).then((res) => {
const data = _.map(res.result, (item, index) => {
item.index = index;
item.key = index;
return item;
});
item.index = index
item.key = index
return item
})
this.setState({
storeDecorationlist: data,
});
});
};
})
})
}
parseColumn = () => {
return [
{
title: "Sort",
dataIndex: "sort",
title: 'Sort',
dataIndex: 'sort',
width: 30,
className: "drag-visible",
className: 'drag-visible',
render: () => <DragHandle />,
},
{
title: "sequence",
dataIndex: "sequence",
key: "sequence",
className: "drag-visible",
title: 'sequence',
dataIndex: 'sequence',
key: 'sequence',
className: 'drag-visible',
width: 20,
render: (val, record, index) => {
return <div className="index-num">{index + 1}</div>;
return <div className='index-num'>{index + 1}</div>
},
},
{
title: "banner",
dataIndex: "bannerPath",
key: "bannerPath",
className: "drag-visible",
title: 'banner',
dataIndex: 'bannerPath',
key: 'bannerPath',
className: 'drag-visible',
render: (val) => {
return <img src={val} alt="banner" className="web-banner-thumbnail" />;
return <img src={val} alt='banner' className='web-banner-thumbnail' />
},
},
{
title: "操作",
dataIndex: "operation",
width: "20%",
title: '操作',
dataIndex: 'operation',
width: '20%',
render: (val, record) => {
return (
<div className="operation">
<span
className="edit"
onClick={() => this.handleReplaceDecoration(record)}
>
<div className='operation'>
<span className='edit' onClick={() => this.handleReplaceDecoration(record)}>
替换
</span>
<span className="divider-line">{" | "}</span>
<span
className="delete"
onClick={() => this.handleDeleteDecorationConfirm(record)}
>
<span className='divider-line'>{' | '}</span>
<span className='delete' onClick={() => this.handleDeleteDecorationConfirm(record)}>
删除
</span>
</div>
);
)
},
},
];
};
]
}
handleToAddStoreDecoration = () => {
const { choosedBannerId } = this.state;
const { choosedBannerId } = this.state
if (this.state.storeDecorationlist.length >= 5 && !choosedBannerId) {
message.info("最多可添加5条");
return;
message.info('最多可添加5条')
return
}
this.setState({
showSelectFileModal: true,
choosedBannerId: ""
});
};
choosedBannerId: '',
})
}
handleReplaceDecoration = (record) => {
this.setState({
showSelectFileModal: true,
choosedBannerId: record.id,
choosedBannerItem:record
});
};
choosedBannerItem: record,
})
}
handleDeleteDecoration = (record) => {
StoreService.deleteStoreDecorationList({
storeBannerId: record.id,
termType: "WEB_ADMIN",
termType: 'WEB_ADMIN',
}).then((res) => {
message.success("已删除");
this.getStoreDecorationList();
});
};
message.success('已删除')
this.getStoreDecorationList()
})
}
handleDeleteDecorationConfirm = (record) => {
return confirm({
title: "你确定要删除这个banner吗?",
icon: (
<span className="icon iconfont default-confirm-icon">&#xe839; </span>
),
okText: "删除",
title: '你确定要删除这个banner吗?',
icon: <span className='icon iconfont default-confirm-icon'>&#xe839; </span>,
okText: '删除',
okType: 'danger',
cancelText: "取消",
cancelText: '取消',
onOk: () => {
this.handleDeleteDecoration(record);
this.handleDeleteDecoration(record)
},
});
};
})
}
onSortEnd = ({ oldIndex, newIndex }) => {
const { storeDecorationlist } = this.state;
const { storeDecorationlist } = this.state
if (oldIndex !== newIndex) {
const newData = arrayMove(
[].concat(storeDecorationlist),
oldIndex,
newIndex
).filter((el) => !!el);
const newData = arrayMove([].concat(storeDecorationlist), oldIndex, newIndex).filter((el) => !!el)
this.setState(
{
storeDecorationlist: newData,
......@@ -192,131 +171,107 @@ class StoreWebDecoration extends React.Component {
storeBannerId: storeDecorationlist[oldIndex].id,
},
() => {
this.moveBannerSequence();
this.moveBannerSequence()
}
);
)
}
};
}
DraggableBodyRow = ({ className, style, ...restProps }) => {
const { storeDecorationlist } = this.state;
const { storeDecorationlist } = this.state
// function findIndex base on Table rowKey props and should always be a right array index
const index = storeDecorationlist.findIndex(
(x) => x.index === restProps["data-row-key"]
);
return <SortableItem index={index} {...restProps} />;
};
const index = storeDecorationlist.findIndex((x) => x.index === restProps['data-row-key'])
return <SortableItem index={index} {...restProps} />
}
// 选择云盘资源
handleSelectImg = (file) => {
if(file){
if (file) {
this.setState({
visible: true,
imageFile:file
});
imageFile: file,
})
}
};
}
//获取resourceId
getSignature = (blob) => {
Upload.uploadBlobToOSS(blob, "avatar" + new Date().valueOf()).then(
(addBannerPath) => {
this.setState({
Upload.uploadBlobToOSS(blob, 'avatar' + new Date().valueOf()).then((addBannerPath) => {
this.setState(
{
addBannerPath,
visible: false
}, () => {
this.state.choosedBannerId
? this.editStoreBanner()
: this.addStoreBanner();
});
}
);
};
visible: false,
},
() => {
this.state.choosedBannerId ? this.editStoreBanner() : this.addStoreBanner()
}
)
})
}
editStoreBanner = () => {
const { addBannerPath, choosedBannerId } = this.state;
const { addBannerPath, choosedBannerId } = this.state
const params = {
bannerPath: addBannerPath,
storeBannerId: choosedBannerId,
termType: "WEB_ADMIN",
};
termType: 'WEB_ADMIN',
}
StoreService.editStoreBanner(params).then((res) => {
message.success("设置成功");
this.getStoreDecorationList();
});
};
message.success('设置成功')
this.getStoreDecorationList()
})
}
moveBannerSequence = () => {
const { newSequence, storeBannerId } = this.state;
const { newSequence, storeBannerId } = this.state
const params = {
sequence: newSequence,
storeBannerId: storeBannerId,
termType: "WEB_ADMIN",
};
termType: 'WEB_ADMIN',
}
StoreService.moveBannerSequence(params).then((res) => {
this.getStoreDecorationList();
});
};
this.getStoreDecorationList()
})
}
addStoreBanner = () => {
const { addBannerPath } = this.state;
const { addBannerPath } = this.state
const params = {
bannerPath: addBannerPath,
storeId: User.getStoreId(),
termType: "WEB_ADMIN",
};
termType: 'WEB_ADMIN',
}
StoreService.addStoreBanner(params).then((res) => {
message.success("设置成功");
this.getStoreDecorationList();
});
};
message.success('设置成功')
this.getStoreDecorationList()
})
}
render() {
const {
storeDecorationlist,
showSelectFileModal,
diskList,
visible,
cutImageBlob,
hasImgReady,
imageFile
} = this.state;
const DraggableContainer = (props) => (
<SortableContainer
useDragHandle
helperClass="row-dragging"
onSortEnd={this.onSortEnd}
{...props}
/>
);
const { storeDecorationlist, showSelectFileModal, diskList, visible, cutImageBlob, hasImgReady, imageFile } = this.state
const DraggableContainer = (props) => <SortableContainer useDragHandle helperClass='row-dragging' onSortEnd={this.onSortEnd} {...props} />
return (
<div className="store-decoration-web-page">
<div className="box-header">
<div className="banner-setting">
<div className="title">banner设置</div>
<div className="tip">
图片支持bmp、jpeg、jpg、png、gif格式,最大5M,最多可添加5张,拖动可排序。建议尺寸1232*212px。
</div>
<div className='store-decoration-web-page'>
<div className='box-header'>
<div className='banner-setting'>
<div className='title'>banner设置</div>
<div className='tip'>图片支持bmp、jpeg、jpg、png、gif格式,最大5M,最多可添加5张,拖动可排序。建议尺寸1232*212px。</div>
</div>
<Button
onClick={() => {
this.handleToAddStoreDecoration();
this.handleToAddStoreDecoration()
}}
type="primary"
className="add-show-btn"
>
type='primary'
className='add-show-btn'>
添加Banner
</Button>
</div>
<div className="box-body">
<XMTable
<div className='box-body'>
<XMTable
renderEmpty={{
image: college,
description: '暂无数据'
description: '暂无数据',
}}
size={"middle"}
size={'middle'}
pagination={false}
dataSource={storeDecorationlist}
columns={this.parseColumn()}
......@@ -331,23 +286,32 @@ class StoreWebDecoration extends React.Component {
/>
</div>
<SelectPrepareFileModal
operateType="select"
accept="image/jpeg,image/png,image/jpg"
selectTypeList={["JPG", "JPEG", "PNG"]}
tooltip="支持文件类型:jpg、jpeg、png"
operateType='select'
accept='image/jpeg,image/png,image/jpg'
selectTypeList={['JPG', 'JPEG', 'PNG']}
tooltip='支持文件类型:jpg、jpeg、png'
isOpen={showSelectFileModal}
diskList={diskList}
onClose={() => {
this.setState({ showSelectFileModal: false });
this.setState({ showSelectFileModal: false })
}}
onSelect={this.handleSelectImg}
/>
{ visible &&
<ImgClipModal visible={visible} imgUrl={imageFile.ossUrl} aspectRatio='500/73' cropBoxHeight='73' onConfirm={this.getSignature} onClose={()=>{this.setState({ visible: false });}}/>
}
{visible && (
<ImgClipModal
visible={visible}
imgUrl={imageFile.ossUrl}
aspectRatio='500/134'
cropBoxHeight='134'
onConfirm={this.getSignature}
onClose={() => {
this.setState({ visible: false })
}}
/>
)}
</div>
);
)
}
}
export default withRouter(StoreWebDecoration);
export default withRouter(StoreWebDecoration)
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