diff --git a/.merge_file_a17580 b/.merge_file_a17580 new file mode 100644 index 000000000..47e471767 --- /dev/null +++ b/.merge_file_a17580 @@ -0,0 +1,529 @@ +import React, {Component} from 'react'; +import logo from './logo.svg'; +import './App.css'; +import {LocaleProvider} from 'antd' +import zhCN from 'antd/lib/locale-provider/zh_CN'; +import { + BrowserRouter as Router, + Route, + Switch +} from 'react-router-dom'; +import axios from 'axios'; +import '@icedesign/base/dist/ICEDesignBase.css'; + +import '@icedesign/base/index.scss'; + +import LoginDialog from './modules/login/LoginDialog'; +import Notcompletedysl from './modules/user/Notcompletedysl'; +import Trialapplicationysl from './modules/login/Trialapplicationysl'; +import Trialapplicationreview from './modules/user/Trialapplicationreview'; +import Addcourses from "./modules/courses/coursesPublic/Addcourses"; +import AccountProfile from"./modules/user/AccountProfile"; + + +import Trialapplication from './modules/login/Trialapplication' + +import NotFoundPage from './NotFoundPage' + +import Loading from './Loading' + +import Loadable from 'react-loadable'; + + +import moment from 'moment' + +import {MuiThemeProvider, createMuiTheme} from 'material-ui/styles'; + +// import './AppConfig' + +import history from './history'; + +import {SnackbarHOC} from 'educoder' +import {initAxiosInterceptors} from './AppConfig' + + +// !!!tpi需要这个来加载css +import {TPMIndexHOC} from './modules/tpm/TPMIndexHOC'; + + +const theme = createMuiTheme({ + palette: { + primary: { + main: '#4CACFF', + contrastText: 'rgba(255, 255, 255, 0.87)' + }, + secondary: {main: '#4CACFF'}, // #11cb5f This is just green.A700 as hex. + }, +}); +// +// const Trialapplication= Loadable({ +// loader: () =>import('./modules/login/Trialapplication'), +// loading:Loading, +// }) +//登入 +const EducoderLogin = Loadable({ + loader: () => import('./modules/login/EducoderLogin'), + loading: Loading, +}) +const TestIndex = Loadable({ + loader: () => import('./modules/test'), + loading: Loading, +}) + +const IndexWrapperComponent = Loadable({ + loader: () => import('./modules/page/IndexWrapper'), + loading: Loading, +}) + +const CommentComponent = Loadable({ + loader: () => import('./modules/comment/CommentContainer'), + loading: Loading, +}) + +const TestMaterialDesignComponent = Loadable({ + loader: () => import('./modules/test/md/TestMaterialDesign'), + loading: Loading, +}) +const TestCodeMirrorComponent = Loadable({ + loader: () => import('./modules/test/codemirror/TestCodeMirror'), + loading: Loading, +}) + +const TestComponent = Loadable({ + loader: () => import('./modules/test/TestRC'), + loading: Loading, +}) +const TestUrlQueryComponent = Loadable({ + loader: () => import('./modules/test/urlquery/TestUrlQuery'), + loading: Loading, +}) + +const TPMIndexComponent = Loadable({ + loader: () => import('./modules/tpm/TPMIndex'), + loading: Loading, +}) +const TPMShixunsIndexComponent = Loadable({ + loader: () => import('./modules/tpm/shixuns/ShixunsIndex'), + loading: Loading, +}) + +//实训课程(原实训路径) +const ShixunPaths = Loadable({ + loader: () => import('./modules/paths/Index'), + loading: Loading, +}) + +//在线课堂 +const CoursesIndex = Loadable({ + loader: () => import('./modules/courses/Index'), + loading: Loading, +}) +const SearchPage = Loadable({ + loader: () => import('./search/SearchPage'), + loading: Loading, +}) + +//教学案例 +const MoopCases = Loadable({ + loader: () => import('./modules/moop_cases/index'), + loading: Loading, +}) + +// 课堂讨论 +// const BoardIndex = Loadable({ +// loader: () => import('./modules/courses/boards/BoardIndex'), +// loading:Loading, +// }) + +// //课堂普通作业&分组作业 +// const CoursesWorkIndex = Loadable({ +// loader: () => import('./modules/courses/busyWork/Index'), +// loading:Loading, +// }) +// + +// const TPMShixunchildIndexComponent = Loadable({ +// loader: () => import('./modules/tpm/shixunchild/ShixunChildIndex'), +// loading: Loading, +// }) + + +// const TPMshixunfork_listIndexComponent = Loadable({ +// loader: () => import('./modules/tpm/shixunchild/Shixunfork_list'), +// loading: Loading, +// }) + + +const ForumsIndexComponent = Loadable({ + loader: () => import('./modules/forums/ForumsIndex'), + loading: Loading, +}) + +// trustie plus forum +// const TPForumsIndexComponent = Loadable({ +// loader: () => import('./modules/tp-forums/TPForumsIndex'), +// loading: Loading, +// }) + + +// const TestPageComponent = Loadable({ +// loader: () => import('./modules/page/Index'), +// loading: Loading, +// }) + + +//新建实训 +const Newshixuns = Loadable({ + loader: () => import('./modules/tpm/newshixuns/Newshixuns'), + loading: Loading, +}) + + +//实训首页 +const ShixunsHome = Loadable({ + loader: () => import('./modules/home/shixunsHome'), + loading: Loading, +}) + + +const CompatibilityPageLoadable = Loadable({ + loader: () => import('./modules/common/CompatibilityPage'), + loading: Loading, +}) + +//403页面 +const Shixunauthority = Loadable({ + loader: () => import('./modules/403/Shixunauthority'), + loading: Loading, +}) + + +//404页面 +const Shixunnopage = Loadable({ + loader: () => import('./modules/404/Shixunnopage'), + loading: Loading, +}) + +//500页面 +const http500 = Loadable({ + loader: () => import('./modules/500/http500'), + loading: Loading, +}) + +// 登录注册 +const LoginRegisterPage = Loadable({ + loader: () => import('./modules/user/LoginRegisterPage'), + loading: Loading, +}) +const AccountPage = Loadable({ + loader: () => import('./modules/user/AccountPage'), + loading: Loading, +}) + +// 个人主页 +const UsersInfo = Loadable({ + loader: () => import('./modules/user/usersInfo/Infos'), + loading: Loading, +}) + +// 兴趣页面 +const Interestpage = Loadable({ + loader: () => import('./modules/login/EducoderInteresse'), + loading: Loading, +}) + +//众包创新 +const ProjectPackages=Loadable({ + loader: () => import('./modules/projectPackages/ProjectPackageIndex'), + loading: Loading, +}) + +class App extends Component { + constructor(props) { + super(props) + // this.state = { + // isRenders:false, + // } + + } + + componentDidMount() { + // force an update if the URL changes + history.listen(() => { + this.forceUpdate() + const $ = window.$ + // https://www.trustie.net/issues/21919 可能会有问题 + $("html").animate({ scrollTop: $('html').scrollTop() - 0 }) + }); + + initAxiosInterceptors(this.props) + + // + // axios.interceptors.response.use((response) => { + // // console.log("response"+response); + // if(response!=undefined) + // // console.log("response"+response.data.statu); + // if (response&&response.data.status === 407) { + // this.setState({ + // isRenders: true, + // }) + // } + // return response; + // }, (error) => { + // //TODO 这里如果样式变了会出现css不加载的情况 + // }); + } + //修改登录方法 + Modifyloginvalue=()=>{ + this.setState({ + isRender:false, + }) + } + + render() { + + + return ( + + + + + this.Modifyloginvalue()}> + + + + + + {/*{*/} + {/* isRender === true?*/} + {/* : ""*/} + {/*}*/} + + {/*{*/} + {/* isRenders === true?*/} + {/**/} + {/*:""*/} + {/*}*/} + + + + {/**/} + + {/*众包创新*/} + + {/*认证*/} + + + {/*403*/} + + + + + {/*404*/} + + + + + + () + }> + {/**/} + + + + + + + + + + + + {/*列表页*/} + + + {/* + + + */} + + {/**/} + {/**/} + + + {/*实训课程(原实训路径)*/} + + + () + } + > + + {/*课堂*/} + + + {/* 课堂讨论 */} + {/* */} + + {/* + */} + + {/* */} + {/* 兴趣页面*/} + {/**/} + + + + + + + + + {/* 教学案例 */} + () + }/> + + {/* */} + {/*列表页*/} + {/**/} + {/*首页*/} + + + + {/**/} + + + + + + ); + } +} + +// moment国际化,设置为中文 +moment.defineLocale('zh-cn', { + months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort: '周日_周一_周二_周三_周四_周五_周六'.split('_'), + weekdaysMin: '日_一_二_三_四_五_六'.split('_'), + longDateFormat: { + LT: 'Ah点mm分', + LTS: 'Ah点m分s秒', + L: 'YYYY-MM-DD', + LL: 'YYYY年MMMD日', + LLL: 'YYYY年MMMD日Ah点mm分', + LLLL: 'YYYY年MMMD日ddddAh点mm分', + l: 'YYYY-MM-DD', + ll: 'YYYY年MMMD日', + lll: 'YYYY年MMMD日Ah点mm分', + llll: 'YYYY年MMMD日ddddAh点mm分' + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || + meridiem === '上午') { + return hour; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } else { + // '中午' + return hour >= 11 ? hour : hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; + } + }, + calendar: { + sameDay: function () { + return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT'; + }, + nextDay: function () { + return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT'; + }, + lastDay: function () { + return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT'; + }, + nextWeek: function () { + var startOfWeek, prefix; + startOfWeek = moment().startOf('week'); + prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]'; + return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm'; + }, + lastWeek: function () { + var startOfWeek, prefix; + startOfWeek = moment().startOf('week'); + prefix = this.unix() < startOfWeek.unix() ? '[上]' : '[本]'; + return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm'; + }, + sameElse: 'LL' + }, + ordinalParse: /\d{1,2}(日|月|周)/, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '日'; + case 'M': + return number + '月'; + case 'w': + case 'W': + return number + '周'; + default: + return number; + } + }, + relativeTime: { + future: '%s内', + past: '%s前', + s: '几秒', + m: '1分钟', + mm: '%d分钟', + h: '1小时', + hh: '%d小时', + d: '1天', + dd: '%d天', + M: '1个月', + MM: '%d个月', + y: '1年', + yy: '%d年' + }, + week: { + // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } +}); +export default SnackbarHOC()(App); \ No newline at end of file diff --git a/public/react/config/webpack.config.dev.js b/public/react/config/webpack.config.dev.js index 12d5e437f..15e7e6bef 100644 --- a/public/react/config/webpack.config.dev.js +++ b/public/react/config/webpack.config.dev.js @@ -29,7 +29,7 @@ const env = getClientEnvironment(publicUrl); module.exports = { // You may want 'eval' instead if you prefer to see the compiled output in DevTools. // See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s - devtool: "eval", // 开启调试 + devtool: "source-map", // 开启调试 // These are the "entry points" to our application. // This means they will be the "root" imports that are included in JS bundle. // The first two entry points enable "hot" CSS and auto-refreshes for JS. diff --git a/public/react/src/common/course/ActionBtn.js b/public/react/src/common/course/ActionBtn.js index 03da0d3e7..e5eeb11a4 100644 --- a/public/react/src/common/course/ActionBtn.js +++ b/public/react/src/common/course/ActionBtn.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import {Link} from 'react-router-dom' -const map={"blue":"blueFull","greyBack":"greyBack","grey":"greyWidthFixed","green":"greenBack", +const map={"blue":"blueFull","greyBack":"greyBack","grey":"greyWidthFixed","green":"greenBack",'greyLine':"greyLine", 'colorBlue': 'colorBlue', // 蓝字白底 } class ActionBtn extends Component { diff --git a/public/react/src/modules/courses/css/Courses.css b/public/react/src/modules/courses/css/Courses.css index 57b1e37f9..47db2f595 100644 --- a/public/react/src/modules/courses/css/Courses.css +++ b/public/react/src/modules/courses/css/Courses.css @@ -702,6 +702,12 @@ a.white-btn.use_scope-btn:hover{ .Actionbtn.middle { padding: 0px 18px; } +.greyLine{ + background: #fff; + border:1px solid #eaeaea; + color: #999!important; + padding:0px 10px; +} .colorFF6800{ diff --git a/public/react/src/modules/moop_cases/CaseDetail.js b/public/react/src/modules/moop_cases/CaseDetail.js new file mode 100644 index 000000000..189744c25 --- /dev/null +++ b/public/react/src/modules/moop_cases/CaseDetail.js @@ -0,0 +1,163 @@ +import React,{ Component } from "react"; +import './css/moopCases.css' +import '../courses/css/Courses.css' + +import { getImageUrl , MarkdownToHtml , ActionBtn } from 'educoder'; + +import Tags from './CaseTags' + +import axios from 'axios'; +import Modals from '../modals/Modals' + +class CaseDetail extends Component{ + constructor(props){ + super(props); + this.state={ + modalsType:"", + modalsTopval:"", + modalsBottomval:"", + modalCancel:"", + } + } + + componentDidMount =()=>{ + let caseID = this.props.match.params.caseID; + this.props.getDetail(caseID); + } + // 是否删除 + delCases=()=>{ + this.setState({ + modalsType:true, + modalsTopval:"是否确认删除?", + modalsBottomval:"" + }) + } + + // 取消删除 + cancelDelClasses=()=>{ + this.setState({ + modalsType:false, + modalsTopval:"", + modalsBottomval:"" + }) + } + // 确定删除 + sureDelClasses=()=>{ + let caseID = this.props.match.params.caseID; + let url =`/libraries/${caseID}.json`; + axios.delete(url).then((result)=>{ + if(result){ + this.props.showNotification("删除成功") + this.props.history.push("/moop_cases"); + } + }).catch((error)=>{ + console.log(error); + }) + } + + + render(){ + let { CaseDetail , praise_count , creator , operation , user_praised , tags , attachments }=this.props + let { + modalsType, + modalsTopval, + modalsBottomval, + } = this.state; + return( +
+ + +

