diff --git a/public/images/educoder/project_packagesHead.jpg b/public/images/educoder/project_packagesHead.jpg new file mode 100644 index 000000000..181045e03 Binary files /dev/null and b/public/images/educoder/project_packagesHead.jpg differ diff --git a/public/react/src/App.js b/public/react/src/App.js index 49dac07cd..6d1e2a521 100644 --- a/public/react/src/App.js +++ b/public/react/src/App.js @@ -226,6 +226,12 @@ const Interestpage = Loadable({ loading: Loading, }) +//众包创新 +const ProjectPackages=Loadable({ + loader: () => import('./modules/projectPackages/ProjectPackageIndex'), + loading: Loading, +}) + class App extends Component { constructor(props) { super(props) @@ -296,6 +302,9 @@ class App extends Component { {/**/} + + {/*众包创新*/} + {/*认证*/} diff --git a/public/react/src/modules/projectPackages/MDEditors.js b/public/react/src/modules/projectPackages/MDEditors.js new file mode 100644 index 000000000..b6fee5582 --- /dev/null +++ b/public/react/src/modules/projectPackages/MDEditors.js @@ -0,0 +1,337 @@ +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 = '您上次有已保存的数据,是否恢复 ? / 不恢复'; + $("#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: "
", + testIcon1: "
", + nullBtton: "
点击插入填空项
", + }, + //这个配置在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 = `/upload_with_markdown?container_id=&container_type=Memo`; + // 创建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 = () => { + this.props.setcheckoutcontent() + 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 ( + +
+ {/* padding10-20 */} +
+ +
+
+
+
+
+ {noStorage == true ? ' ' :

 

} + {/* {noStorage == true ? ' ' :

 

} */} +
+
+ ) + } +} + + diff --git a/public/react/src/modules/projectPackages/PackageIndex/PackageBanner.js b/public/react/src/modules/projectPackages/PackageIndex/PackageBanner.js new file mode 100644 index 000000000..bc5aee524 --- /dev/null +++ b/public/react/src/modules/projectPackages/PackageIndex/PackageBanner.js @@ -0,0 +1,25 @@ +import React, {Component} from 'react'; +import {Link} from "react-router-dom"; + +class PackageBanner extends Component { + constructor(props) { + super(props) + this.state = { + + } + } + componentDidMount() { + + + } + + + render() { + return ( +
+ ) + } +} + +export default PackageBanner; + diff --git a/public/react/src/modules/projectPackages/PackageIndex/PackageConcent.js b/public/react/src/modules/projectPackages/PackageIndex/PackageConcent.js new file mode 100644 index 000000000..46e36f90f --- /dev/null +++ b/public/react/src/modules/projectPackages/PackageIndex/PackageConcent.js @@ -0,0 +1,298 @@ +import React, {Component} from 'react'; +import {Link} from "react-router-dom"; +import axios from 'axios'; +import { Input ,Icon,Button,Pagination} from 'antd'; +import moment from 'moment'; +import '../packageconcnet.css'; + +const { Search } = Input; +// let categorylist=[ +// {name:"全部",value:undefined}, +// {name:"前端开发",value:"front"}, +// {name:"后端开发",value:"backend"}, +// {name:"移动开发",value:"mobile"}, +// {name:"数据库",value:"database"}, +// {name:"云计算和大数据",value:"cloud_compute_and_big_data"}, +// {name:"人工智能",value:"ai"}, +// {name:"其他",value:"other"}, +// ] +// +// function setcategorylist(val){ +// let vals="" +// categorylist.some((item,key)=> { +// if (item.value === val) { +// vals=item.name +// return true +// } +// } +// ) +// +// return vals +// } + + + +class PackageConcent extends Component { + constructor(props) { + super(props) + this.state = { + data:undefined, + project_packages:undefined, + category:undefined, + keyword:undefined, + sort_by:"recently", + sort_direction:"desc", + page:1, + per_page:20, + categories:[] + } + } + //desc’, ‘desc’, ‘asc’ + //否 string 排序,默认最新, ‘recently’, ‘price’ + // 否 string 类型, front,backend,mobile,database, cloud_compute_and_big_data,devops_and_test,ai,other + componentDidMount() { + window.document.title = '众包创新' + let {category,keyword,sort_by,sort_direction,page}=this.state + this.setdatas(category,keyword,sort_by,sort_direction,page) + + let Url = `/project_package_categories.json`; + axios.get(Url).then((response) => { + // console.log(response) + this.setState({ + categories:response.data.categories + }) + }).catch((error) => { + console.log(error) + }) + + } + + setdatas=(category,keyword,sort_by,sort_direction,page)=>{ + + let Url = `/project_packages.json`; + axios.get(Url,{params:{ + category_id:category, + keyword:keyword, + sort_by:sort_by, + sort_direction:sort_direction, + page:page, + per_page:20, + }} + ).then((response) => { + this.setState({ + data:response.data, + project_packages:response.data.project_packages + }) + }).catch((error) => { + console.log(error) + }) + } + + setdatafuns=(value)=>{ + let {category,keyword,sort_by,sort_direction,page}=this.state + this.setState({ + keyword:value + }) + this.setdatas(category,value,sort_by,sort_direction,page) + } + + + setcategory=(value)=>{ + let {category,keyword,sort_by,sort_direction,page}=this.state + this.setState({ + category:value + }) + this.setdatas(value,keyword,sort_by,sort_direction,page) + } + + setsort_byfun=(value)=>{ + let {category,keyword,sort_by,sort_direction,page}=this.state + + this.setState({ + sort_by:value + }) + let sort_directionvalue; + if(value===sort_by){ + if(sort_direction==="desc"){ + this.setState({ + sort_direction:"asc" + }) + sort_directionvalue="asc"; + }else{ + this.setState({ + sort_direction:"desc" + }) + sort_directionvalue="desc"; + } + }else{ + this.setState({ + sort_direction:"desc" + }) + sort_directionvalue="desc"; + } + + this.setdatas(category,keyword,value,sort_directionvalue,page) + } + render() { + let {data,page,category,sort_by,sort_direction,project_packages}=this.state; + + return ( +
+ +
+
+
+
+
+ + + {/*concent*/} +
+
+

