Merge branch 'dev_aliyun' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_aliyun

dev_admin
jingquan huang 6 years ago
commit 2c511b6ec8

@ -924,16 +924,23 @@ class CoursesController < ApplicationController
course_message = CourseMessage.new(course_id: course.id, user_id: course.tea_id, status: 0, course_message = CourseMessage.new(course_id: course.id, user_id: course.tea_id, status: 0,
course_message_id: current_user.id, course_message_type: "JoinCourseRequest", course_message_id: current_user.id, course_message_type: "JoinCourseRequest",
viewed: false) viewed: false)
course_message.content = 2 if params[:professor].present? && params[:professor].to_i == 1 if params[:professor].present? && params[:professor].to_i == 1
course_message.content = 3 if params[:assistant_professor].present? && params[:assistant_professor].to_i == 1 course_message.content = 2
role = 9
message = "教师申请已提交,请等待审核"
else
course_message.content = 3
role = 7
message = "助教申请已提交,请等待审核"
end
course_message.save! course_message.save!
role = course_message.content == 2 ? '9' : '7' # 7:助教 9:教师 # role = course_message.content == 2 ? '9' : '7' # 7:助教 9:教师
ApplyTeacherRoleJoinCourseNotifyJob.perform_later(current_user.id, course.id, role) ApplyTeacherRoleJoinCourseNotifyJob.perform_later(current_user.id, course.id, role)
message = "#{course_message.content == 2 ? '教师' : '助教'}申请已提交,请等待审核" # message = "#{course_message.content == 2 ? '教师' : '助教'}申请已提交,请等待审核"
else else
message = "#{existing_course_message.content == 2 ? '教师' : '助教'}申请已提交,请等待审核" message = "#{existing_course_message.content == '2' ? '教师' : '助教'}申请已提交,请等待审核"
end end
else else
message = "您已是课堂成员" message = "您已是课堂成员"

@ -11,7 +11,7 @@ class CourseMessage < ApplicationRecord
def pass! def pass!
update!(status: :PASSED) update!(status: :PASSED)
send_deal_tiding send_deal_tiding(1)
end end
def application_user def application_user
@ -20,16 +20,16 @@ class CourseMessage < ApplicationRecord
def reject! def reject!
update!(status: :REJECTED) update!(status: :REJECTED)
send_deal_tiding send_deal_tiding(2)
end end
private private
def send_deal_tiding def send_deal_tiding deal_status
# 发送申请处理结果消息 # 发送申请处理结果消息
Tiding.create!( Tiding.create!(
user_id: course_message_id, trigger_user: User.current, container_id: course_id, container_type: 'DealCourse', user_id: course_message_id, trigger_user: User.current, container_id: course_id, container_type: 'DealCourse',
belong_container: course, extra: content.to_i == 2 ? '7' : '9', tiding_type: 'System', status: status == :PASSED ? 1 : 2 belong_container: course, extra: content.to_i == 2 ? '9' : '7', tiding_type: 'System', status: deal_status
) )
# 将申请消息置为已处理 # 将申请消息置为已处理
Tiding.where(trigger_user_id: user_id, container_id: course_id, container_type: 'JoinCourse', status: 0).update_all(status: 1) Tiding.where(trigger_user_id: user_id, container_id: course_id, container_type: 'JoinCourse', status: 0).update_all(status: 1)