+ 教学案例 > { CaseDetail && CaseDetail.title} +

+

+ + { CaseDetail && CaseDetail.title} + + + + 草稿 + + 返回 +

+
+
+
+ 82274?1563067098 +
+
  • + {creator && creator.name} + { + operation && operation.can_deletable ? 删除:"" + } + + { + operation && operation.can_editable ? 编辑:"" + } +
  • +
  • + {creator && creator.school_name} + + 编码:{CaseDetail && CaseDetail.uuid} + 发布时间:{CaseDetail && CaseDetail.published_at} + +
  • +
    +
    +
    + 作者:{CaseDetail && CaseDetail.author_name}/{CaseDetail && CaseDetail.author_school_name} +
    + +
    + { CaseDetail && CaseDetail.content && } +
    + { attachments && +
    + { + attachments.map((item,key)=>{ + return( +

    + + + + {item.title} + {item.filesize} +

    + ) + }) + } +
    + } +
    + { + user_praised ? +

    + 已赞 + {praise_count} +

    + : +

    this.props.praisePoint(this.props.match.params.caseID)} className="pointsBtn"> + + {praise_count} +

    + } +
    +
    +
    +
    + ) + } +} +export default CaseDetail; \ No newline at end of file diff --git a/public/react/src/modules/moop_cases/CaseItem.js b/public/react/src/modules/moop_cases/CaseItem.js index 45be0b3cb..a5086133b 100644 --- a/public/react/src/modules/moop_cases/CaseItem.js +++ b/public/react/src/modules/moop_cases/CaseItem.js @@ -1,5 +1,4 @@ import React,{ Component } from "react"; -import { Spin } from "antd"; import './css/moopCases.css' import '../courses/css/Courses.css' @@ -23,16 +22,18 @@ class CaseItem extends Component{
  • {item.id}
    -

    - {item.title} - +

    + {item.title} +

    -

    +

    {item.author_name} {item.author_school_name} - {item.download_count} 下载 - {item.praise_count} 赞 - {item.visited_count} 浏览 + + {item.visited_count} 浏览 + {item.praise_count} 赞 + {item.download_count} 下载 +

  • diff --git a/public/react/src/modules/moop_cases/CaseList.js b/public/react/src/modules/moop_cases/CaseList.js new file mode 100644 index 000000000..b968cc930 --- /dev/null +++ b/public/react/src/modules/moop_cases/CaseList.js @@ -0,0 +1,134 @@ +import React,{ Component } from "react"; +import { Input , Spin , Pagination } from "antd"; +import './css/moopCases.css' +import '../courses/css/Courses.css' + +import { ActionBtn } from 'educoder'; + +import axios from 'axios' + +import NoneData from '../courses/coursesPublic/NoneData' + +import mainImg from '../../images/moop_cases/teach_ex.jpg' +import CaseItem from './CaseItem' + + +const Search = Input.Search; +class CaseList extends Component{ + constructor(props){ + super(props); + this.state={ + type:0, + search:undefined, + page:1, + pageSize:20, + libraries:undefined, + totalCount:undefined + } + } + + componentDidMount = () =>{ + let { type , search , page , pageSize } = this.state; + this.InitList(type,search,page,pageSize); + } + + // 列表 + InitList = (type,search,page,pageSize) =>{ + let url = `/libraries.json`; + axios.get(url,{params:{ + type:type == 0 ? undefined : "mine", + keyword:search, + page, + per_page:pageSize + }}).then((result)=>{ + if(result){ + this.setState({ + libraries:result.data.libraries, + totalCount:result.data.count + }) + } + }).catch((error)=>{ + console.log(error); + }) + } + + // tab切换 + changeType = (type) =>{ + this.setState({ + type, + page:1 + }) + let { search , page , pageSize } = this.state; + this.InitList(type,search,page,pageSize); + } + + // 输入搜索内容 + inputStudent=(e)=>{ + this.setState({ + search:e.target.value + }) + } + + // 搜索 + searchInfo = () =>{ + let { type , search , pageSize } = this.state; + this.InitList( type , search , 1 , pageSize ); + } + + // 切换分页 + onChangePage =(pageNumber)=>{ + this.setState({ + page:pageNumber + }) + let { type , search , pageSize } = this.state; + this.InitList( type , search , pageNumber , pageSize ); + } + + render(){ + let { type , search ,libraries , totalCount ,pageSize ,page } = this.state; + return( + + +
    +
    +

    + 教学案例 + this.addQuestion(null, Q_TYPE_SINGLE)}>发布案例 +

    +
    +
      +
    • this.changeType(0)}> + 全部 +
    • +
    • this.changeType(1)}> + 我的 +
    • +
    +
    + +
    +
    +
    + { + libraries && libraries.length > 0 && + } + { + libraries && libraries.length == 0 &&
    + } + { + totalCount && totalCount > pageSize && +
    + +
    + } +
    +
    + ) + } +} +export default CaseList \ No newline at end of file diff --git a/public/react/src/modules/moop_cases/CaseNew.js b/public/react/src/modules/moop_cases/CaseNew.js new file mode 100644 index 000000000..a388b482c --- /dev/null +++ b/public/react/src/modules/moop_cases/CaseNew.js @@ -0,0 +1,381 @@ +import React,{ Component } from "react"; +import './css/moopCases.css' +import '../courses/css/Courses.css' +import { Form , Input , Upload , Button , Icon , message , Tooltip } from "antd"; + +import { getImageUrl , MarkdownToHtml , ActionBtn , appendFileSizeToUploadFile , appendFileSizeToUploadFileAll , getUrl , getUploadActionUrl } from 'educoder'; + +import Tags from './CaseTags' + +import axios from 'axios'; +import TPMMDEditor from '../tpm/challengesnew/TPMMDEditor'; + +const { Dragger } = Upload; +function beforeUpload(file) { + const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; + if (!isJpgOrPng) { + message.error('You can only upload JPG/PNG file!'); + } + const isLt2M = file.size / 1024 / 1024 < 2; + if (!isLt2M) { + message.error('Image must smaller than 2MB!'); + } + return isJpgOrPng && isLt2M; +} +function getBase64(img, callback) { + const reader = new FileReader(); + reader.addEventListener('load', () => callback(reader.result)); + reader.readAsDataURL(img); +} + const $ = window.$; +class CaseNew extends Component{ + constructor(props){ + super(props); + this.DescMdRef = React.createRef(); + + this.state={ + goldCases:false, + bankCases:false, + contentFileList:[], + imageUrl:undefined, + loading: false, + checkTag:false, + coverID:undefined + } + } + + // 上传附件-删除确认框 + onAttachmentRemove = (file, stateName) => { + this.props.confirm({ + content: '是否确认删除?', + onOk: () => { + this.deleteAttachment(file, stateName) + }, + onCancel() { + console.log('Cancel'); + }, + }); + return false; + } + + // 上传附件-确认删除 + deleteAttachment = (file, stateName) => { + // 初次上传不能直接取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[stateName].indexOf(file); + const newFileList = state[stateName].slice(); + newFileList.splice(index, 1); + return { + [stateName]: newFileList, + }; + }); + } + } + }) + .catch(function (error) { + console.log(error); + }); + } + // 上传附件-change + handleContentUploadChange = (info) => { + let contentFileList = info.fileList; + this.setState({ contentFileList: appendFileSizeToUploadFileAll(contentFileList)}); + } + + // 上传封面图-change + handleChange = (info) => { + if (info.file.status === 'uploading') { + this.setState({ loading: true }); + return; + } + if (info.file.status === 'done') { + // Get this url from response in real world. + getBase64(info.file.originFileObj, imageUrl => + this.setState({ + imageUrl, + loading: false + }), + ); + console.log(info.file); + this.setState({ + coverID:info.file.response && info.file.response.id + }) + } + }; + + // 编辑时加载数据 + componentDidMount=()=>{ + if(this.props.match.params.caseID){ + this.InitEditData(); + } + } + + componentDidUpdate=(prevState)=>{ + if(this.props.CaseDetail && prevState.CaseDetail != this.props.CaseDetail){ + this.props.form.setFieldsValue({ + caseTitle:this.props.CaseDetail.title, + userName:this.props.CaseDetail.author_name, + userUnit:this.props.CaseDetail.author_school_name, + }) + this.setState({ + contentFileList:this.props.CaseDetail.attachments.map(item => { + return { + id: item.id, + uid: item.id, + name: appendFileSizeToUploadFile(item), + url: item.url, + filesize: item.filesize, + status: 'done' + } + }), + coverID:this.props.cover && this.props.cover.id, + imageUrl:this.props.CaseDetail.cover && getImageUrl(this.props.CaseDetail.cover.url) + }) + this.props.tags.map((item)=>{ + if(item.name=="入库案例"){ + this.setState({bankCases:true}) + }else{ + this.setState({goldCases:true}) + } + }) + } + } + + InitEditData=()=>{ + let caseID = this.props.match.params.caseID; + this.props.getDetail(caseID); + } + + // 申请提交和保存 + handleSubmit = (type) => { + console.log(type); + this.props.form.validateFieldsAndScroll((err, values) => { + let { goldCases , bankCases } = this.state; + if(!goldCases && !bankCases){ + $("html").animate({ scrollTop: $("#tagFormItem").offset().top - 100 }); + this.setState({ + checkTag:true + }) + return; + } + const mdContnet = this.DescMdRef.current.getValue().trim(); + console.log(values); + let url=`/libraries/:id.json`; + // axios.put(()) + }) + } + + // 选择标签 + changeType=(type)=>{ + let { goldCases , bankCases } = this.state; + if(type=="gold"){ + this.setState({ + goldCases:!goldCases + }) + }else{ + this.setState({ + bankCases:!bankCases + }) + } + if(!goldCases == true || !bankCases == true){ + this.setState({checkTag:false}) + } + } + + render(){ + let { caseID } = this.props.match.params; + let { CaseDetail } = this.props; + let { goldCases , bankCases , contentFileList , imageUrl , checkTag } = this.state; + const {getFieldDecorator} = this.props.form; + + + // 上传附件点击事件 + const uploadProps = { + width: 600, + multiple: true, + fileList:contentFileList, + action: `${getUploadActionUrl()}`, + onChange: this.handleContentUploadChange, + onRemove: (file) => this.onAttachmentRemove(file, 'contentFileList'), + beforeUpload: (file) => { + const isLt150M = file.size / 1024 / 1024 < 150; + if (!isLt150M) { + message.error('文件大小必须小于150MB!'); + } + return isLt150M; + } + }; + // 上传封面图-html + const uploadButton = ( +
    + +
    + ); + // 上传封面图点击事件 + const uploadCover = { + listType:"picture-card", + className:"avatar-uploader", + showUploadList:false, + action:`${getUploadActionUrl()}`, + onChange:this.handleChange, + } + return( +
    + +

    + 教学案例 > { caseID ? "编辑" : "新建" } +

    +

    上传教学案例

    +
    +
    + + {getFieldDecorator('caseTitle', { + rules: [{required: true, message: "案例标题不能为空"}], + })( + + )} + 简明扼要介绍文档/视频所包含的主要的内容 + +
    + + {getFieldDecorator('userName', { + rules: [{required: true, message: "请输入作者姓名"}], + })( + + )} + + + {getFieldDecorator('userUnit', { + rules: [{required: true, message: "请输入作者单位名称"}], + })( + + )} + +
    +
    + 标签 +
      +
    • this.changeType("gold")}>获奖案例
    • +
    • this.changeType("bank")}>入库案例
    • +
    + { + checkTag &&
    请选择标签
    + } +
    + + {getFieldDecorator('description', { + rules: [{ + required: true, message: '请输入描述内容' + }], + })( + + )} + +
    + +

    上传附件

    +

    从我的电脑选择要上传的文档:按住CTRL可以上传多份文档。单个文件最大限制:150MB

    +
    +
    +

    + 封面图(上传尺寸:120*90 px) +

    +
    + + { imageUrl ? + + avatar + + : + + {uploadButton} + + } + +
    +
    +
    +
  • 审核说明
  • +
      +
    • 平台管理员将对每天新上传的文档进行审核,审核通过的文档将公开显示,否则将私有化或移除
    • +
    +
    +
    +
  • 温馨提示
  • +
      +
    • 1.请勿上传已设置加密口令的文档资源;
    • +
    • 2.可以上传符合教学案例标准的文档资料,如 + 案例入库标准、 + 案例使用说明书以及其他资料等,上传支持的文件最大容量:100MB;
    • +
    • 3.请确保上传内容无侵权或违反国家关于互联网政策的不良行为;
    • +
    • 4.请使用Chrome,Firefox,Safari,IE11(及以上版本)浏览器;
    • +
    +
    + +
    + { + !caseID && + } + this.handleSubmit("save")}>保存 +
    +
    + +
    + ) + } +} +const WrappedCoursesNewApp = Form.create({name: 'CaseNew'})(CaseNew); +export default WrappedCoursesNewApp; \ No newline at end of file diff --git a/public/react/src/modules/moop_cases/CaseTags.js b/public/react/src/modules/moop_cases/CaseTags.js index 0826b8645..4b4f0670c 100644 --- a/public/react/src/modules/moop_cases/CaseTags.js +++ b/public/react/src/modules/moop_cases/CaseTags.js @@ -14,7 +14,7 @@ class CaseTags extends Component{ { tags && tags.map((item,key)=>{ return( - {item} + {item.name} ) }) } diff --git a/public/react/src/modules/moop_cases/css/moopCases.css b/public/react/src/modules/moop_cases/css/moopCases.css index 95e539c7b..a840d0682 100644 --- a/public/react/src/modules/moop_cases/css/moopCases.css +++ b/public/react/src/modules/moop_cases/css/moopCases.css @@ -41,10 +41,101 @@ border: 1px solid #FC2B6A; line-height: 17px; } +.edu-activity-green { + background-color: green; + color: #fff!important; + cursor: pointer; + border: 1px solid green; + line-height: 17px; +} .edu-activity-blue { background-color: #4CACFF; color: #fff!important; cursor: pointer; border: 1px solid #4CACFF; line-height: 17px; +} + +.pointsBtn { + width: 70px; + height: 70px; + background-color: #4cacff; + border-radius: 50%; + color: #fff; + text-align: center; + margin: 0 auto; + -webkit-box-sizing: border-box; + box-sizing: border-box; + padding: 2px 0; + cursor: pointer; + line-height: 22px; + padding-top: 12px; +} +.pointedBtn{ + background: #BCD1E3; + cursor: default +} +.pointsBtn span{ + display: block; +} +.upload_Title { + position: relative; + margin-right: 20px; + float: left; + line-height: 35px; + font-size: 16px; + width: 56px; + color:rgba(0, 0, 0, 0.85); + text-align: center +} +.upload_Title.must:before { + display: inline-block; + margin-right: 4px; + color: #f5222d; + font-size: 14px; + font-family: SimSun, sans-serif; + line-height: 1; + content: '*'; +} +.upload_Title:after{ + content: ':'; + position: relative; + top: -0.5px; + margin: 0 8px 0 2px; +} +.libraries_tab li { + width: 120px; + height: 35px; + line-height: 33px; + border-radius: 18px; + border: 1px solid #4C98FF; + color: #4C98FF; + cursor: pointer; + margin-right: 30px; + float: left; + text-align: center; +} +.libraries_tab li.active { + background: #4C98FF; + color: #fff; +} +.librariesField .ant-upload{ + width: 100%; + background: #F2F9FF; + justify-content: center; + align-items: center; + display: -webkit-flex; + text-align: center; + height: 120px!important; + border-radius: 4px; + border: 1px dashed #4cacff!important; + display: block; + cursor: pointer; +} +.uploadImage .ant-upload.ant-upload-select-picture-card{ + width:120px; + height: 90px; +} +.uploadImage .ant-upload.ant-upload-select-picture-card > .ant-upload{ + padding:0px!important; } \ No newline at end of file diff --git a/public/react/src/modules/moop_cases/index.js b/public/react/src/modules/moop_cases/index.js index f35925388..91c3557b8 100644 --- a/public/react/src/modules/moop_cases/index.js +++ b/public/react/src/modules/moop_cases/index.js @@ -1,133 +1,117 @@ import React,{ Component } from "react"; -import { Input , Spin , Pagination } from "antd"; import './css/moopCases.css' import '../courses/css/Courses.css' -import { SnackbarHOC , ActionBtn , WordsBtn } from 'educoder'; +import { SnackbarHOC } from 'educoder'; + import { TPMIndexHOC } from '../tpm/TPMIndexHOC'; import { CNotificationHOC } from '../courses/common/CNotificationHOC' -import axios from 'axios' +import {BrowserRouter as Router,Route,Switch} from 'react-router-dom'; +import Loading from '../../Loading'; +import Loadable from 'react-loadable'; + +import axios from 'axios'; -import NoneData from '../courses/coursesPublic/NoneData' +const CaseList = Loadable({ + loader: () => import('./CaseList'), + loading:Loading, +}) +const CaseDetail = Loadable({ + loader: () => import('./CaseDetail'), + loading:Loading, +}) +const CaseNew = Loadable({ + loader: () => import('./CaseNew'), + loading:Loading, +}) -import mainImg from '../../images/moop_cases/teach_ex.jpg' -import CaseItem from './CaseItem' -const Search = Input.Search; class Index extends Component{ constructor(props){ super(props); this.state={ - type:0, - search:undefined, - page:1, - pageSize:20, - libraries:undefined, - totalCount:undefined + praise_count:0, + CaseDetail:undefined, + cover:undefined, + creator:undefined, + operation:undefined, + tags:undefined, + attachments:undefined, + user_praised:true, } } - - componentDidMount = () =>{ - let { type , search , page , pageSize } = this.state; - this.InitList(type,search,page,pageSize); - } - - // 列表 - InitList = (type,search,page,pageSize) =>{ - let url = `/libraries.json`; - axios.get(url,{params:{ - type:type == 0 ? undefined : "mine", - keyword:search, - page, - per_page:pageSize - }}).then((result)=>{ + // 获取案例详情 + getDetail = (caseID) =>{ + let url=`/libraries/${caseID}.json` + axios.get(url).then((result)=>{ if(result){ this.setState({ - libraries:result.data.libraries, - totalCount:result.data.count + CaseDetail:result.data, + praise_count:result.data.praise_count, + cover:result.data.cover, + creator:result.data.creator, + operation:result.data.operation, + user_praised:result.data.operation.user_praised, + tags:result.data.tags, + attachments:result.data.attachments }) } }).catch((error)=>{ console.log(error); }) } - - // tab切换 - changeType = (type) =>{ - this.setState({ - type, - page:1 - }) - let { search , page , pageSize } = this.state; - this.InitList(type,search,page,pageSize); - } - - // 输入搜索内容 - inputStudent=(e)=>{ - this.setState({ - search:e.target.value - }) - } - - // 搜索 - searchInfo = () =>{ - let { type , search , pageSize } = this.state; - this.InitList( type , search , 1 , pageSize ); - } - - // 切换分页 - onChangePage =(pageNumber)=>{ - this.setState({ - page:pageNumber - }) - let { type , search , pageSize } = this.state; - this.InitList( type , search , pageNumber , pageSize ); + // 点赞 + praisePoint=(caseID)=>{ + let { praise_count }=this.state; + let url =`/praise_tread/like.json`; + axios.post(url,{ + object_id:caseID, + object_type:"library" + }).then((result)=>{ + if(result){ + this.setState({ + praise_count: parseInt(praise_count)+1, + user_praised:true + }) + } + }).catch((error)=>{ + console.log(error); + }) } render(){ - let { type , search ,libraries , totalCount ,pageSize ,page } = this.state; + return(
    - -
    -
    -

    - 教学案例 - this.addQuestion(null, Q_TYPE_SINGLE)}>发布案例 -

    -
    - -
    - -
    -
    -
    - { - libraries && libraries.length > 0 && - } - { - libraries && libraries.length == 0 &&
    - } - { - totalCount && totalCount > pageSize && -
    - -
    - } -
    + + + () + } + > + + () + } + > + + () + } + > + + + () + } + > + +
    ) }