+

+ 搜索} + onSearch={ (value)=>this.setdatafuns(value)} /> + +

+

+
+
+ +
+

+

+ 类型: +

+
  • this.setcategory(undefined)}>全部
  • + {this.state.categories.map((item,key)=>{ + return( +
  • this.setcategory(item.id)}>{item.name}
  • + ) + })} + +
    +

    + +

    + 排序: +

    +
  • this.setsort_byfun("recently")}> + 最新 + + + + +
  • + +
  • this.setsort_byfun("price")}> + 价格 + + + + +
  • +
    +

    +

    +
    + + + {project_packages&&project_packages.map((item,key)=>{ + return( +
    + +
    + +
    + +
    + +
    + +
    + + + +
    + +
    + {item.min_price===null?"":¥{item.min_price}} + {item.max_price===null||item.min_price===null?"":~} + {item.max_price===null?"":¥{item.max_price}} + {item.min_price===null&&item.max_price===null?可议价:""} +
    + +
    + +
    +
    {item.category_name}
    +
    + +
    +
    + + {item.visit_count}人浏览 +
    +
    + + + {moment(item.deadline_at).endOf('day').fromNow()}竞标截止 + +
    +
    + + + {item.bidding_users_count}人竞标 + +
    +
    +
    + {item.published_at===null?更新于:{moment(item.updated_at).format("YYYY-MM-DD HH:mm")} : + 发布于:{moment(item.published_at).format("YYYY-MM-DD HH:mm")} } +
    +
    + +
    + +
    +
    + ) + })} + {project_packages&&project_packages.length===0?
    +
    + +

    暂无数据哦~

    +
    :""} + +
    + +
    + + +
    +
    +
    +
    +
    +
    + ) + } +} + +export default PackageConcent; + diff --git a/public/react/src/modules/projectPackages/PackageIndex/PackageIndex.js b/public/react/src/modules/projectPackages/PackageIndex/PackageIndex.js new file mode 100644 index 000000000..e6c7cdc98 --- /dev/null +++ b/public/react/src/modules/projectPackages/PackageIndex/PackageIndex.js @@ -0,0 +1,30 @@ +import React, { Component } from 'react'; +import {BrowserRouter as Router,Route,Switch} from 'react-router-dom'; + +//业务组件 +import PackageBanner from "./PackageBanner"; +import PackageConcent from "./PackageConcent"; + +class PackageIndex extends Component{ + constructor(props) { + super(props) + } + + componentDidMount(){ + window.document.title = '众包创新' + } + + render() { + return ( +
    +
    + {/*头部banner*/} + + {/*内容banner*/} + +
    +
    + ) + } +} +export default PackageIndex; \ No newline at end of file diff --git a/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/NEITaskDetailsModel.js b/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/NEITaskDetailsModel.js new file mode 100644 index 000000000..16e22dae0 --- /dev/null +++ b/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/NEITaskDetailsModel.js @@ -0,0 +1,41 @@ +import React, { Component } from 'react'; +import { Spin, Icon , Modal,Input,Button} from 'antd'; +class NEITaskDetailsModel extends Component { + + constructor(props) { + super(props); + this.state = { + + } + } + + render() { + + return( + +
    +

    +

    {this.props.applyvalue}
    +
    {this.props.applybottom}
    +

    +
    + 取消 + 确定 +
    + +
    +
    + ) + } +} + +export default NEITaskDetailsModel; \ No newline at end of file diff --git a/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/PackageIndexNEITaskDetails.js b/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/PackageIndexNEITaskDetails.js new file mode 100644 index 000000000..4f06a0cba --- /dev/null +++ b/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/PackageIndexNEITaskDetails.js @@ -0,0 +1,485 @@ +import React, {Component} from 'react'; +import {Link} from "react-router-dom"; +import axios from 'axios'; +import { Input ,Icon,Button,Pagination,DatePicker,Breadcrumb} from 'antd'; +import { handleDateString,markdownToHTML,bytesToSize} from 'educoder'; +import NEITaskDetailsModel from './NEITaskDetailsModel'; +import moment from 'moment'; +import '../packageconcnet.css'; +import './pds.css' +import gouxuan from './img/gouxuan.png' +import weigouxuan from './img/weigouxuan.png' +const { Search } = Input; +// let categorylist=[ +// {name:"全部",value:undefined}, +// {name:"前端开发",value:"front"}, +// {name:"后端开发",value:"backend"}, +// {name:"移动开发",value:"mobile"}, +// {name:"数据库",value:"database"}, +// {name:"云计算和大数据",value:"cloud_compute_and_big_data"}, +// {name:"人工智能",value:"ai"}, +// {name:"其他",value:"other"}, +// ] +// +// function setcategorylist(val){ +// let vals="" +// categorylist.some((item,key)=> { +// if (item.value === val) { +// vals=item.name +// return true +// } +// } +// ) +// +// return vals +// } + +class PackageIndexNEITaskDetails extends Component { + constructor(props) { + super(props) + this.contentMdRef = React.createRef(); + this.state = { + data:undefined, + modalCancel: false, + overtype:false, + setbiddingmantype:false, + datalist:[] + } + } + + componentDidMount() { + this.getdatas() + window.document.title = '众包创新' + } + + getdatas=()=>{ + let url =`/project_packages/${this.props.match.params.id}.json`; + axios.get(url).then((response) => { + this.setState({ + data:response.data + }) + }).catch((error) => { + console.log(error); + + }) + } + + setbiddingman=()=>{ + this.setState({ + setbiddingmantype:true + }) + } + + notsetbiddingman=()=>{ + let {data} =this.state; + let gouxuans2=data.bidding_users + for (var i=0;i{ + this.setState({ + modalCancel:false + }) + } + + setbiddingusers=()=>{ + let{datalist}=this.state; + if(datalist.length>0){ + this.setState({ + applytype:true, + applyvalue:`选择的${datalist.length}个竞标者将被设定为“中标”`, + applybottom:"是否确认执行?", + applycancel:this.setApplycancel, + applyconfirm:this.setApplysumbit + }) + } + + } + + setApplysumbit=()=>{ + this.setState({ + applytype:false, + }) + let{datalist}=this.state; + let newlist=[]; + datalist.map((item,key)=>{ + newlist.push(item.id) + }) + + + let url=`/project_packages/${this.props.match.params.id}/bidding_users/win.json`; + axios.post(url,{ + user_ids:newlist + }).then((response) => { + if(response.data.status===0){ + this.props.showSnackbar("提交成功"); + this.setState({ + setbiddingmantype:false + }) + this.getdatas() + }else if(response.data.status===-1){ + this.props.showSnackbar(response.data.message); + } + }).catch((error) => { + console.log(error) + }) + + } + + + + Clickteacher2=(e)=>{ + let {data} =this.state; + let newlist=[] + let gouxuans2=data.bidding_users + for (var i=0;i{ + this.setState({ + overtype:true + }) + } + + setout=()=>{ + this.setState({ + overtype:false + }) + } + + deletePackages=()=>{ + this.setState({ + applytype:true, + applyvalue:"是否确认删除?", + applycancel:this.setApplycancel, + applyconfirm:this.setApplydelect + }) + } + + setApplydelect=()=>{ + this.setState({ + applytype:false, + }) + let url=`/project_packages/${this.props.match.params.id}.json`; + axios.delete(url ).then((response) => { + // const status = response.data.status + // console.log(response) + this.props.showSnackbar('删除成功'); + }).catch((error) => { + console.log(error) + }) + } + + setBiddingApply=()=>{ + this.setState({ + applytype:true, + applyvalue:"是否确认报名?", + applycancel:this.setApplycancel, + applyconfirm:this.setApplyconfirm + }) + } + + setApplycancel=()=>{ + this.setState({ + applytype:false, + }) + } + + setApplyconfirm=()=>{ + this.setState({ + applytype:false, + }) + let url=`/project_packages/${this.props.match.params.id}/bidding_users.json`; + axios.post(url).then((response) => { + if(response.data.status===0){ + this.props.showSnackbar("报名成功"); + this.getdatas() + }else if(response.data.status===-1){ + this.props.showSnackbar(response.data.message); + } + }).catch((error) => { + console.log(error) + }) + + } + goback = () => { + window.history.go(-1) + } + + render() { + let {overtype,data}=this.state; + // console.log(data&&data.creator.login) + // console.log(this.props.current_user.login) + return ( +
    +
    + +
    + + '} className={"fl"}> + {/*{this.props.current_user.username}*/} + + 众包创新 + + {data&&data.title} + + + 返回 +
    + +

    + +

    +
    + +
    + {data&&data.status==="pending"?
    +
    + + 未申请 +
    :data&&data.status==="applying"?
    +
    + + 待发布 +
    :""} + +
    +
    +
    + + + +
    + {data&&data.creator.name} +
    + + {data&&data.creator.login===this.props.current_user.login?"":
    + {overtype===false? 头像联系TA: + 头像联系TA} +
    } +
    + + +
    + +
    + +
    + +
    + {data&&data.title} + +
    + +
    + {data&&data.min_price===null?"":{data&&data.min_price}} + {data&&data.max_price===null||data&&data.min_price===null?"":~} + {data&&data.max_price===null?"":{data&&data.max_price}} + {data&&data.min_price===null&&data&&data.max_price===null?可议价:""} +
    + +
    + +
    +
    {data&&data.category_name}
    +
    + +
    +
    + {data&&data.published_at===null? + 更新时间:{moment(data&&data.updated_at).format("YYYY-MM-DD HH:mm")} + : + 发布时间:{moment(data&&data.published_at).format("YYYY-MM-DD HH:mm")} + } +
    +
    + 竞标截止时间:{moment(data&&data.deadline_at).format("YYYY-MM-DD HH:mm")} +
    +
    + +
    + +
    +
    + +
    +
    + + {/*详情*/} +
    +
    +
    + 需求详情: + + {data&&data.status==="pending"&&data&&data.operation.can_select_bidding_user===true?
    + 编辑 + 删除 +
    :""} + +
    +
    +
    +
    + +
    + + {data&&data.attachments.length>0?
    +
    + 需求文件: +
    + {data&&data.attachments.map((item,key)=>{ + return( + + )})} +
    :""} +
    + + + + {/*发布者和竞选者状态show*/} + {this.state.setbiddingmantype===false&&data&&data.published_at!=null?
    + {/*下面是头像*/} +
    +
    +
    + 报名列表({data&&data.bidding_users.length}) +
    +
    + {data&&data.operation.can_bidding===true?:""} + {data&&data.operation.can_select_bidding_user===true?:""} +
    +
    +
    + +
    +
    +
    +
    + + {data&&data.bidding_users.map((item,key)=>{ + return( +
    + {item.status==="bidding_won"?:""} + +

    {item.name}

    + {this.props.current_user.login!=item.login? + 头像联系TA + :""} +
    + ) + })} + + {data&&data.bidding_users.length===0?
    +
    + +

    暂无人员竞标~

    +
    :""} + + +
    +
    +
    +
    :""} + + + {this.state.setbiddingmantype===true?
    + {/*发布人选择状态*/} + {/*下面是头像*/} +
    +
    +
    + 报名列表({data&&data.bidding_users.length}) +
    + +
    +
    + 已选 ({this.state.datalist.length}) +
    + 取消 + +
    +
    +
    +
    +
    +
    +
    + {data&&data.bidding_users.map((item,key)=>{ + return( +
    + ) + })} + + {data&&data.bidding_users.length===0?
    +
    + +

    暂无人员竞标~

    +
    :""} + +
    +
    +
    +
    :""} + +

    + +
    + + +
    +
    +
    + ) + } +} + +export default PackageIndexNEITaskDetails; + + + diff --git a/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/img/gouxuan.png b/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/img/gouxuan.png new file mode 100644 index 000000000..5bc53f007 Binary files /dev/null and b/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/img/gouxuan.png differ diff --git a/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/img/weigouxuan.png b/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/img/weigouxuan.png new file mode 100644 index 000000000..40ca55728 Binary files /dev/null and b/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/img/weigouxuan.png differ diff --git a/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/newsone.png b/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/newsone.png new file mode 100755 index 000000000..9aadd57c2 Binary files /dev/null and b/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/newsone.png differ diff --git a/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/newstwo.png b/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/newstwo.png new file mode 100755 index 000000000..8ac58b2c4 Binary files /dev/null and b/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/newstwo.png differ diff --git a/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/pds.css b/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/pds.css new file mode 100644 index 000000000..a6f9e10dc --- /dev/null +++ b/public/react/src/modules/projectPackages/PackageIndexNEITaskDetails/pds.css @@ -0,0 +1,60 @@ +.ysldivhome2{ + display: flex; + flex-flow: row wrap; + align-content:stretch; + flex-direction: row; + margin-bottom: 20px; +} + +.ysllogin_register_contents{ + display: flex; + margin-top: 20px; + /*justify-content: center;*/ + background: #fff; +} + +.ysllogin_register_contentss{ + margin-top:0px !important; + padding-top: 10px; + padding-bottom: 10px; +} + +.ysldivhomediv1{ + width: 80px; + height: 130px; + display: flex; + flex-direction:column; + margin-left: 48px; + margin-top: 20px; +} +.yslgouxuanimg{ + width: 20px; + height: 20px; + margin-left: 64px; + +} +.yslgouxuanimg2{ + height: 20px; +} +.div1img{ + display: flex; + justify-content:center; + width: 80px; + height: 80px; + border-radius:50%; + +} +.textall{ + text-align: center; + font-size: 13px; + color: #4B4B4B; + +} +.ptext{ + width: 80px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; +} +.ysllogin_section { + display: flex; + align-items: center; + flex-direction: column; +} \ No newline at end of file diff --git a/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNEIBanner.js b/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNEIBanner.js new file mode 100644 index 000000000..ffb28d3df --- /dev/null +++ b/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNEIBanner.js @@ -0,0 +1,41 @@ +import React, {Component} from 'react'; +import {Link} from "react-router-dom"; +import { Steps, Divider } from 'antd'; +const { Step } = Steps; + +class PackageIndexNEIBanner extends Component { + constructor(props) { + super(props) + this.state = { + current:0 + } + } + componentDidMount() { + + + } + + onChange=(current)=>{ + debugger + console.log('onChange:', current); + this.setState({ current }); + }; + + render() { + const { current } = this.state; + return ( +
    +

    + + + + + +

    +
    + ) + } +} + +export default PackageIndexNEIBanner; + diff --git a/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNEIBannerConcent.js b/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNEIBannerConcent.js new file mode 100644 index 000000000..e7e4b20a2 --- /dev/null +++ b/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNEIBannerConcent.js @@ -0,0 +1,932 @@ +import React, {Component} from 'react'; +import {Link} from "react-router-dom"; +import axios from 'axios'; +import { Input , Spin, Icon ,Button,Pagination,DatePicker} from 'antd'; +import { handleDateString,getUrl,bytesToSize} from 'educoder'; +import locale from 'antd/lib/date-picker/locale/zh_CN'; +import MDEditors from '../MDEditors'; +import PhoneModel from './PhoneModel'; +import moment from 'moment'; +import '../packageconcnet.css'; +const { Search } = Input; +const $ = window.$; +let origin = getUrl(); + +// load +if (!window.postUpMsg) { + $.getScript( + `${origin}/javascripts/attachments.js`, + (data, textStatus, jqxhr) => { + + }); +} + + +function checkPhone(phone){ + + if(!(/^1[3456789]\d{9}$/.test(phone))){ + // alert("手机号码有误,请重填"); + return false; + } +} + +function range(start, end) { + const result = []; + for (let i = start; i < end; i++) { + result.push(i); + } + return result; +} + +function disabledDateTime() { + return { + disabledMinutes: () => range(1, 30).concat(range(31, 60)), + }; +} +class PackageIndexNEIBannerConcent extends Component { + constructor(props) { + super(props) + this.contentMdRef = React.createRef(); + this.state = { + modalCancel:false, + getverificationcodes:true, + seconds:35, + springtype:false, + category:undefined, + title:undefined, + content:undefined, + attachment_ids:undefined, + deadline_at:undefined, + min_price:undefined, + max_price:undefined, + contact_name:undefined, + contact_phone:undefined, + code:undefined, + publish:false, + categories:[] + } + } + componentDidUpdate = (prevProps) => { + if(prevProps.current_user.username!=this.props.current_user.username){ + this.setState({ + contact_name:this.props.current_user.username + }) + } + } + + componentDidMount() { + window.document.title = '众包创新' + if(this.props.match.params.id!=undefined){ + + let url=`/project_packages/${this.props.match.params.id}.json` + axios.get((url)).then((response) => { + console.log(response) + let data=response.data + this.setState({ + category:data.category_id, + title:data.title, + content:data.content, + deadline_at:moment(data.deadline_at), + min_price:data.min_price, + max_price:data.max_price, + contact_name:data.contact_name==null||data.contact_name==undefined?this.props.current_user.username:data.contact_name, + phones:data.contact_phone, + attachments:data.attachments, + + }) + }).catch((error) => { + console.log(error); + + }) + }else{ + this.setState({ + contact_name:this.props.current_user.username + }) + } + + let Url = `/project_package_categories.json`; + axios.get(Url).then((response) => { + // console.log(response) + if(response.data.status===-1){ + + }else{ + this.setState({ + categories:response.data.categories + }) + } + + }).catch((error) => { + console.log(error) + }) + + // this.contentMdRef.current.setValue("测试赋值") + } + //获取验证码; + getverificationcode =()=>{ + // if (this.state.logins&&this.state.logins.length === 0) { + // // 判断没有输入手机号 + // return + // } + if(this.state.getverificationcodes === undefined){ + console.log("undefined"); + return; + } + if (this.state.getverificationcodes === true) { + this.setState({ + getverificationcodes: undefined, + }) + let timer = setInterval(() => { + this.setState((preState) => ({ + seconds: preState.seconds - 1, + }), () => { + if (this.state.seconds == 0) { + clearInterval(timer); + this.setState({ + getverificationcodes: false, + seconds: 35, + }) + } + }); + }, 1000) + //其他的网络请求也可以 + this.SMSverification(); + } else { + this.setState({ + getverificationcodes: undefined, + }) + let timer = setInterval(() => { + this.setState((preState) => ({ + seconds: preState.seconds - 1, + }), () => { + if (this.state.seconds == 0) { + clearInterval(timer); + this.setState({ + getverificationcodes: false, + seconds: 35, + + }) + } + }); + }, 1000) + //其他的网络请求也可以 + this.SMSverification(); + } + } + //短信验证 + SMSverification = () => { + let {contact_phone,code}=this.state; + var url = `/account/get_verification_code.json`; + axios.get((url), { + params: { + value: contact_phone, + type: 9, + } + }).then((result) => { + //验证有问题{"status":1,"message":"success"} + // console.log(result); + this.openNotification("验证码已发送,请注意查收!",2); + + + }).catch((error) => { + console.log(error); + + }) + } + + + onChangeTimePicker = (value, dateString) => { + if(value===null){ + this.setState({ + deadline_at:"" + }) + }else{ + if(moment(handleDateString(dateString))===undefined||moment(handleDateString(dateString))===null||moment(handleDateString(dateString))===""){ + this.setState({ + deadline_attypes:true + }) + }else{ + this.setState({ + deadline_attypes:false + }) + } + if(moment(handleDateString(dateString)){ + const content = this.contentMdRef.current.getValue().trim(); + if(content===undefined||content===null||content===""){ + this.setState({ + contenttypes:true + }) + }else{ + this.setState({ + contenttypes:false + }) + } + } + + + setcheckout=(min_price,max_price)=>{ + // if(min_price===undefined){ + // this.setState({ + // min_pricetype:true + // }) + // }else{ + // this.setState({ + // min_pricetype:false + // }) + // } + + + // if(parseInt(min_price)===undefined||parseInt(min_price)===null||parseInt(min_price)===""){ + // + // this.setState({ + // min_pricetype:true + // }) + // }else{ + // this.setState({ + // min_pricetype:false + // }) + // } + + // if(parseInt(max_price)===undefined||parseInt(max_price)===null||parseInt(max_price)===""){ + // + // this.setState({ + // min_pricetype:true + // }) + // + // }else{ + // this.setState({ + // min_pricetype:false + // }) + // } + + if(parseInt(min_price)<=0){ + this.setState({ + smallstype:true + }) + }else{ + this.setState({ + smallstype:false + }) + } + + if(parseInt(max_price){ + const content = this.contentMdRef.current.getValue().trim(); + // console.log(content) + // console.log(this.state.deadline_at._i) + this.setState({ + publish:type + }) + let types=type; + let {category,title,attachment_ids,deadline_at,min_price,max_price,contact_name,contact_phone,code,modalCancel}=this.state; + + if(category===undefined||category===null||category===""){ + this.setState({ + categorytypes:true + }) + this.scrollToAnchor("publishtimestart"); + return + } + + if(title===undefined||title===null||title===""){ + this.setState({ + titletypes:true + }) + this.scrollToAnchor("publishtimestart"); + return + } + + if(content===undefined||content===null||content===""){ + this.setState({ + contenttypes:true + }) + this.scrollToAnchor("publishtimestart"); + return + } + + if(deadline_at===undefined||deadline_at===null||deadline_at===""){ + this.setState({ + deadline_attypes:true + }) + this.scrollToAnchor("publishtime"); + return + } + + + if(moment(deadline_at) { + if(response.data.status===0){ + if(type===true){ + this.props.setPublicationfun(response.data.id) + }else{ + window.location.href="/crowdsourcing/"+response.data.id + } + this.setState({ + springtype:false + }) + }else if(response.data.status===-1){ + if(response.data.message==="无效的验证码"){ + this.setState({ + codeypesno:true, + springtype:false + }) + } + } + this.setState({ + springtype:false + }) + }).catch((error) => { + console.log(error) + this.setState({ + springtype:false + }) + }) + + + }else{ + + // edit + + const url = `/project_packages/${this.props.match.params.id}.json`; + + axios.put(url, { + category_id: category, + title: title, + content: content, + attachment_ids: attachment_ids, + deadline_at:deadline_at._i, + min_price:parseInt(min_price), + max_price:parseInt(max_price), + contact_name: contact_name===null||contact_name===undefined?this.props.current_user.username:contact_name, + contact_phone: contact_phone===undefined?this.props.current_user.phone:contact_phone, + code:code, + publish:types + } + ).then((response) => { + if(response.data.status===0){ + if(type===true){ + this.props.setPublicationfun(response.data.id) + }else{ + window.location.href="/crowdsourcing/"+response.data.id + } + this.setState({ + springtype:false + }) + }else if(response.data.status===-1){ + if(response.data.message==="无效的验证码"){ + this.setState({ + codeypesno:true, + springtype:false + }) + } + } + this.setState({ + springtype:false + }) + }).catch((error) => { + console.log(error) + this.setState({ + springtype:false + }) + }) + + + } + + + + } + + modalCancel=()=>{ + this.setState({ + modalCancel:false, + contact_phone:undefined, + code:undefined, + }) + } + + editmodels=()=>{ + this.setState({ + modalCancel:true + }) + } + + + setcategory=(value)=>{ + if(value===undefined||value===null||value===""){ + this.setState({ + categorytypes:true + }) + }else{ + this.setState({ + categorytypes:false + }) + } + this.setState({ + category:value + }) + } + + settitlefun=(e)=>{ + + if(e.target.value===undefined||e.target.value===null||e.target.value===""){ + this.setState({ + titletypes:true + }) + }else{ + this.setState({ + titletypes:false + }) + } + + this.setState({ + title:e.target.value + }) + } + + + onChangemin_prices=(e)=>{ + let{max_price}=this.state; + this.setState({ + min_price:e.target.value + }) + this.setcheckout(e.target.value,max_price) + + + } + onChangemax_prices=(e)=>{ + let{min_price}=this.state; + this.setState({ + max_price:e.target.value + }) + this.setcheckout(min_price,e.target.value) + + } + + onChangeContact_name=(e)=>{ + + if(e.target.value===undefined||e.target.value===""||e.target.value===null){ + this.setState({ + contact_nametype:true + }) + }else{ + this.setState({ + contact_nametype:false + }) + } + + + this.setState({ + contact_name:e.target.value + }) + } + + onChangeContact_phone=(e)=>{ + let {modalCancel}=this.state; + // if(modalCancel===false){ + // if(this.props.current_user.phone===undefined||this.props.current_user.phone===null||this.props.current_user.phone===""){ + // this.setState({ + // current_userphonetype:true + // }) + // }else{ + // this.setState({ + // current_userphonetype:false + // }) + // } + // } + if(modalCancel===true||this.props.current_user.phone===null){ + if(e.target.value===undefined||e.target.value===null||e.target.value===""){ + this.setState({ + contact_phonetype:true + }) + }else{ + this.setState({ + contact_phonetype:false + }) + } + + if(checkPhone(e.target.value)===false){ + this.setState({ + contact_phonetypes:true + }) + }else{ + this.setState({ + contact_phonetypes:false + }) + } + } + + + this.setState({ + contact_phone:e.target.value + }) + } + + onChangeCode=(e)=>{ + if(e.target.value===undefined||e.target.value===""||e.target.value===null){ + this.setState({ + codeypes:true + }) + }else{ + this.setState({ + codeypes:false + }) + } + this.setState({ + code:e.target.value + }) + } + + //跳转道描点的地方 + scrollToAnchor = (anchorName) => { + if (anchorName) { + // 找到锚点 + let anchorElement = document.getElementById(anchorName); + // 如果对应id的锚点存在,就跳转到锚点 + if(anchorElement) { anchorElement.scrollIntoView(); } + } + } + + render() { + let {modalCancel,seconds,getverificationcodes,attachments, + category,title}=this.state; + let categorylist=[ + {name:"前端开发",value:"front"}, + {name:"后端开发",value:"backend"}, + {name:"移动开发",value:"mobile"}, + {name:"数据库",value:"database"}, + {name:"云计算和大数据",value:"cloud_compute_and_big_data"}, + {name:"人工智能",value:"ai"}, + {name:"其他",value:"other"}, + ] + + + return ( + +
    + {/**/} + +

    + +

    +
    +
    + +
    + +

    +

    + {this.state.categories.map((item,key)=>{ + return( +
  • this.setcategory(item.id)}>{item.name}
  • + ) + })} +
    +

    + {this.state.categorytypes===true?
    请选择类型
    :""} + +
    + +
    + + + {this.state.titletypes===true?
    不能为空
    :""} + this.setcheckoutcontent()}> + {/* 请求status 422 */} + {this.state.contenttypes===true?
    不能为空
    :""} + {/*
    */} + {/* window.$('#_file').click()}*/} + {/*data-tip-down="请选择文件上传">*/} + {/*/!**!/*/} + {/*上传附件*/} + {/**/} + {/*(最多可添加 5 个图片/文件,每个大小不超过 10MB)*/} + {/*
    */} + {/*{attachments&&attachments.map((item,key)=>{*/} + {/*return(*/} + {/**/} + {/*)})}*/} + {/*
    */} + {/**/} + {/**/} + {/**/} + {/* {*/} + {/*debugger;*/} + {/*console.log(window.$('.file_selector')[0])*/} + {/*window.addInputFiles(window.$('.file_selector')[0])*/} + {/*}}*/} + {/*style={{'display': 'none'}}*/} + {/*type="file">*/} + {/**/} + {/**/} + {/*
    */} + + +
    +
    + +
    +
    +
    + +
    +

    + 竞标截止: + + + {this.state.deadline_attypes===true?

    不能为空
    :""} + + {this.state.deadline_attypexy===true?
    不能早于当前时间
    :""} +

    +

    + 支付费用: + this.onChangemin_prices(e)} + suffix={ + ¥ + } + /> + + this.onChangemax_prices(e)} + suffix={ + ¥ + } + />不填,则表示可议价 + {this.state.min_pricetype===true?

    不能为空
    :""} + {this.state.smallstype===true?
    不能小于零
    :""} + {this.state.minmaxtype===true?
    最高费用不能小于最低费用
    :""} +

    +
    + +
    +

    + 姓名: + this.onChangeContact_name(e)} + /> + {this.state.contact_nametype===true?

    不能为空
    :""} +

    + + {modalCancel===false&&this.props.current_user.phone!=null?

    + 手机号: + + + this.editmodels()}> + +

    :""} + {/*{this.state.current_userphonetype===true?
    不能为空
    :""}*/} + {modalCancel===true||this.props.current_user.phone===null?

    + + + {/*未注册才显示!*/} + + 手机号: + this.onChangeContact_phone(e)} + /> + {this.state.contact_phonetype===true?

    不能为空
    :""} + {this.state.contact_phonetypes===true?
    请输入正确的手机号
    :""} + + + + + 重新发送 ({seconds}s): getverificationcodes === true ?获取验证码 :重新发送} + onSearch={()=>this.getverificationcode()} + onInput={(e)=>this.onChangeCode(e)} + /> + {this.state.codeypes===true?
    验证码不能为空
    :""} + {this.state.codeypesno===true?
    验证码不正确
    :""} +
    + + {/**/} + + + + this.modalCancel()}>X + +

    :""} + + +
    +
    +

    + +
    + + this.setPublication(false)}>保存 +
    +
    +
    + + ) + } +} + +export default PackageIndexNEIBannerConcent; + +// attachments:[ +// { +// id: 206525, +// title: "412420b57ed8c141963d4c548bde551f", +// filesize: 18523, +// description: null, +// url: "/api/attachments/206525" +// } +// ] + diff --git a/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNEISubmit.js b/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNEISubmit.js new file mode 100644 index 000000000..9f287e90e --- /dev/null +++ b/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNEISubmit.js @@ -0,0 +1,49 @@ +import React, {Component} from 'react'; +import {Link} from "react-router-dom"; +import { Icon ,Button} from 'antd'; + +class PackageIndexNEISubmit extends Component { + constructor(props) { + super(props) + this.state = { + current:0 + } + } + componentDidMount() { + window.document.title = '众包创新' + } + setageload=(sum)=>{ + if(sum===undefined){ + window.location.href="/crowdsourcing/new" + }else{ + // this.props.history.push("/project_packages/"+sum) + window.location.href="/crowdsourcing/"+sum + } + + } + render() { + + return ( + + ) + } +} + +export default PackageIndexNEISubmit; + diff --git a/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNewandEditIndex.js b/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNewandEditIndex.js new file mode 100644 index 000000000..1571fd77a --- /dev/null +++ b/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNewandEditIndex.js @@ -0,0 +1,61 @@ +import React, { Component } from 'react'; +import {BrowserRouter as Router,Route,Switch} from 'react-router-dom'; + +//业务组件 +import PackageIndexNEIBanner from "./PackageIndexNEIBanner"; + +import PackageIndexNEIBannerConcent from "./PackageIndexNEIBannerConcent" + +import PackageIndexNEISubmit from './PackageIndexNEISubmit' +import '../packageconcnet.css'; +class PackageIndexNewandEditIndex extends Component{ + constructor(props) { + super(props) + this.state = { + setPublication:false, + id:undefined + } + } + + componentDidMount(){ + window.document.title = '众包创新' + } + + setPublicationfun=(ids)=>{ + this.setState({ + setPublication:true, + id:ids + }) + } + render() { + let {setPublication}=this.state; + return ( +
    +
    + {setPublication===false?
    + +

    + + {this.props.match.params.id!=undefined?"编辑":"新建"} +

    + + + + + +
    : +
    + +
    } +
    +
    + ) + } +} +export default PackageIndexNewandEditIndex; \ No newline at end of file diff --git a/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PhoneModel.js b/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PhoneModel.js new file mode 100644 index 000000000..99d63e7c2 --- /dev/null +++ b/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PhoneModel.js @@ -0,0 +1,140 @@ +import React, { Component } from 'react'; +import { Spin, Icon , Modal,Input,Button} from 'antd'; +class PhoneModel extends Component { + //getverificationcodes 是否是重新发送或者是获取验证码 + //多少秒 + constructor(props) { + super(props); + this.state = { + funmodalsType:false, + istype:false, + getverificationcodes:true, + seconds:35, + } + } + //获取验证码 + getverificationcode =()=>{ + // if (this.state.logins&&this.state.logins.length === 0) { + // 判断没有输入手机号 + // return + // } + + if (this.state.getverificationcodes === true) { + this.setState({ + getverificationcodes: undefined, + }) + let timer = setInterval(() => { + this.setState((preState) => ({ + seconds: preState.seconds - 1, + }), () => { + if (this.state.seconds == 0) { + clearInterval(timer); + this.setState({ + getverificationcodes: false, + seconds: 35, + }) + } + }); + }, 1000) + //其他的网络请求也可以 + this.SMSverification(); + } else { + this.setState({ + getverificationcodes: undefined, + }) + let timer = setInterval(() => { + this.setState((preState) => ({ + seconds: preState.seconds - 1, + }), () => { + if (this.state.seconds == 0) { + clearInterval(timer); + this.setState({ + getverificationcodes: false, + seconds: 35, + + }) + } + }); + }, 1000) + //其他的网络请求也可以 + this.SMSverification(); + } + } + //短信验证 + SMSverification = () => { + // var url = `/accounts/get_verification_code.json`; + // axios.get((url), { + // params: { + // login: this.state.logins, + // type: 1, + // } + // }).then((result) => { + // //验证有问题{"status":1,"message":"success"} + // // console.log(result); + // this.openNotification("验证码已发送,请注意查收!",2); + // + // + // }).catch((error) => { + // console.log(error); + // + // }) + } + render() { + let{getverificationcodes,seconds} =this.state; + const antIcons = + return( + +
    + + ) + } +} + +export default PhoneModel; \ No newline at end of file diff --git a/public/react/src/modules/projectPackages/ProjectPackageIndex.js b/public/react/src/modules/projectPackages/ProjectPackageIndex.js new file mode 100644 index 000000000..097e012e0 --- /dev/null +++ b/public/react/src/modules/projectPackages/ProjectPackageIndex.js @@ -0,0 +1,76 @@ +import React, { Component } from 'react'; + +import { Redirect } from 'react-router'; + +import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom"; + +import Loading from '../../Loading' + +import Loadable from 'react-loadable'; +import { TPMIndexHOC } from '../tpm/TPMIndexHOC' +import { SnackbarHOC } from 'educoder' + + +const PackageIndex = Loadable({ + loader: () => import('./PackageIndex/PackageIndex'), + loading: Loading, +}) + +const PackageIndexNewandEdit = Loadable({ + loader: () => import('./PackageIndexNewandEdit/PackageIndexNewandEditIndex'), + loading: Loading, +}) + +const PackageIndexNEITaskDetails = Loadable({ + loader: () => import('./PackageIndexNEITaskDetails/PackageIndexNEITaskDetails'), + loading: Loading, +}) + +class ProjectPackageIndex extends Component { + constructor(props) { + super(props) + } + + componentDidMount(){ + window.document.title = '众包创新' + } + + render() { + + return ( +
    + + + {/*众包首页*/} + + () + } + > + + () + } + > + + () + } + > + + () + } + > + + +
    + ); + } +} + +export default SnackbarHOC() (TPMIndexHOC (ProjectPackageIndex)) ; \ No newline at end of file diff --git a/public/react/src/modules/projectPackages/packageconcnet.css b/public/react/src/modules/projectPackages/packageconcnet.css new file mode 100644 index 000000000..c17d95c9b --- /dev/null +++ b/public/react/src/modules/projectPackages/packageconcnet.css @@ -0,0 +1,338 @@ +.width1240{ + width:1240px; +} +.packinput .ant-input{ + height: 50px; + width:749px; + border-color: #E1EDF8 !important; +} + +.packinput .ant-input-group-addon .ant-btn{ + width:140px !important; + font-size: 18px; + height: 50px; + background:rgba(76,172,255,1); + margin-right:18px; +} + +.setissues{ + width:280px; + height:50px; + background:rgba(76,172,255,1); + border-radius:4px; + margin-left: 15px; +} + +.pagetype li{ + color:#8F8F8F !important; +} + +.maxwidth700{ + max-width: 700px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.mbf10{ + margin-bottom:-10px; +} + +.PackageIndexNEIBanner{ + width:1200px; + height:110px; + background:rgba(255,255,255,1); + box-shadow:0px 2px 6px 0px rgba(125,125,125,0.26); + border-radius:8px; +} + +.padding110{ + padding: 39px 110px 0px; + box-sizing: border-box; +} + +.borderccc{ + border: 1px solid #ccc; +} + +.input-100-40s{ + width: 100%; + 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; +} +.fafas .ant-input-group-addon .ant-btn{ + width:140px !important; + font-size: 14px; + height: 40px; + background:rgba(76,172,255,1); +} + +.newFormbox .upload_filename{ + line-height: 32px; +} + +.newFormbox .attachment span{ + line-height: 23px; +} + +.newFormbox .attachment .remove-upload{ + line-height: 28px; +} + +.pd26a0{ + padding: 26px 26px 16px 26px; +} + +.newFormbox .attachment .icon-fujian{ + font-size: 14px !important; + line-height: 14px; + margin-top: 9px; +} + +.newFormbox{ + height:20px +} + +.ml24{ + margin-left:24px; +} + +.defalutCancelbtns{ + display: block; + border: 1px solid #4CACFF !important; + background-color: #fff; + color: #4CACFF !important; + width:130px; + height:40px; + text-align: center; + line-height: 40px; + border-radius: 4px; +} + +.defalutSubmitbtns{ + background-color: #4CACFF; + height:40px; +} + +.defalutSubmitbtnmodels{ + width:127px; + height:30px; + background-color: #4CACFF; +} + +.ant-steps-item-process .ant-steps-item-icon{ + background-color: #4CACFF !important; +} + +.ant-steps-item-process .ant-steps-item-icon{ + background-color: #4CACFF !important; +} + +.padding200{ + padding: 115px 200px 215px 200px; +} + +.fontcircle{ + font-size: 80px; + display: inherit; +} + +.sumbtongs{ + font-size: 24px; + display: inherit; + text-align: center; +} + +.terraces{ + font-size: 16px; + display: inherit; + text-align: center; + color:#999; +} +.padding251{ + padding: 0px 251px; +} + +.ant-modal-title{ + text-align: center; +} +.ml17{ + margin-left: 17px; +} + +.project-package-items{ + display: -webkit-flex; + display: flex; + flex-direction: row; + margin:0px !important; + padding: 20px; + background: white; + margin-bottom:0px !important; + box-shadow: none !important; +} + +.mtf7{ + margin-top:-7px; +} + +.publicpart.orangeGreen { + border-left: 80px solid #29BD8B; +} + +.publicwords{ + left: 3px; + top: 18px; +} + +.project-packages-list .project-package-items .item-image{ + width:100px !important; +} + +.height185{ + height: 185px; +} + +.ContacttheTA{ + width: 80px; + height: 26px; + font-size: 14px; + line-height: 26px; + display: block; + border: 1px solid #4CACFF !important; + background-color: #fff; + color: #4CACFF !important; + text-align: center; + border-radius: 4px; +} +.ContacttheTAs{ + width: 80px; + height: 26px; + font-size: 14px; + line-height: 24px; + /*display: block;*/ + border: 1px solid #fff !important; + background-color: #4CACFF; + color: #fff !important; + text-align: center; + border-radius: 4px; +} +.ml28{ + margin-left: 28px; +} + +.longboxs{ + font-size: 16px; + font-family: MicrosoftYaHei-Bold; + font-weight: bold; + color: rgba(5,16,26,1); + border-left: 4px solid rgba(76,172,255,1); + padding-left: 10px; + margin-bottom: 20px; +} + +.padding020{ + padding: 0px 20px 20px; +} + +.mtf3{ + margin-top:-3px; +} + +.task-btn-nebules{ + background: #fff!important; + color: #4CACFF!important; + border: 1px solid #4CACFF!important; + margin-left: 20px; + cursor: pointer; + display: inline-block; + padding: 0 12px; + letter-spacing: 1px; + text-align: center; + font-size: 14px; + height: 30px; + line-height: 30px; + border-radius: 2px; +} + +.packageabsolute{ + position: absolute; + right: -16px; + top: -7px; +} +.relativef{ + position: relative; +} + +.homehove:hover .ptext{ + color: #4CACFF!important; +} + +.homehove:hover .ContacttheTAs{ + display: block; +} + +.topsj{ + position: absolute; + top: -6px; +} +.bottomsj{ + position: absolute; + bottom: -6px; +} +.touchSelect .ant-spin-dot-spin{ + margin-top: 30% !important; +} + +.pagenoedits{ + margin-left: 20px; + color: #ccc; +} + +.pagemancenter{ + text-align: center; +} + +.ml0{ + margin-left: 0px; +} +.tabelcli{ + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 850px; + display: table-cell; +} + +.mtf10{ + margin-top:-10px; +} + +.padding26{ + padding: 26px; + box-sizing: border-box; +} + +.pd26{ + padding: 26px; +} +.pd30a0{ + padding: 30px 30px 16px 30px; +} \ No newline at end of file diff --git a/public/react/src/modules/tpm/NewHeader.js b/public/react/src/modules/tpm/NewHeader.js index 3d1136371..379c70e27 100644 --- a/public/react/src/modules/tpm/NewHeader.js +++ b/public/react/src/modules/tpm/NewHeader.js @@ -716,7 +716,10 @@ submittojoinclass=(value)=>{ />
  • 教学案例
  • -
  • 众包创新
  • +
  • 众包创新
  • 交流问答