众包发布需求

project_pack
杨树明 6 years ago
parent 0d5748ab18
commit c368f8037a

@ -25,6 +25,12 @@ class NotFoundPage extends Component {
<Link to="/test">test</Link>
|
<Link to="/demo">上海社区</Link>
|
<Link to={"/project_packages"}>zb</Link>
|
<Link to={"/project_packages/new"}>zbne</Link>
</div>
);
}

@ -0,0 +1,336 @@
import React, {Component} from 'react';
import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal} from 'antd';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
import { getImageUrl, toPath, getUrl } from 'educoder';
require('codemirror/lib/codemirror.css');
let origin = getUrl();
let path = getUrl("/editormd/lib/")
const $ = window.$;
let timeout;
let currentValue;
const Option = Select.Option;
const RadioGroup = Radio.Group;
// 保存数据
function md_add_data(k,mdu,d){
window.sessionStorage.setItem(k+mdu,d);
}
// 清空保存的数据
function md_clear_data(k,mdu,id){
window.sessionStorage.removeItem(k+mdu);
var id1 = "#e_tip_"+id;
var id2 = "#e_tips_"+id;
if(k == 'content'){
$(id2).html(" ");
}else{
$(id1).html(" ");
}
}
window.md_clear_data = md_clear_data
// editor 存在了jquery对象上应用不需要自己写md_rec_data方法了
function md_rec_data(k, mdu, id) {
if (window.sessionStorage.getItem(k + mdu) !== null) {
var editor = $("#e_tips_" + id).data('editor');
editor.setValue(window.sessionStorage.getItem(k + mdu));
// debugger;
// /shixuns/b5hjq9zm/challenges/3977/tab=3 setValue可能导致editor样式问题
md_clear_data(k, mdu, id);
}
}
window.md_rec_data = md_rec_data;
function md_elocalStorage(editor,mdu,id){
if (window.sessionStorage){
var oc = window.sessionStorage.getItem('content'+mdu);
if(oc !== null ){
console.log("#e_tips_"+id)
$("#e_tips_"+id).data('editor', editor);
var h = '您上次有已保存的数据,是否<a style="cursor: pointer;" class="link-color-blue" onclick="md_rec_data(\'content\',\''+ mdu + '\',\'' + id + '\')">恢复</a> ? / <a style="cursor: pointer;" class="link-color-blue" onclick="md_clear_data(\'content\',\''+ mdu + '\',\'' + id + '\')">不恢复</a>';
$("#e_tips_"+id).html(h);
}
setInterval(function() {
var d = new Date();
var h = d.getHours();
var m = d.getMinutes();
var s = d.getSeconds();
h = h < 10 ? '0' + h : h;
m = m < 10 ? '0' + m : m;
s = s < 10 ? '0' + s : s;
if(editor.getValue().trim() != ""){
md_add_data("content",mdu,editor.getValue());
var id1 = "#e_tip_"+id;
var id2 = "#e_tips_"+id;
var textStart = " 数据已于 "
var text = textStart + h + ':' + m + ':' + s +" 保存 ";
// 占位符
var oldHtml = $(id2).html();
if (oldHtml && oldHtml != ' ' && oldHtml.startsWith(textStart) == false) {
$(id2).html( oldHtml.split(' (')[0] + ` (${text})`);
} else {
$(id2).html(text);
}
// $(id2).html("");
}
},10000);
}else{
$("#e_tip_"+id).after('您的浏览器不支持localStorage.无法开启自动保存草稿服务,请升级浏览器!');
}
}
function create_editorMD(id, width, high, placeholder, imageUrl, callback, initValue,
onchange, watch, { noStorage, showNullButton }, that) {
// 还是出现了setting只有一份被共用的问题
var editorName = window.editormd(id, {
width: width,
height: high===undefined?400:high,
path: path, // "/editormd/lib/"
markdown : initValue,
dialogLockScreen: false,
watch:watch===undefined?true:watch,
syncScrolling: "single",
tex: true,
tocm: true,
emoji: true,
taskList: true,
codeFold: true,
searchReplace: true,
htmlDecode: "style,script,iframe",
sequenceDiagram: true,
autoFocus: false,
// mine
toolbarIcons: function (mdEditor) {
let react_id = `react_${id}`;
const __that = window[react_id]
// Or return editormd.toolbarModes[name]; // full, simple, mini
// Using "||" set icons align right.
const icons = ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "|", "testIcon", "testIcon1", '|', "image", "table", '|', "watch", "clear"];
if (__that.props.showNullButton) {
icons.push('nullBtton')
}
return icons
},
toolbarCustomIcons: {
testIcon: "<a type=\"inline\" class=\"latex\" ><div class='zbg'></div></a>",
testIcon1: "<a type=\"latex\" class=\"latex\" ><div class='zbg_latex'></div></a>",
nullBtton: "<a type=\"nullBtton\" class='pr' title='增加填空'><div class='border-left'><span></span></div><span class='fillTip'>点击插入填空项</span><i class=\"iconfont icon-edit font-16\"></i></a>",
},
//这个配置在simple.html中并没有但是为了能够提交表单使用这个配置可以让构造出来的HTML代码直接在第二个隐藏的textarea域中方便post提交表单。
saveHTMLToTextarea: true,
// 用于增加自定义工具栏的功能可以直接插入HTML标签不使用默认的元素创建图标
dialogMaskOpacity: 0.6,
placeholder: placeholder,
imageUpload: true,
imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp", "JPG", "JPEG", "GIF", "PNG", "BMP", "WEBP"],
imageUploadURL: imageUrl,//url
onchange: onchange,
onload: function() {
let _id = this.id // 如果要使用this这里不能使用箭头函数
let _editorName = this;
let react_id = `react_${_editorName.id}`;
const __that = window[react_id]
// this.previewing();
// let _id = id;
$("#" + _id + " [type=\"latex\"]").bind("click", function () {
_editorName.cm.replaceSelection("```latex");
_editorName.cm.replaceSelection("\n");
_editorName.cm.replaceSelection("\n");
_editorName.cm.replaceSelection("```");
var __Cursor = _editorName.cm.getDoc().getCursor();
_editorName.cm.setCursor(__Cursor.line - 1, 0);
});
$("#" + _id + " [type=\"inline\"]").bind("click", function () {
_editorName.cm.replaceSelection("$$$$");
var __Cursor = _editorName.cm.getDoc().getCursor();
_editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 2);
_editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");
$("[type=\"latex\"]").attr("title", "多行公式");
if (__that.props.showNullButton) {
const NULL_CH = '▁'
// const NULL_CH = ''
// const NULL_CH = '🈳'
$("#" + _id + " [type=\"nullBtton\"]").bind("click", function () {
_editorName.cm.replaceSelection(NULL_CH);
// var __Cursor = _editorName.cm.getDoc().getCursor();
// _editorName.cm.setCursor(__Cursor.line - 1, 0);
});
}
if (noStorage == true) {
} else {
md_elocalStorage(_editorName, `MDEditor__${_id}`, _id);
}
callback && callback(_editorName)
}
});
return editorName;
}
export default class MDEditors extends Component {
constructor(props) {
super(props)
this.state = {
initValue: ''
}
}
componentDidUpdate(prevProps, prevState) {
// 不能加,影响了试卷填空题
// if (this.props.initValue != prevProps.initValue) {
// this.answers_editormd.setValue(this.props.initValue)
// }
}
// react_mdEditor_
componentDidMount = () => {
const { mdID, initValue, placeholder, showNullButton} = this.props;
let _id = `mdEditor_${mdID}`
this.contentChanged = false;
const _placeholder = placeholder || "";
// amp;
// 编辑时要传memoId
const imageUrl = `/api/attachments.json`;
// 创建editorMd
let react_id = `react_${_id}`;
window[react_id] = this
const answers_editormd = create_editorMD(_id, '100%', this.props.height, _placeholder, imageUrl, (__editorName) => {
react_id = `react_${__editorName.id}`;
const that = window[react_id]
setTimeout(() => {
console.log('timeout', __editorName.id)
__editorName.resize()
__editorName.cm && __editorName.cm.refresh()
}, that.props.refreshTimeout || 500)
if (that.props.initValue != undefined && that.props.initValue != '') {
__editorName.setValue(that.props.initValue)
}
if (that.state.initValue) {
__editorName.setValue(that.state.initValue)
}
__editorName.cm.on("change", (_cm, changeObj) => {
that.contentChanged = true;
if (that.state.showError) {
that.setState({showError: false})
}
that.onEditorChange()
})
that.props.onCMBlur && __editorName.cm.on('blur', () => {
that.props.onCMBlur()
})
that.props.onCMBeforeChange && __editorName.cm.on('beforeChange', (cm,change) => {
that.props.onCMBeforeChange(cm,change)
})
that.answers_editormd = __editorName;
window[_id] = __editorName;
}, initValue, this.onEditorChange,this.props.watch, {
noStorage: this.props.noStorage,
showNullButton: this.props.showNullButton
}, this);
}
showError = () => {
this.setState({showError: true})
}
onEditorChange = () => {
if (!this.answers_editormd) return;
const val = this.answers_editormd.getValue();
try {
this.props.onChange && this.props.onChange(val)
} catch(e) {
// http://localhost:3007/courses/1309/common_homeworks/6566/setting
// 从这个页面,跳转到编辑页面,再在编辑页面点击返回的时候,这里会报错
console.error('出错')
console.error(e)
}
}
resize = () => {
if (!this.answers_editormd) { // 还未初始化
return;
}
this.answers_editormd.resize()
this.answers_editormd.cm && this.answers_editormd.cm.refresh()
this.answers_editormd.cm.focus()
}
getValue = () => {
try {
return this.answers_editormd.getValue()
} catch (e) {
return ''
}
}
setValue = (val) => {
try {
this.answers_editormd.setValue(val)
} catch (e) {
// TODO 这里多实例的时候前一个实例的state会被后面这个覆盖 参考NewWork.js http://localhost:3007/courses/1309/homework/9300/edit/1
// 未初始化
this.setState({ initValue: val })
}
}
render() {
let {
showError
} = this.state;
let { mdID, className, noStorage } = this.props;
let _style = {}
if (showError) {
_style.border = '1px solid red'
}
return (
<React.Fragment>
<div className={`df ${className}`} >
{/* padding10-20 */}
<div className="edu-back-greyf5 radius4" id={`mdEditor_${mdID}`} style={{..._style}}>
<textarea style={{display: 'none'}} id="evaluate_script_show" name="content"></textarea>
<div className="CodeMirror cm-s-defualt">
</div>
</div>
</div>
<div className={"fr rememberTip"}>
{noStorage == true ? ' ' : <p id={`e_tips_mdEditor_${mdID}`} className="edu-txt-right color-grey-cd font-12"> </p>}
{/* {noStorage == true ? ' ' : <p id={`e_tips_mdEditor_${mdID}`} className="edu-txt-right color-grey-cd font-12"> </p>} */}
</div>
</React.Fragment>
)
}
}