@ -1,449 +1,449 @@
import React,{ Component } from "react"; import React,{ Component } from "react";
import { import {
Form, Input, InputNumber, Switch, Radio, Form, Input, InputNumber, Switch, Radio,
Slider, Button, Upload, Icon, Rate, Checkbox, message, Slider, Button, Upload, Icon, Rate, Checkbox, message,
Row, Col, Select, Modal, Divider Row, Col, Select, Modal, Divider
} from 'antd'; } from 'antd';
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor'; import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import axios from 'axios' import axios from 'axios'
import './board.css' import './board.css'
import "../common/formCommon.css" import "../common/formCommon.css"
import AddDirModal from './AddDirModal' import AddDirModal from './AddDirModal'
import { RouteHOC } from './common.js' import { RouteHOC } from './common.js'
import CBreadcrumb from '../common/CBreadcrumb' import CBreadcrumb from '../common/CBreadcrumb'
import {getUploadActionUrl, bytesToSize, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll} from 'educoder'; import {getUploadActionUrl, bytesToSize, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll} from 'educoder';
const confirm = Modal.confirm; const confirm = Modal.confirm;
const $ = window.$ const $ = window.$
const { Option } = Select; const { Option } = Select;
// https://lanhuapp.com/web/#/item/project/board/detail?pid=a3bcd4b1-99ce-4e43-8ead-5b8b0a410807&project_id=a3bcd4b1-99ce-4e43-8ead-5b8b0a410807&image_id=71072679-b925-4824-aceb-4649535e3652 // https://lanhuapp.com/web/#/item/project/board/detail?pid=a3bcd4b1-99ce-4e43-8ead-5b8b0a410807&project_id=a3bcd4b1-99ce-4e43-8ead-5b8b0a410807&image_id=71072679-b925-4824-aceb-4649535e3652
class BoardsNew extends Component{ class BoardsNew extends Component{
constructor(props){ constructor(props){
super(props); super(props);
this.mdRef = React.createRef(); this.mdRef = React.createRef();
this.state = { this.state = {
fileList: [], fileList: [],
boards: [], boards: [],
title_num: 60 title_num: 60
} }
} }
addSuccess = () => { addSuccess = () => {
this.fetchBoards() this.fetchBoards()
} }
fetchBoards = () => { fetchBoards = () => {
const isEdit = this.isEdit const isEdit = this.isEdit
const boardId = this.props.match.params.boardId const boardId = this.props.match.params.boardId
const boardsUrl = `/courses/board_list.json?board_id=${boardId}` const boardsUrl = `/courses/board_list.json?board_id=${boardId}`
axios.get(boardsUrl, { }) axios.get(boardsUrl, { })
.then((response) => { .then((response) => {
if (response.data.status == 0) { if (response.data.status == 0) {
this.setState({ this.setState({
boards: response.data.data.boards || [], boards: response.data.data.boards || [],
course_id: response.data.data.course_id course_id: response.data.data.course_id
}) })
if (!isEdit) { if (!isEdit) {
response.data.data.boards.forEach( board => { response.data.data.boards.forEach( board => {
if (board.id == boardId) { if (board.id == boardId) {
this.setState({ board_name: board.name }) this.setState({ board_name: board.name })
} }
}) })
// board_name // board_name
} }
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} }
componentDidMount = () => { componentDidMount = () => {
const topicId = this.props.match.params.topicId const topicId = this.props.match.params.topicId
const isEdit = !!topicId const isEdit = !!topicId
this.isEdit = isEdit this.isEdit = isEdit
const boardId = this.props.match.params.boardId const boardId = this.props.match.params.boardId
this.fetchBoards() this.fetchBoards()
if (isEdit) { if (isEdit) {
const url = `/messages/${topicId}.json` const url = `/messages/${topicId}.json`
axios.get(url, { axios.get(url, {
}) })
.then((response) => { .then((response) => {
if (response.data.status == 0) { if (response.data.status == 0) {
const { id, data } = response.data; const { id, data } = response.data;
if (data) { if (data) {
this.editTopic = data; this.editTopic = data;
this.props.form.setFieldsValue({ this.props.form.setFieldsValue({
sticky: !!data.sticky, sticky: !!data.sticky,
content: data.content, content: data.content,
subject: data.subject, subject: data.subject,
select_board_id: data.board_id // TODO 没返回给前端 select_board_id: data.board_id // TODO 没返回给前端
}); });
this.mdRef.current.setValue(data.content) this.mdRef.current.setValue(data.content)
const _fileList = data.attachments.map(item => { const _fileList = data.attachments.map(item => {
return { return {
id: item.id, id: item.id,
uid: item.id, uid: item.id,
name: appendFileSizeToUploadFile(item), name: appendFileSizeToUploadFile(item),
url: item.url, url: item.url,
status: 'done' status: 'done'
} }
}) })
this.setState({ fileList: _fileList, board_name: data.board_name, title_num: 60 - parseInt(data.subject.length) }) this.setState({ fileList: _fileList, board_name: data.board_name, title_num: 60 - parseInt(data.subject.length) })
} }
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} else { } else {
const boardId = this.props.match.params.boardId const boardId = this.props.match.params.boardId
this.props.form.setFieldsValue({ this.props.form.setFieldsValue({
select_board_id: parseInt(boardId) select_board_id: parseInt(boardId)
}); });
} }
} }
handleSubmit = (e) => { handleSubmit = (e) => {
e.preventDefault(); e.preventDefault();
const cid = this.state.course_id const cid = this.state.course_id
const boardId = this.props.match.params.boardId const boardId = this.props.match.params.boardId
this.props.form.validateFieldsAndScroll((err, values) => { this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) { if (!err) {
console.log('Received values of form: ', values); console.log('Received values of form: ', values);
if (this.isEdit == true) { if (this.isEdit == true) {
const editTopic = this.editTopic const editTopic = this.editTopic
const editUrl = `/messages/${editTopic.id}.json` const editUrl = `/messages/${editTopic.id}.json`
let attachment_ids = undefined let attachment_ids = undefined
if (this.state.fileList) { if (this.state.fileList) {
attachment_ids = this.state.fileList.map(item => { attachment_ids = this.state.fileList.map(item => {
return item.response ? item.response.id : item.id return item.response ? item.response.id : item.id
}) })
} }
axios.put(editUrl, { axios.put(editUrl, {
subject: values.subject, subject: values.subject,
select_board_id: values.select_board_id, select_board_id: values.select_board_id,
content: values.content, content: values.content,
sticky: values.sticky, sticky: values.sticky,
attachment_ids, attachment_ids,
}) })
.then((response) => { .then((response) => {
if (response.data.status == 0) { if (response.data.status == 0) {
const { id } = response.data; const { id } = response.data;
console.log('--- success') console.log('--- success')
this.props.toDetailPage(cid, values.select_board_id, editTopic.id) this.props.toDetailPage(cid, values.select_board_id, editTopic.id)
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} else { } else {
const url = `/boards/${boardId}/messages.json` const url = `/boards/${boardId}/messages.json`
let attachment_ids = undefined let attachment_ids = undefined
if (this.state.fileList) { if (this.state.fileList) {
attachment_ids = this.state.fileList.map(item => { attachment_ids = this.state.fileList.map(item => {
return item.response.id return item.response.id
}) })
} }
axios.post(url, { axios.post(url, {
...values, ...values,
course_id: cid, course_id: cid,
attachment_ids, attachment_ids,
}) })
.then((response) => { .then((response) => {
if (response.data.data && response.data.status == 0) { if (response.data.data && response.data.status == 0) {
const { id } = response.data.data; const { id } = response.data.data;
if (id) { if (id) {
console.log('--- success') console.log('--- success')
this.props.toDetailPage(cid, values.select_board_id, id) this.props.toDetailPage(cid, values.select_board_id, id)
} }
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} }
} else { } else {
$("html").animate({ scrollTop: $('html').scrollTop() - 100 }) $("html").animate({ scrollTop: $('html').scrollTop() - 100 })
} }
}); });
} }
// 附件相关 START // 附件相关 START
handleChange = (info) => { handleChange = (info) => {
let fileList = info.fileList; let fileList = info.fileList;
this.setState({ fileList: appendFileSizeToUploadFileAll(fileList) this.setState({ fileList: appendFileSizeToUploadFileAll(fileList)
}); });
} }
onAttachmentRemove = (file) => { onAttachmentRemove = (file) => {
confirm({ confirm({
// title: '确定要删除这个附件吗?', // title: '确定要删除这个附件吗?',
title: '是否确认删除?', title: '是否确认删除?',
okText: '确定', okText: '确定',
cancelText: '取消', cancelText: '取消',
// content: 'Some descriptions', // content: 'Some descriptions',
onOk: () => { onOk: () => {
this.deleteAttachment(file) this.deleteAttachment(file)
}, },
onCancel() { onCancel() {
console.log('Cancel'); console.log('Cancel');
}, },
}); });
return false; return false;
} }
deleteAttachment = (file) => { deleteAttachment = (file) => {
// 初次上传不能直接取uid // 初次上传不能直接取uid
const url = `/attachments/${file.response ? file.response.id : file.uid}.json` const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
axios.delete(url, { axios.delete(url, {
}) })
.then((response) => { .then((response) => {
if (response.data) { if (response.data) {
const { status } = response.data; const { status } = response.data;
if (status == 0) { if (status == 0) {
console.log('--- success') console.log('--- success')
this.setState((state) => { this.setState((state) => {
const index = state.fileList.indexOf(file); const index = state.fileList.indexOf(file);
const newFileList = state.fileList.slice(); const newFileList = state.fileList.slice();
newFileList.splice(index, 1); newFileList.splice(index, 1);
return { return {
fileList: newFileList, fileList: newFileList,
}; };
}); });
} }
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} }
// 附件相关 ------------ END // 附件相关 ------------ END
changeTitle=(e)=>{ changeTitle=(e)=>{
console.log(e.target.value.length); console.log(e.target.value.length);
this.setState({ this.setState({
title_num: 60 - parseInt(e.target.value.length) title_num: 60 - parseInt(e.target.value.length)
}) })
} }
render() { render() {
let { addGroup, fileList, course_id, title_num } = this.state; let { addGroup, fileList, course_id, title_num } = this.state;
const { getFieldDecorator } = this.props.form; const { getFieldDecorator } = this.props.form;
const { current_user } = this.props const { current_user } = this.props
const formItemLayout = { const formItemLayout = {
labelCol: { labelCol: {
xs: { span: 24 }, xs: { span: 24 },
// sm: { span: 8 }, // sm: { span: 8 },
sm: { span: 24 }, sm: { span: 24 },
}, },
wrapperCol: { wrapperCol: {
xs: { span: 24 }, xs: { span: 24 },
// sm: { span: 16 }, // sm: { span: 16 },
sm: { span: 24 }, sm: { span: 24 },
}, },
}; };
const uploadProps = { const uploadProps = {
width: 600, width: 600,
fileList, fileList,
multiple: true, multiple: true,
// https://github.com/ant-design/ant-design/issues/15505 // https://github.com/ant-design/ant-design/issues/15505
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。 // showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
// showUploadList: false, // showUploadList: false,
action: `${getUploadActionUrl()}`, action: `${getUploadActionUrl()}`,
onChange: this.handleChange, onChange: this.handleChange,
onRemove: this.onAttachmentRemove, onRemove: this.onAttachmentRemove,
beforeUpload: (file) => { beforeUpload: (file) => {
console.log('beforeUpload', file.name); console.log('beforeUpload', file.name);
const isLt150M = file.size / 1024 / 1024 < 150; const isLt150M = file.size / 1024 / 1024 < 150;
if (!isLt150M) { if (!isLt150M) {
message.error('文件大小必须小于150MB!'); message.error('文件大小必须小于150MB!');
} }
return isLt150M; return isLt150M;
}, },
}; };
const isAdmin = this.props.isAdmin() const isAdmin = this.props.isAdmin()
const courseId=this.props.match.params.coursesId; const courseId=this.props.match.params.coursesId;
const boardId = this.props.match.params.boardId const boardId = this.props.match.params.boardId
return( return(
<div className="newMain "> <div className="newMain ">
<AddDirModal {...this.props} <AddDirModal {...this.props}
title="添加目录" title="添加目录"
label="目录名称" label="目录名称"
ref="addDirModal" ref="addDirModal"
addSuccess={this.addSuccess} addSuccess={this.addSuccess}
></AddDirModal> ></AddDirModal>
<style>{` <style>{`
.courseForm .ant-form { .courseForm .ant-form {
} }
.courseForm .formBlock { .courseForm .formBlock {
padding: 20px 30px 30px 30px; padding: 20px 30px 30px 30px;
border-bottom: 1px solid #EDEDED; border-bottom: 1px solid #EDEDED;
margin-bottom: 0px; margin-bottom: 0px;
background: #fff; background: #fff;
} }
.courseForm .noBorder { .courseForm .noBorder {
border-bottom: none; border-bottom: none;
} }
`}</style> `}</style>
<div className="edu-class-container edu-position courseForm"> <div className="edu-class-container edu-position courseForm">
<CBreadcrumb items={[ <CBreadcrumb items={[
{ to: current_user.first_category_url, name: this.props.coursedata ? this.props.coursedata.name : ''}, { to: current_user&&current_user.first_category_url, name: this.props.coursedata ? this.props.coursedata.name : ''},
{ to: `/courses/${courseId}/boards/${boardId}`, name: this.state.board_name }, { to: `/courses/${courseId}/boards/${boardId}`, name: this.state.board_name },
{ name: this.isEdit ? '帖子编辑' : '帖子新建'} { name: this.isEdit ? '帖子编辑' : '帖子新建'}
]}></CBreadcrumb> ]}></CBreadcrumb>
<p className="clearfix mt20 mb20"> <p className="clearfix mt20 mb20">
<span className="fl font-24 color-grey-3">{this.isEdit ? "编辑" : "新建"}帖子</span> <span className="fl font-24 color-grey-3">{this.isEdit ? "编辑" : "新建"}帖子</span>
<a href="javascript:void(0)" className="color-grey-6 fr font-16 mr2" <a href="javascript:void(0)" className="color-grey-6 fr font-16 mr2"
onClick={() => this.props.history.goBack()}> onClick={() => this.props.history.goBack()}>
返回 返回
</a> </a>
</p> </p>
{/* notRequired */} {/* notRequired */}
<Form {...formItemLayout} onSubmit={this.handleSubmit}> <Form {...formItemLayout} onSubmit={this.handleSubmit}>
<div className="formBlock" style={{paddingBottom: '0px', position: 'relative'}}> <div className="formBlock" style={{paddingBottom: '0px', position: 'relative'}}>
{ isAdmin && { isAdmin &&
<React.Fragment> <React.Fragment>
{getFieldDecorator('sticky', { {getFieldDecorator('sticky', {
valuePropName: 'checked', valuePropName: 'checked',
})( })(
isAdmin && <Checkbox style={{ right: '22px', isAdmin && <Checkbox style={{ right: '22px',
top: '28px', top: '28px',
position: 'absolute' position: 'absolute'
}}>置顶</Checkbox> }}>置顶</Checkbox>
)} )}
{/* checkbox 有个边距样式 .ant-checkbox-wrapper + span, */} {/* checkbox 有个边距样式 .ant-checkbox-wrapper + span, */}
<span style={{ "padding-left": 0, "padding-right": 0 }}></span> <span style={{ "padding-left": 0, "padding-right": 0 }}></span>
</React.Fragment> </React.Fragment>
} }
<Form.Item <Form.Item
label="标题" label="标题"
className="topicTitle " className="topicTitle "
> >
{getFieldDecorator('subject', { {getFieldDecorator('subject', {
rules: [{ rules: [{
required: true, message: '请输入标题', required: true, message: '请输入标题',
}, { }, {
max: 60, message: '最大限制为60个字符', max: 60, message: '最大限制为60个字符',
}], }],
})( })(
<Input placeholder="请输入帖子标题最大限制60个字符" className="searchViewAfter" maxLength="60" <Input placeholder="请输入帖子标题最大限制60个字符" className="searchViewAfter" maxLength="60"
onInput={this.changeTitle} addonAfter={String(title_num)} /> onInput={this.changeTitle} addonAfter={String(title_num)} />
)} )}
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="" label=""
style={{ display: 'inline-block' }} style={{ display: 'inline-block' }}
> >
{getFieldDecorator('select_board_id', { {getFieldDecorator('select_board_id', {
// initialValue: '3779', // initialValue: '3779',
})( })(
<Select style={{ width: 230 }} <Select style={{ width: 230 }}
dropdownRender={menu => ( dropdownRender={menu => (
<div> <div>
{menu} {menu}
<Divider style={{ margin: '4px 0' }} /> <Divider style={{ margin: '4px 0' }} />
<div style={{ padding: '8px', cursor: 'pointer' }} onMouseDown={() => this.refs['addDirModal'].open()}> <div style={{ padding: '8px', cursor: 'pointer' }} onMouseDown={() => this.refs['addDirModal'].open()}>
<Icon type="plus" /> 添加目录 <Icon type="plus" /> 添加目录
</div> </div>
</div> </div>
)} )}
> >
{this.state.boards.map(item => { {this.state.boards.map(item => {
return ( return (
<Option value={item.id}>{item.name}</Option> <Option value={item.id}>{item.name}</Option>
) )
})} })}
</Select> </Select>
)} )}
</Form.Item> </Form.Item>
{/* { isAdmin && <Form.Item {/* { isAdmin && <Form.Item
label="" label=""
style={{ display: 'inline-block', marginLeft: "14px" }} style={{ display: 'inline-block', marginLeft: "14px" }}
> >
{getFieldDecorator('sticky', { {getFieldDecorator('sticky', {
})( })(
<Checkbox>置顶</Checkbox> <Checkbox>置顶</Checkbox>
)} )}
</Form.Item> } */} </Form.Item> } */}
</div> </div>
<style>{` <style>{`
.courseMessageMD { .courseMessageMD {
width: 1140px; width: 1140px;
} }
.uploadBtn.ant-btn { .uploadBtn.ant-btn {
border: none; border: none;
color: #4CACFF; color: #4CACFF;
box-shadow: none; box-shadow: none;
background: transparent; background: transparent;
padding: 0 6px; padding: 0 6px;
} }
.upload_1 .ant-upload-list { .upload_1 .ant-upload-list {
width: 350px; width: 350px;
} }
`}</style> `}</style>
<div className="formBlock noBorder"> <div className="formBlock noBorder">
<Form.Item <Form.Item
label="内容" label="内容"
className="mdInForm" className="mdInForm"
> >
{getFieldDecorator('content', { {getFieldDecorator('content', {
rules: [{ rules: [{
required: true, message: '请输入帖子内容', required: true, message: '请输入帖子内容',
}, { }, {
max: 10000, message: '最大限制为10000个字符', max: 10000, message: '最大限制为10000个字符',
}], }],
})( })(
<TPMMDEditor ref={this.mdRef} placeholder={'请在此输入帖子详情最大限制为10000个字符'} <TPMMDEditor ref={this.mdRef} placeholder={'请在此输入帖子详情最大限制为10000个字符'}
mdID={'courseMessageMD'} initValue={this.editTopic ? this.editTopic.content : ''} className="courseMessageMD"></TPMMDEditor> mdID={'courseMessageMD'} initValue={this.editTopic ? this.editTopic.content : ''} className="courseMessageMD"></TPMMDEditor>
)} )}
</Form.Item> </Form.Item>
<Upload {...uploadProps} className="upload_1"> <Upload {...uploadProps} className="upload_1">
<Button className="uploadBtn"> <Button className="uploadBtn">
<Icon type="upload" /> 上传附件 <Icon type="upload" /> 上传附件
</Button> </Button>
(单个文件150M以内) (单个文件150M以内)
</Upload> </Upload>
</div> </div>
<Form.Item> <Form.Item>
<div className="clearfix mt30 mb30"> <div className="clearfix mt30 mb30">
<Button type="primary" htmlType="submit" className="defalutSubmitbtn fl mr20">提交</Button> <Button type="primary" htmlType="submit" className="defalutSubmitbtn fl mr20">提交</Button>
<a className="defalutCancelbtn fl" <a className="defalutCancelbtn fl"
onClick={() => this.isEdit ? onClick={() => this.isEdit ?
this.props.toDetailPage(Object.assign({}, this.props.match.params, {'coursesId': course_id})) : this.props.toDetailPage(Object.assign({}, this.props.match.params, {'coursesId': course_id})) :
this.props.toListPage(Object.assign({}, this.props.match.params, {'coursesId': course_id})) }>取消</ a> this.props.toListPage(Object.assign({}, this.props.match.params, {'coursesId': course_id})) }>取消</ a>
</div> </div>
</Form.Item> </Form.Item>
</Form> </Form>
</div> </div>
</div> </div>
) )
} }
} }
const WrappedBoardsNew = Form.create({ name: 'boardsNew' })(BoardsNew); const WrappedBoardsNew = Form.create({ name: 'boardsNew' })(BoardsNew);
export default RouteHOC()(WrappedBoardsNew); export default RouteHOC()(WrappedBoardsNew);

File diff suppressed because it is too large Load Diff

@ -223,7 +223,7 @@ class CommonWorkDetailIndex extends Component{
} }
`}</style> `}</style>
{current_user && <CBreadcrumb items={[ {current_user && <CBreadcrumb items={[
{ to: current_user.first_category_url , name: course_name}, { to: current_user&&current_user.first_category_url , name: course_name},
{ to: `/courses/${courseId}/${moduleEngName}/${category_id}`, name: category_name }, { to: `/courses/${courseId}/${moduleEngName}/${category_id}`, name: category_name },
window.location.pathname.indexOf('appraise') == -1 ? { } : { to: `/courses/${courseId}/${moduleEngName}/${workId}/list`, name: '作业详情' }, window.location.pathname.indexOf('appraise') == -1 ? { } : { to: `/courses/${courseId}/${moduleEngName}/${workId}/list`, name: '作业详情' },
// 1. 与上一条联动当匿评他人作品时TA人作品的作者真实姓名切换为“匿名” // 1. 与上一条联动当匿评他人作品时TA人作品的作者真实姓名切换为“匿名”

@ -90,7 +90,7 @@ class WorkDetailPageHeader extends Component{
} }
`}</style> `}</style>
<CBreadcrumb items={[ <CBreadcrumb items={[
{ to: current_user.first_category_url, name: course_name}, { to: current_user&&current_user.first_category_url, name: course_name},
{ to: `/courses/${courseId}/${moduleEngName}/${category_id}`, name: category_name }, { to: `/courses/${courseId}/${moduleEngName}/${category_id}`, name: category_name },
window.location.pathname.indexOf('appraise') == -1 ? { } : { to: `/courses/${courseId}/${moduleEngName}/${workId}/list`, name: '作业详情' }, window.location.pathname.indexOf('appraise') == -1 ? { } : { to: `/courses/${courseId}/${moduleEngName}/${workId}/list`, name: '作业详情' },
// 1. 与上一条联动当匿评他人作品时TA人作品的作者真实姓名切换为“匿名” // 1. 与上一条联动当匿评他人作品时TA人作品的作者真实姓名切换为“匿名”

File diff suppressed because it is too large Load Diff

@ -105,7 +105,7 @@ class GraduateTopicDetail extends Component{
<div className="newMain"> <div className="newMain">
<div className="educontent mt10 mb50"> <div className="educontent mt10 mb50">
<p className="clearfix mb15 lineh-20"> <p className="clearfix mb15 lineh-20">
<WordsBtn style="grey" className="fl" to={current_user.first_category_url}>{tableData && tableData.course_name}</WordsBtn> <WordsBtn style="grey" className="fl" to={current_user&&current_user.first_category_url}>{tableData && tableData.course_name}</WordsBtn>
<span className="color-grey-9 fl ml3 mr3">&gt;</span> <span className="color-grey-9 fl ml3 mr3">&gt;</span>
<WordsBtn style="grey" className="fl" to={`/courses/${tableData.course_id}/graduation_topics/${tableData.graduation_id}`}>{tableData.graduation_name}</WordsBtn> <WordsBtn style="grey" className="fl" to={`/courses/${tableData.course_id}/graduation_topics/${tableData.graduation_id}`}>{tableData.graduation_name}</WordsBtn>
<span className="color-grey-9 fl ml3 mr3">&gt;</span> <span className="color-grey-9 fl ml3 mr3">&gt;</span>

@ -323,7 +323,7 @@ class GraduateTopicNew extends Component{
`}</style> `}</style>
<div className="edu-class-container edu-position courseForm"> <div className="edu-class-container edu-position courseForm">
<p className="clearfix mb20 mt10"> <p className="clearfix mb20 mt10">
<WordsBtn style="grey" className="fl" to={current_user.first_category_url}>{course_name}</WordsBtn> <WordsBtn style="grey" className="fl" to={current_user&&current_user.first_category_url}>{course_name}</WordsBtn>
<span className="color-grey-9 fl ml3 mr3">&gt;</span> <span className="color-grey-9 fl ml3 mr3">&gt;</span>
<WordsBtn style="grey" className="fl" to={`/courses/${coursesId}/graduation_topics/${left_banner_id}`}>{left_banner_name}</WordsBtn> <WordsBtn style="grey" className="fl" to={`/courses/${coursesId}/graduation_topics/${left_banner_id}`}>{left_banner_name}</WordsBtn>
<span className="color-grey-9 fl ml3 mr3">&gt;</span> <span className="color-grey-9 fl ml3 mr3">&gt;</span>

@ -691,39 +691,42 @@ class MemoDetail extends Component {
<div className="clearfix"> <div className="clearfix">
<div id="forum_list" className="forum_table mh650"> <div id="forum_list" className="forum_table mh650">
<div className="padding40-30 bor-bottom-greyE"> <div className="padding40-30 bor-bottom-greyE">
<div className="font-16 mb5 cdefault clearfix pr pr35"> <div className="font-16 mb5 cdefault clearfix pr pr35" style={{display: 'flex', alignItems: 'center'}}>
<span className="noteDetailTitle">{memo.subject}</span> <span className="noteDetailTitle">{memo.subject}</span>
{ memo.sticky && <span className="btn-cir btn-cir-red ml10 mt10">置顶</span>} { memo.sticky && <span className="btn-cir btn-cir-red ml10 " style={{ height: '20px' }}>置顶</span>}
{ !!memo.reward && <span className="color-orange font-14 ml15" { !!memo.reward && <span className="color-orange font-14 ml15"
data-tip-down={`获得平台奖励金币:${memo.reward}`} > data-tip-down={`获得平台奖励金币:${memo.reward}`} >
<i className="iconfont icon-gift mr5"></i>{memo.reward} <i className="iconfont icon-gift mr5"></i>{memo.reward}
</span> } </span> }
{ _current_user && (_current_user.admin === true || _current_user.user_id === author_info.user_id) &&
<div className="edu-position-hidebox" style={{position: 'absolute', right: '12px',top:'4px'}}> <div style={{ flex: 1 }}>
<a href="javascript:void(0);"><i className="fa fa-bars font-16"></i></a> { _current_user && (_current_user.admin === true || _current_user.user_id === author_info.user_id) &&
<ul className="edu-position-hide undis"> <div className="edu-position-hidebox" style={{position: 'absolute', right: '12px',top:'4px'}}>
{ _current_user.admin === true && <a href="javascript:void(0);"><i className="fa fa-bars font-16"></i></a>
( memo.sticky === true ? <ul className="edu-position-hide undis">
<li><a href="javascript:void(0);" onClick={() => this.setTop(memo)}>取消置顶</a></li> { _current_user.admin === true &&
: ( memo.sticky === true ?
<li><a href="javascript:void(0);" onClick={() => this.setTop(memo)}>&nbsp;&nbsp;</a></li> ) <li><a href="javascript:void(0);" onClick={() => this.setTop(memo)}>取消置顶</a></li>
} :
<li><Link to={`/forums/${memo.id}/edit`}>&nbsp;&nbsp;</Link></li> <li><a href="javascript:void(0);" onClick={() => this.setTop(memo)}>&nbsp;&nbsp;</a></li> )
<li> }
<a href="javascript:void(0)" onClick={() => <li><Link to={`/forums/${memo.id}/edit`}>&nbsp;&nbsp;</Link></li>
window.delete_confirm_box_2_react(`onMemoDelete`, '您确定要删除吗?' , memo)}> <li>
<a href="javascript:void(0)" onClick={() =>
&nbsp;&nbsp;</a> window.delete_confirm_box_2_react(`onMemoDelete`, '您确定要删除吗?' , memo)}>
</li>
</ul> &nbsp;&nbsp;</a>
</div> </li>
} </ul>
<Link className={`task-hide fr return_btn color-grey-6 mt2 ${ _current_user && (_current_user.admin === true </div>
|| _current_user.user_id === author_info.user_id) ? '': 'no_mr'} `} to="/forums" }
style={{ marginRight: '10px'}} <Link className={`task-hide fr return_btn color-grey-6 mt2 ${ _current_user && (_current_user.admin === true
> || _current_user.user_id === author_info.user_id) ? '': 'no_mr'} `} to="/forums"
返回 style={{ marginRight: '10px'}}
</Link> >
返回
</Link>
</div>
</div> </div>
<div className="color-grey-9 clearfix"> <div className="color-grey-9 clearfix">
<span className="fl">{moment(memo.time).fromNow()} 发布</span> <span className="fl">{moment(memo.time).fromNow()} 发布</span>
@ -804,7 +807,7 @@ class MemoDetail extends Component {
></Comments> ></Comments>
{ hasMoreComments ? { hasMoreComments ?
<div className="memoMore"> <div className="memoMore" style={{ cursor: 'default' }}>
<a onClick={this.moreMemos}>查看更多评论</a> <a onClick={this.moreMemos}>查看更多评论</a>
<div className="writeCommentBtn" onClick={this.showCommentInput}>写评论</div> <div className="writeCommentBtn" onClick={this.showCommentInput}>写评论</div>
</div> </div>

@ -27,7 +27,7 @@
cursor: pointer; cursor: pointer;
} }
#forum_list .return_btn.no_mr { #forum_list .return_btn.no_mr {
margin-right: -16px; margin-right: -24px !important;
} }
div#forum_list>div { div#forum_list>div {
background: #fff; background: #fff;

@ -126,7 +126,7 @@ return function wrap(WrappedComponent) {
} }
const orderTypeMap = { const orderTypeMap = {
'hottest': 'replies_count', 'hottest': 'replies_count',
'newest': 'updated_at', // 'created_at', 'newest': 'created_at', // 'created_at',
} }
const _search = this.props.history.location.search; const _search = this.props.history.location.search;
const parsed = queryString.parse(_search); const parsed = queryString.parse(_search);

@ -495,10 +495,10 @@ class MessagSub extends Component{
<div className="bor-top-greyE mycenter"> <div className="bor-top-greyE mycenter">
{/*这里可以进行数据处理*/} {/*这里可以进行数据处理*/}
<div className="myw100baifenbi"> <div className="myw100baifenbi">
<Spin size="large" className="myw100baifenbi" spinning={isSpin}> <Spin size="large" className="myw100baifenbi mt10" spinning={isSpin}>
{ {
data===undefined? data===undefined?"":data.length===0?
<div className="edu-tab-con-box clearfix edu-txt-center"> <div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/> <img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb20">暂无数据哦~</p> <p className="edu-nodata-p mb20">暂无数据哦~</p>
@ -562,7 +562,7 @@ class MessagSub extends Component{
` `
} }
</style> </style>
<p className="color-grey-6 break_word_firefox yslspansk markdown-body mt3" style={{wordBreak: "break-word"}} dangerouslySetInnerHTML={{__html: markdownToHTML(item.content).replace(/▁/g, "▁▁▁")}} ></p> <p className="color-grey-6 break_word_firefox yslspansk markdown-body mt10" style={{wordBreak: "break-word"}} dangerouslySetInnerHTML={{__html: markdownToHTML(item.content).replace(/▁/g, "▁▁▁")}} ></p>
</div> </div>
<span className={item.new_tiding===true?"new-point fr mr40 mt22":""}></span> <span className={item.new_tiding===true?"new-point fr mr40 mt22":""}></span>

@ -160,14 +160,13 @@ class MessagePrivate extends Component{
<Spin size="large" className="myw100baifenbi" spinning={isSpin}> <Spin size="large" className="myw100baifenbi" spinning={isSpin}>
{ {
data===undefined? data===undefined?"":data.length===0?
<div className="edu-tab-con-box clearfix edu-txt-center"> <div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/> <img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb20">暂无数据哦~</p> <p className="edu-nodata-p mb20">暂无数据哦~</p>
</div> </div>
:data.map((item,key)=>{ :data.map((item,key)=>{
return( return(
<div className="private-item clearfix df" key={key} onClick={()=>this.smyJump(3,item.target.id)}> <div className="private-item clearfix df" key={key} onClick={()=>this.smyJump(3,item.target.id)}>
<a className="fl mr10 private_message_a" onMouseDown={()=>this.myCome(item)}> <a className="fl mr10 private_message_a" onMouseDown={()=>this.myCome(item)}>
<img onMouseDown={()=>this.myCome(item)} src={getImageUrl("images/"+item.target.image_url)} className="radius myimgw48 myimgh48"/> <img onMouseDown={()=>this.myCome(item)} src={getImageUrl("images/"+item.target.image_url)} className="radius myimgw48 myimgh48"/>
@ -179,12 +178,11 @@ class MessagePrivate extends Component{
<span className="color-grey-c mr20">[{item.message_count}{"条"}]</span> <span className="color-grey-c mr20">[{item.message_count}{"条"}]</span>
<span className="color-grey-c">{moment(item.send_time).fromNow()}</span> <span className="color-grey-c">{moment(item.send_time).fromNow()}</span>
</p> </p>
<span className="color-grey-6 break_word_firefox markdown-body" dangerouslySetInnerHTML={{__html: markdownToHTML(item.content).replace(/▁/g, "▁▁▁")}} ></span> <div className="color-grey-6 break_word_firefox markdown-body mt10" dangerouslySetInnerHTML={{__html: markdownToHTML(item.content).replace(/▁/g, "▁▁▁")}} ></div>
</div> </div>
{item.unread === true ?<span className="new-point fr mt22"></span>:""} {item.unread === true ?<span className="new-point fr mt22"></span>:""}
</div> </div>
) )
})} })}
</Spin> </Spin>

@ -409,7 +409,7 @@ class PackageIndexNEITaskDetails extends Component {
return( return(
<div className="ysldivhomediv1s homehove" key={key}> <div className="ysldivhomediv1s homehove" key={key}>
{item.status==="bidding_won"?<img src={gouxuan} className="yslgouxuanimg"/>:""} {item.status==="bidding_won"?<img src={gouxuan} className="yslgouxuanimg"/>:""}
<a href={`/users/${item.login}`}><img className="div1imgs" src={getImageUrl("images/"+item.image_url)}/></a> <a className={item.status==="bidding_won"?"":"mt20"} href={`/users/${item.login}`}><img className="div1imgs" src={getImageUrl("images/"+item.image_url)}/></a>
<div className="textall mt10" title={item.name}> <p className="ptext">{item.name}</p></div> <div className="textall mt10" title={item.name}> <p className="ptext">{item.name}</p></div>
{this.props.current_user&&this.props.current_user.login!=item.login?<a className="ContacttheTAs fl none" target="_blank" href={`/messages/${this.props.current_user&&this.props.current_user.login}/message_detail?target_ids=${item.id}`}> {this.props.current_user&&this.props.current_user.login!=item.login?<a className="ContacttheTAs fl none" target="_blank" href={`/messages/${this.props.current_user&&this.props.current_user.login}/message_detail?target_ids=${item.id}`}>
<img alt="头像" className="mr5" src={require('./newstwo.png')}/>联系TA <img alt="头像" className="mr5" src={require('./newstwo.png')}/>联系TA

@ -1391,13 +1391,13 @@ export default class TPMsettings extends Component {
}) })
} }
</Select> </Select>
<p {/*<p*/}
className="edu-txt-left font-12" {/*className="edu-txt-left font-12"*/}
style={{display:operateauthority?"block":'none'}} {/*style={{display:operateauthority?"block":'none'}}*/}
> {/*>*/}
列表中没有 {/*列表中没有?*/}
<a className="color-blue" onClick={this.post_apply}>申请新建</a> {/*<a className="color-blue" onClick={this.post_apply}>申请新建</a>*/}
</p> {/*</p>*/}
<Modal <Modal
keyboard={false} keyboard={false}

Loading…
Cancel
Save