import React,{ Component } from "react"; import {Checkbox,Radio, Input,InputNumber,Spin} from "antd"; import '../css/members.css' import '../css/busyWork.css' import '../poll/pollStyle.css' import '../css/Courses.css' import moment from 'moment' import { WordsBtn,markdownToHTML,ActionBtn,getImageUrl, MarkdownToHtml } from 'educoder' import Modals from '../../modals/Modals' import CoursesListType from '../coursesPublic/CoursesListType'; import Multiple from './question/multiple' import Single from './question/single' import FillEmpty from './question/fillEmpty' import SimpleAnswer from './question/simpleAnswer' import ShixunAnswer from './question/shixunAnswer' import update from 'immutability-helper' import axios from 'axios'; import './new/common.css' const Textarea =Input.TextArea const tagArray = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ] const $ = window.$; const statudmap={1:"未发布",2:"已发布",3:"已截止"} const type=["单选题","多选题","判断题","填空题","简答题","实训题"] const format="YYYY-MM-DD HH:mm" class ExerciseReviewAndAnswer extends Component{ constructor(props){ super(props); this.state={ data:undefined, questionPanelFixed:false, e_ReviewInfo:undefined, e_AnswerInfo:undefined, courseName:undefined, exercise:undefined, question_types:undefined, exercise_questions:undefined, time:undefined, hour:0, minute:0, second:0, Modalstype:false, Modalstopval:undefined, modalsBottomval:undefined, ModalCancel:undefined, ModalSave:undefined, Loadtype:undefined, // 问卷是否可以被编辑(老师/试卷已截止/问卷已提交为1) user_exercise_status:undefined, // 开始答题时间 exercise_start_at:undefined, //老师身份 exercise_scores:undefined, exercise_answer_user:undefined, //学生身份 question_status:undefined, score:undefined, setScoreReason:undefined, setTip:"", Id:undefined, // 试卷总分 exerciseTotalScore:undefined, // 加载效果 isSpin:false, // 调分数组 ajustSore:undefined } } componentDidUpdate (prevProps) { // 需要等get_user_info执行完才能getInfo if (!prevProps.coursedata.name && this.props.coursedata.name) { this.getInfo() } } componentDidMount(){ if(this.props.coursedata.name){ this.getInfo(); } //window.addEventListener('scroll', this.handleScroll); } remainTime=()=>{ let { time } = this.state; let h=moment(parseInt(time)*1000).hour()-8; let m=moment(parseInt(time)*1000).minutes(); let s=moment(parseInt(time)*1000).seconds(); this.timer = setInterval(() => { if(time>0){ if(s==0){ if(m > 0){ m--; } s=59; }else{ s--; } this.setState({ hour:h, minute:m, second:s }) if(h==0 && m==0 && s==0){ clearInterval(this.timer); this.autoCommitExercise(); } }else{ clearInterval(this.timer); } },1000) } //自动交卷 autoCommitExercise=()=>{ let eId=this.props.match.params.Id; let url=`/exercises/${eId}/commit_exercise.json`; axios.post(url,{ commit_method:2 }).then((result)=>{ if(result){ this.setState({ Modalstype:true, Modalstopval:'答题结束了,系统已自动提交试卷', modalsBottomval:"不能再修改答题", ModalCancel:undefined, ModalSave:this.sureCommit, Loadtype:true }) this.props.showNotification(`${result.data.message}`); } }).catch((error)=>{ console.log(error); }) } sureCommit=()=>{ let coursesId = this.props.match.params.coursesId; let eId = this.props.match.params.Id; this.props.history.push(`/courses/${coursesId}/exercises/${eId}/student_exercise_list?tab=0`); } // 滚动定位 handleScroll=()=>{ if(parseInt(window.scrollY)>550){ this.setState({ questionPanelFixed:true }) }else{ this.setState({ questionPanelFixed:false }) } } getInfo=()=>{ this.setState({ courseName:this.props.current_user.course_name, isSpin:true }) let eId=this.props.match.params.Id; let user_id=this.props.match.params.userId; let isAdmin=this.props.isAdmin(); if(isAdmin){ let url=`/exercises/${eId}/review_exercise.json` axios.get((url),{params:{ login:user_id }}).then((result)=>{ if(result){ this.setState({ data:result.data, e_ReviewInfo:result.data, exercise:result.data.exercise, exercise_types:result.data.exercise_scores.exercise_types, exercise_scores:result.data.exercise_scores, exercise_start_at:result.data.exercise_answer_user.start_at, exercise_answer_user:result.data.exercise_answer_user, exercise_questions:result.data.exercise_questions, user_exercise_status:1, Id:result.data.exercise_answer_user.user_id, exerciseTotalScore:result.data.exercise_answer_user.score, isSpin:false, }) // 先将未批的简答题放入到调分数组中 let ajustSore = []; result.data && result.data.exercise_questions.length>0 && result.data.exercise_questions.map((item,key)=>{ if( item.question_type == 4 && item.answer_status == 0 ){ ajustSore.push({ inputSore:0, desc:undefined, id:item.question_id, position:item.q_position, setTip:"" }) } }) this.setState({ ajustSore }) } }).catch((error)=>{ console.log(error); }) }else{ let url=`/exercises/${eId}/start_answer.json` axios.get((url),{params:{ login:user_id }}).then((result)=>{ if(result.status==200){ this.setState({ data:result.data, e_AnswerInfo:result.data, exercise:result.data.exercise, exercise_types:result.data.exercise_types, question_status:result.data.question_status, exercise_start_at:result.data.exercise.exercise_start_at, exercise_scores:result.data.exercise_scores, exercise_questions:result.data.exercise_questions, user_exercise_status:result.data.exercise.user_exercise_status, time:result.data.exercise.left_time, exerciseTotalScore:result.data.user_score, isSpin:false }) if(result.data.exercise.left_time != null){ this.remainTime(); } } }).catch((error)=>{ console.log(error); }) } } scrollToAnchor=(index)=>{ let name="Anchor_"+index; // console.log($("#Anchor_"+index).scrollTop()); if (index) { // let anchorElement = document.getElementById(name); // if(anchorElement) { anchorElement.scrollIntoView(); } $("html").animate({ scrollTop: $("#Anchor_"+index).offset().top - 150 }) } } //答题后更改题目列表得状态 changeQuestionStatus=(No,flag)=>{ this.setState( (prevState) => ({ question_status : update(prevState.question_status, {[No]: { ques_status: {$set: flag} }}) }) ) } // 调分 showSetScore=(key,flag,position,type,id)=>{ this.setState( (prevState) => ({ exercise_questions : update(prevState.exercise_questions, {[key]: { setScore: {$set: flag == undefined || flag==false ? true : false}}}) }),()=>{ if (position && type && (flag == undefined || flag==false)) { $("#input_"+position+"_"+type).focus(); $("html").animate({ scrollTop: $("#Anchor_"+position+"_"+type).offset().top - 150 }); if(id){ let { ajustSore } = this.state; let obj = ajustSore.filter(obj => obj.id === id).length > 0; if(!obj){ ajustSore.push({ id, inputSore:0, desc:undefined, position:position, setTip:"" }) } } } } ) // this.setState({ // score:undefined // }) } inputScore=(value,id)=>{ let { ajustSore } = this.state; var index = ajustSore.map(function (item) { return item.id; }).indexOf(id); let reg = /^[0-9]+.?[0-9]*$/; if(reg.test(value)==false){ // this.setState({ // setTip:"请输入数字" // }) this.setState( (prevState) => ({ ajustSore : update(prevState.ajustSore, {[index]: { setTip: {$set: "请输入数字"}}}) }) ) return; }else{ // this.setState({ // setTip:"", // score:value // }) this.setState( (prevState) => ({ ajustSore : update(prevState.ajustSore, {[index]: { inputSore: {$set: value},setTip:{$set: ""}}}) }) ) } } changeScoreReasons=(e,id)=>{ // console.log(e.target.value); // this.setState({ // setScoreReason:e.target.value // }) let value = e.target.value; let { ajustSore } = this.state; var index = ajustSore.map(function (item) { return item.id; }).indexOf(id); this.setState( (prevState) => ({ ajustSore : update(prevState.ajustSore, {[index]: { desc: {$set: value}}}) }) ) } //确认调分 setAction=(key,q_id,maxScore,oldScore)=>{ let {ajustSore}=this.state; let list = ajustSore.filter(obj => obj.id == q_id); let index = ajustSore.map(function (item) { return item.id; }).indexOf(q_id); let score = list[0].inputSore; let setScoreReason = list[0].desc; let{ setTip }=this.state; if(!score && score != 0){ // this.setState({ // setTip:"请输入分数" // }) this.setState( (prevState) => ({ ajustSore : update(prevState.ajustSore, {[index]: { setTip: {$set: "请输入分数"}}}) }) ) return; } if(score < 0){ // this.setState({ // setTip:"分数必须大于或者等于0" // }) this.setState( (prevState) => ({ ajustSore : update(prevState.ajustSore, {[index]: { setTip: {$set: "分数必须大于或者等于0"}}}) }) ) return; } if(score > maxScore){ // this.setState({ // setTip:"分数不能大于当前题目的分数" // }) this.setState( (prevState) => ({ ajustSore : update(prevState.ajustSore, {[index]: { setTip: {$set: "分数不能大于当前题目的分数"}}}) }) ) return; } if(setTip==""){ let url=`/exercise_questions/${q_id}/adjust_score.json` axios.post((url),{ score:score, user_id:this.state.Id, comment:setScoreReason }).then((result)=>{ if(result.status==200){ this.props.showNotification('调分成功'); this.getInfo(); // let statusScore = score==0 ? 0 : score > 0 && score < maxScore ? 2 : 1; // this.setState( // (prevState) => ({ // exercise_questions : update(prevState.exercise_questions, {[key]: { user_score: {$set: parseFloat(score).toFixed(1)},answer_status : {$set: statusScore},question_comments:{$set:result.data.question_comments} }}), // }) // ) // this.setState( // (prevState) => ({ // ajustSore : update(prevState.ajustSore, {[index]: { desc: {$set: undefined},inputSore:{ $set:undefined }}}) // }) // ) // let {exerciseTotalScore} = this.state; // let newScore = parseFloat(parseFloat(exerciseTotalScore)+parseFloat(score)-parseFloat(oldScore)).toFixed(1); // this.setState({ // exerciseTotalScore:newScore // }) // this.showSetScore(key,true); } }).catch((error)=>{ console.log(error); }) } } // 选择题,切换答案 changeOption = (index,ids) =>{ //console.log(index+" "+ids); this.setState( (prevState) => ({ exercise_questions : update(prevState.exercise_questions, {[index]: { user_answer: {$set: ids} }}), }) ) } //简答题 显示和隐藏答案 changeA_flag=(index,status)=>{ this.setState( (prevState) => ({ exercise_questions : update(prevState.exercise_questions, {[index]: { a_flag: {$set: status} }}) }) ) } //交卷和保存前判断是否有题未答 checkExerciseNumber=(index)=>{ let url= `/exercises/${this.props.match.params.Id}/begin_commit.json`; axios.get(url).then((result)=>{ if(result){ if(result.data.question_undo !=0 || result.data.shixun_undo !=0) { let tip=""; if(result.data.question_undo !=0 && result.data.shixun_undo !=0){ tip =`有 ${result.data.question_undo} 题未答,${result.data.shixun_undo} 实训未通关`; }else if(result.data.question_undo !=0 && result.data.shixun_undo ==0){ tip =`有 ${result.data.question_undo} 题未答`; }else if(result.data.question_undo ==0 && result.data.shixun_undo !=0){ tip =`有 ${result.data.shixun_undo} 实训未通关`; } this.setState({ Modalstype:true, Modalstopval:tip, modalsBottomval:index === 0 ? `在${moment(result.data.end_time).format(format)}之前,允许修改答题` : `提交后无法再修改答题,是否确认提交?`, ModalCancel:this.cancelCommit, ModalSave:()=>this.sureCommitOrSave(index), Loadtype:index === 0 ? true :false }) }else{ this.setState({ Modalstype:true, Modalstopval:index === 0 ? `在${moment(result.data.end_time).format(format)}之前,允许修改答题` : `提交后无法再修改答题,是否确认提交?`, modalsBottomval:undefined, ModalCancel:this.cancelCommit, ModalSave:()=>this.sureCommitOrSave(index), Loadtype:index === 0 ? true :false }) } } }).catch((error)=>{ console.log(error); }) } //交卷 commitExercise=()=>{ this.checkExerciseNumber(1); } //保存 saveExercise=()=>{ this.checkExerciseNumber(0); } //确认交卷或者保存 sureCommitOrSave=(index)=>{ if(index===0){ //确认保存 this.cancelCommit(); this.sureCommit(); }else{ //交卷 let eId=this.props.match.params.Id; let url=`/exercises/${eId}/commit_exercise.json`; axios.post(url,{ commit_method:1 }).then((result)=>{ if(result){ this.setState({ Modalstype:false, Modalstopval:undefined, modalsBottomval:undefined, ModalCancel:undefined, ModalSave:undefined, Loadtype:undefined }) this.props.showNotification(`${result.data.message}`); this.getInfo(); } }).catch((error)=>{ console.log(error); }) } } cancelCommit=()=>{ this.setState({ Modalstype:false, Modalstopval:undefined, modalsBottomval:undefined, ModalCancel:undefined, ModalSave:undefined, Loadtype:undefined }) } // 打回重做 RepeatExercise=()=>{ let status=parseInt(this.state.exercise.exercise_status); if(status === 3){ this.setState({ Modalstype:true, Modalstopval:'截止时间已到,无法打回试卷', modalsBottomval:'请在修改截止时间后再操作', ModalCancel:this.cancelCommit, ModalSave:this.cancelCommit, Loadtype:true }) }else{ this.setState({ Modalstype:true, Modalstopval:'学生将得到一次重新答题的机会,现有的答题情况将被清空', modalsBottomval:'是否确认回退TA的试卷答题', ModalCancel:this.cancelCommit, ModalSave:this.sureRepeatExercise, Loadtype:false }) } } sureRepeatExercise=()=>{ let eId=this.props.match.params.Id; let user_id=this.state.Id; let url=`/exercises/${eId}/redo_exercise.json` axios.post((url),{ user_ids:[user_id] }).then((result)=>{ if(result){ this.props.showNotification(`${result.data.message}`); //打回重做后跳转到答题列表页 this.sureCommit(); } }).catch((error)=>{ console.log(error); }) } // 返回 returnBtn = () =>{ let coursesId=this.props.match.params.coursesId; let eId=this.props.match.params.Id; this.props.history.push(`/courses/${coursesId}/exercises/${eId}/student_exercise_list?tab=0`) } render(){ let coursesId=this.props.match.params.coursesId; let eId=this.props.match.params.Id; let{ data, questionPanelFixed, courseName, exercise, exercise_types, exercise_start_at, exercise_scores, exercise_questions, user_exercise_status,//试卷是否可以编辑 exercise_answer_user, question_status, score, setScoreReason, setTip, time, hour, minute, second, Modalstype, Modalstopval, modalsBottomval, ModalCancel, ModalSave, Loadtype, exerciseTotalScore, isSpin, ajustSore }=this.state let isAdmin = this.props.isAdmin(); let isStudent =this.props.isStudent(); const { current_user } = this.props // console.log(data&&data.exercise.user_name) return(
{/*

*/}

{courseName} > {data && data.left_banner_name} > {data && data.left_banner_name}详情> {exercise_answer_user&&exercise_answer_user.user_name}{data&&data.exercise.user_name}

{exercise && exercise.exercise_name} { (isAdmin || ( isStudent && exercise && user_exercise_status == 1)) ? 返回 : time && time != 0 ?

  • { hour >= 10 ? hour : '0'+hour}
  • :
  • { minute >= 10 ? minute : '0'+minute}
  • :
  • { second >= 10 ? second : '0'+second}
  • :"" } { isAdmin && 打回重做 }

    { exercise && exercise.exercise_description &&

    {exercise.exercise_description}

    }

    { exercise_types && exercise_types.q_singles > 0 && 单选题 {exercise_types.q_singles} 题,共 {exercise_types && exercise_types.q_singles_scores} 分 } { exercise_types && exercise_types.q_doubles > 0 && 多选题 {exercise_types.q_doubles} 题,共 {exercise_types && exercise_types.q_doubles_scores} 分 } { exercise_types && exercise_types.q_judges > 0 && 判断题 {exercise_types.q_judges} 题,共 {exercise_types && exercise_types.q_judges_scores} 分 } { exercise_types && exercise_types.q_nulls > 0 && 填空题 {exercise_types.q_nulls} 题,共 {exercise_types && exercise_types.q_nulls_scores} 分 } { exercise_types && exercise_types.q_mains > 0 && 简答题 {exercise_types.q_mains} 题,共 {exercise_types && exercise_types.q_mains_scores} 分 } { exercise_types && exercise_types.q_shixuns > 0 && 实训题 {exercise_types.q_shixuns} 题,共 {exercise_types && exercise_types.q_shixuns_scores} 分 } {exercise_types &&exercise_types.q_scores} 合计 {exercise_types &&exercise_types.q_counts} 题:

    { exercise_start_at && 开始答题时间:{ exercise_start_at && moment(exercise_start_at).format(format) } } { (isAdmin || (isStudent && exercise && exercise.exercise_status == 3)) && exerciseTotalScore && 总分: { exerciseTotalScore } } { // 老师身份 || 学生身份且试卷已经截止 (isAdmin || (isStudent && exercise && exercise.exercise_status == 3)) &&
    { exercise_scores && exercise_scores.objective_scores && exercise_scores.objective_scores.length > 0 &&

    客观题 正确 错误 部分得分

    } { exercise_scores && exercise_scores.subjective_scores.length > 0 &&

    主观题 已评 未评

    }
    } { //学生身份 且试卷还未截止 isStudent && exercise && exercise.exercise_status == 2 ?

    已答 未答

    :"" }
    {/* 试卷题目 */}
    { exercise_questions && exercise_questions.map((item,key)=>{ let list = ajustSore && ajustSore.filter(obj => obj.id === item.question_id); return(

    {item.q_position}、{type[item.question_type]}({item.question_score}分) { // 填空(一直都有调分),和简答题调分:老师身份 已经评分的才能出现调分按钮 isAdmin && ((parseInt(item.answer_status) != 0 && item.question_type == 4) || item.question_type == 3 || item.question_type == 1) ? this.showSetScore(key,item.setScore,item.q_position,item.question_type,item.question_id)}>调分:"" } { // 简答题,未评分的显示未批 isAdmin && parseInt(item.answer_status) == 0 && item.question_type == 4 ? 未批:"" } { // 客观题:老师||学生(试卷已截止且答案公开)显示正确答案 item.question_type < 3 && item.standard_answer_show ? 正确答案:{ item.standard_answer_show } :"" } { //(老师身份且除实训题外) || (学生身份且试卷已经截止)就显示用户当前题目所得分数 ( isAdmin || (isStudent && exercise.exercise_status == 3)) && item.question_type != 5 && item.user_score ? {item.user_score} : "" } { //实训题 ,答题 item.question_type == 5 && 实训详情 }

  • {/*

    */}
  • { // 选择题和判断题共用 (item.question_type == 0 || item.question_type == 2) && this.changeOption(index,ids)} changeQuestionStatus={(No,flag)=>this.changeQuestionStatus(No,flag)} index={key} > } { // 多选题 item.question_type == 1 && this.changeOption(index,ids)} changeQuestionStatus={(No,flag)=>this.changeQuestionStatus(No,flag)} index={key} > } { // 填空题 item.question_type == 3 && this.changeQuestionStatus(No,flag)} index={key} > } { // 简答题 item.question_type == 4 && this.changeQuestionStatus(No,flag)} changeA_flag={(index,status)=>this.changeA_flag(index,status)} index={key} > } { // 实训题 item.question_type == 5 && } { //调分理由部分 item.question_comments && item.question_comments.comment && (item.question_type == 3 || item.question_type == 4 || item.question_type == 1) &&
  • {item.question_comments.user_name} {moment(item.question_comments.updated_at).format(format)}
  • {item.question_comments.comment}
  • } { // 调分输入部分 isAdmin && ((item.setScore && item.question_type == 3) || (item.setScore && item.question_type == 1) || ((item.setScore || parseInt(item.answer_status) == 0) && item.question_type == 4))?
    *调分:
  • 0 && list[0].inputSore} step={0.1} precision={1} className={ list && list.length>0 && list[0].setTip !="" ? "edu-txt-center winput-115-40 fl mt3 noticeTip inputNumber30" : "edu-txt-center winput-115-40 fl mt3 inputNumber30"} onChange={(value)=>this.inputScore(value,item.question_id)} id={`${"input_"+item.q_position+"_"+item.question_type}`} > { parseInt(item.answer_status) == 0 && item.question_type == 4 ? 未评分 : '' } this.setAction(key,item.question_id,item.question_score,item.user_score)}>确认

    { list && list.length > 0 && list[0].setTip !="" ?

    { list[0].setTip }

    :"" }
  • :"" }
    ) }) }
    { isStudent && user_exercise_status == 0 ?

    交卷 保存 { exercise && time != null ? 保存或者离开页面后,系统将持续计时,到达时长系统将自动交卷 :"" }

    :"" }
    ) } } export default ExerciseReviewAndAnswer