@ -28,9 +28,9 @@ class PackageIndexNEIBanner extends Component {
<div className="edu-back-white mb20 PackageIndexNEIBanner">
<p className="clearfix padding110">
<Steps current={current} >
<Step title="发布需求"onClick={()=>this.onChange(0)}/>
<Step title="筛选合适的接包方" onClick={()=>this.onChange(1)}/>
<Step title="线下交易,完成实施"onClick={()=>this.onChange(2)}/>
<Step title="发布需求"/>
<Step title="筛选合适的接包方"/>
<Step title="线下交易,完成实施"/>
</Steps>
</p>
</div>

@ -1,30 +1,44 @@
import React, {Component} from 'react';
import {Link} from "react-router-dom";
import axios from 'axios';
import { Input ,Icon,Button,Pagination} from 'antd';
import { Input ,Icon,Button,Pagination,DatePicker} from 'antd';
import locale from 'antd/lib/date-picker/locale/zh_CN';
import MDEditors from '../MDEditors';
import '../packageconcnet.css';
const { Search } = Input;
class PackageIndexNEIBannerConcent extends Component {
constructor(props) {
super(props)
this.contentMdRef = React.createRef();
this.state = {
}
}
componentDidMount() {
}
setclick=()=>{
const mdContnet = this.contentMdRef.current.getValue().trim();
console.log(mdContnet)
}
onChangeTimePicker = (value, dateString) => {
this.setState({
TimePickervalue: dateString
})
}
render() {
return (
<div className="edu-back-white mb20">
<div className="mb20">
<p className="clearfix ">
<div className={"stud-class-set padding30 coursenavbox edu-back-white"}>
<div className={"ant-row ant-form-item contentbox mdInForm "}>
<div className={"stud-class-set pd30a0 coursenavbox edu-back-white"}>
<div className={"ant-row contentbox mdInForm "}>
<div className="ant-form-item-label mb10">
<label htmlFor="coursesNew_description" className="ant-form-item-required font-16">请选择需求类型</label>
</div>
@ -44,19 +58,133 @@ class PackageIndexNEIBannerConcent extends Component {
<div className="ant-form-item-label mb10">
<label htmlFor="coursesNew_description" className="ant-form-item-required font-16">需求标题和详情</label>
<label htmlFor="coursesNew_description" className="ant-form-item-required font-16" >需求标题和详情</label>
</div>
<Input placeholder="请输入需求标题示例美食类APP开发最大限制60个字符" maxLength="60" className="input-100-40s mt5 fafafas" />
<Input placeholder="请输入需求标题示例美食类APP开发最大限制60个字符" maxLength="60" className="input-100-40s mt5 fafafas mb20" />
<MDEditors ref={this.contentMdRef} placeholder="请填写清晰完整的需求内容" mdID={'courseContentMD'} refreshTimeout={5000}
watch={false} className="courseMessageMD" initValue={this.state.description}></MDEditors>
{/* 请求status 422 */}
<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">上传附件</span>
</a>
<span style={{ fontSize: "14px"}}>(最多可添加 <span className={"color-orange06"}>5</span> / <span className={"color-orange06"}>10MB</span>)</span>
</div>
<form className="newForm newFormbox mt10 mb20">
<span id={`attachments_fields`} className="attachments_fields"
xmlns="http://www.w3.org/1999/html">
</span>
<span className="add_attachment">
<input className="file_selector"
data-are-you-sure="您确定要删除吗?"
data-delete-all-files="您确定要删除所有文件吗"
data-description-placeholder="可选的描述"
data-field-is-public="公开"
data-file-count="个文件已上传"
data-lebel-file-uploding="个文件正在上传"
data-max-concurrent-uploads="2"
data-max-file-size-message="该文件无法上传。超过文件大小限制 (10 MB)建议上传到百度云等其他共享工具里然后在txt文档里给出链接以及共享密码并上传"
data-max-file-size="10485760" data-upload-path="/uploads.js"
id="_file"
multiple="multiple" name="attachments[dummy][file]"
onChange={() => {
debugger;
window.addInputFiles(window.$('.file_selector')[0])
}}
style={{'display': 'none'}} type="file">
</input>
</span>
</form>
</div>
</div>
<div className={"stud-class-set padding30 coursenavbox edu-back-white"} style={{borderTop: '1px solid #EAEAEA'}}>
<div className={"ant-row contentbox mdInForm "}>
<div className="ant-form-item-label mb10">
<label htmlFor="coursesNew_description" className="ant-form-item-required font-16">工期与预算</label>
</div>
<p className="clearfix mb20 shaiContent">
<span className="shaiTitle fl mt5 ml10">竞标截止</span>
<DatePicker
showToday={false}
showTime
locale={locale}
style={{"width": "260px"}}
format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择任务的竞标截止日期"
className={"fafas"}
onChange={this.onChangeTimePicker}
/>
</p>
<p className="clearfix mb20 shaiContent">
<span className="shaiTitle fl mt5 ml10">支付费用</span>
<Input
className={"fafas"}
style={{"width": "260px"}}
format="YYYY-MM-DD HH:mm:ss"
placeholder="支付多少费用(最低)"
onChange={this.onChangeTimePicker}
suffix={
<span >¥</span>
}
/>
<span className={"ml10 mr10"}></span>
<Input
className={"fafas"}
style={{"width": "260px"}}
format="YYYY-MM-DD HH:mm:ss"
placeholder="支付多少费用(最高)"
onChange={this.onChangeTimePicker}
suffix={
<span >¥</span>
}
/>
</p>
<div className="ant-form-item-label mb10">
<label htmlFor="coursesNew_description" className="ant-form-item-required font-16" >联系方式</label>
</div>
<p className="clearfix mb20 shaiContent">
<span className="shaiTitle fl mt5 ml38">姓名</span>
<Input
className={"fafafas"}
style={{"width": "260px"}}
format="YYYY-MM-DD HH:mm:ss"
placeholder="请输入姓名"
onChange={this.onChangeTimePicker}
/>
</p>
<p className="clearfix mb20 shaiContent">
<span className="shaiTitle fl mt5 ml25">手机号</span>
<Input
className={"fafafas fl"}
style={{"width": "260px"}}
format="YYYY-MM-DD HH:mm:ss"
placeholder="请输入手机号"
disabled={true}
onChange={this.onChangeTimePicker}
/>
<a className="fl ml20">
<i className="iconfont icon-bianjidaibeijing font-26 color-blue"></i>
</a>
</p>
</div>
</div>
</p>
<div className="clearfix mt30 mb30">
<Button type="primary" className="defalutSubmitbtn fl mr20 defalutSubmitbtns">申请发布</Button>
<a className="defalutCancelbtns fl">保存</ a>
</div>
</div>
)
}

@ -57,15 +57,71 @@
.input-100-40s{
width: 100%;
height: 40px;
padding: 5px;
box-sizing: border-box;
}
.fafafas{
background-color: #fafafa!important;
height: 40px;
}
.fafafas:focus{
background-color: #fff!important;
}
.fafas .ant-input{
background-color: #fafafa!important;
height: 40px;
}
.fafas .ant-input:focus{
background-color: #fff!important;
}
.upload_filename{
line-height: 32px;
}
.attachment span{
line-height: 23px;
}
.attachment .remove-upload{
line-height: 28px;
}
.pd30a0{
padding: 30px 30px 0 30px;
}
.attachment .icon-fujian{
font-size: 12px !important;
line-height: 14px;
}
.newFormbox{
height:20px
}
.ml24{
margin-left:24px;
}
.defalutCancelbtns{
display: block;
border: 1px solid #4CACFF !important;
background-color: #fafafa;
color: #4CACFF !important;
width:130px;
height:40px;
text-align: center;
line-height: 40px;
border-radius: 4px;
}
.defalutSubmitbtns{
background-color: #4CACFF;
height:40px;
}

@ -114,7 +114,7 @@ function addFile(inputEl, file, eagerUpload,btnId) {
fileSpan.append(
$('<i></i>').attr({
'class': 'fa fa-folder mr5 color-blue fl mt8',
'class': 'color-green iconfont icon-fujian mr5 fl mt8',
'aria-hidden': true
}),
$('<input>', {

Loading…
Cancel
Save