|
|
|
@ -7,17 +7,17 @@ import PropTypes from 'prop-types';
|
|
|
|
|
|
|
|
|
|
import classNames from 'classnames'
|
|
|
|
|
|
|
|
|
|
import { Select,Icon } from 'antd';
|
|
|
|
|
import { Select,Icon, Upload, Button } from 'antd';
|
|
|
|
|
|
|
|
|
|
// demo http://react-component.github.io/upload/examples/simple.html
|
|
|
|
|
import Upload from 'rc-upload';
|
|
|
|
|
// import Upload from 'rc-upload';
|
|
|
|
|
|
|
|
|
|
import axios from 'axios'
|
|
|
|
|
|
|
|
|
|
import 'antd/lib/select/style/index.css'
|
|
|
|
|
import TPMMDEditor from '../tpm/challengesnew/TPMMDEditor'
|
|
|
|
|
|
|
|
|
|
import { getUrl } from 'educoder'
|
|
|
|
|
import { getUrl, getUploadActionUrl, appendFileSizeToUploadFileAll, appendFileSizeToUploadFile } from 'educoder'
|
|
|
|
|
const Option = Select.Option;
|
|
|
|
|
const $ = window.$;
|
|
|
|
|
|
|
|
|
@ -169,14 +169,16 @@ class MemoNew extends Component {
|
|
|
|
|
|
|
|
|
|
repertoires: [],
|
|
|
|
|
currentSelectRepertoiresIndex: -1,
|
|
|
|
|
repertoiresTagMap: {}
|
|
|
|
|
repertoiresTagMap: {},
|
|
|
|
|
|
|
|
|
|
fileList: []
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
onCommit() {
|
|
|
|
|
const { memoSubject, memoRepertoire, memoLanguage, currentMemoId, memoType } = this.state;
|
|
|
|
|
const { showSnackbar } = this.props;
|
|
|
|
|
const { showNotification } = this.props;
|
|
|
|
|
if (!memoSubject) {
|
|
|
|
|
showSnackbar('请先输入话题名称')
|
|
|
|
|
showNotification('请先输入话题名称')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
let mdVal;
|
|
|
|
@ -184,17 +186,17 @@ class MemoNew extends Component {
|
|
|
|
|
mdVal = this.mdRef.current.getValue()
|
|
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
showSnackbar('编辑器还未加载完毕,请稍后')
|
|
|
|
|
showNotification('编辑器还未加载完毕,请稍后')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mdVal) {
|
|
|
|
|
showSnackbar('请先输入话题内容')
|
|
|
|
|
showNotification('请先输入话题内容')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// !memoRepertoire ||
|
|
|
|
|
if (memoType === 5 && ( !memoLanguage || memoLanguage.length === 0 )) {
|
|
|
|
|
showSnackbar('请先选择技术标签')
|
|
|
|
|
showNotification('请先选择技术标签')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
@ -207,19 +209,21 @@ class MemoNew extends Component {
|
|
|
|
|
// collect attachments
|
|
|
|
|
const $ = window.$;
|
|
|
|
|
const attachmentsMap = {};
|
|
|
|
|
const attachmentIds = []
|
|
|
|
|
$('#attachments_fields .attachment').each(( index, item ) => {
|
|
|
|
|
const filename = $(item).find('.upload_filename').val();
|
|
|
|
|
// $($('#attachments_fields .attachment')[0]).find('input:nth-child(6)').val()
|
|
|
|
|
const token = $(item).find('input:nth-child(7)').val()
|
|
|
|
|
const attachment_id = parseInt($(item).children().last().val())
|
|
|
|
|
attachmentsMap[index] = {
|
|
|
|
|
filename,
|
|
|
|
|
token,
|
|
|
|
|
attachment_id
|
|
|
|
|
}
|
|
|
|
|
attachmentIds.push(attachment_id)
|
|
|
|
|
const attachmentIds = this.state.fileList.map(item => {
|
|
|
|
|
return item.response ? item.response.id : item.id
|
|
|
|
|
})
|
|
|
|
|
// $('#attachments_fields .attachment').each(( index, item ) => {
|
|
|
|
|
// const filename = $(item).find('.upload_filename').val();
|
|
|
|
|
// // $($('#attachments_fields .attachment')[0]).find('input:nth-child(6)').val()
|
|
|
|
|
// const token = $(item).find('input:nth-child(7)').val()
|
|
|
|
|
// const attachment_id = parseInt($(item).children().last().val())
|
|
|
|
|
// attachmentsMap[index] = {
|
|
|
|
|
// filename,
|
|
|
|
|
// token,
|
|
|
|
|
// attachment_id
|
|
|
|
|
// }
|
|
|
|
|
// attachmentIds.push(attachment_id)
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (currentMemoId) {
|
|
|
|
@ -253,7 +257,7 @@ class MemoNew extends Component {
|
|
|
|
|
// language: memoLanguage.join(languageSeparator),
|
|
|
|
|
//
|
|
|
|
|
// },
|
|
|
|
|
attachments: attachmentsMap
|
|
|
|
|
attachment_ids: attachmentsMap
|
|
|
|
|
}, {
|
|
|
|
|
// withCredentials: true,
|
|
|
|
|
})
|
|
|
|
@ -263,7 +267,7 @@ class MemoNew extends Component {
|
|
|
|
|
window.$("html,body").animate({"scrollTop":0})
|
|
|
|
|
this.props.history.push(`/forums/${currentMemoId}`)
|
|
|
|
|
} else {
|
|
|
|
|
this.props.showSnackbar(message)
|
|
|
|
|
this.props.showNotification(message)
|
|
|
|
|
}
|
|
|
|
|
}).catch((error) => {
|
|
|
|
|
console.log(error)
|
|
|
|
@ -283,7 +287,7 @@ class MemoNew extends Component {
|
|
|
|
|
// repertoire_name: memoRepertoire,
|
|
|
|
|
|
|
|
|
|
// },
|
|
|
|
|
attachments: attachmentsMap
|
|
|
|
|
attachment_ids: attachmentsMap
|
|
|
|
|
}, {
|
|
|
|
|
// withCredentials: true,
|
|
|
|
|
})
|
|
|
|
@ -293,7 +297,7 @@ class MemoNew extends Component {
|
|
|
|
|
window.$("html,body").animate({"scrollTop":0})
|
|
|
|
|
this.props.history.push(`/forums/${memo_id}`)
|
|
|
|
|
} else {
|
|
|
|
|
this.props.showSnackbar(message)
|
|
|
|
|
this.props.showNotification(message)
|
|
|
|
|
}
|
|
|
|
|
}).catch((error) => {
|
|
|
|
|
console.log(error)
|
|
|
|
@ -349,7 +353,7 @@ class MemoNew extends Component {
|
|
|
|
|
if (tag_list) {
|
|
|
|
|
// this.setState({...response.data})
|
|
|
|
|
const { content, forum_id, id, repertoire_name, subject,
|
|
|
|
|
current_user, tag_list, attachments_url, memo_tags } = response.data;
|
|
|
|
|
current_user, tag_list, attachments_url, memo_tags, attachments } = response.data;
|
|
|
|
|
this.initMD(content);
|
|
|
|
|
// this.onRepertoiresChange(repertoire_name)
|
|
|
|
|
// tag -> memo_tags
|
|
|
|
@ -360,7 +364,18 @@ class MemoNew extends Component {
|
|
|
|
|
return item.id + ""
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
const fileList = attachments.map(item => {
|
|
|
|
|
return {
|
|
|
|
|
id: item.id,
|
|
|
|
|
uid: item.id,
|
|
|
|
|
name: appendFileSizeToUploadFile(item),
|
|
|
|
|
url: item.url,
|
|
|
|
|
filesize: item.filesize,
|
|
|
|
|
status: 'done'
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
this.setState({
|
|
|
|
|
fileList,
|
|
|
|
|
currentMemoId: memoId,
|
|
|
|
|
memoSubject: subject,
|
|
|
|
|
memoType: forum_id,
|
|
|
|
@ -466,7 +481,7 @@ class MemoNew extends Component {
|
|
|
|
|
|
|
|
|
|
onTagChange(value) {
|
|
|
|
|
if (value && value.length > 3) {
|
|
|
|
|
this.props.showSnackbar(`最多选择3个技术标签`)
|
|
|
|
|
this.props.showNotification(`最多选择3个技术标签`)
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -531,6 +546,55 @@ class MemoNew extends Component {
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
return attachments;
|
|
|
|
|
}
|
|
|
|
|
handleChange = (info) => {
|
|
|
|
|
let fileList = info.fileList;
|
|
|
|
|
this.setState({
|
|
|
|
|
fileList: appendFileSizeToUploadFileAll(fileList)
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
onAttachmentRemove = (file) => {
|
|
|
|
|
this.props.confirm({
|
|
|
|
|
// title: '确定要删除这个附件吗?',
|
|
|
|
|
content: '是否确认删除?',
|
|
|
|
|
|
|
|
|
|
okText: '确定',
|
|
|
|
|
cancelText: '取消',
|
|
|
|
|
// content: 'Some descriptions',
|
|
|
|
|
onOk: () => {
|
|
|
|
|
this.deleteAttachment(file)
|
|
|
|
|
},
|
|
|
|
|
onCancel() {
|
|
|
|
|
console.log('Cancel');
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
deleteAttachment = (file) => {
|
|
|
|
|
// 初次上传不能直接取uid
|
|
|
|
|
const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
|
|
|
|
|
axios.delete(url, {
|
|
|
|
|
})
|
|
|
|
|
.then((response) => {
|
|
|
|
|
if (response.data) {
|
|
|
|
|
const { status } = response.data;
|
|
|
|
|
if (status == 0) {
|
|
|
|
|
console.log('--- success')
|
|
|
|
|
|
|
|
|
|
this.setState((state) => {
|
|
|
|
|
const index = state.fileList.indexOf(file);
|
|
|
|
|
const newFileList = state.fileList.slice();
|
|
|
|
|
newFileList.splice(index, 1);
|
|
|
|
|
return {
|
|
|
|
|
fileList: newFileList,
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(function (error) {
|
|
|
|
|
console.log(error);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
render() {
|
|
|
|
|
const { match, history } = this.props
|
|
|
|
@ -538,8 +602,28 @@ class MemoNew extends Component {
|
|
|
|
|
// repertoires, repertoiresTagMap, currentSelectRepertoiresIndex, memoRepertoire,
|
|
|
|
|
tag_list,
|
|
|
|
|
memoSubject, memoType,
|
|
|
|
|
memoLanguage, attachments_url } = this.state;
|
|
|
|
|
memoLanguage, attachments_url, fileList } = this.state;
|
|
|
|
|
const memoId = match.params.memoId;
|
|
|
|
|
|
|
|
|
|
const uploadProps = {
|
|
|
|
|
width: 600,
|
|
|
|
|
fileList,
|
|
|
|
|
multiple: true,
|
|
|
|
|
// https://github.com/ant-design/ant-design/issues/15505
|
|
|
|
|
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
|
|
|
|
|
// showUploadList: false,
|
|
|
|
|
action: `${getUploadActionUrl()}`,
|
|
|
|
|
onChange: this.handleChange,
|
|
|
|
|
onRemove: this.onAttachmentRemove,
|
|
|
|
|
beforeUpload: (file) => {
|
|
|
|
|
console.log('beforeUpload', file.name);
|
|
|
|
|
const isLt150M = file.size / 1024 / 1024 < 150;
|
|
|
|
|
if (!isLt150M) {
|
|
|
|
|
// message.error('文件大小必须小于150MB!');
|
|
|
|
|
}
|
|
|
|
|
return isLt150M;
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
return (
|
|
|
|
|
<div >
|
|
|
|
|
<div className="pt20 pl20 pr20 pb20 bor-bottom-greyE clearfix" style={{background: '#fff'}}>
|
|
|
|
@ -592,13 +676,13 @@ class MemoNew extends Component {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<form className="newForm">
|
|
|
|
|
{/* <form className="newForm">
|
|
|
|
|
<span id={`attachments_fields`} className="attachments_fields"
|
|
|
|
|
xmlns="http://www.w3.org/1999/html">
|
|
|
|
|
{ attachments_url && !!attachments_url.length &&
|
|
|
|
|
this.renderAttachment()
|
|
|
|
|
}
|
|
|
|
|
</span>
|
|
|
|
|
</span>
|
|
|
|
|
<span className="add_attachment">
|
|
|
|
|
<input className="file_selector" data-are-you-sure="您确定要删除吗?"
|
|
|
|
|
data-delete-all-files="您确定要删除所有文件吗" data-description-placeholder="可选的描述"
|
|
|
|
@ -610,19 +694,39 @@ class MemoNew extends Component {
|
|
|
|
|
onChange={()=>{debugger;window.addInputFiles( window.$('.file_selector')[0] ) }}
|
|
|
|
|
style={{'display':'none'}} type="file">
|
|
|
|
|
</input>
|
|
|
|
|
</span>
|
|
|
|
|
</form>
|
|
|
|
|
</span>
|
|
|
|
|
</form>*/}
|
|
|
|
|
|
|
|
|
|
<style>{`
|
|
|
|
|
.memo_upload.upload_1 {
|
|
|
|
|
margin-left: 36px;
|
|
|
|
|
}
|
|
|
|
|
.memo_upload.upload_1 .ant-upload-list {
|
|
|
|
|
margin-left: 30px;
|
|
|
|
|
}
|
|
|
|
|
.memo_upload.upload_1 .ant-upload-list-item-info .anticon-paper-clip {
|
|
|
|
|
top: 4px;
|
|
|
|
|
}
|
|
|
|
|
`}</style>
|
|
|
|
|
{/*<Upload {...this.uploaderProps} ref="inner"><a>开始上传</a></Upload>*/}
|
|
|
|
|
<Upload {...uploadProps} className="upload_1 memo_upload" >
|
|
|
|
|
<Button className="uploadBtn">
|
|
|
|
|
<Icon type="upload" /> 上传附件
|
|
|
|
|
</Button>
|
|
|
|
|
(单个文件150M以内)
|
|
|
|
|
</Upload>
|
|
|
|
|
|
|
|
|
|
{/* 请求status 422 */}
|
|
|
|
|
<div className="df uploadBtn">
|
|
|
|
|
|
|
|
|
|
{/* <Icon type="upload" ></Icon> */}
|
|
|
|
|
{/* <div className="df uploadBtn">
|
|
|
|
|
<a href="javascript:void(0);" className="fl" onClick={()=>window.$('#_file').click()}
|
|
|
|
|
data-tip-down="请选择文件上传">
|
|
|
|
|
<i className="fa fa-upload mr5 color-blue"></i>
|
|
|
|
|
<span className="color-blue"> <Icon type="upload" > 上传附件</Icon></span><span style={{color: '#CDCDCD', fontSize: "14px"}}>(单个文件50M以内)</span>
|
|
|
|
|
<span className="color-blue"> 上传附件
|
|
|
|
|
</span><span style={{color: '#CDCDCD', fontSize: "14px"}}>(单个文件50M以内)</span>
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div> */}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{/* TODOTODO 这里重复的html代码太多,如果有其他页面有类似需求,需要封装*/}
|
|
|
|
|