Commit df1c6376 by guomingpang

fix:线下课新建分类

parent 6a729fcf
...@@ -2,17 +2,19 @@ ...@@ -2,17 +2,19 @@
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-08-05 10:07:47 * @Date: 2020-08-05 10:07:47
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-07-22 18:33:14 * @LastEditTime: 2021-07-15 12:04:00
* @Description: 线下课新增/编辑页 * @Description: 线下课新增/编辑页
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
*/ */
import React from 'react' import React from 'react'
import { Button, Input, Radio, message, Modal, Select, Switch, TimePicker, InputNumber, Tooltip } from 'antd' import { Button, Input, Radio, message, Modal, TreeSelect, Select, Switch, TimePicker, InputNumber, Tooltip } from 'antd'
import $ from 'jquery' import $ from 'jquery'
import { CourseCatalogSelect, RangePicker } from '@/modules/common/'
import RangePicker from '@/modules/common/DateRangePicker'
import ShowTips from '@/components/ShowTips' import ShowTips from '@/components/ShowTips'
import Breadcrumbs from '@/components/Breadcrumbs' import Breadcrumbs from '@/components/Breadcrumbs'
import SelectStudent from '../modal/select-student'
import SelectPrepareFileModal from '../../prepare-lesson/modal/SelectPrepareFileModal' import SelectPrepareFileModal from '../../prepare-lesson/modal/SelectPrepareFileModal'
import PreviewOfflineModal from './modal/PreviewOfflineModal' import PreviewOfflineModal from './modal/PreviewOfflineModal'
import StoreService from '@/domains/store-domain/storeService' import StoreService from '@/domains/store-domain/storeService'
...@@ -24,12 +26,12 @@ import moment from 'moment' ...@@ -24,12 +26,12 @@ import moment from 'moment'
import Upload from '@/core/upload' import Upload from '@/core/upload'
import GraphicsEditor from '../components/GraphicsEditor' import GraphicsEditor from '../components/GraphicsEditor'
import MultipleDatePicker from '@/components/MultipleDatePicker' import MultipleDatePicker from '@/components/MultipleDatePicker'
import ImgClipModal from '@/components/ImgClipModal'
import './AddOfflineCourse.less' import './AddOfflineCourse.less'
import Bus from '@/core/bus' import Bus from '@/core/bus'
const { Option } = Select const { Option } = Select
const defaultCoverUrl = 'https://image.xiaomaiketang.com/xm/pxbWKsYA87.png' const defaultCoverUrl = 'https://image.xiaomaiketang.com/xm/pxbWKsYA87.png'
let cutFlag = false
const unitList = [ const unitList = [
{ key: 'HOUR', value: '小时' }, { key: 'HOUR', value: '小时' },
{ key: 'MINUTE', value: '分钟' }, { key: 'MINUTE', value: '分钟' },
...@@ -39,8 +41,8 @@ class AddOfflineCourse extends React.Component { ...@@ -39,8 +41,8 @@ class AddOfflineCourse extends React.Component {
constructor(props) { constructor(props) {
super(props) super(props)
const courseId = window.getParameterByName('id') const courseId = getParameterByName('id')
const pageType = window.getParameterByName('type') const pageType = getParameterByName('type')
this.state = { this.state = {
courseId, // 线下课ID,编辑的时候从URL上带过来 courseId, // 线下课ID,编辑的时候从URL上带过来
...@@ -156,6 +158,7 @@ class AddOfflineCourse extends React.Component { ...@@ -156,6 +158,7 @@ class AddOfflineCourse extends React.Component {
const { result = {} } = res || {} const { result = {} } = res || {}
const { const {
courseName, courseName,
courseState,
categoryId, categoryId,
offlinePlace, offlinePlace,
whetherVisitorsJoin, whetherVisitorsJoin,
...@@ -338,10 +341,79 @@ class AddOfflineCourse extends React.Component { ...@@ -338,10 +341,79 @@ class AddOfflineCourse extends React.Component {
} }
handleSelectCover = (file) => { handleSelectCover = (file) => {
this.setState({ this.uploadCoverImage(file)
visible: true, }
imageFile: file,
}) //上传图片
uploadCoverImage = (imageFile) => {
const { folderName } = imageFile
const fileName = window.random_string(16) + folderName.slice(folderName.lastIndexOf('.'))
const self = this
this.setState(
{
visible: true,
},
() => {
setTimeout(() => {
const okBtnDom = document.querySelector('#headPicModal')
const options = {
size: [500, 282],
ok: okBtnDom,
maxZoom: 3,
style: {
jpgFillColor: 'transparent',
},
done: function (dataUrl) {
clearTimeout(self.timer)
self.timer = setTimeout(() => {
if (self.state.rotate != this.rotate() || self.state.scale != this.scale()) {
const _dataUrl = this.clip()
const cutImageBlob = self.convertBase64UrlToBlob(_dataUrl)
self.setState({
cutImageBlob,
dataUrl: _dataUrl,
rotate: this.rotate(),
scale: this.scale(),
})
}
}, 500)
const cutImageBlob = self.convertBase64UrlToBlob(dataUrl)
self.setState({
cutImageBlob,
dataUrl,
})
setTimeout(() => {
cutFlag = false
}, 2000)
},
fail: (failInfo) => {
message.error('图片上传失败了,请重新上传')
},
loadComplete: function (img) {
setTimeout(() => {
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(imgUrl)
this.setState({
photoclip: _photoclip,
})
} else {
this.state.photoclip.clear()
this.state.photoclip.load(imgUrl)
}
}, 200)
}
)
} }
//获取resourceId //获取resourceId
...@@ -367,6 +439,17 @@ class AddOfflineCourse extends React.Component { ...@@ -367,6 +439,17 @@ class AddOfflineCourse extends React.Component {
}) })
} }
// base64转换成blob
convertBase64UrlToBlob = (urlData) => {
const bytes = window.atob(urlData.split(',')[1])
const ab = new ArrayBuffer(bytes.length)
const ia = new Uint8Array(ab)
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i)
}
return new Blob([ab], { type: 'image/png' })
}
preSubmit = () => { preSubmit = () => {
//过期判断 //过期判断
if (User.getExpirationTime() && moment().valueOf() > Number(User.getExpirationTime())) { if (User.getExpirationTime() && moment().valueOf() > Number(User.getExpirationTime())) {
...@@ -615,7 +698,7 @@ class AddOfflineCourse extends React.Component { ...@@ -615,7 +698,7 @@ class AddOfflineCourse extends React.Component {
} }
StoreService.getStoreUserBasicPage(_query).then((res) => { StoreService.getStoreUserBasicPage(_query).then((res) => {
const { result = {} } = res const { result = {} } = res
const { records = [], hasNext } = result const { records = [], total = 0, hasNext } = result
const list = current > 1 ? teacherList.concat(records) : records const list = current > 1 ? teacherList.concat(records) : records
this.setState({ this.setState({
hasNext, hasNext,
...@@ -625,7 +708,11 @@ class AddOfflineCourse extends React.Component { ...@@ -625,7 +708,11 @@ class AddOfflineCourse extends React.Component {
}) })
} }
changeIntro = (value) => { changeIntro = (value, textLength) => {
// const isMore = textLength > 1000;
// if (isMore) {
// message.warning('内容过长,不能超过1000字');
// }
this.setState({ introduce: value }) this.setState({ introduce: value })
} }
...@@ -649,11 +736,6 @@ class AddOfflineCourse extends React.Component { ...@@ -649,11 +736,6 @@ class AddOfflineCourse extends React.Component {
} }
whetherVisitorsJoinChange = () => { whetherVisitorsJoinChange = () => {
const { whetherSetApply, whetherVisitorsJoin } = this.state
if (whetherSetApply == 'NO') {
message.warning('关闭报名无法获取手机号!')
return
}
if (this.state.whetherVisitorsJoin === 'NO') { if (this.state.whetherVisitorsJoin === 'NO') {
this.setState({ whetherVisitorsJoin: 'YES' }) this.setState({ whetherVisitorsJoin: 'YES' })
} else { } else {
...@@ -673,11 +755,14 @@ class AddOfflineCourse extends React.Component { ...@@ -673,11 +755,14 @@ class AddOfflineCourse extends React.Component {
coverUrl, coverUrl,
introduce, introduce,
categoryId, categoryId,
categoryList,
courseCatalogList, courseCatalogList,
whetherVisitorsJoin, whetherVisitorsJoin,
loadintroduce, loadintroduce,
showSelectCoverModal, showSelectCoverModal,
visible, visible,
hasImgReady,
cutImageBlob,
teacherId, teacherId,
teacherList, teacherList,
calendarTime, calendarTime,
...@@ -701,7 +786,6 @@ class AddOfflineCourse extends React.Component { ...@@ -701,7 +786,6 @@ class AddOfflineCourse extends React.Component {
quota, quota,
offlinePlace, offlinePlace,
isEditDisablie, isEditDisablie,
imageFile,
} = this.state } = this.state
const isDefaultCover = coverUrl === defaultCoverUrl const isDefaultCover = coverUrl === defaultCoverUrl
return ( return (
...@@ -758,12 +842,7 @@ class AddOfflineCourse extends React.Component { ...@@ -758,12 +842,7 @@ class AddOfflineCourse extends React.Component {
<span className='label special'> <span className='label special'>
<span className='require'>*</span>课程分类: <span className='require'>*</span>课程分类:
</span> </span>
<CourseCatalogSelect <TreeSelect
courseCatalogList={courseCatalogList}
value={categoryId}
onChange={(value, label) => this.handleChangeCatalogList(value, label)}
/>
{/* <TreeSelect
showSearch showSearch
treeNodeFilterProp='title' treeNodeFilterProp='title'
style={{ width: 240 }} style={{ width: 240 }}
...@@ -774,9 +853,9 @@ class AddOfflineCourse extends React.Component { ...@@ -774,9 +853,9 @@ class AddOfflineCourse extends React.Component {
value={categoryId} value={categoryId}
treeDefaultExpandAll treeDefaultExpandAll
onChange={(value, label) => { onChange={(value, label) => {
this.handleChangeCatalogList(value, label); this.handleChangeCatalogList(value, label)
}} }}
/> */} />
</div> </div>
<div className='course-catalog'> <div className='course-catalog'>
<span className='label special'> <span className='label special'>
...@@ -844,7 +923,7 @@ class AddOfflineCourse extends React.Component { ...@@ -844,7 +923,7 @@ class AddOfflineCourse extends React.Component {
) )
}} }}
getPopupContainer={() => document.getElementById('teacher')}> getPopupContainer={() => document.getElementById('teacher')}>
{_.map(teacherList, (item) => { {_.map(teacherList, (item, index) => {
return ( return (
<Option value={item.id} key={item.id}> <Option value={item.id} key={item.id}>
{item.nickName} {item.nickName}
...@@ -853,6 +932,13 @@ class AddOfflineCourse extends React.Component { ...@@ -853,6 +932,13 @@ class AddOfflineCourse extends React.Component {
})} })}
</Select> </Select>
</div> </div>
<div className='allow-tourist-join'>
<span className='label'>观看设置:</span>
<div className='content'>
<Switch checked={whetherVisitorsJoin === 'NO' ? true : false} onChange={this.whetherVisitorsJoinChange} />
<div className='desc'>{whetherVisitorsJoin === 'NO' ? '已开启,学员需绑定手机号才可观看' : '已关闭,学员无需绑定手机号即可观看'}</div>
</div>
</div>
<div className='introduce'> <div className='introduce'>
<span className='label'>课程简介:</span> <span className='label'>课程简介:</span>
<div className='content'> <div className='content'>
...@@ -885,7 +971,7 @@ class AddOfflineCourse extends React.Component { ...@@ -885,7 +971,7 @@ class AddOfflineCourse extends React.Component {
</span> </span>
<div> <div>
<div className='select-day'> <div className='select-day'>
已选 <span className='mark-day'>{window.isLongArr(calendarTime) ? calendarTime.length : 0}</span> 已选 <span className='mark-day'>{isLongArr(calendarTime) ? calendarTime.length : 0}</span>
</div> </div>
<MultipleDatePicker disabled={isEditDisablie} selectDateList={calendarTime} onSelect={this.selectMultiDate} canSelectTodayBefore={false} /> <MultipleDatePicker disabled={isEditDisablie} selectDateList={calendarTime} onSelect={this.selectMultiDate} canSelectTodayBefore={false} />
</div> </div>
...@@ -956,8 +1042,7 @@ class AddOfflineCourse extends React.Component { ...@@ -956,8 +1042,7 @@ class AddOfflineCourse extends React.Component {
startTimeApply: undefined, startTimeApply: undefined,
endTimeApply: undefined, endTimeApply: undefined,
quota: null, quota: null,
whetherVisitorsJoin: value ? whetherVisitorsJoin : 'YES' })
});
}} }}
/> />
<span className='switch-tip'>开启后可设置课程报名时间,获取报名数据</span> <span className='switch-tip'>开启后可设置课程报名时间,获取报名数据</span>
...@@ -974,8 +1059,8 @@ class AddOfflineCourse extends React.Component { ...@@ -974,8 +1059,8 @@ class AddOfflineCourse extends React.Component {
onChange={(dates) => { onChange={(dates) => {
this.handleChangeDates(dates) this.handleChangeDates(dates)
}} }}
renderExtraFooter={() => ( renderExtraFooter={() =>
<If condition={calendarTime[0]}> calendarTime[0] ? (
<div style={{ position: 'absolute', bottom: 8, cursor: 'pointer' }}> <div style={{ position: 'absolute', bottom: 8, cursor: 'pointer' }}>
<span <span
onClick={() => onClick={() =>
...@@ -1035,8 +1120,8 @@ class AddOfflineCourse extends React.Component { ...@@ -1035,8 +1120,8 @@ class AddOfflineCourse extends React.Component {
上课前3天 上课前3天
</span> </span>
</div> </div>
</If> ) : null
)} }
/> />
</div> </div>
)} )}
...@@ -1068,15 +1153,6 @@ class AddOfflineCourse extends React.Component { ...@@ -1068,15 +1153,6 @@ class AddOfflineCourse extends React.Component {
)} )}
</div> </div>
</div> </div>
<div className='allow-tourist-join'>
<span className='label'>观看设置:</span>
<div className='content'>
<Switch checked={whetherVisitorsJoin === 'NO' ? true : false} onChange={this.whetherVisitorsJoinChange} />
<div className='desc'>
{whetherVisitorsJoin === 'NO' ? '已开启,仅限绑定了手机号的学员报名线下课' : '已关闭,允许未绑定手机号的学员报名线下课'}
</div>
</div>
</div>
<div className='course-catalog'> <div className='course-catalog'>
<span className='label'>考勤签到:</span> <span className='label'>考勤签到:</span>
<div className='switch-box'> <div className='switch-box'>
...@@ -1277,16 +1353,61 @@ class AddOfflineCourse extends React.Component { ...@@ -1277,16 +1353,61 @@ class AddOfflineCourse extends React.Component {
onSelect={this.handleSelectCover} onSelect={this.handleSelectCover}
/> />
)} )}
{visible && ( <Modal
<ImgClipModal title='设置图片'
visible={visible} width={1080}
imgUrl={imageFile.ossUrl} visible={visible}
onConfirm={this.getSignature} maskClosable={false}
onClose={() => { closeIcon={<span className='icon iconfont modal-close-icon'>&#xe6ef;</span>}
this.setState({ visible: false }) onCancel={() => {
}} this.setState({ visible: false })
/> }}
)} zIndex={10001}
footer={[
<Button
key='back'
onClick={() => {
this.setState({ visible: false })
}}>
重新上传
</Button>,
<Button
key='submit'
type='primary'
disabled={!hasImgReady}
onClick={() => {
if (!cutFlag) {
cutFlag = true
this.refs.hiddenBtn.click()
}
this.getSignature(cutImageBlob)
}}>
确定
</Button>,
]}>
<div className='clip-box'>
<div
id='headPicModal'
ref='headPicModal'
style={{
width: '500px',
height: '430px',
marginBottom: 0,
}}></div>
<div id='clipBtn' style={{ display: 'none' }} ref='hiddenBtn'></div>
<div className='preview-img'>
<div className='title'>效果预览</div>
<div id='preview-url-box' style={{ width: 500, height: 282 }}>
<img src={this.state.dataUrl} style={{ width: '100%' }} alt='' />
</div>
<div className='tip-box'>
<div className='tip'>温馨提示</div>
<div className='tip'>①预览效果图时可能存在延迟,单击左侧图片刷新即可</div>
<div className='tip'>②设置图片时双击可旋转图片,滚动可放大或缩小图片</div>
</div>
</div>
</div>
</Modal>
{this.state.previewOfflineModal} {this.state.previewOfflineModal}
</div> </div>
) )
......
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